chiark / gitweb /
allow repeated starts by master; optimise slave
authorian <ian>
Sat, 26 Nov 2005 17:36:54 +0000 (17:36 +0000)
committerian <ian>
Sat, 26 Nov 2005 17:36:54 +0000 (17:36 +0000)
detpic/i2clib.asm
detpic/i2clib.inc
detpic/morse.messages
detpic/test-sofar.asm

index b1d4e890ebde69a7f36e14d3865e93d344be2a8e..1ebebb351b87cc03eb9049e89ebcc41e7d7cdb73 100644 (file)
@@ -61,6 +61,7 @@ sspstat               res     1
 sspcon1                res     1
 sspcon2                res     1       ; master only
 slave          res     1       ; master only
+slave_next     res     1       ; master only
 
 st             res     1
 st_orig                res     1
@@ -71,8 +72,8 @@ st_starting   equ 7 ; Writing-Setup?,Reading-Busy?
 st_addressing  equ 6 ; Writing-Setup?,Reading-Busy?
 st_writing     equ 5 ; Writing-*                       [Idle-going-]Receiving
 st_subsequent  equ 4 ; Writing?                        Receiving
-st_reading     equ 3 ; Reading-*                       Transmitting
-st_awaiting    equ 2 ; Reading-Wait
+st_reading     equ 3 ; Reading-*                       Transmit-*
+st_awaiting    equ 2 ; Reading-Wait                    Transmit-Wait
 st_acking      equ 1 ; Reading-Busy?,Stopping(from read)
 st_stopping    equ 0 ; Stopping
                  ; ...? means not always set in that state
@@ -88,6 +89,10 @@ slave2addr
                rlc_w
                return
 
+;----------
+improper_read_done_data
+               panic   morse_SD
+
 ;======================================================================
 ; MASTER
 
@@ -96,6 +101,7 @@ i2cm_init
                mov_lw  i2c_sspadd
                mov_wf  SSPADD
                clr_f   st
+               clr_f   slave_next
                mov_lw  0x08    ; !SSPEN, Master mode
                mov_wf  SSPCON1
                clr_f   SSPCON2 ; nothing going
@@ -163,10 +169,11 @@ m_start
 ; expects to return directly to main program (caller)
                mov_wf  slave
                bra_z   m_improper_slave
+               bs_f    SSPCON2, SEN
+m_start_or_restart
                and_lw  ~31
                bra_nz  m_improper_slave
                bs_f    st, st_starting
-               bs_f    SSPCON2, SEN
                return
 
 ;----------
@@ -273,11 +280,24 @@ i2cm_read_start
 ;      State                   Idle            Reading-Busy
 ;      W                       slave number    any
                tst_f_ifnz st
-               bra     m_improper_read_start
+               bra     m_read_start_busy
 
                bs_f    st, st_reading
                bra     m_start
 
+;----------
+m_read_start_busy
+               bt_f_if1 st, st_awaiting
+               bra     m_read_another
+               panic   morse_SR
+
+;----------
+m_read_another
+; Main program would like to address another slave.
+               mov_wf  slave_next
+               bra_z   m_improper_slave
+               bra     m_read_ack
+
 ;----------
 m_event_done_addressing_read
 m_event_done_acking_readmore
@@ -323,7 +343,7 @@ i2cm_read_done
                bc_f    st, st_reading
                
                bt_f_if0 st, st_awaiting
-               bra     m_improper_read_done
+               bra     improper_read_done_data
                ; OK:
 
                bra     m_read_ack
@@ -335,20 +355,18 @@ m_event_done_acking
                bt_f_if1 st, st_reading
                bra     m_event_done_acking_readmore
 
-               bra     m_stop
-
-;----------
-m_improper_read_start
-               panic   morse_SR
+               mov_fw  slave_next
+               bra_z   m_stop
+; ok, we want to read another:
+               mov_wf  slave
+               bs_f    st, st_reading
+               bs_f    SSPCON2, RSEN
+               bra     m_start_or_restart
 
 ;----------
 m_improper_read_another
                panic   morse_SA
 
-;----------
-m_improper_read_done
-               panic   morse_SD
-
 ;======================================================================
 ; SLAVE
 
@@ -398,8 +416,8 @@ init_enable
 
 ; Some macros:
 
-chkvals_start_sspstat macro
-               mov_fw  sspstat
+chkvals_start macro what
+               mov_fw  what
                endm
 
 chkval macro lastval, value, label
@@ -414,7 +432,7 @@ chkvals_addrrecv macro lastval
 chkvals_addrrecv_lastval equ 0x89
 
 ;----------
