From 751dac946d671405365168521040a7032533878e Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 16 Nov 2005 00:39:02 +0000 Subject: [PATCH] before copies of ssp* --- detpic/i2clib.asm | 120 ++++++++++++++++++++---- detpic/i2clib.inc | 181 +++++++++++++++++++------------------ detpic/morse-auto.messages | 16 +++- 3 files changed, 207 insertions(+), 110 deletions(-) diff --git a/detpic/i2clib.asm b/detpic/i2clib.asm index 0b4041d..5188fe4 100644 --- a/detpic/i2clib.asm +++ b/detpic/i2clib.asm @@ -12,11 +12,17 @@ udata_acs -ssp res 1 - -st res 1 ; bitmask: -st_writing equ 0 -st_subsequent equ 0 +sspstat res 1 +sspcon1 res 1 +sspcon2 res 1 + +st res 1 ; bitmask, bit set in visible states: + ; master slave +st_reading equ 0 ; Reading-* Transmitting +st_writing equ 1 ; Writing-* [Idle-going-]Receiving +st_subsequent equ 2 ; Receiving +st_working equ 3 ; Writing-*,Reading-Busy,Stopping +st_starting equ 4 ; Writing-Setup,Reading-Busy code @@ -29,6 +35,86 @@ slave2addr rlc_w return +;---------- +check_wcolsspov + mov_fw SSPCON1 + mov_wf ssp + and_lw 0xc0 ; WCOL,SSPOV + bra_z intr_wcolsspov + return + +;---------- +intr_wcolsspov + panic morse_SV + +;====================================================================== +; MASTER + +;---------- +i2cm_init + mov_lw 100-1 ; baud rate = Fosc/(4*(SSPADD+1)) + mov_wf SSPADD ; Fosc=20MHz, so SSPADD==99 means 50kbit/s + mov_lw 0x08 ; !SSPEN, Master mode + mov_wf SSPCON1 + clr_f SSPCON2 ; nothing going + mov_lw 0x80 ; SMP(noslew), !CKE(!smbus) + bra init_enable + +;---------- +i2cm_write_start +; At call On return +; State Idle Writing-Setup +; W slave number any + tst_f_ifnz st + bra m_bad_write_start + bs_f st, st_writing +m_start + bs_f st, st_starting + bs_f SSPCON2, SEN + return + +;---------- +m_bad_write_start + panic morse_SPW + +;---------- +i2cm_interrupt + ; Do we have a doomy clash ? + bsr check_wcolsspov + + ; No ? Well, then the I2C should be idle now: + mov_fw SSPCON2 + mov_wf ssp + and_lw ~0x60 ; ACKSTAT,ACKDT + bra_nz m_bad_sspcon2 + ; OK, what's happening; + + bt_f_if0 PIR1, SSPIF + return + ; We have an interrupt: + + bt_f_if1 st, st_starting + bra m_event_starting + ; not just done SEN + + fixme + +;---------- +m_bad_sspcon2 + panic morse_SM + + +;---------- +m_event_starting + mov_lw 0x88 + bsr m_check_sspstat + + +m_check_sspstat +; W expected bit values any +; Panics if (SSPSTAT ^ W) & mask != 0 + mov_ff SSPSTAT, ssp + ;====================================================================== ; SLAVE @@ -43,8 +129,18 @@ i2cs_init mov_wf SSPCON1 mov_lw 0x01 ; !GCEN, SEN mov_wf SSPCON2 - mov_lw 0x8 ; SMP(noslew), !CKE, !BF(empty) + mov_lw 0x8 ; SMP(noslew), !CKE(!smbus) mov_wf SSPSTAT +ms_init_enable +; Actually engages the I2C controller, which must already have +; been set up (all but SSPEN): +; SSPADD,SSPCON1,SSPCON2 configured correctly unchanged +; SSPSTAT configured correctly unchanged, except: +; SSPSTAT 0 (disabled) 1 (enabled) +; SSPIE 0 (disabled) 1 (enabled) +; TRISB<1,0> any configured for I2C +; SSPIP any configured correctly +; GIEL 0 (disabled) 0 (disabled) bs_f TRISB, 0 bs_f TRISB, 1 bc_f IPR1, SSPIP @@ -91,12 +187,7 @@ i2cs_interrupt bc_f PIR1, SSPIF ; Check that nothing obvious is wrong: - mov_fw SSPCON1 - mov_wf ssp - and_lw 0xc0 ; WCOL, SSPOV - bra_nz i2cs_interrupt_wcolsspov_endif - panic morse_SV -i2cs_interrupt_wcolsspov_endif + bsr check_wcolsspov bt_f_if0 st, st_reading bra s_event_reading @@ -198,11 +289,6 @@ s_event_writing_datarecv bs_f st, st_subsequent goto i2csu_write_begin -;====================================================================== -; MASTER - - - ;====================================================================== include i2clib.inc diff --git a/detpic/i2clib.inc b/detpic/i2clib.inc index 8195fbd..8fbb578 100644 --- a/detpic/i2clib.inc +++ b/detpic/i2clib.inc @@ -66,7 +66,7 @@ extern i2cm_init ; i2c controller any for use by i2clib ; i2c interrupt config any enabled, low priority ; global interrupt enable disabled unchanged -; State Not-in-use Idle +; State Not-in-use Idle (as master) ;-------------------- extern i2cs_init @@ -78,12 +78,12 @@ extern i2cs_init ; i2c controller any for use by i2clib ; i2c interrupt config any enabled, low priority ; global interrupt enable disabled unchanged -; State Not-in-use Idle +; State Not-in-use Idle (as slave) ; W slave number any ;-------------------- -extern i2cs_interrupt extern i2cm_interrupt +extern i2cs_interrupt ; ; Must be called by the main program's low priority interrupt handler. ; The main program's interrupt handler is responsible for saving W and @@ -102,92 +102,6 @@ extern i2cm_interrupt ; from i2c?_inerrupt. -;====================================================================== -; SLAVE -; -; States: -; -; [Not-in-use] -; | -; |init -; v -; [Idle]<-------------------------. -; write_begin/ \ | -; / \read_begin | -; V V | -; ,->[Receiving] [Transmitting]<-. | -; `-----' | | `------' | -; write_another | | read_another | -; | read_done| | -; write_done| \ | - `--------------+->----------------' - -;======================================== -; SLAVE - WRITES (ie, reception of data from the master) - -;-------------------- -extern i2csu_write_begin -; -; Called to notify the main program that the master PIC has selected this -; slave to talk to, for writing. Provides the first byte of data -; we received from the master PIC. -; -; Beforehand At call On return -; State Idle Receiving Receiving -; W data from master any - -;-------------------- -extern i2csu_write_another -; -; Called to notify the main program that the master PIC has continued -; by transmitting another byte of data. Provides the byte we received. -; -; Beforehand At call On return -; State Receiving Receiving Receiving -; W data from master any - -;-------------------- -extern i2csu_write_done -; -; Called to notify the main program that the master PIC has stopped -; transmitting data (ie, finished the i2c conversation). -; -; Beforehand At call On return -; State Receiving Idle - -;======================================== -; SLAVE - READS (ie, transmission of data to the master) - -;-------------------- -extern i2csu_read_begin -; -; Called to notify the main program that the master PIC has selected -; this slave to talk to, for reading, and to obtain the first byte of -; data that we should transmit to the master. -; -; Beforehand At call On return -; State Idle Transmitting Transmitting -; W any data for master - -;-------------------- -extern i2csu_read_another -; -; Called to notify the main program that the master PIC has continued -; by asking for another byte of data. Must provide the byte. -; -; Beforehand At call On return -; State Transmitting Transmitting Transmitting -; W any data for master - -;-------------------- -extern i2csu_read_done -; -; Called to notify the main program that the master PIC has stopped -; asking for data (ie, finished receiving). -; -; Beforehand At call On return -; State Transmitting Idle - ;====================================================================== ; MASTER ; @@ -197,7 +111,7 @@ extern i2csu_read_done ; |init ; v ; [Idle]<-----------------------------. -; write_start/ \ | +; write_start/ \read_start | ; / \ | ; V V | ; [Writing-Setup] [Reading-Busy]<---------. | @@ -317,4 +231,91 @@ extern i2cm_read_done ; At call On return ; State Reading-Wait Stopping + +;====================================================================== +; SLAVE +; +; States: +; +; [Not-in-use] +; | +; |init +; v +; [Idle]<-------------------------. +; write_begin/ \ | +; / \read_begin | +; V V | +; ,->[Receiving] [Transmitting]<-. | +; `-----' | | `------' | +; write_another | | read_another | +; | read_done| | +; write_done| \ | + `--------------+->----------------' + +;======================================== +; SLAVE - WRITES (ie, reception of data from the master) + +;-------------------- +extern i2csu_write_begin +; +; Called to notify the main program that the master PIC has selected this +; slave to talk to, for writing. Provides the first byte of data +; we received from the master PIC. +; +; Beforehand At call On return +; State Idle Receiving Receiving +; W data from master any + +;-------------------- +extern i2csu_write_another +; +; Called to notify the main program that the master PIC has continued +; by transmitting another byte of data. Provides the byte we received. +; +; Beforehand At call On return +; State Receiving Receiving Receiving +; W data from master any + +;-------------------- +extern i2csu_write_done +; +; Called to notify the main program that the master PIC has stopped +; transmitting data (ie, finished the i2c conversation). +; +; Beforehand At call On return +; State Receiving Idle + +;======================================== +; SLAVE - READS (ie, transmission of data to the master) + +;-------------------- +extern i2csu_read_begin +; +; Called to notify the main program that the master PIC has selected +; this slave to talk to, for reading, and to obtain the first byte of +; data that we should transmit to the master. +; +; Beforehand At call On return +; State Idle Transmitting Transmitting +; W any data for master + +;-------------------- +extern i2csu_read_another +; +; Called to notify the main program that the master PIC has continued +; by asking for another byte of data. Must provide the byte. +; +; Beforehand At call On return +; State Transmitting Transmitting Transmitting +; W any data for master + +;-------------------- +extern i2csu_read_done +; +; Called to notify the main program that the master PIC has stopped +; asking for data (ie, finished receiving). +; +; Beforehand At call On return +; State Transmitting Idle + ;====================================================================== diff --git a/detpic/morse-auto.messages b/detpic/morse-auto.messages index b83c3bf..32235fd 100644 --- a/detpic/morse-auto.messages +++ b/detpic/morse-auto.messages @@ -32,13 +32,23 @@ TI4 ; for iwj TI5 ; for iwj # Messages for i2clib, S* -SV SSPSTAT, ssp ; WCOL or SSPOV (ssp = SSPCON1, unusually) +# in both +SV SSPSTAT, ssp, st ; WCOL or SSPOV (ssp = SSPCON1, unusually) + +# in master +SM SSPSTAT, SSPCON1, ssp, st ; interrupt with unexpected bits in SSPCON2 + ; (ssp = SSPCON2, unusually) + + +# in slave SI ssp, SSPCON1 ; bad SSPSTAT when idle SR ssp, SSPCON1 ; bad SSPSTAT when reading SW ssp, SSPCON1 ; bad SSPSTAT when writing -SS ssp, SSPCON1 ; slave got i2c interrupt but bad SSPSTAT -ST ssp, st ; slave got i2c interrupt but bad st + + +SPW st ; write_start when not permitted + SA SSPCON2 ; Slave didn't I2C ack address SD SSPCON2 ; Slave didn't I2C ack data -- 2.30.2