Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
arnoz
Date:
Fri Oct 01 08:19:46 2021 +0000
Revision:
116:7a67265d7c19
Parent:
82:4f6209cb5c33
- Correct information regarding your last merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 82:4f6209cb5c33 1 ; Edge detector scan mode 2
mjr 70:9f58735a1732 2 ; This is an assembly language implementation of "scan mode 2",
mjr 82:4f6209cb5c33 3 ; described more fully in edgeSensor.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 82:4f6209cb5c33 10 AREA edgeScanMode2_asm, CODE, READONLY
mjr 70:9f58735a1732 11
mjr 82:4f6209cb5c33 12 ; void edgeScanMode2(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 82:4f6209cb5c33 22 EXPORT edgeScanMode2
mjr 82:4f6209cb5c33 23 edgeScanMode2
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 73:4e8ce0b18915 101 BLT L0 ; then update minmax to current pixel
mjr 73:4e8ce0b18915 102
mjr 73:4e8ce0b18915 103 L0A ; update the window
mjr 73:4e8ce0b18915 104 LDRB R6, [R0] ; tmp = curpix[0]
mjr 73:4e8ce0b18915 105 ADD R4, R4, R6 ; leftSum -= curpix[-10], but the running total is
mjr 70:9f58735a1732 106 ; rightSum - leftSum, so ADD this to the running total
mjr 70:9f58735a1732 107
mjr 70:9f58735a1732 108 LDRB R6, [R0,#10] ; tmp = curpix[10]
mjr 73:4e8ce0b18915 109 SUBS R4, R4, R6 ; total -= curpix[10] (subtract from right sum)
mjr 73:4e8ce0b18915 110 SUBS R4, R4, R6 ; total -= curpix[10] (add to left sum -> subtract from total)
mjr 70:9f58735a1732 111
mjr 70:9f58735a1732 112 LDRB R6, [R0,#20] ; tmp = curpix[20]
mjr 70:9f58735a1732 113 ADDS R4, R4, R6 ; rightSum += curPix[20]
mjr 70:9f58735a1732 114
mjr 70:9f58735a1732 115 ; increment the index and loop
mjr 70:9f58735a1732 116 ADDS R0, R0, #1 ; curPix++
mjr 70:9f58735a1732 117 CMPS R0, R1 ; if curPix <= endPix
mjr 73:4e8ce0b18915 118 BLS ForwardScan ; then loop
mjr 73:4e8ce0b18915 119 B Done ; else return
mjr 70:9f58735a1732 120
mjr 73:4e8ce0b18915 121 L0 ; update min/max to current pixel
mjr 73:4e8ce0b18915 122 MOVS R5, R4 ; minmax = slope
mjr 73:4e8ce0b18915 123 MOVS R3, R0 ; minmaxIdx = curpix
mjr 73:4e8ce0b18915 124 B L0A ; resume loop
mjr 70:9f58735a1732 125
mjr 70:9f58735a1732 126 ; Reverse scan: scanning from dark end to bright end, so look for
mjr 70:9f58735a1732 127 ; steepest positive slope
mjr 70:9f58735a1732 128 ReverseScan
mjr 70:9f58735a1732 129 CMPS R4, R5 ; if slope > minmax
mjr 73:4e8ce0b18915 130 BGT L1 ; then update minmax to current pixel
mjr 73:4e8ce0b18915 131
mjr 73:4e8ce0b18915 132 L1A ; update the window
mjr 70:9f58735a1732 133 LDRB R6, [R0,#0] ; tmp = curpix[0]
mjr 70:9f58735a1732 134 ADDS R4, R4, R6 ; leftSum -= curpix[-10], but the running total is
mjr 70:9f58735a1732 135 ; rightSum - leftSum, so ADD this to the running total
mjr 70:9f58735a1732 136
mjr 70:9f58735a1732 137 LDRB R6, [R0,#10] ; tmp = curpix[10]
mjr 73:4e8ce0b18915 138 SUBS R4, R4, R6 ; total -= curpix[10] (subtract from right sum)
mjr 73:4e8ce0b18915 139 SUBS R4, R4, R6 ; total -= curpix[10] (add to left sum -> subtract from total)
mjr 70:9f58735a1732 140
mjr 70:9f58735a1732 141 LDRB R6, [R0,#20] ; tmp = curpix[20]
mjr 70:9f58735a1732 142 ADDS R4, R4, R6 ; rightSum += curPix[20]
mjr 70:9f58735a1732 143
mjr 70:9f58735a1732 144 ; increment the index and loop
mjr 70:9f58735a1732 145 ADDS R0, R0, #1 ; curPix++
mjr 70:9f58735a1732 146 CMPS R0, R1 ; if curPix <= endPix
mjr 73:4e8ce0b18915 147 BLS ReverseScan ; then loop
mjr 73:4e8ce0b18915 148 B Done ; else return
mjr 70:9f58735a1732 149
mjr 73:4e8ce0b18915 150 L1 ; update min/max with current pixel
mjr 73:4e8ce0b18915 151 MOVS R5, R4 ; minmax = slope
mjr 73:4e8ce0b18915 152 MOVS R3, R0 ; minmaxIdx = curpix
mjr 73:4e8ce0b18915 153 B L1A ; resume loop
mjr 73:4e8ce0b18915 154
mjr 70:9f58735a1732 155 Done
mjr 70:9f58735a1732 156 ; presume failure - return false
mjr 70:9f58735a1732 157 MOVS R0, #0
mjr 70:9f58735a1732 158
mjr 70:9f58735a1732 159 ; if we found an edge, adjust the index for the window offset
mjr 70:9f58735a1732 160 CMPS R5, #0 ; if minmax != 0, we found an edge
mjr 70:9f58735a1732 161 BEQ L2 ; nope, no edge
mjr 70:9f58735a1732 162 ADDS R3, #10 ; add the pixel window offset
mjr 70:9f58735a1732 163 STR R3, [R2] ; store the result in *edgep
mjr 70:9f58735a1732 164 MOVS R0, #1 ; return true
mjr 70:9f58735a1732 165
mjr 70:9f58735a1732 166 L2
mjr 70:9f58735a1732 167 ; done - pop registers and return
mjr 70:9f58735a1732 168 LDMFD R13!, {R4-R6,PC}
mjr 70:9f58735a1732 169
mjr 70:9f58735a1732 170 END