-i2cs_interrupt
+i2cs_interrupt ; 4cy interrupt latency + 3cy until branch to here
                bt_f_if0 PIR1, SSPIF
                return
                ; We have an interrupt:
@@ -423,23 +441,22 @@ i2cs_interrupt
 ; while we faff, the interrupt will be regenerated:
                bc_f    PIR1, SSPIF
 
-               mov_ff  SSPSTAT, sspstat
-               mov_ff  SSPCON1, sspcon1
                mov_ff  st, st_orig
 
                mov_lw  (1<<WCOL) | (1<<SSPOV)
-               and_wfw sspcon1
+               and_wfw SSPCON1
                bra_nz  s_event_bad
 
+               ; 8cy from entry to here, so total of 15cy
                bt_f_if1 st, st_reading
-               bra     s_event_reading
+               bra     s_event_reading ; 18cy to 1st insn of event_reading
 
                bt_f_if1 st, st_writing
                bra     s_event_writing
 
 s_event_idle
-               chkvals_start_sspstat
-               chkvals_addrrecv 0
+               chkvals_start SSPSTAT
+               chkvals_addrrecv 0 ; 23cy to 1st insn of addrrecvread
 s_event_bad
                panic   morse_SS ; slave, interrupt, controller in bad state
 
@@ -448,25 +465,22 @@ s_event_bad
 
 ;----------
 s_event_idle_addrrecvread
-               bs_f    st, st_reading
-               call    i2csu_read_begin
-               bra     s_events_reading_datasend
+               bs_f    st, st_awaiting
+               goto    i2csu_read_begin ; 26cy until 1st insn of read_begin
 
 ;----------
 s_event_reading
-               chkvals_start_sspstat
-               chkval  0, 0xac, s_event_reading_datasent ; D,!P, S,R,!BF
+               bs_f    st, st_awaiting ; (probably)
 
-; mov_fw st
-; bra_z nopanic
-; panic morse_Z
-;nopanic
+               chkvals_start SSPSTAT
+               chkval  0, 0xac, i2csu_read_another ; D,!P, S,R,!BF
+                       ; 23cy until 1st insn of i2csu_read_another
 
                ; Whatever is happening, we're done reading now !
                clr_f   st
                call    i2csu_read_done
 
-               chkvals_start_sspstat
+               chkvals_start SSPSTAT
                chkval  0, 0xa8, s_event_reading_datanack ; D,!P, S,!R,!BF
                ; Or, maybe it was nack and then we were reselected:
                chkvals_addrrecv 0xa8
@@ -474,11 +488,16 @@ s_event_reading
                bra     s_event_bad
 
 ;----------
-s_event_reading_datasent
-               call    i2csu_read_another
-s_events_reading_datasend
+i2cs_read_data
+;      W               byte for master         any
+;      State           Transmit-Wait           Transmit-Busy
                mov_wf  SSPBUF
                bs_f    SSPCON1, CKP
+               
+               bt_f_if0 st, st_awaiting
+               bra     improper_read_done_data
+               bc_f    st, st_awaiting
+               bs_f    st, st_reading
 s_event_reading_datanack
                return
 
@@ -500,7 +519,7 @@ s_write_slurpbyte
 
 ;----------
 s_event_writing
-               chkvals_start_sspstat
+               chkvals_start SSPSTAT
                chkval  0, 0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
 
                ; Well, we're done writing now in any case
@@ -514,11 +533,11 @@ s_event_writing
                ; too picky.
 
                ; First, the nice cases:
-               chkvals_start_sspstat
+               chkvals_start SSPSTAT
                chkvals_addrrecv 0
 
                ; Then random junk:
-               mov_fw  sspstat
+               mov_fw  SSPSTAT
                and_lw  0xc7 ; ?D_A, ?P; ?S
                xor_lw  0x80 ; SMP, !CKE, !R_W, !UA, !BF
                bt_f_if1 STATUS, Z
index d96cbd655c486cc720210514bfa59f2f68e1160a..8d0c1dd0bfe8bd9439c2d76dd9c062aac0110b5f 100644 (file)
 ;                                   v
 ;                         [Idle]<-----------------------------.
 ;              write_start/    \read_start                    |
