I think DOUT is the column and DIN is the row. There is a parameter to reverse the polarity of the diodes but I don’t know if that affects the row/column terminology. It might be useful to look at sm_fast.inc as modified by QBas for the 32x32 scan matrix to see how the size of the matrix was altered.
Now Graham and I are both trying to really understand sm_fast.inc so that we can create some switch matrix projects. I have commented SM_Init thusly:
;; --------------------------------------------------------------------------
;; FUNCTION: SM_Init
;; DESCRIPTION: This function initializes the scan matrix.
;; It should be called from USER_Init
;; IN: -
;; OUT: -
;; USES: BSR
;; --------------------------------------------------------------------------
SM_Init
;; set button value to initial value (1) for all 64 buttons in data buffer
lfsr FSR0, SM_ROW0_VALUE ; FSR0 <- first row address
movlw 0x08 ; set Reg F as row loop counter
movwf TMP1
SM_Init_Loop1
setf POSTINC0 ; set all bits for row and increment row address
decfsz TMP1, F ; dec loop counter
rgoto SM_Init_Loop1
;; init values of all 64 buttons
lfsr FSR0, SM_ROW0_VALUE ; FSR0 <- first row address
movlw 0x08 ; set Reg F as row loop counter
movwf TMP1
SM_Init_Loop2
setf POSTINC0 ; set all bits for row and increment row address
decfsz TMP1, F ; dec loop counter
rgoto SM_Init_Loop2
;; deselect all columns by setting the DOUT data bit and shifting through all registers
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK ; clear the shift clock
bsf SM_SRIO_LAT_DOUT, SM_SRIO_PIN_DOUT ; set DOUT data bit
movlw 16 ; 16*8 shifts for up to 16 shift registers
movwf TMP1 ; Reg F is the register loop counter
SM_Init_Loop3 ; set and clear the DIO Shift Clock 8 times to shift through one pair of registers
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bsf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
bcf SM_SRIO_LAT_SCLK, SM_SRIO_PIN_SCLK
decfsz TMP1, F
rgoto SM_Init_Loop3 ; loop though 16 pairs of registers
;; latch DOUT values that were shifted in by clearing and setting the DIO Register Latch Pin
bcf SM_SRIO_LAT_RCLK, SM_SRIO_PIN_RCLK
nop
nop
nop
bsf SM_SRIO_LAT_RCLK, SM_SRIO_PIN_RCLK
return
Do have this much right?
Why are the row values set twice, once in SM_Init_Loop1 and then again in SM_Init_Loop2?
I think, that the second loop can be savely removed - could you please doublecheck this?
I could give you write access to the repository, so that your additional comments won’t get lost
QBas removed the second loop in his scan matrix enhancements. I removed the second loop with no apparent ill effects. I think it is confirmed that it can be safely removed.
I will contact you regarding repository access when I think my update is ready.
SM_DOUT_VALUE is a 1 of 8 bit code for the *next* column to be selected by DOUT:
;; determine DOUT value for *next* iteration step
;; this value gets active with the next latch pulse
incf SM_BUTTON_COLUMN, W, BANKED
call MIOS_HLP_GetBitANDMask ; (inverted 1 of 8 code)
movwf SM_DOUT_VALUE, BANKED
The SM_BUTTON_HANDLER_SHIFT MACRO is used 8 times in each loop of a column select to shift in the 8 bits of the DIN and shift out bits according to SM_DOUT_VALUE to set up DOUT for the next latch which will select the next column. This is the code that chooses when to shift the 0 into the DOUT shift register for the next column select:
;; set DOUT value
bsf SM_SRIO_LAT_DOUT, SM_SRIO_PIN_DOUT
btfss SM_DOUT_VALUE, 7-bit_number
bcf SM_SRIO_LAT_DOUT, SM_SRIO_PIN_DOUT
Because btfss tests bit (7-bit_number) column 0 is selected by Q7 of the DOUT register, column 1 by Q6, and so on. I tried changing the test to simply:
btfss SM_DOUT_VALUE, bit_number
There were no obvious problems and Q0 selected column 0 etc. which seems easier to deal with for wiring. Any subtlety I’m overlooking?