Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Plunger/edgeSensorScan2.s
- Committer:
- arnoz
- Date:
- 2021-10-01
- Revision:
- 116:7a67265d7c19
- Parent:
- 82:4f6209cb5c33
File content as of revision 116:7a67265d7c19:
; Edge detector scan mode 2 ; This is an assembly language implementation of "scan mode 2", ; described more fully in edgeSensor.h. This scan mode searches ; for the steepest edge in the pixel array, averaging over a few ; pixels on each side of the edge. The assembly version is ; necessary because the best C++ implementation I can come up ; with is too slow (about 12ms run time); this assembly version ; runs in about 1.5ms. AREA edgeScanMode2_asm, CODE, READONLY ; void edgeScanMode2(const uint8_t *pix, int npix, const uint8_t **edgep, int dir) ; R0 = pix = pointer to first byte of pixel array ; R1 = npix = number of pixels in the array ; R2 = edgep = filled in with pixel index of best edge on return, ; or null if no edge was found ; R3 = dir = direction: 1 = bright region starts at first pixel, ; -1 = bright region starts at last pixel ; ; Note: arguments passed in R0, R1,... per ARM conventions. EXPORT edgeScanMode2 edgeScanMode2 ; save used registers plus return link STMFD R13!, {R4-R6,LR} ; set up registers: ; R0 = current pixel index ; R1 = end pixel index ; R4 = running total ; R5 = minmax so far ; R6 = tmp (scratch register) ADDS R1, R0, R1 ; endPix = pix + npix SUBS R1, R1, #20 ; endPix -= pixel window size * 2 MOVS R5, #0 ; minmax = 0 STR R5, [R2] ; *edgep = null - no edge found yet ; Figure sum(right window pixels) - sum(left window pixels). ; We'll this as a running total. On each iteration, we'll ; subtract the outgoing left pixel (because it comes out of ; the positive left sum), add the pixel on the border (since ; it's coming out of the negative right sum and going into the ; positive left sum), and subtract the incoming right pixel ; (since it's going into the negative right sum). ; figure the right sum LDRB R4, [R0,#10] LDRB R6, [R0,#11] ADDS R4, R4, R6 LDRB R6, [R0,#12] ADDS R4, R4, R6 LDRB R6, [R0,#13] ADDS R4, R4, R6 LDRB R6, [R0,#14] ADDS R4, R4, R6 LDRB R6, [R0,#15] ADDS R4, R4, R6 LDRB R6, [R0,#16] ADDS R4, R4, R6 LDRB R6, [R0,#17] ADDS R4, R4, R6 LDRB R6, [R0,#18] ADDS R4, R4, R6 LDRB R6, [R0,#19] ADDS R4, R4, R6 ; subtract the left sum LDRB R6, [R0,#0] SUBS R4, R4, R6 LDRB R6, [R0,#1] SUBS R4, R4, R6 LDRB R6, [R0,#2] SUBS R4, R4, R6 LDRB R6, [R0,#3] SUBS R4, R4, R6 LDRB R6, [R0,#4] SUBS R4, R4, R6 LDRB R6, [R0,#5] SUBS R4, R4, R6 LDRB R6, [R0,#6] SUBS R4, R4, R6 LDRB R6, [R0,#7] SUBS R4, R4, R6 LDRB R6, [R0,#8] SUBS R4, R4, R6 LDRB R6, [R0,#9] SUBS R4, R4, R6 ; check which direction we're going CMPS R3, #0 BLT ReverseScan ; R3 is now available for other uses. Use it as the pointer to ; the best result so far. ; Forward scan: scanning from bright end to dark end, so look for ; steepest negative slope ForwardScan CMPS R4, R5 ; if slope < minmax BLT L0 ; then update minmax to current pixel L0A ; update the window LDRB R6, [R0] ; tmp = curpix[0] ADD R4, R4, R6 ; leftSum -= curpix[-10], but the running total is ; rightSum - leftSum, so ADD this to the running total LDRB R6, [R0,#10] ; tmp = curpix[10] SUBS R4, R4, R6 ; total -= curpix[10] (subtract from right sum) SUBS R4, R4, R6 ; total -= curpix[10] (add to left sum -> subtract from total) LDRB R6, [R0,#20] ; tmp = curpix[20] ADDS R4, R4, R6 ; rightSum += curPix[20] ; increment the index and loop ADDS R0, R0, #1 ; curPix++ CMPS R0, R1 ; if curPix <= endPix BLS ForwardScan ; then loop B Done ; else return L0 ; update min/max to current pixel MOVS R5, R4 ; minmax = slope MOVS R3, R0 ; minmaxIdx = curpix B L0A ; resume loop ; Reverse scan: scanning from dark end to bright end, so look for ; steepest positive slope ReverseScan CMPS R4, R5 ; if slope > minmax BGT L1 ; then update minmax to current pixel L1A ; update the window LDRB R6, [R0,#0] ; tmp = curpix[0] ADDS R4, R4, R6 ; leftSum -= curpix[-10], but the running total is ; rightSum - leftSum, so ADD this to the running total LDRB R6, [R0,#10] ; tmp = curpix[10] SUBS R4, R4, R6 ; total -= curpix[10] (subtract from right sum) SUBS R4, R4, R6 ; total -= curpix[10] (add to left sum -> subtract from total) LDRB R6, [R0,#20] ; tmp = curpix[20] ADDS R4, R4, R6 ; rightSum += curPix[20] ; increment the index and loop ADDS R0, R0, #1 ; curPix++ CMPS R0, R1 ; if curPix <= endPix BLS ReverseScan ; then loop B Done ; else return L1 ; update min/max with current pixel MOVS R5, R4 ; minmax = slope MOVS R3, R0 ; minmaxIdx = curpix B L1A ; resume loop Done ; presume failure - return false MOVS R0, #0 ; if we found an edge, adjust the index for the window offset CMPS R5, #0 ; if minmax != 0, we found an edge BEQ L2 ; nope, no edge ADDS R3, #10 ; add the pixel window offset STR R3, [R2] ; store the result in *edgep MOVS R0, #1 ; return true L2 ; done - pop registers and return LDMFD R13!, {R4-R6,PC} END