-;                         /             \                             |
-;                       V        V                            |
-;            [Writing-Setup]    [Reading-Busy]<---------.      |
-;                   |                |                 |      |
-;    write_next_byte|                |read_got_byte    |      |
-;    must return NZ |                |                 |      |
-;                  V                 V                 |      |
-;           ,-->[Writing]         [Reading-Wait]       |      |
-;           `-------'  \           /     `-------------'      |
-;    write_next_byte    \         /       read_another        |
-;       returns NZ       |       /                            |
-;                        |       /read_done                           |
-;         write_next_byte|      |                             |
+;                         /             \          ,--------------.   |
+;                       V        V         V              |   |
+;            [Writing-Setup]    [Reading-Busy]<---------.  |   |
+;                   |                |                 |  |   |
+;    write_next_byte|                |read_got_byte    |  |   |
+;    must return NZ |                |                 |  |   |
+;                  V                 V                 |  |   |
+;           ,-->[Writing]         [Reading-Wait]       |  |   |
+;           `-------'  \           /  |  `-------------'  |   |
+;    write_next_byte    \         /   |   read_another    |   |
+;       returns NZ       |       /    `._________________,'   |
+;                        |       /             read_start      |
+;         write_next_byte|      |read_done                    |
 ;             returns Z  |      |                                     |
 ;                        V      V                             |
 ;                              [Stopping]                             |
 ;           write_begin/    \                          |
 ;                    /      \read_begin               |
 ;                   V        V                        |
-;        ,->[Receiving]      [Transmitting]<-.         |
-;               `-----'     |             |  `------'         |
-;    write_another   |             |   read_another    |
-;                   |    read_done|                   |
-;          write_done|             \                   |
-;                   `--------------+->----------------'
+;        ,->[Receiving]     [Transmit-Wait]<-.         |
+;               `-----'     |        |              |         |
+;    write_another   |        |read_data     |         |
+;                   |        V              |         |
+;                   |      [Transmit-Busy]  |         |
+;                   |        |       `------'         |
+;                   |        |        read_another    |
+;                   |        |                        |
+;                   |        |read_done               |
+;          write_done|        \                        |
+;                   `---------+->---------------------'
 
 ;========================================
 ; SLAVE - WRITES (ie, reception of data from 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.
+; this slave to talk to, for reading.  The main program should call
+; i2cs_read_data with first byte of data that we should transmit to
+; the master.
+;
+;              Beforehand      At call
+;   State      Idle            Transmit-Wait
+
+
+;--------------------
+ extern i2cs_read_data
+; Transmits the byte of data to the master
 ;
 ;              Beforehand      At call                 On return
-;   State      Idle            Transmitting            Transmitting
-;   W                          any                     data for master
+;   State      Transmit-Wait   Transmit-Busy           Transmit-Busy
+;   W                          byte for master         any
 
 ;--------------------
  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.
+; by asking for another byte of data.  The main program should once
+; more call i2cs_read_data.
 ;
-;              Beforehand      At call                 On return
-;   State      Transmitting    Transmitting            Transmitting
-;   W                          any                     data for master
+;              Beforehand      At call
+;   State      Transmit-Busy   Transmit-Wait
 
 ;--------------------
  extern i2csu_read_done
 ; asking for data (ie, finished receiving).
 ;
 ;              Beforehand      At call                 On return
-;   State      Transmitting    Idle
+;   State      Transmit-Busy   Idle
index a785f2070320cea85f58de14b49fe1698a562063..7dd4d33780e20a6c4f7869c3570c23cf7b9a06ab 100644 (file)
@@ -35,11 +35,11 @@ ZS  i2clib:st,:sspstat,:sspcon1,:st_orig ; for testing
 
 # Messages for i2clib, S*
 SM     i2clib:st,:sspstat,:sspcon1,:sspcon2 ; m.,i., ctrlr bad state
-SS     i2clib:st,:sspstat,:sspcon1,:st_orig ; s.,i., controller bad state
+SS     i2clib:st,SSPSTAT,SSPCON1,:st_orig ; s.,i., controller bad state
 SK     i2clib:slave                    ; m. couldn't address slave (no ack)
 SN     i2clib:slave                    ; improper slave number
 SW     i2clib:st                       ; improper i2cm_write_start
 SF     i2clib:st                       ; improper i2cmu_write_next_byte Z
 SR     i2clib:st                       ; improper i2cm_read_start
 SA     i2clib:st                       ; improper i2cm_read_another
-SD     i2clib:st                       ; improper i2cm_read_done
+SD     i2clib:st                       ; impr. i2cm_read_done/i2cs_read_data
index 6ce7b67e5555b7cf64ff5aecf11535841443ebfd..38db82b2516ca4eea4efda5e5e2fab41f5e2021a 100644 (file)
@@ -291,7 +291,7 @@ i2csu_read_begin
 i2csu_read_another
        mov_fw  POSTINC1
        bc_f    FSR1L, s_bufbit
-       return
+       goto    i2cs_read_data
 
 ;----------
 s_buffer_erase