Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Plunger/edgeSensorScan2.s@116:7a67265d7c19, 2021-10-01 (annotated)
- 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?
User | Revision | Line number | New 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 |