chiark / gitweb /
before copies of ssp*
authorian <ian>
Wed, 16 Nov 2005 00:39:02 +0000 (00:39 +0000)
committerian <ian>
Wed, 16 Nov 2005 00:39:02 +0000 (00:39 +0000)
detpic/i2clib.asm
detpic/i2clib.inc
detpic/morse-auto.messages

index 0b4041d2d70fb1da9e36ac7d04abf9a48c2750fd..5188fe4da599f0dd0491e66879e9289dc5e6f0eb 100644 (file)
 
                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<SSPEN>          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
index 8195fbd741b0f171b1d4a836f8a0efaf1f6e6a80..8fbb578b57e0886aa82a1f762f77774b49f35008 100644 (file)
@@ -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
+
 ;======================================================================
index b83c3bf8c1a31599d79c4c61fa266da1fe023c9d..32235fdea6b117a47ef128dad6ce896c537ebec4 100644 (file)
@@ -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