This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SSI (SPI) interface on TM4C123GXL



Hi, can anyone help me? I'm trying to use de SSI interface of my microcontroler. Cause I have no clear how to program it I decided set the loopback flag. I selected the SSI2 as master. I send some data but all i have recieved is 0x0000.
I've tried with SSI3 too.

Any ideas?

I paste my code:
void SPI2_Init(void){ //Puerto b4,b5,b6,b7 -> clk, Fss,rx,tx
    SYSCTL_RCGCSSI_R|=0x04;                     //enable module ssi2
    SYSCTL_RCGCGPIO_R |=0x02;                    //clock puerto B
    GPIO_PORTB_AFSEL_R |= 0xF0;             //alternate function select en pines
    GPIO_PORTB_PCTL_R |=0x22220000;         //bits 7,6,5,4 funcion sspi2 tabla 23-5
    GPIO_PORTB_DEN_R |= 0xF0;                 //son digitales
 //GPIO_PORTB_PUR_R |=0x80;                     //pullup en clock para steady state high
    SSI2_CR1_R &= ~0x02;                            //inhabilita SSI2 bit SSE  
    SSI2_CR1_R |= 0x01;                        //loopback
    SSI2_CR1_R &= ~0x04;                                    //master
    SSI2_CC_R &= ~0x07;                                        //clock ssi igual al del sistema y factor de division
    SSI2_CPSR_R |= 0x32; //50d                    //BR=SysClk/(CPSDVSR * (1 + SCR)  (bit rate=clock/valor pongo en cpsr *(i sr que pongo en cro)
    SSI2_CR0_R |=0x5827;                            //SCR=1 MICROWIRE
    SSI2_IM_R |=0x04;                                        //habilita interrupcion en rx
    SSI2_CR1_R |= 0x02;                                //habilita SSI2 bit SSE  
}


void SPI2_envia(unsigned char letra){
    unsigned short palabra16=0x2222;
    unsigned char bitbusy;
    bitbusy=SSI2_SR_R & 0x40;
    palabra16 |= letra;
    while(bitbusy==0x40){};                         //wait while busy
    SSI2_DR_R =palabra16;                                    //write to send.
}


void SSI2_Handler(void){
    unsigned long data;
            while((SSI2_SR_R & 0x04)==0x04 ){  //fifo rx no empty
                if((SSI2_SR_R & 0x10) ==0x00){         //no busy
                    data=    SSI2_DR_R        ;           
                }
            }
}

  • Hello Jose

    First of all the DRM is especially not a good manner to program the device. I may have a tough time reading what is being programmed. I would suggest moving over the code to TivaWare. There is an example code for SSI in TivaWare Installation under examples/peripheral/ssi for Loopback mode. I would suggest porting that over and using the same.

    Regards
    Amit
  • Amit Ashara said:
    First of all the DRM is especially not a good manner to program the device.

    So true - fully agree - yet we wonder, "How did poster make this choice?"   Did poster even know that a powerful code library exists?

    We've long noted that DRM (Direct Register Macros) are the (predominant) code examples w/in the otherwise detailed MCU Manuals.   In fact - the MCU Manuals - unless they've changed recently - give no hint that StellarisWare or TivaWare even exist!   That seems a glaring oversight - does it not - and may explain why "too many" posters present here - using strictly DRM!

    Multiple mentions of the extensive driver library - w/in the MCU Manuals - may reduce the (much harder) use of DRM by posters who are unaware of the extensive code libraries...   (this reporter has past appealed for such "code library mention" - to the (usual) vendor silence...)

  • Thanks Amit for your answer.


    I'm a newbie using this microcontroller so i thought i was a great idea try to program something using registers directly to understand the architecture of the microcontroller and adquaire some experience. Until now I had never programmed an arm.  Thank you for your advice about the example. I'll try to follow it.


    Thanks.

  • Hi cb1.
    I did this choice because i wanted to know what would be doing any library i had used. I'm a newbie and i want to know the registers. I agree with you the seller don't give you enough and clear information about the libraries you can use when you buy this microcontroller. By now i'm using the microcontroller datasheet and, as you can imagine, sometimes i have a lot of doubs.

    thanks for your support :)
  • Hi Amit.

    Following your advice i downloaded Tiva libraries and examples and i tried to program the SSI2 of my TM4C123GH6PMI following the example. My code is pasted below.
     I'm still having the same problems... I recieve nothing but 0x00. I've done different test. Sometimes using interruptions and other times not using it. Using tiva the interruption Rx flag is not set despite is enable RX interruption in the SSIIM register and the global interruptions are enable. On the other hand when I use the blocking RX commad of TIva to receive the data i previusly send I only get 0x00.


    void Init_SSI2(){
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);

        // For this example SSI2 is used with PortB[4:7]. clock, fss, rx, tx
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB4_SSI2CLK); 
        GPIOPinConfigure(GPIO_PB5_SSI2FSS);
        GPIOPinConfigure(GPIO_PB6_SSI2RX);
        GPIOPinConfigure(GPIO_PB7_SSI2TX);  
        GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4); //tx, rx, fss, clock
          
        SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 1000000, 3);
            
         //!!!!!!!
         SSI2_CR1_R |= 0x01;  // I set the  loopback operation mode manually


        SSIEnable(SSI2_BASE);    // Enable the SSI0 module.
            
         // Read any residual data from the SSI port.
        while(SSIDataGetNonBlocking(SSI2_BASE, &buffSSIRx[0]))    {  }      
    }

    //SEND function
    void UART0Enviar(const unsigned char *pbuff, short numdatos){ // Send a string to the UART.
        while(numdatos--){   // Loop while there are more characters to send.
                letra=    *pbuff;
          ROM_UARTCharPutNonBlocking(UART0_BASE, *pbuff++);        // Write the next character to the UART.
        }
    }}

    //RECEIVE function. i've been using different options.
    void SSI2recibir(){
        unsigned long data;
        while((SSI2_SR_R & 0x04)==0x04 ){  //fifo rx not empty RNE
            if((SSI2_SR_R & 0x10) ==0x00){         //no busy BSY
                data=    SSI2_DR_R;            
                OuttoUART0( data,"SSI2_DR_R ")
            }
        }
    }

    Any idea???

  • Hello Jose.

    Where are you writing the data to the SSI Data Register?

    Regards
    Amit
  • I wrote it to:  unsigned short data; while there are data in the Rx FIFO and SSI2 is not busy. But I always get 0x00.

    Have any idea which is the problem?

  • Hello Jose

    I do not see that in your latest code. After you have cleared the received FIFO, can you add the following line where pui32DataTx contains the data to transmit and pui32DataRx gets the data

    uint32_t pui32DataTx = 0xA;
    uint32_t pui32DataRx;

    SSIDataPut(SSI2_BASE, pui32DataTx);
    //
    // Wait until SSI0 is done transferring all the data in the transmit FIFO.
    //
    while(SSIBusy(SSI2_BASE))
    {
    }
    //
    // Receive the data using the "blocking" Get function. This function
    // will wait until there is data in the receive FIFO before returning.
    //
    SSIDataGet(SSI2_BASE, &pui32DataRx);

    Regards0
    Amit