Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Tue Jan 03 23:31:59 2017 +0000
Revision:
70:9f58735a1732
Child:
73:4e8ce0b18915
Reboot after timeout on initial connect; CCD sensor scan method #2 assembly version for faster processing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 70:9f58735a1732 1 ; CCD sensor scan mode 2
mjr 70:9f58735a1732 2 ; This is an assembly language implementation of "scan mode 2",
mjr 70:9f58735a1732 3 ; described more fully in ccdSensor.h. This scan mode searches
mjr 70:9f58735a1732 4 ; for the steepest edge in the pixel array, averaging over a few
mjr 70:9f58735a1732 5 ; pixels on each side of the edge. The assembly version is
mjr 70:9f58735a1732 6 ; necessary because the best C++ implementation I can come up
mjr 70:9f58735a1732 7 ; with is too slow (about 12ms run time); this assembly version
mjr 70:9f58735a1732 8 ; runs in about 1.5ms.
mjr 70:9f58735a1732 9
mjr 70:9f58735a1732 10 AREA ccdScanMode2_asm, CODE, READONLY
mjr 70:9f58735a1732 11
mjr 70:9f58735a1732 12 ; void ccdScanMode2(const uint8_t *pix, int npix, const uint8_t **edgep, int dir)
mjr 70:9f58735a1732 13 ; R0 = pix = pointer to first byte of pixel array
mjr 70:9f58735a1732 14 ; R1 = npix = number of pixels in the array
mjr 70:9f58735a1732 15 ; R2 = edgep = filled in with pixel index of best edge on return,
mjr 70:9f58735a1732 16 ; or null if no edge was found
mjr 70:9f58735a1732 17 ; R3 = dir = direction: 1 = bright region starts at first pixel,
mjr 70:9f58735a1732 18 ; -1 = bright region starts at last pixel
mjr 70:9f58735a1732 19 ;
mjr 70:9f58735a1732 20 ; Note: arguments passed in R0, R1,... per ARM conventions.
mjr 70:9f58735a1732 21
mjr 70:9f58735a1732 22 EXPORT ccdScanMode2
mjr 70:9f58735a1732 23 ccdScanMode2
mjr 70:9f58735a1732 24
mjr 70:9f58735a1732 25 ; save used registers plus return link
mjr 70:9f58735a1732 26 STMFD R13!, {R4-R6,LR}
mjr 70:9f58735a1732 27
mjr 70:9f58735a1732 28 ; set up registers:
mjr 70:9f58735a1732 29 ; R0 = current pixel index
mjr 70:9f58735a1732 30 ; R1 = end pixel index
mjr 70:9f58735a1732 31 ; R4 = running total
mjr 70:9f58735a1732 32 ; R5 = minmax so far
mjr 70:9f58735a1732 33 ; R6 = tmp (scratch register)
mjr 70:9f58735a1732 34 ADDS R1, R0, R1 ; endPix = pix + npix
mjr 70:9f58735a1732 35 SUBS R1, R1, #20 ; endPix -= pixel window size * 2
mjr 70:9f58735a1732 36 MOVS R5, #0 ; minmax = 0
mjr 70:9f58735a1732 37 STR R5, [R2] ; *edgep = null - no edge found yet
mjr 70:9f58735a1732 38
mjr 70:9f58735a1732 39 ; Figure sum(right window pixels) - sum(left window pixels).
mjr 70:9f58735a1732 40 ; We'll this as a running total. On each iteration, we'll
mjr 70:9f58735a1732 41 ; subtract the outgoing left pixel (because it comes out of
mjr 70:9f58735a1732 42 ; the positive left sum), add the pixel on the border (since
mjr 70:9f58735a1732 43 ; it's coming out of the negative right sum and going into the
mjr 70:9f58735a1732 44 ; positive left sum), and subtract the incoming right pixel
mjr 70:9f58735a1732 45 ; (since it's going into the negative right sum).
mjr 70:9f58735a1732 46
mjr 70:9f58735a1732 47 ; figure the right sum
mjr 70:9f58735a1732 48 LDRB R4, [R0,#10]
mjr 70:9f58735a1732 49 LDRB R6, [R0,#11]
mjr 70:9f58735a1732 50 ADDS R4, R4, R6
mjr 70:9f58735a1732 51 LDRB R6, [R0,#12]
mjr 70:9f58735a1732 52 ADDS R4, R4, R6
mjr 70:9f58735a1732 53 LDRB R6, [R0,#13]
mjr 70:9f58735a1732 54 ADDS R4, R4, R6
mjr 70:9f58735a1732 55 LDRB R6, [R0,#14]
mjr 70:9f58735a1732 56 ADDS R4, R4, R6
mjr 70:9f58735a1732 57 LDRB R6, [R0,#15]
mjr 70:9f58735a1732 58 ADDS R4, R4, R6
mjr 70:9f58735a1732 59 LDRB R6, [R0,#16]
mjr 70:9f58735a1732 60 ADDS R4, R4, R6
mjr 70:9f58735a1732 61 LDRB R6, [R0,#17]
mjr 70:9f58735a1732 62 ADDS R4, R4, R6
mjr 70:9f58735a1732 63 LDRB R6, [R0,#18]
mjr 70:9f58735a1732 64 ADDS R4, R4, R6
mjr 70:9f58735a1732 65 LDRB R6, [R0,#19]
mjr 70:9f58735a1732 66 ADDS R4, R4, R6
mjr 70:9f58735a1732 67
mjr 70:9f58735a1732 68 ; subtract the left sum
mjr 70:9f58735a1732 69 LDRB R6, [R0,#0]
mjr 70:9f58735a1732 70 SUBS R4, R4, R6
mjr 70:9f58735a1732 71 LDRB R6, [R0,#1]
mjr 70:9f58735a1732 72 SUBS R4, R4, R6
mjr 70:9f58735a1732 73 LDRB R6, [R0,#2]
mjr 70:9f58735a1732 74 SUBS R4, R4, R6
mjr 70:9f58735a1732 75 LDRB R6, [R0,#3]
mjr 70:9f58735a1732 76 SUBS R4, R4, R6
mjr 70:9f58735a1732 77 LDRB R6, [R0,#4]
mjr 70:9f58735a1732 78 SUBS R4, R4, R6
mjr 70:9f58735a1732 79 LDRB R6, [R0,#5]
mjr 70:9f58735a1732 80 SUBS R4, R4, R6
mjr 70:9f58735a1732 81 LDRB R6, [R0,#6]
mjr 70:9f58735a1732 82 SUBS R4, R4, R6
mjr 70:9f58735a1732 83 LDRB R6, [R0,#7]
mjr 70:9f58735a1732 84 SUBS R4, R4, R6
mjr 70:9f58735a1732 85 LDRB R6, [R0,#8]
mjr 70:9f58735a1732 86 SUBS R4, R4, R6
mjr 70:9f58735a1732 87 LDRB R6, [R0,#9]
mjr 70:9f58735a1732 88 SUBS R4, R4, R6
mjr 70:9f58735a1732 89
mjr 70:9f58735a1732 90 ; check which direction we're going
mjr 70:9f58735a1732 91 CMPS R3, #0
mjr 70:9f58735a1732 92 BLT ReverseScan
mjr 70:9f58735a1732 93
mjr 70:9f58735a1732 94 ; R3 is now available for other uses. Use it as the pointer to
mjr 70:9f58735a1732 95 ; the best result so far.
mjr 70:9f58735a1732 96
mjr 70:9f58735a1732 97 ; Forward scan: scanning from bright end to dark end, so look for
mjr 70:9f58735a1732 98 ; steepest negative slope
mjr 70:9f58735a1732 99 ForwardScan
mjr 70:9f58735a1732 100 CMPS R4, R5 ; if slope < minmax
mjr 70:9f58735a1732 101 BGE L0
mjr 70:9f58735a1732 102 MOVS R5, R4 ; ...then minmax = slope
mjr 70:9f58735a1732 103 MOVS R3, R0 ; ...and minmaxIdx = curpix
mjr 70:9f58735a1732 104 L0
mjr 70:9f58735a1732 105 ; update the window
mjr 70:9f58735a1732 106 LDRB R6, [R0,#0] ; tmp = curpix[0]
mjr 70:9f58735a1732 107 ADDS R4, R4, R6 ; leftSum -= curpix[-10], but the running total is
mjr 70:9f58735a1732 108 ; rightSum - leftSum, so ADD this to the running total
mjr 70:9f58735a1732 109
mjr 70:9f58735a1732 110
mjr 70:9f58735a1732 111 LDRB R6, [R0,#10] ; tmp = curpix[10]
mjr 70:9f58735a1732 112 MOVS R6, R6, LSL #1 ; tmp *= 2: we're subtracting the pixel from rightSum
mjr 70:9f58735a1732 113 ; and adding it to leftSum, but leftSum is negative in
mjr 70:9f58735a1732 114 ; the running total, so it's like we're subtracting it
mjr 70:9f58735a1732 115 ; twice, thus we double it
mjr 70:9f58735a1732 116 SUBS R4, R4, R6 ; running total -= curpix[10]*2
mjr 70:9f58735a1732 117
mjr 70:9f58735a1732 118 LDRB R6, [R0,#20] ; tmp = curpix[20]
mjr 70:9f58735a1732 119 ADDS R4, R4, R6 ; rightSum += curPix[20]
mjr 70:9f58735a1732 120
mjr 70:9f58735a1732 121 ; increment the index and loop
mjr 70:9f58735a1732 122 ADDS R0, R0, #1 ; curPix++
mjr 70:9f58735a1732 123 CMPS R0, R1 ; if curPix <= endPix
mjr 70:9f58735a1732 124 BLS ForwardScan ; loop
mjr 70:9f58735a1732 125
mjr 70:9f58735a1732 126 ; done
mjr 70:9f58735a1732 127 B Done
mjr 70:9f58735a1732 128
mjr 70:9f58735a1732 129 ; Reverse scan: scanning from dark end to bright end, so look for
mjr 70:9f58735a1732 130 ; steepest positive slope
mjr 70:9f58735a1732 131 ReverseScan
mjr 70:9f58735a1732 132 CMPS R4, R5 ; if slope > minmax
mjr 70:9f58735a1732 133 BLE L1
mjr 70:9f58735a1732 134 MOVS R5, R4 ; ...then minmax = slope
mjr 70:9f58735a1732 135 MOVS R3, R0 ; ...and minmaxIdx = curpix
mjr 70:9f58735a1732 136 L1
mjr 70:9f58735a1732 137 ; update the window
mjr 70:9f58735a1732 138 LDRB R6, [R0,#0] ; tmp = curpix[0]
mjr 70:9f58735a1732 139 ADDS R4, R4, R6 ; leftSum -= curpix[-10], but the running total is
mjr 70:9f58735a1732 140 ; rightSum - leftSum, so ADD this to the running total
mjr 70:9f58735a1732 141
mjr 70:9f58735a1732 142
mjr 70:9f58735a1732 143 LDRB R6, [R0,#10] ; tmp = curpix[10]
mjr 70:9f58735a1732 144 MOVS R6, R6, LSL #1 ; tmp *= 2: we're subtracting the pixel from rightSum
mjr 70:9f58735a1732 145 ; and adding it to leftSum, but leftSum is negative in
mjr 70:9f58735a1732 146 ; the running total, so it's like we're subtracting it
mjr 70:9f58735a1732 147 ; twice, thus we double it
mjr 70:9f58735a1732 148 SUBS R4, R4, R6 ; running total -= curpix[10]*2
mjr 70:9f58735a1732 149
mjr 70:9f58735a1732 150 LDRB R6, [R0,#20] ; tmp = curpix[20]
mjr 70:9f58735a1732 151 ADDS R4, R4, R6 ; rightSum += curPix[20]
mjr 70:9f58735a1732 152
mjr 70:9f58735a1732 153 ; increment the index and loop
mjr 70:9f58735a1732 154 ADDS R0, R0, #1 ; curPix++
mjr 70:9f58735a1732 155 CMPS R0, R1 ; if curPix <= endPix
mjr 70:9f58735a1732 156 BLS ReverseScan ; loop
mjr 70:9f58735a1732 157
mjr 70:9f58735a1732 158 Done
mjr 70:9f58735a1732 159 ; presume failure - return false
mjr 70:9f58735a1732 160 MOVS R0, #0
mjr 70:9f58735a1732 161
mjr 70:9f58735a1732 162 ; if we found an edge, adjust the index for the window offset
mjr 70:9f58735a1732 163 CMPS R5, #0 ; if minmax != 0, we found an edge
mjr 70:9f58735a1732 164 BEQ L2 ; nope, no edge
mjr 70:9f58735a1732 165 ADDS R3, #10 ; add the pixel window offset
mjr 70:9f58735a1732 166 STR R3, [R2] ; store the result in *edgep
mjr 70:9f58735a1732 167 MOVS R0, #1 ; return true
mjr 70:9f58735a1732 168
mjr 70:9f58735a1732 169 L2
mjr 70:9f58735a1732 170 ; done - pop registers and return
mjr 70:9f58735a1732 171 LDMFD R13!, {R4-R6,PC}
mjr 70:9f58735a1732 172
mjr 70:9f58735a1732 173 END