• AVR Freaks

Hot!PIC32 - SPI goes round in circle

Author
tynnor
New Member
  • Total Posts : 10
  • Reward points : 0
  • Joined: 2018/04/17 05:59:34
  • Location: 0
  • Status: offline
2019/07/19 03:04:47 (permalink)
0

PIC32 - SPI goes round in circle

Hello,
 
I am using SPI on my PIC32MX675F512L. I wrote my own SPI ISR, I receive well every byte from the master (that I programmed too, with an other PIC32)
Howerver, I have (likely) a little issue. My SPI ISR goes in circle. My program seems looped some times in the state SPI_RECEIVING because indexListMax is incremented several times instead of once and the same block of data is copied in my array listPacketReceived
 
Have you got an idea ? Thank you for your help :) 
 
 
void SPI_ISR(){
    
    //interrupts for RX only
    
    if(IFS0bits.SPI1RXIF && SPI1STATbits.SPIRBF)
    {
 
            //Without activity for 20 ms, the machine state and the indexes will be reset 
            timeoutSpi = 0;

            switch (mStateSPI) //state machine variable
            {
                case SPI_IDLE:
                {
                    mStateSPI = SPI_RECEIVING; //at the first byte received, go on the next state
                    indexBuffRx = 0;
                    memset((void*) bufferRx, 0, sizeof(PacketSPI));
                    
                }
                //no break; here !

                case SPI_RECEIVING:
                {
                    bufferRx[indexBuffRx] = SPI1BUF;
                    indexBuffRx++;
                    
                    if(indexBuffRx > taillePacketSPI-1)
                    {
                        /*
                         * if we receive the whole frame, perform processing

 
                        *
                         * Put the frame in irs future index (indexListMax). If the frame if the CRC test if good,
                         * increment @indexListMax,
                         * Otherwise, the next good frame will replace the previous frame
                         */
                        
                        memcpy((void*) &listPacketReceived[indexListMax], (void*) bufferRx, taillePacketSPI);

                        //calculate CRC8
                        CRC8_Init();
                        CRC8_Calc((uint8_t*)&listPacketReceived[indexListMax].cmd, SPI_SIZE_PACKET_DATA+1);
                        volatile uint_fast8_t crcCalculated = CRC8_Get();
                        
                        if(listPacketReceived[indexListMax].crc != crcCalculated){
                            
                          //CRC error
                          SPI1BUF = SPI_CRC_ERROR;
                          
                        }
                        else
                        {
                            indexListMax++;
                            if(indexListMax >= LEN_LIST_PACKET)
                                indexListMax = 0;
                            
                            indexBuffRx = 0;
                            
                            //prepare answer for master
                            SPI1BUF = SPI_OK;
                        }

                        //on attend que le maitre lise notre donnée
                        mStateSPI = SPI_SEND_ANSWER;
                    }
                }
                break;


                case SPI_SEND_ANSWER:
                {
                    SPI1BUF;
                    mStateSPI = SPI_IDLE;
                }
                break;
              
            }


    }

    //clear flag
    /*IFS0bits.SPI1RXIF = 0;
    IFS0bits.SPI1TXIF = 0;
    IFS0bits.SPI1EIF = 0;*/
    SPI1STATbits.SPIROV = 0;
    IFS0CLR = 0x3800000;
}

 
#1

7 Replies Related Threads

    NorthGuy
    Super Member
    • Total Posts : 5544
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: PIC32 - SPI goes round in circle 2019/07/19 05:44:09 (permalink)
    4 (1)
    You must clear the IF flag. Or the ISR will be called again.
     
    Then this:
     
    if(IFS0bits.SPI1RXIF && SPI1STATbits.SPIRBF)

     
    Why are you doing this? If there's a possibility that a different interrupt enters the same ISR, you must handle it too. You must make sure that every time the ISR is called, the IF flag for the corresponding interrupt is cleared (whether you need to do things with the interrupt or not). Otherwise, the ISR will be called again.
    #2
    tynnor
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2018/04/17 05:59:34
    • Location: 0
    • Status: offline
    Re: PIC32 - SPI goes round in circle 2019/07/22 02:11:05 (permalink)
    0
    Hello,
    Thank you for your answer !
    Yes obviously I cleared the flags, and your right, the condition you pointed out is useless...I thought I was safer
     
    In fact, the problem came from the master which sent the frame again because of wrong CRC. Now my problem is to know why the master cannot read from the slave sucessfully. 
    In my slave RX ISR interrupt, I write the answer like in post #1, but what I receive is wrong
     
    Below, the piece of code to read and write from the master :
     
    uint8_t SPI_SendByte(uint8_t dataOut)
    {

        while(!SPI1STATbits.SPITBE);

        SPI1BUF = dataOut;

        while(SPI1STATbits.SPIRBF == 0){} //tant que le buffer RX est vide, on attend
        
        return SPI1BUF;
    }

     
     
            case SPI_SEND_DATA:
            {

                // 1 : send command
                SPI_SendByte(mListPacket[index].cmd);
                
                
                // 2 : send data frame
                volatile uint8_t i = 0;
                for(i = 0; i < SPI_SIZE_PACKET_DATA; i++){
                    spiAnswer = SPI_SendByte(mListPacket[index].data[i]);
                }


                // 3 : send CRC
                spiAnswer = SPI_SendByte(mListPacket[index].crc);
                

                //send dummy byte to read slave answer
                spiAnswer = SPI_SendByte(0xBB);
                if(spiAnswer != SPI_OK)
                {                
                    /*
                       other actions...........
                    */
                    
                    mStateSPI = SPI_END; //do the same things in case of success, for debugging
                    Nop();
                }
                else
                {
                    mStateSPI = SPI_END;
                }
            }
            break;

     
    How to answer to the master from the slave, properly ? 
    Thank you for your help :)
    #3
    ric
    Super Member
    • Total Posts : 23221
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC32 - SPI goes round in circle 2019/07/22 02:15:30 (permalink)
    0
    To start with, you need to see what the Master is receiving.
    Is it always zero?
     

    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!
    #4
    tynnor
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2018/04/17 05:59:34
    • Location: 0
    • Status: offline
    Re: PIC32 - SPI goes round in circle 2019/07/22 02:25:24 (permalink)
    0
    Thank you for your quick answer.
    Below an update of the ISR slave :
     
     

    volatile uint8_t counter = 0;
     
    void SPI_ISR(){
        
        //interrupts for RX only
                //Without activity for 20 ms, the machine state and the indexes will be reset
                timeoutSpi = 0;

                switch (mStateSPI) //state machine variable
                {
                    case SPI_IDLE:
                    {
                        mStateSPI = SPI_RECEIVING; //at the first byte received, go on the next state
                        indexBuffRx = 0;
                        memset((void*) bufferRx, 0, sizeof(PacketSPI));
                        
                    }
                    //no break; here !

                    case SPI_RECEIVING:
                    {
                        bufferRx[indexBuffRx] = SPI1BUF;
                        indexBuffRx++;
                        
                        if(indexBuffRx > taillePacketSPI-1)
                        {
                            /*
                             * if we receive the whole frame, perform processing
     
                            *
                             * Put the frame in irs future index (indexListMax). If the frame if the CRC test if good,
                             * increment @indexListMax,
                             * Otherwise, the next good frame will replace the previous frame
                             */
                            
                            memcpy((void*) &listPacketReceived[indexListMax], (void*) bufferRx, taillePacketSPI);

                            //calculate CRC8
                            CRC8_Init();
                            CRC8_Calc((uint8_t*)&listPacketReceived[indexListMax].cmd, SPI_SIZE_PACKET_DATA+1);
                            volatile uint_fast8_t crcCalculated = CRC8_Get();
                            
                            if(listPacketReceived[indexListMax].crc != crcCalculated){
                                
                              //CRC error
                              SPI1BUF = SPI_CRC_ERROR;
                              
                            }
                            else
                            {
                                indexListMax++;
                                if(indexListMax >= LEN_LIST_PACKET)
                                    indexListMax = 0;
                                
                                indexBuffRx = 0;
                                
                                //prepare answer for master
                                SPI1BUF = SPI_OK;
                            }

                            //on attend que le maitre lise notre donnée
                            mStateSPI = SPI_SEND_ANSWER;
                        
                    }
     
     
     
     
     
     
     
                   else{
     
                        SPI1BUF = counter++;
     
                   }
                    break;
                  }
    }

     
    No the master doesn't receive 0, but I don't know what the received data means, except, at the last call of SPI_SendByte() where I received again the last byte (CRC) of my data. But the previous received bytes mean nothing...but I am beware of the debugger
     
    post edited by tynnor - 2019/07/22 02:30:08
    #5
    ric
    Super Member
    • Total Posts : 23221
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC32 - SPI goes round in circle 2019/07/22 03:01:14 (permalink)
    0
    tynnor
    ...but I am beware of the debugger

    What does this mean?
     

    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!
    #6
    tynnor
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2018/04/17 05:59:34
    • Location: 0
    • Status: offline
    Re: PIC32 - SPI goes round in circle 2019/07/22 03:10:49 (permalink)
    0
    It happened to me the debugger didn't show me the truth
    #7
    tynnor
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2018/04/17 05:59:34
    • Location: 0
    • Status: offline
    Re: PIC32 - SPI goes round in circle 2019/07/26 06:36:46 (permalink)
    0
    I have finally found. The ISR did too much things (memcpy() + crc )
    The resolve this, the master gives time to the slave to perform the last step
    #8
    Jump to:
    © 2019 APG vNext Commercial Version 4.5