⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bbu_codec.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 4 页
字号:

        stmfd   sp!,    {r1-r7,lr}      ; Save used registers

        bl      BBU_TSI_LIFT    ; Get user command from touch screen
        mov     r5,     r1      ; Copy Y data to r5
;
;       When the code gets here, it means the user has touched the LCD and
;       lifted the pen (or stylus, or finger). Now the code will figure out
;       if the last point touched falls within a previously defined box that
;       was drawn on the LCD using the BBU_LCD_TBOX subroutine.
;
;       The first step is convert the touch panel data into pixel location
;       data based on the current configuraqtion of the LCD. For the Littleton
;       the ideal touch panel data would come back as follows:
;
;         FF,00 +---------+ 00,00 (X,Y)
;               |         |
;               |         |
;               |         |  X,Y data in hex format
;               |         |  X data is in r4 (0-255)
;               |   LCD   |  Y data is in r5 (0-255)
;               |         |
;               |         |
;               |         |
;               |         |
;         FF,FF +---------+ 00,FF
;
;       BBU "flips" the X data so 00 is on the left and FF is on the right.
;
;       BBU uses the touch panel calibration data to provide more accurate
;       feedback on the location the user touched on the panel. the general
;       formula used is:
;
;       pos = PW * (upos-LL) / (UL - LL)
;
;       Or, The position (pos) in pixels = the pixel width times the reported
;       user position (upos) minus the lower calibration limit (LL), all divided
;       by the upper calibration limit (UL) minus the lower limit (LL).
;
        mov     r2,     #0xFF           ; Prepare to flip the X data
        sub     r4,     r2,     r0      ; Flip the X data and place in r4
        ldr     r2,     =BBU_LCD_TYPE   ; Address where LCD type is kept
        ldrb    r3,     [r2]            ; Get the LCD type
        ands    r3,     r3,     #0x01   ; Is it in VGA mode?
	movne   r1,     #240            ; No - QVGA X multiplier
	movne   r2,     #320            ; No - QVGA Y multiplier
	moveq   r1,     #480            ; Yes - VGA X multiplier
	moveq   r2,     #620            ; Yes - VGA Y multiplier
;
;       Calculate X position
;
        ldr     r6,     =BBU_TCAL_DATA  ; Location of calibration data
        ldr     r3,     [r6]            ; Fetch X min/max values
        mov     r7,     r3,     LSR #16 ; Load X min value into r7
        sub     r4,     r4,     r7      ; r4 = upos - LL for X position
        mul     r0,     r4,     r1      ; r4 = X pixel location before division
        and     r3,     r3,     #0xFF   ; Mask out max X calibration data
        subs    r1,     r3,     r7      ; r1 = UL - LL
