• AVR Freaks

Hot!SPI Slave mode interrupt or not (poll)...

Page: 12345 > Showing page 1 of 5
Author
JustRob
Super Member
  • Total Posts : 584
  • Reward points : 0
  • Joined: 2008/09/04 12:49:27
  • Location: Hudson Massachusetts United States
  • Status: online
2020/05/09 08:45:18 (permalink)
0

SPI Slave mode interrupt or not (poll)...

I have two circuit boards both with a PIC18LF47K42, MPLAB X v5.15, the XC8 v2.05 compiler and the ICD3
 
LCD_ctrl is the master circuit board for SPI communication and interfaces to a 3.5" lcd
THERMAL_ctrl is the slave circuit board for SPI communication and controls temperature for a thermal device
 
I have done many designs in spi master mode but have yet to do a spi slave design.
 
I would simply like the master spi to write a byte then read a byte.  Conversely, I want the spi slave to read a byte then write one.
 
For the slave I tried writing an interrupt routine but I'm getting this error:
"unknown "irq" (PIR2bits.SPI1IF) in __interrupt attribute/specifier" for the following interrupt routine:

// interrupt service routine
void __interrupt(irq(PIR2bits.SPI1IF),high_priority) spi_ISR(void){

    //slave chip select detected
    PIR2bits.SPI1IF = 0;
    spi_incomming = 1;
                
}

 
OR...
Should I just poll for received spi data in my main while loop with then read a byte then write a byte?:

// check for spi read byte
uint8_t SPI_data_ready() //Check whether the data is ready to read
{
  if(SPI1STATUSbits.RXBF)
    return 1;
  else
    return 0;
}

 
#1

