📄 spi.asm
字号:
* SPI.asm
**********************************************************************
* Software serial peripheral interface. *
**********************************************************************
**********************************************************************
* MCU_Master & MCU_Slave *
* These subroutines set the data direction of the I/O pins used *
* as the SPI interface. It also sets the state of the /RST pin *
* which determines whether the Romeo2 is the master or slave. *
* PTA[4] = Romeo2 MISO *
* PTA[3] = Romeo2 SCK *
* PTA[2] = Romeo2 MOSI *
* PTA[1] = Romeo2 /RST *
**********************************************************************
MCU_Master: BSET 1,PTA ;Reset Romeo2 bit counter.
PSHA
LDA #$FF
DBNZA *
PULA
BCLR 1,PTA ;Put Romeo2 in slave mode
BCLR 3,PTA ;Hold SCK low
BCLR 2,PTA ;Hold MOSI low
BCLR 4,DDRA ;Romeo2 MISO is input
BSET 3,DDRA ;Romeo2 SCK is output
BSET 2,DDRA ;Romeo2 MOSI is output
RTS
MCU_Slave: BCLR 4,PTA ;Hold MISO low
BSET 4,DDRA ;Romeo2 MISO is output
BCLR 3,DDRA ;Romeo2 SCK is input
BCLR 2,DDRA ;Romeo2 MOSI is input
BSET 1,PTA ;Put Romeo2 in master mode
PSHA ;Wait a little
LDA #$FF
DBNZA *
PULA
RTS
**********************************************************************
* RomeoConfig *
* Sends the data stored in WRITE_SPI to the Romeo2. *
* Also stores data read in READ_SPI. To read, clock 3 bytes with *
* the first MOSI bit set (i.e. CR1 = 0x80). The read values will be *
* stored in READ_SPI. *
* PTA[4] = Romeo2 MISO *
* PTA[3] = Romeo2 SCK *
* PTA[2] = Romeo2 MOSI *
* PTA[1] = Romeo2 /RST *
**********************************************************************
RomeoConfig: PSHA
LDA #!24 ;Reset the bit counter.
BSR MCU_Master ;Set Romeo2 as slave.
MOV WRITE_SPI,BUFFER ;Buffer the config data.
MOV WRITE_SPI+1,BUFFER+1
MOV WRITE_SPI+2,BUFFER+2
Next_Bit: LSL BUFFER+2 ;Shift a data bit into the carry bit.
ROL BUFFER+1
ROL BUFFER
BCS Set ;Check if data = 1 or 0.
Clear: BCLR 2,PTA ;Clear the data output pin.
Toggle_Clk: BSET 3,PTA ;Set the clock.
NOP ;Wait a little.
NOP
NOP
BCLR 3,PTA ;Clear the clock.
BRCLR 4,PTA,Data_In ;Check state of the data pin (note carry bit).
Data_In: ROL READ_SPI+2 ;Shift data bit from carry into register.
ROL READ_SPI+1
ROL READ_SPI
DBNZA Next_Bit ;Decrement the bit counter.
BRA Done
Set: BSET 2,PTA ;Set data out line to 1.
BRA Toggle_Clk ;Go toggle the clock.
Done: BRSET 7,WRITE_SPI,Really_Done ;If MSB is set, we're reading, not writing.
BSR CheckConfig ;Verify the configuration went okay.
Really_Done: PULA
RTS
**********************************************************************
* CheckConfig *
* Confirms the Romeo2 configuration registers. If an error (caused *
* by data corruption on the wire, or a bad connection to Romeo2), *
* all LEDs are turned on until the error is corrected. *
* PTA[4] = Romeo2 MISO *
* PTA[3] = Romeo2 SCK *
* PTA[2] = Romeo2 MOSI *
* PTA[1] = Romeo2 /RST *
**********************************************************************
CheckConfig: BSET 7,WRITE_SPI ;MSB = 1 to read Romeo2 configuration.
JSR RomeoConfig
LDA READ_SPI
CMP WRITE_SPI
BNE Romeo_Error
LDA READ_SPI+1 ;Get the configuration data.
CMP WRITE_SPI+1 ;Check if Romeo2 configured properly.
BNE Romeo_Error ;If a problem, turn on all LEDs.
LDA READ_SPI+2
CMP WRITE_SPI+2
BNE Romeo_Error
BRA Romeo_OK ;Romeo is configured properly.
Romeo_Error: JSR TurnOnLEDs
RSP ;Reset the stack pointer.
JMP Main ;Try again.
Romeo_OK: RTS
**********************************************************************
* GetSPIData *
* SPI slave mode receive routine. Note that the data are reversed *
* in memory: i.e. DATA+7 is the first ID byte, DATA+6 is the second *
* ID byte, and DATA+1 is the status byte. This makes the code *
* much more efficient. *
* Normally, the time base module is running generating periodic int- *
* errupts. Once the first clock is detected here, TBM interrupts *
* are disabled and the timer starts running. The timer is used so *
* that if a partial frame is sent by the Romeo2 SPI, it will not *
* affect the next data frame. *
* *
* Data frame: *
* 4 bytes of ID *
* 1 byte of Pressure data *
* 1 byte of Temperature data *
* 1 byte of Status data *
* 1 byte of Checksum data *
* 1 byte of irrelevant data *
* Perhaps 1 more byte of irrelevant data (see Romeo2 spec). *
* The data are then stored in the 8 bytes labeled "DATA." *
* *
* PTA[4] = Romeo2 MISO *
* PTA[3] = Romeo2 SCK *
* PTA[2] = Romeo2 MOSI *
* PTA[1] = Romeo2 /RST *
**********************************************************************
GetSPIData: BSR MCU_Slave
CLRH
LDX #NB_DATA ;Byte counter
BSET 4,TSC ;Reset the timer counter registers.
Rst_Bit_Cnt: LDA #!8 ;Bit counter
Hold_Low: BRCLR 3,PTA,* ;Clock is initially low: wait here.
BRCLR 3,PTA,* ;Debounce
BCLR 2,TBCR ;Mask TBM interrupts.
BCLR 5,TSC ;The timer starts counting here.
BRSET 3,PTA,* ;Clock has gone high: wait for falling edge.
BRSET 3,PTA,* ;Debounce
BRSET 2,PTA,Store_Data ;Falling edge detected: load data into carry bit.
Store_Data: ROL DATA-1,X ;Rotate data from carry into RAM.
BSET 4,TSC ;Reset the timer counter registers.
DBNZA Hold_Low ;Check if a whole byte received.
DBNZX Rst_Bit_Cnt ;Check if all data received.
MOV #%01110000,TSC ;Get the timer ready, stop the counter.
BSET 2,TBCR ;Unmask TBM interrupts.
LDX #$01 ;1 byte of irrelevant data might need
JSR Delay ;to be ignored before returning.
RTS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -