Connect with us

SS not working on spi

Discussion in 'Microcontrollers, Programming and IoT' started by Daniel Morley, Dec 5, 2019.

Scroll to continue with content
  1. Daniel Morley

    Daniel Morley

    4
    0
    Dec 5, 2019
    I am a little new to programming spi and need help with a tiny 416. I am trying to talk to a slave 25r3911b from STMicroelectronics. I am using the below function to send a task to the slave. Basically read the operation control register.

    Code:
    void Read25r3911b (uint8_t commandaddress)
    {   uint8_t data;
        uint8_t TEMP;
        TEMP=commandaddress;
     
        PORTC_set_pin_level(3,low);
     
        SPI_0_write_block(&TEMP,1);
     
        PORTC_set_pin_level(3,high);
     
     
    
    //    SPI_0_read_block(&TEMP,1);
     
     
    }
    It is giving the expected output on the MOSI of 0x42. The problem is the chip select is going high on the SS.
     

    Attached Files:

    Last edited by a moderator: Dec 6, 2019
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    10,396
    2,271
    Nov 17, 2011
    I pt your code in a code box for better readability.

    By SS you mean Slave Select which would be SPI-Enable in your screenshot, right? I recommend you use the same terms in text and image to allow us to correlate items. I further assume that Port C3 is the SPI-Enable signal.
    I think (and this is purely my interpretation) the issue you experience is that the SPI write cycle is executed asynchronously to your program by the hardware SPI unit. Meaning:
    You set SPI-Enable low, then start the SPI write cycle and immediately set SPI-Enable to high. But the SPI write cycle continues in hardware in parallel while the program also continues. Therefore SPI-Enable goes high too early.
    Remedy: After SPI_0_write... put in a loop and check the SPI status. Continue with PORTC_set_pin_level(3, high) only after the SPI transfer has completed.
    See e.g. here.

    Hope this helps.
     
    Daniel Morley likes this.
  3. Daniel Morley

    Daniel Morley

    4
    0
    Dec 5, 2019
    I think your right. That helps. I am still confused when I look for the interupt flag it, the ss pin is still going high too soon.

    void Read25r3911b (uint8_t commandaddress)
    { uint8_t data;
    uint8_t TEMP;
    TEMP=commandaddress;

    PORTC_set_pin_level(3,low);

    SPI_0_write_block(&TEMP,1);
    while (((SPI0.INTFLAGS >> 6) & 1) == 1);



    SPI_0_write_block(&TEMP,1);
    while (((SPI0.INTFLAGS >> 6) & 1) == 1);



    PORTC_set_pin_level(3,high);



    }
     

    Attached Files:

  4. Harald Kapp

    Harald Kapp Moderator Moderator

    10,396
    2,271
    Nov 17, 2011
    In between these instructions
    Code:
    PI_0_write_block(&TEMP,1);
    while (((SPI0.INTFLAGS >> 6) & 1) == 1);
    
    
    
    SPI_0_write_block(&TEMP,1);
    while (((SPI0.INTFLAGS >> 6) & 1) == 1);
    you need to clear the interrupt flag. A little bit further in the discussion I linked in post #2 you'll find this box:
    It seems you didn't do this (either by adding a suitable interrupt routine or by clearing the flag in software). Therefore when your program reaches the 2nd SPI_0_write_block instruction the interrupt flag is still high and the loop after the SPI_0_write_block instruction is never executed, leading to PORTC_set_pin_level(3,high); being immediately executed.

    By the way:
    1. Code is easier to read if you use the insert code menu entry (menu bar, left of the sub/sup button.
    2. I recommend you increase the resolution of your logic analyzer to improve the accuracy of the display. With your current resolution e.g. the clock signal is not symmetrical, which is surely not due to a fault in the hardware but an artifact of sampling at too low a rate.
     
  5. Daniel Morley

    Daniel Morley

    4
    0
    Dec 5, 2019
    uint8_t Read25r3911b (uint8_t commandaddress)
    { uint8_t data;
    uint8_t TEMP;
    TEMP=commandaddress;

    PORTC_set_pin_level(3,low);

    SPI_0_write_block(&TEMP,1);
    while ((SPI0.INTFLAGS & SPI_RXCIF_bm) == 0) ;
    SPI0.INTFLAGS &= ~(1<<INTERUPT_FLAG);
    // while (SPI_0_status_done());

    // SPI_0_write_block(&TEMP,1);
    // while (((SPI0.INTFLAGS >> 6) & 1) == 1);



    SPI_0_read_block(&TEMP,1);
    while ((SPI0.INTFLAGS & SPI_RXCIF_bm) == 0) ;
    SPI0.INTFLAGS &= ~(1<<INTERUPT_FLAG); //INTERUPT_FLAG is 7

    PORTC_set_pin_level(3,high);


    SPI_0_read_block(&TEMP,1);
    while ((SPI0.INTFLAGS & SPI_RXCIF_bm) == 0) ;
    SPI0.INTFLAGS &= ~(1<<INTERUPT_FLAG);

    //PORTC_set_pin_level(3,high);

    // while (SPI_0_status_done());
    return TEMP;
    }
     
  6. Daniel Morley

    Daniel Morley

    4
    0
    Dec 5, 2019
    I am not seeing a sup/sub button nor a button that is will isolate the code. I clear RXCIF/IF and it is still messing with spi communication.
     

    Attached Files:

  7. Harald Kapp

    Harald Kapp Moderator Moderator

    10,396
    2,271
    Nov 17, 2011
    upload_2019-12-9_18-48-57.png

    Unfortunately I'm not into the details of PIC programming, but I do not see where you would clear the interrupt flag.
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-