;
;       Ready to divide, but first we need to use the Y pixel width data in r2
;       to free up this register for the divide routine. 
;
        ldr     r4,     [r6, #4]        ; Fetch Y min/max values
        mov     r6,     r4,     LSR #16 ; Load Y min value into r6
        sub     r5,     r5,     r6      ; r5 = upos - LL for Y position
        mul     r5,     r5,     r2      ; r5 = Y pixel location before division
        bl      BBU_U32Divide           ; Divide to get the X pixel location in r2
        mov     r0,     r5              ; Move Y data into r0 for division
        and     r4,     r4,     #0xFF   ; get Y max value in r4
        sub     r1,     r4,     r6      ; Generate divisor for Y position in r1
        mov     r4,     r2              ; Save calculated X pixel position in r4
        bl      BBU_U32Divide           ; Divide to get the Y pixel location in r2
        mov     r5,     r2              ; Save this result in r5
;
;       r4 now equals the estimated X location of the pixel
;       r5 now equals the estimated Y location of the pixel
;
;       Now the code looks at the touch box data to see if this location can
;       be matched up with a box. The r4/r5 data must be greater than the
;       location of the upper left corner of the box AND less then the location
;       of the lower right corner of the box in order to get a match.
;
        ldr     r1,     =TBOX_ARR       ; Touch Box data array
        ldr     r0,     =0xFFFF         ; End of array marker
        mov     r6,     #0              ; Set box number to zero
476     ldr     r2,     [r1, #4]        ; Get lower right data
        cmp     r2,     r0              ; End of array?
        moveq   r0,     #0xFF           ; Yes - no match found
        beq     %F479                   ; ...and exit
        cmp     r2,     #0              ; Is this data = zero
        bne     %F478                   ; No - skip to compare code
        add     r1,     r1,     #8      ; Yes - point to next array entry
        b       %B476                   ; And get another entry
;
;       Non-zero table entry found - Do the compare on the upper left corner
;
478     ldr     r2,     [r1],   #4      ; Fetch upper left corner data
        and     r3,     r2,     r0      ; Extract the Y data into r3
        cmp     r3,     r5              ; Is the user pixel "below" this value?
        addgt   r1,     r1,     #4      ; No - point to next array entry
        addgt   r6,     r6,     #1      ; Increment box counter
        bgt     %B476                   ; ...and get next array entry
        mov     r3,     r2,     LSR #16 ; r2 = X location of upper left corner
        cmp     r3,     r4              ; Is the user pixel to the right?
        addgt   r1,     r1,     #4      ; No - point to next array entry
        addgt   r6,     r6,     #1      ; Increment box counter
        bgt     %B476                   ; ...and get next array entry
;
;       If the code got here the user pixel is below and to the right of the
;       top left corner of this box. Test to see if it's above and to the left
;       of the bottom right corner.
;
        ldr     r3,     [r1],   #4      ; Fetch the lower right corner data
        add     r2,     r2,     r3      ; Calculate pixel location of LR corner
        and     r3,     r2,     r0      ; Extract the Y data into r3
        cmp     r3,     r5              ; Compare to the user Y pixel data
        addlt   r6,     r6,     #1      ; Not valid - increment box counter
        blt     %B476                   ; ...and get next box entry
        mov     r2,     r2,     LSR #16 ; r2 = X location of lower right corner
        cmp     r2,     r4              ; Is the user pixel to the left?
        addlt   r6,     r6,     #1      ; No - increment box counter
        blt     %B476                   ; ...and get next box entry
;
;       We have a match - return box count to the caller in r0
;
        mov     r0,     r6
479     ldmfd   sp!,    {r1-r7,pc}     ; Return to caller
        ENDFUNC
;
;*******************************************************************************
;
;       ******************
;       *                * 
;       * BBU_CODEC_TCAL * Subroutine
;       *                *
;       ******************
;
;       This subroutine is used to calibrate the touch panel on the LCD
;
; PARAMETER PASSING:
;
;       INPUT:
;
;          None
;
;       OUTPUT:
;
;          none (However, the touch screen calibration data is updated)
;
BBU_CODEC_TCAL  FUNCTION

        stmfd   sp!,    {r0-r6,lr}      ; Save used registers
        ldr     r0,     =BBU_TCAL_UD1   ; User directions
        bl      BBU_putstr              ; Output to the user

        mov     r0,     #0x7E0          ; Set the LCD background color to GREEN
        bl      BBU_LCD_COLOR           ; Update the LCD
        mov     r0,     #15             ; Row 15
        mov     r1,     #2              ; Column 6
        ldr     r2 ,    =BBU_TCAL_MSG   ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
        ldr     r4,     =BBU_TCAL_DATA  ; Calibration data saved here
;
;       Display upper left calibration point
;
        mov     r0,     #0              ; Row 0
        mov     r1,     #0              ; Column 0
        ldr     r2 ,    =BBU_TCAL_PLUS  ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
        bl      BBU_TSI_LIFT            ; Get user command from touch screen
; 
;       Save upper left calibation data
;
        mov     r0,     r0,     LSL #16 ; Move X data 16 bits to the left
        orr     r0,     r0,     r1      ; Load Y data into the bottom 16 bits
        str     r0,     [r4],   #4      ; Save data & increment pointer
;
;       Display upper right calibration point
;
        mov     r0,     #0              ; Row 0
        mov     r1,     #0              ; Column 0
        ldr     r2 ,    =BBU_TCAL_BLANK ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD

        mov     r0,     #0              ; Row 0
        mov     r1,     #29             ; Column 29
        ldr     r2 ,    =BBU_TCAL_PLUS  ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
        bl      BBU_TSI_LIFT            ; Get user command from touch screen
; 
;       Save upper right calibation data
;
        mov     r0,     r0,     LSL #16 ; Move X data 16 bits to the left
        orr     r0,     r0,     r1      ; Load Y data into the bottom 16 bits
        str     r0,     [r4],   #4      ; Save data & increment pointer
;
;       Display lower left calibration point
;
        mov     r0,     #0              ; Row 0
        mov     r1,     #29             ; Column 29
        ldr     r2 ,    =BBU_TCAL_BLANK ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD

        mov     r0,     #31             ; Row 31
        mov     r1,     #0              ; Column 0
        ldr     r2 ,    =BBU_TCAL_PLUS  ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
        bl      BBU_TSI_LIFT            ; Get user command from touch screen
; 
;       Save lower left calibation data
;
        mov     r0,     r0,     LSL #16 ; Move X data 16 bits to the left
        orr     r0,     r0,     r1      ; Load Y data into the bottom 16 bits
        str     r0,     [r4],   #4      ; Save data & increment pointer
;
;       Display lower right calibration point
;
        mov     r0,     #31             ; Row 31
        mov     r1,     #0              ; Column 0
        ldr     r2 ,    =BBU_TCAL_BLANK ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD

        mov     r0,     #31             ; Row 31
        mov     r1,     #29             ; Column 29
        ldr     r2 ,    =BBU_TCAL_PLUS  ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
        bl      BBU_TSI_LIFT            ; Get user command from touch screen
; 
;       Save lower right calibation data
;
        mov     r0,     r0,     LSL #16 ; Move X data 16 bits to the left
        orr     r0,     r0,     r1      ; Load Y data into the bottom 16 bits
        str     r0,     [r4]            ; Save data
;
;       Inform user the calibration is done
;
        mov     r0,     #31             ; Row 31
        mov     r1,     #29             ; Column 29
        ldr     r2 ,    =BBU_TCAL_BLANK ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD

        mov     r0,     #15             ; Row 15
        mov     r1,     #2              ; Column 6
        ldr     r2 ,    =BBU_TCAL_DONE  ; Message to LCD
        bl      BBU_LCD_put16x20str     ; Send to LCD
;
;       At this point there are 4 pairs of X,Y data in the data array. BBU will
;       compute the average values of the max/min X, Y values by averaging the
;       max and min X Y values and reload the array with this data so the the
;       min/max value for the X value is in the first doubleword and the min/max
;       value for the Y value is in the second doubleword. the data is currently
;       arranged in the array as follows:
;
;                bits:    31:16     15:0
;                       +--------+--------+
;       Upper Left (UL) | X data | Y Data |  BBU_TCAL_DATA + 0x0
;                       +--------+--------+
;       Upper Right(UR) | X data | Y Data |  BBU_TCAL_DATA + 0x4
;                       +--------+--------+
;       Lower Left (LL) | X data | Y Data |  BBU_TCAL_DATA + 0x8
;                       +--------+--------+
;       Lower Right(LR) | X data | Y Data |  BBU_TCAL_DATA + 0xC
;                       +--------+--------+
;
        ldr     r4,     =BBU_TCAL_DATA  ; Calibration data saved here

        ldr     r0,     [r4, #0x4]      ; Fetch UR data
        ldr     r1,     [r4, #0xC]      ; Fetch LR data
        add     r0,     r0,     r1      ; Add the min X values in bits 31:16
        mov     r0,     r0,     LSR #1          ; divide by 2
        and     r0,     r0,     #0xFF0000       ; Mask out all other data

        ldr     r1,     [r4, #0x0]      ; Fetch UL data
        ldr     r2,     [r4, #0x8]      ; Fetch LL data
        add     r1,     r1,     r2      ; Add the max X values in bits 31:16
        mov     r1,     r1,     LSR #17 ; divide by 2 & shift to bits 15:0
        and     r1,     r1,     #0xFF   ; Mask out all other data
        orr     r0,     r0,     r1      ; r0 = average min/max X data

        ldr     r1,     [r4, #0x0]      ; Fetch UL data
        ldr     r2,     [r4, #0x4]      ; Fetch UR data
        add     r1,     r1,     r2      ; Add the min Y values in bits 15:0
        mov     r1,     r1,     LSR #1  ; divide by 2
        and     r1,     r1,     #0xFF   ; Mask out all other data
        mov     r1,     r1,     LSL #16 ; Move min value to bits 31:16

        ldr     r2,     [r4, #0x8]      ; Fetch LL data
        ldr     r3,     [r4, #0xC]      ; Fetch LR data
        add     r2,     r2,     r3      ; Add the max Y values in bits 15:0
        mov     r2,     r2,     LSR #1  ; Divide by 2
        and     r2,     r2,     #0xFF   ; Mask out unwanted data
        orr     r1,     r1,     r2      ; R1 = average min/max Y data

        str     r0,     [r4]            ; Save ave min/max X value
        str     r1,     [r4, #4]        ; Save ave min/max Y value
;
;       The array now contains the following data:
;
;                bits:    31:16     15:0
;                       +--------+--------+
;       Average X data  |  X min |  X max |  BBU_TCAL_DATA + 0x0 (updated)
;                       +--------+--------+
;       Average Y data  |  Y min |  Y max |  BBU_TCAL_DATA + 0x4 (updated)
;                       +--------+--------+
;       Lower Left (LL) | X data | Y Data |  BBU_TCAL_DATA + 0x8 (unchanged)
;                       +--------+--------+
;       Lower Right(LR) | X data | Y Data |  BBU_TCAL_DATA + 0xC (unchanged)
;                       +--------+--------+
;
;       The average X, Y data will be used to estimate the point on the LCD that
;       was touched. The lower left/right data (above) is simply ingnored.
;
499     ldmfd   sp!,    {r0-r6,pc}      ; Return to caller
;
;       TCAL Messages
;
BBU_TCAL_UD1    DCB     0xD,0xA,"               TOUCH PANEL CALIBRATION",0xD,0xA,0xA
                DCB     "  Touch each of the four plus signs (+) as they appear",0xD,0xA
                DCB     "  on the LCD to accuratly calibrate the touch panel to",0xD,0xA
                DCB     "  the LCD screen.",0xD,0xA,0xA,0
BBU_TCAL_PLUS   DCB     "+",0
BBU_TCAL_BLANK  DCB     " ",0
BBU_TCAL_MSG    DCB     "Touch the + in each corner.",0
BBU_TCAL_DONE   DCB     "     Calibration done!     ",0
        ALIGN   4
;
;       Touch panel calibration data below is the raw X,Y data from the four
;       corners of the touch panel. For all practical purposes, these values can
;       be assumed to be in the extreme corners of the display (the difference
;       between touching the center of the + in each corner and the LCD active
;       area corner may only change the value recorded by 1 or 2 bits)
;
BBU_TCAL_DATA   DCD     0,0,0,0 ; Touch panel calibration data
        ENDFUNC
        END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -