• AVR Freaks

Hot![solved] 32MX sending a string to a 24FJ via SPI - how best to synchronize?

Author
Spottymaldoon
Super Member
  • Total Posts : 223
  • Reward points : 0
  • Joined: 2010/02/05 09:25:22
  • Location: 0
  • Status: offline
2020/06/05 07:19:53 (permalink)
0

[solved] 32MX sending a string to a 24FJ via SPI - how best to synchronize?


I am sending a time code "unsigned char RTC[8]" via SPI from a 32MX (which is the slave) to a 24FJ. Sending a single pass byte works fine - the 24FJ is waiting for an enable signal and the SPI is set up:


//32MX has been doing another job but now needs to transmit a byte to the 24FJ which is waiting with SPI enabled
 
 
 
//in slave mode
 
 
 

writeSPI3(byte);// and that's it
ENABLE_24FJ;//


//then

//24FJ

SSen;//enable slave
while(!MX_READY) ;//is sitting waiting for the transmission
DELAY;//a few uS
s=readSPI3();
SSdis;


But then I want send multiple bytes like this:

 
 
 

//32MX
ENABLE_24FJ;
for(i=0;i<9;i++)
{
writeSPI3(RTC[i]);
}

//24FJ
SSen;
while(!MX_READY) ;
for(i=0;i<9;i++)
{
RTC[i]=readSPI3();//so that I can reassemble RTC[] on the other side.
}
SSdis;


Now, obviously, there is no synchrony here and so this won't work - each chip has a GPIO token it can send the other saying "ready" - or not. What is the most elegant way to do this?

Note: I have the 32MX as slave because, later, I have a mass of data to send from the 24FJ.
post edited by Spottymaldoon - 2020/06/07 19:13:43
#1

