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.

EK-TM4C129EXL: Forward SPI frame

Part Number: EK-TM4C129EXL


Hi Folks,

In my application I want to chain arbitrary number of CPU boards via SPI:

the FSS and CLK signals are common

Tx and Rx are connected from board to board

and a master board should send data. Each board needs 1 byte of frame.

My question is, is it possible to send arbitrary size of SPI frame? If I set the frame size to 8 bit, the first board will get it every time, but nobody following it gets any valid data.

Regards,

Norbert

  • Yes, use advanced mode, with hold frame enabled. You send all bytes with SSIDataPut() except the last byte you send with SSIAdvDataPutFrameEnd(). To get the data to pass from one slave to the next, it will be necessary to read the received data and, if FSS is not deasserted, put it into the output buffer so it will be sent to the next slave. This will need to be done before the master starts transmitting the next byte. I have to admit that I do not have time to write this code and verify it, but here is what I think it looks like to initialize a master (example uses SSI1) and a slave (example uses SSI3).

    #define MASTER SSI1_BASE
    #define SLAVE SSI3_BASE
    
    // Initialize SSI1 as master
    void QSSIMasterInit(uint32_t SysClk_Freq, uint32_t baud_rate)
    {
    	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
        MAP_GPIOPinConfigure(GPIO_PB5_SSI1CLK);
        MAP_GPIOPinConfigure(GPIO_PB4_SSI1FSS);
        MAP_GPIOPinConfigure(GPIO_PE4_SSI1XDAT0);
    
        MAP_GPIOPinTypeSSI(GPIO_PORTB_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
        MAP_GPIOPinTypeSSI(GPIO_PORTE_AHB_BASE, GPIO_PIN_4 );
    
        MAP_SSIConfigSetExpClk(MASTER, SysClk_Freq, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, baud_rate, 8);
        MAP_SSIEnable(MASTER);
        SSIAdvModeSet(MASTER, SSI_ADV_MODE_READ_WRITE);
        SSIAdvFrameHoldEnable(MASTER);
    }
    
    // Initialize SSI3 as slave
    void QSSISlaveInit(uint32_t SysClk_Freq, uint32_t baud_rate)
    {
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
    
        MAP_GPIOPinConfigure(GPIO_PQ0_SSI3CLK);
        MAP_GPIOPinConfigure(GPIO_PQ1_SSI3FSS);
        MAP_GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0);
    
        MAP_GPIOPinTypeSSI(GPIO_PORTQ_BASE, GPIO_PIN_0 | GPIO_PIN_1 |GPIO_PIN_2 );
    
        MAP_SSIConfigSetExpClk(SLAVE, SysClk_Freq, SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, baud_rate, 8);
        MAP_SSIEnable(SLAVE);
        SSIAdvModeSet(SLAVE, SSI_ADV_MODE_READ_WRITE);
        SSIAdvFrameHoldEnable(SLAVE);
    }
    

  • Hi,

    It sounds very well, but two more things raised up:

    1. I'm looking for a solution, where I don't have to take care about the frame timing. So: you mentioned that I have to read out the data in the slave and write into the FIFO again before the master sends new frame, but I would like to avoid such a software "redirections"
    2. E.g.: the SSI1 FSS signal can be present on more than one pin (in case of TM4C123A these are PF3, PD1): the question is: if I configure them to be SSI1Fss signals, will they connected "electrical" ?

    • I mean, the master connected to one pin,
    • the master initiate a frame sending, so the Fss change
    • does it appear on the other pin too?

    Regards,

    Norbert

  • 1, Sorry, the hardware does not support that the value shifted into the shift register is automatically shifted out if you just keep clocking. DMA can be used to do the transfer to avoid the CPU interrupts.
    2. If the same signal is assigned to two different GPIO port pins, the signal is assigned to the port with the lowest letter and the assignment to the higher letter port is ignored.
  • Hi,

    Starting with 2): seems you try now to select which board will get data, although you said in first post SSIFSS will be common - you can do that with separate pins configured as GPIO pins and used as FSS, but it will be a nightmare  - one pin for each board, unspecified number, and one function for send/ receive for each board. Much simpler if you use an external decoder, like 138, and extra 3 pins for selecting the board, and FSS can be either automatic, either GPIO, and a single function to send/receive.

    Also, in this case, a more flexible connection will be the use of UART, only 2 pins, and a little bit software. Selection can be done by first byte as address of board, the next bytes to be data.

    Depending the distance between boards, also the CAN interface could be used.