84 Replies Related Threads

    mbrowning
    USNA79
    • Total Posts : 1773
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 10:36:10 (permalink)
    0
    The interrupt source IRQ numbers are in the device .h file (pic18lf47k42.h) and in the chip documentation (18lf47k42.html) and are NOT the flag.
     
    Here is my SPI slave interrupt declaration:
    void __interrupt(irq(IRQ_SPI1RX),base(IVT_BASE),high_priority)spi1_rx_isr(void){



    #2
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 11:17:54 (permalink)
    0
    I can't open the pic18lf47k42.h file because it is too big when I try.  I have looked but can't find a list of the interrupts nor and html file
    #3
    mbrowning
    USNA79
    • Total Posts : 1773
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 11:49:30 (permalink)
    0
    for xc8 2.05
    C:\Program Files (x86)\Microchip\xc8\v2.05\docs\chips\18lf47k42.html
     
    You should install a programming editor. I use PSPAD. It will open any file.
    And MPLABX can surely open the .h file. If it complains that the file is too big, open it anyway. I've never had any issues.
     
     
    #4
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 12:19:49 (permalink)
    0
    Got it.  Thanks
     
    Now to figure out how to be a slave.
    #5
    du00000001
    Just Some Member
    • Total Posts : 3778
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 13:39:08 (permalink)
    0
    JustRob
    Got it.  Thanks
     
    Now to figure out how to be a slave.



    Either use MCC (maybe in some "configuration project") - or the doc (that somewhat lengthy .pdf)  :)

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #6
    ric
    Super Member
    • Total Posts : 27630
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 15:27:07 (permalink)
    0
    JustRob
    ....
    I would simply like the master spi to write a byte then read a byte.  Conversely, I want the spi slave to read a byte then write one.

    If you've used SPI before, then I guess you are aware it will take two SPI transfers to do this.
    i.e. when the Master first writes, it will get a dummy back from the Slave, and it has to do a dummy write to get the second byte from the slave.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    mbrowning
    USNA79
    • Total Posts : 1773
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 16:07:38 (permalink)
    0
    In our products we implement 32b SPI accessible registers in the PIC (K42 or soon Q43) or Igloo. The master sends 6 bytes - byte 1 is 7b address and RW. Byte 2 is 0 to allow the slave time to access data to be returned in Bytes 3-6. For write commands, bytes 3-6 are write data, 0x00000000 for read commands. The returned data is either the requested register data for reads or a diagnostic code for write commands.
     
    The Igloo slave SPI SCLK can be 30MHz, but the PIC takes time to act on the command byte and put returned data in the FIFO. With inline interrupt asm, careful variable placement, and PIC writes to SPI register ram locations implemented in interrupt disabled inline asm, I have reliable 7MHz SCLK (at 64MHz Fosc). We limit SCLK to 6MHz for margin.
     
    As part of initialization, main() stuffs 0's in the 2B TX FIFO. All SPI operations for the 6B transfer occur during the SPI receive interrupt, stuffing 0's in the TX FIFO before returning. Thus the first two bytes from the Master get 0's from the slave.
     
    The OP hasn't clearly (in my opinion) described exactly how his SPI slave should work, but my method would work for him. 3B transfer - first byte command, second byte dummy, third byte returned data. Might get 10MHz out of it.
     
     
    #8
    du00000001
    Just Some Member
    • Total Posts : 3778
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/09 17:28:08 (permalink)
    0
    I have to guess somewhat:
    Rob might want to send the desired temperature to the temp controller and get back the current temperature. In this case (and if the delay by 1 cycle doesn't matter) he could get away with the simple scheme he described: writing the current temperature to the slave's SPI TX register  -to be transmitted during the next cycle that will transmit the desired temperature (cyclically).
    Just a guess...

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #9
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 14:56:57 (permalink)
    0
    Here is my setup.  This is the first time I've done two circuit boards with 1 MPLabX IDE and 1 ICD3.
    1. I have the LCD Controller as master sending 1 byte (desired temp) to the thermal controller
    2. Then the LCD Controller sends 1 byte 0x00 to read the current temp from the Thermal Controller
    3. I have the Thermal Controller as slave reading 1 byte (desired temp) from LCD Controller
    4. Then the Thermal Controller sends 1 byte (current temp) in response to LCD Controller
    The code below is:
    1. LCD Controller main doing the get_set_temp()
    2. LCD Controller's Thermal_Board_interface file containing get_set_temp()
    3. LCD Controller's spi_pic_18 code containing SPI_read_write()
    4. Thermal Controller's spi_pic_18f_slave code containing spi_init() (initializing as spi slave) and SPI_get_return_temp()
    5. And Thermal Controller Main() where the interrupt routine is.

        x = set_get_temp(desired_temp);

     

    uint8_t set_get_temp (uint8_t temp){
        
        uint8_t x;
        
        THERMAL_SPI_CS_LATCH = 0; // select thermal controller board for spi comm
        SPI_MISO_ENn_LATCH = 0; // enable miso tri-state buffer
        
        x = SPI_read_write(temp);
        x = SPI_read_write(0x00);
            
        THERMAL_SPI_CS_LATCH = 1; // deselect thermal controller board for spi comm
        SPI_MISO_ENn_LATCH = 1; // disable miso tri-state buffer
        
        return x;
        
    }


    uint8_t SPI_read_write(uint8_t data_byte){

        SPI1TXB = data_byte;
        NOP();
        NOP();
        
        while(SPI1CON2bits.BUSY);
        
        return SPI1RXB;
        
    } // SPI_read_write



    /****************************************************************************
     * Function: *
     * void SPI_init(void) *
     * *
     * Summary: *
     * Configures the pic18f47k42 spi channel per section 32.6 as slave *
     * *
     * Precondition: *
     * A receiving spi device is connected *
     * *
     * Parameters: *
     * None *
     * *
     * Returns: *
     * None *
     * *
     * Remarks: *
     ****************************************************************************/

    void SPI_init(){

        SPI_SCK_TRIS = 1; // SPI SCK set to input
        SPI_SLAVE_SDO_TRIS = 1; // SPI SDO set to tri-state when cs is inactive
        SPI_SLAVE_SDI_TRIS = 1; // SPI SDI data set to input
        THERMAL_SPI_CS_TRIS = 1; // SPI CS set to input
        
        // assign peripheral pins
        SPI1SDIPPS = SPI_SLAVE_SDI_PPS; // sets the spi sdi peripheral pin location
        RC5PPS = SPI_SLAVE_SDO_PPS; // sets the spi sdo peripheral pin location
        SPI1SCKPPS = SPI_SCK_PPS; // sets the spi sck peripheral pin location SPI_SCK_PPS = RC3PPS
        SPI1SSPPS = THERMAL_SPI_CS_PPS; // sets the spi ss peripheral pin location THERMAL_SPI_CS_PPS = RA5PPS

        // configure the SPICON0 register
        SPI1CON0bits.EN = 0; // disable SPI1
        SPI1CON0bits.LSBF = 0; // spi msb first
        SPI1CON0bits.MST = 0; // spi operates as slave
        SPI1CON0bits.BMODE = 1; // spi byte mode
        
        
        // configure the SPICON1 register
        SPI1CON1bits.CKP = 1; // SPI clock polarity ~ clock idle state is high
        SPI1CON1bits.SMP = 0; // SPI slave data sampled at the middle
        SPI1CON1bits.CKE = 0; // SPI clock edge select ~ transmit data changes on high to low (idle to active)
        SPI1CON1bits.SSP = 1; // spi chip select active low
        SPI1CON1bits.SDIP = 0; // spi sdi polarity is active high
        SPI1CON1bits.SDOP = 0; // spi sdo polarity is active high
        
        // configure the SPI1CON2 register
        SPI1CON2bits.SSET = 0; // slave mode spi ss(in) enables/disables data input and tri-states
                                                // SDO if the TRIS bit associated with the SDO pin is set
        SPI1CON2bits.TXR = 1; // spi txfifo data is required for transfer
        SPI1CON2bits.RXR = 1; // data transfers are suspended if rxfifo is full
            
        // configure the number of bits transfered in each byte
        SPI1TWIDTHbits.TWIDTH = 0b000; // each byte transfers 8 bits
        
        // configure spi baud rate
        SPI1BAUDbits.BAUD = 0x07; // sck 4MHz
        
        SPI1INTF = 0x00; // clear all spi interupt flags
        SPI1INTE = 0x40; // enable only the transfer counter = 0 interrupt
        SPI1CON0bits.EN = 1; // enable SPI1
        
    } // SPI_init


    uint8_t SPI_get_return_temp(uint8_t x){
        
        uint8_t y, dummy;
        
        y = SPI_read_write(0x00);
        SPI1CON2bits.TXR = 1;
        dummy = SPI_read_write(x);
        
        return y;
        
    }

     
     
    Note:
    • I made and programmed the LCD Controller that loops sending the set_get_temp() function.
    • I run the Thermal Controller in the ICD3's debugger with a breakpoint in the interrupt routine WHICH NEVER INTERRUPTS
    • See the logic analyzer plot of spi communication:
      • NOTE: LCD Controller Master signals are at the bottom
     
    I feel the problem is that I'm not interrupting and never returning current_temp
     
    #10
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 15:01:25 (permalink)
    0
    I forgot the logic analyzer plot:

    Attached Image(s)

    #11
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 15:05:11 (permalink)
    0
    Analyzer plot zoomed in
     

    Attached Image(s)

    #12
    ric
    Super Member
    • Total Posts : 27630
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 15:21:50 (permalink)
    0
    You've not shown all the setup code in the slave. Have all the pins been switched from analog to digital mode?
    What control bytes have you written to the SPI peripheral?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #13
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 15:58:40 (permalink)
    0
    You've not shown all the setup code in the slave. Have all the pins been switched from analog to digital mode?
    What control bytes have you written to the SPI peripheral?

     
    My spi slave setup code is the 2nd to last code function block I attached (spi_init).  It says in the top comment it initializes as a slave.
     
    No, I did not switch from analog to digital but I will now.
    #14
    ric
    Super Member
    • Total Posts : 27630
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 16:13:19 (permalink)
    0
    JustRob
    My spi slave setup code is the 2nd to last code function block I attached (spi_init).  It says in the top comment it initializes as a slave.

    Sorry, I missed this block.
     However, it does not reveal which pins you are using, apart from RC5 for SDO.
     

    No, I did not switch from analog to digital but I will now.

    Leaving them analog could be fatal.
    I can't check if they are analog capable pins, as I don't know which pins you are using.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #15
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 18:03:19 (permalink)
    0
    The SPI header file press:


    #define SPI_SCK_TRIS TRISCbits.TRISC3 // SPI clock tris
    #define SPI_SLAVE_SDO_TRIS TRISCbits.TRISC5 // SPI slave data out
    #define SPI_SLAVE_SDI_TRIS TRISCbits.TRISC4 // SPI slave data in
    #define THERMAL_SPI_CS_TRIS TRISCbits.TRISC6 // SPI slave cs

    #define SPI_SLAVE_SDI_PPS 0b010100 // SPI SDI peripheral select pin RC4
    #define SPI_SLAVE_SDO_PPS 0b011111 // SPI SDO peripheral select pin RC5
    #define SPI_SCK_PPS 0b010011 // SPI SCK peripheral select pin RC3
    #define THERMAL_SPI_CS_PPS 0b010110 // SPI SS peripheral select pin RC6



    // spi write
    uint8_t SPI_read_write(uint8_t);
    void SPI_send_command(uint8_t);
    void SPI_send_data (uint16_t);
    uint8_t SPI_get_return_temp(uint8_t);
    uint8_t SPI_data_ready();

    // spi init function
    void SPI_init(void);


    /************************************************************************
    * Macro: spi_clk_low *
    * *
    * Preconditions: CS IO must be configured as output. *
    * *
    * Overview: This macro pulls down CS line *
    * to start a new lcd operation. *
    * *
    * Input: None. *
    * *
    * Output: None. *
    * *
    ************************************************************************/
    #define spi_clk_low() SPI_SCK_LATCH = 0;

    /************************************************************************
    * Macro: spi_clk_high *
    * *
    * Preconditions: CS IO must be configured as output. *
    * *
    * Overview: This macro pulls down CS line *
    * to start a new lcd operation. *
    * *
    * Input: None. *
    * *
    * Output: None. *
    * *
    ************************************************************************/
    #define spi_clk_high() SPI_SCK_LATCH = 1;


    #endif // __SPI_H

     
    #16
    ric
    Super Member
    • Total Posts : 27630
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 18:08:52 (permalink)
    0
    So
    SCK RC3
    SDI RC4
    SDO RC5
    SS RC6
     
    Have you written to ANSELC to switch them to digital?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #17
    JustRob
    Super Member
    • Total Posts : 584
    • Reward points : 0
    • Joined: 2008/09/04 12:49:27
    • Location: Hudson Massachusetts United States
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 18:10:31 (permalink)
    0
    Not yet, I'll be back at it tomorrow ~ 11 AM EST
    #18
    du00000001
    Just Some Member
    • Total Posts : 3778
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 18:24:39 (permalink)
    0
    Hi Rob,
     
    have the LCD controller transmit continuously. Then check with the debugger whether any data in the SPI RX buffer is received. The first 2 important signals are /CS (if used) and SCLK. No clock received, no interrupt. That simple. Although there's a number of options to misconfigure - starting with not clearing the ANS bits for the inputs (/CS, SCLK, MOSI) on the temp controller's side.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #19
    ric
    Super Member
    • Total Posts : 27630
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: SPI Slave mode interrupt or not (poll)... 2020/05/11 18:27:21 (permalink)
    0
    du00000001
    starting with not clearing the ANS bits for the inputs (/CS, SCLK, MOSI) on the temp controller's side.

    ANSELx in this device.
    I think we have established that the analog setting is almost certainly responsible.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #20
    Page: 12345 > Showing page 1 of 5
    Jump to:
    © 2020 APG vNext Commercial Version 4.5