10 Replies Related Threads

    NorthGuy
    Super Member
    • Total Posts : 6171
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 08:06:22 (permalink)
    0
    Using UART instead of SPI is the most elegant way.
    #2
    bkamen
    Super Member
    • Total Posts : 835
    • Reward points : 0
    • Joined: 2010/01/26 12:39:27
    • Location: Central Illinois, USA
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 09:00:30 (permalink)
    0
    You really need to have a command structure on the slave.

    Because SPI is clocked by the master, there needs to be some understanding by the slave that the master is expecting data on the next set of clocks.

    When you look at the datasheets of lots of SPI devices (particularly slaves), the master has to send a command that tells the slave it wants data.

    The slave then gets the data and loads it into the buffer for transmission. then the master sends another byte which could be nothing but zeros just so it can clock out what the slave previously put in the buffer.

    SPI is nice because it's faster. But also understand the clock doesn't free-run and so you need to come up with a command-set/protocol for what you want to communicate.

    UARTs are nice, but you still run into the same problem unless the data being send is only of one type ever.
    UARTs are slower most of the time too. (depends on the PIC though.)
    #3
    NorthGuy
    Super Member
    • Total Posts : 6171
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 09:17:26 (permalink)
    0
    bkamen
    UARTs are nice, but you still run into the same problem unless the data being send is only of one type ever.



    How's that? With UART, both parties send at will independently of each other, and there's no need for the slave to wait until master provides the clock. UART also ensures bit synchronization so you can get rid of SS lines. Two wires is all you need.
    #4
    bkamen
    Super Member
    • Total Posts : 835
    • Reward points : 0
    • Joined: 2010/01/26 12:39:27
    • Location: Central Illinois, USA
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 09:35:23 (permalink)
    0

    1: Speed. SPI buses tend to be much faster than UARTs. When your SPI CLK is over 1MHz which ends up being 125KHz for 8bit data, that's still faster than 115,200bps. (again - it depends on the PIC and the UART capabilities)

    2: SPI doesn't have start/stop bits - so that's an improvement is the amount of data per bit.

    3: Your argument of the clock delay is irrelevant for queued/polled data. If the master has to send a command, the slave must wait to receive that command and then the master must wait for N bits of time (8 or 16) to receive the data. (it's actually a little slower considering the wastage of start/stop bits that are included in ASYNC transmissions) - So whether the master sends the clock to the slave is irrelevant.


    #5
    bkamen
    Super Member
    • Total Posts : 835
    • Reward points : 0
    • Joined: 2010/01/26 12:39:27
    • Location: Central Illinois, USA
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 09:39:46 (permalink)
    0
    BTW, I also think it would be a good idea to ask the OP why they chose SPI over UART.

    What kind of data is being sent?
    What kind of performance is needed?
    How far away is the PIC32 from the PIC24? Same PCB or long distances?
    #6
    Spottymaldoon
    Super Member
    • Total Posts : 223
    • Reward points : 0
    • Joined: 2010/02/05 09:25:22
    • Location: 0
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 10:26:25 (permalink)
    0
    Thanks for responding - I have never used UART actually and that SPI channel has been perfect for shifting large amounts of 16 bit AD converter data from the 24FJ (yes, same board). I was hoping I could get a bonus here because there's so little needed in the reverse direction and it would make my package a lot neater so, bkamen, I'll see if I can implement your suggestion first.
     
    It was only when I came to try and write the code using SPI that I saw I had a potential problem.
     
    In fact I am now thinking it will be less tedious just to bit-bang it - I'm assuming we revert to GPIOs if we just temporarily put SPI3CONbits.ON=0? Speed isn't an issue for this transfer - the main one yes.
    post edited by Spottymaldoon - 2020/06/05 10:30:29
    #7
    bkamen
    Super Member
    • Total Posts : 835
    • Reward points : 0
    • Joined: 2010/01/26 12:39:27
    • Location: Central Illinois, USA
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 11:19:13 (permalink)
    0
    If you're going to big-bang it, you will take a serious performance hit.

    You actually want to use IRQ driving data feeders and with the PIC24 and PIC32, I bet their DMA available.

    Keep in mind also, with SPI, a common feature of the ChipSelect (~CS or nCS or CSb) is to reset the state machine of the slave. You can do all sorts of things with this like act as a framing flag and it can be automatic depending on the PIC. (Some will auto-select _CS_ when TXBUF is loaded on the master)

    If your flow is ONLY one way, you don't even really need the MOSI line at all. Just SCK, _CS_ and MISO.

    I would write it like this:
     * get all my SPI calls working right and the data flow in a single taks demo app.
     * Then I would move the SPI data flow into an IRQ driven sub-system. Then I would build the rest of my app.
     * Check the performance. If needed, add DMA if available on the PIC.

    Good Luck,

     -Ben
    #8
    Spottymaldoon
    Super Member
    • Total Posts : 223
    • Reward points : 0
    • Joined: 2010/02/05 09:25:22
    • Location: 0
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 13:52:00 (permalink)
    +1 (1)
    To become a Super Member here all you have to do is post enough garbage! Therefore while I am sure you deserve the title, Ben, I do not - and your advice, while I am sure it's excellent, is a bit over my head and, honestly, for this little segment, performance isn't important. I've come to digital rather late in life and I am just happy if my program does all that I need it to do. Thanks again.
    Richard
    #9
    NorthGuy
    Super Member
    • Total Posts : 6171
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/05 15:49:23 (permalink)
    +2 (2)
    If you want to use SPI, the most important thing is to understand how it works: Master provides clock. While the clock is present, the master and the slave send and receive data - simultaneously.
     
    Slave writes data into a register, but it doesn't go anywhere until the master doesn't send the clock (8 pulses to transfer a byte). Slave has to hang on until that moment, then the slave provides the byte for the next clock.
     
    So, this should work something like:
     
    - master asserts SS
    - slave writes dummy byte to SPIBUF
    - master writes the request command to SPIBUF, which causes clock to be emitted
    - transaction transfers command to the slave
    - master reads the byte from SPIBUF
    - slave reads the command from SPIBUF
    - slave writes first byte of the response to SPIBUF
    - master waits to make sure the slave had enough time to load the byte
    - master writes dummy byte to SPIBUF, which causes clock
    - transaction happens
    - slave reads the dummy byte from SPIBUF
    - master reads the data byte from SPIBUF
    - slave writes the second byte of response to SPIBUF
    - master waits ...
     
    ....(repetated for as many bytes as needed)
     
    - master de-asserts SS
     
    As you can see, the synchronization of every byte is achieved by the master giving slave enough time. Slave cannot be late. If it doesn't put the byte in time. before the master starts clocking, the transmission is ruined.
     
    Some SPI modules have FIFO buffers which makes this easier.
     
    UART is much easier, because both master and slave send at their own pace.
    #10
    Spottymaldoon
    Super Member
    • Total Posts : 223
    • Reward points : 0
    • Joined: 2010/02/05 09:25:22
    • Location: 0
    • Status: offline
    Re: 32MX sending a string to a 24FJ via SPI - how best to synchronize? 2020/06/07 16:29:19 (permalink)
    0
    NorthGuy - Thank you for your detailed reply which I followed closely. I am totally happy with the result and was surprised that I didn't have to insert any delays - maybe I was lucky with my chip combination? Here's what I did & I am amazed something this simple could work:
     

     
    //32MX transmit (slave)
    void SendRTC(void)
    {
    unsigned char i;
    ENABLE_24FJ;
    for(i=0;i<9;i++)
     {
     writeSPI3(RTC[i]);//RTC data&time
     while((!SPI3STATbits.SPIRBF));
     }
    }//ends SendRTC

     

     
    //24FJ receive (master)
    unsigned char GetRTC(void)
    {
    unsigned char i;
    SSen;
    while(!MX_READY);
    for(i=0;i<9;i++)
     {
     RTC[i]=readSPI3();
     }
    SSdis;
    return *RTC;
    }//end GetRTC

     
    Really appreciate your trouble.
    #11
    Jump to:
    © 2020 APG vNext Commercial Version 4.5