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.

TM4C123GH6PM: The byte received is not related to the byte sent using internal loop

Part Number: TM4C123GH6PM

Hi,

This program loops TX to Rx internally  . What  I receive is not related to what I sent. Why ?

#include <lm4f120h5qr.h>

uint8_t send = 0x00;
uint8_t myrxd = 0x00;

void ReadSPI(void){
while ( (SSI2->SR &(1<<2))== 0); //wiat while empty
myrxd = SSI2->DR;
}
void writeSPI(uint8_t data){
SSI2 -> DR = data;
while( (SSI2 -> SR & (1 << 4)) == 1);// wait while busy
}
int main()
{

//15.4 Initialization and Configuration
//1. Enable the SSI module using the RCGCSSI register (see page 346).
SYSCTL -> RCGCSSI |= (1 <<2); // SSI2

//2. Enable the clock to the appropriate GPIO module via the RCGCGPIO register (see page 340).
SYSCTL -> RCGCGPIO |= ( 1 << 1); // PORT B

//3. Set the GPIO AFSEL bits for the appropriate pins (see page 671). To determine which GPIOs to
GPIOB ->AFSEL |= (1 <<4)|(1<<5)|(1<<6)|(1 <<7);// PB4-PB7 SSI pins
GPIOB ->PUR |= (1 <<4)|(1<<5)|(1<<6)|(1 <<7); // enable pull-up


//4. Configure the PMCn fields in the GPIOPCTL register to assign the SSI signals to the appropriate
//pins. See page 688 and Table 23-5 on page 1351.
GPIOB -> PCTL |= ( 2<< 16) | ( 2<<20) | (2 << 24)|(2 <<28); //PMC 4/5/6/7

//5. Program the GPIODEN register to enable the pin's digital function. In addition, the drive strength,

GPIOB -> DEN |= (1 << 4) |(1<<5)|(1<<6)|(1<<7);

//For each of the frame formats, the SSI is configured using the following steps:
//1. Ensure that the SSE bit in the SSICR1 register is clear before making any configuration changes.
SSI2 -> CR1 &=~(1<<1);

//2. Select whether the SSI is a master or slave:
SSI2 -> CR1 = 0x00000000;
SSI2 -> CR1 |= (1<<0); // Internal loop TX-RX


//3. Configure the SSI clock source by writing to the SSICC register.

SSI2 -> CC = 0x00; //sys clock


//4. Configure the clock prescale divisor by writing the SSICPSR register.
SSI2 -> CPSR = 0x10;

//5. Write the SSICR0 register with the following configuration:

SSI2 -> CR0 = (0x7<<0); //0x0007

//6. Optionally, configure the SSI module for µDMA use with the following steps:

//7. Enable the SSI by setting the SSE bit in the SSICR1 register.
SSI2 -> CR1 |=(1<<1); //enable SSI


while(1)
{
writeSPI(send++);

for ( int x=0; x <10 ; x++){
for (int i=0; i < 100000;i++);
}

ReadSPI();

for (int i=0; i < 1;i++);                          //for break
}

return 0;
}

  • Feel your pain - yet had you considered the fact that your (exclusive) use of "DRM" adds (both) time & effort to the Diagnostic Efforts of your "Helper Crüe" - be they vendor agents or outsiders?

    Vendor agents - while not (fully) consistent - mostly advise posters to, "Avoid DRM - due to its increased demand - and provision of (very) slight benefit." (i.e. Adds Workload - while producing NO Gain!)

    There are a substantial number of tested code examples included w/in the vendor's API - almost none - presented under "DRM." These have (long) been proven to, "Speed, Ease & Enhance" your MCU capability & understanding.

    To your issue - most SPI implementations operate in "Full Duplex" (Data OUT and Data IN are clocked by the same SPI clock sequence [possibly upon different clock edges] thus the Data being "Sent" - will not be available (via the API's "SPIDataGet()") until the (next) clock sequence.

    It is usual that the two key SPI functions w/in the API occur "back to back." (i.e. SPIDataPut() followed by SPIDataGet()...)

    Note that your "log-on" appears as "Shamson" ... yet your signature line signed,  "Shamsan!" 

  • cb1_mobile.

    Why you are focusing on my "name" and playing with the words; no one put the gun on your head to answer it.
  • "Attention to Detail" proves CRUCIAL - especially when one deploys the archaic, inefficient DRM.

    Your noting of "focus" proves well "Off Mark" as well - FIVE preceding sentences argue STRONGLY against your "mischaracterization" of FOCUS!

    Indeed I'll avoid any/all subsequent postings - under EITHER ... "WHOOPS ... NOW THREE!"  of your  "banners!"

  • Hello sonMEE,

    Naming debate aside, cb1's description of our support model is accurate. We spent a lot of time & energy into developing TivaWare to remove the need for customers like yourself from having to understand the complex nature of coding with DRM. Our TivaWare API's are well-tested and widely used, and they present the easiest and quickest path to getting TM4C devices working within the scope of your application. Please download TivaWare from http://www.ti.com/tool/SW-TM4C and use that for your project moving forward. If you really are insistent on using DRM due to your own requirements, we won't be able to support that much/if at all, though in that case even then TivaWare may benefit you as you can view how the properly coded API's from TivaWare handle processes like transmitting/receiving over SPI.
  • Hi Ralph,
    I'm following the steps from the data sheet. No other external hardware , slave, involves . Tx internally looping to Rx. It's a small code and easy to tell if one statement is not correct or required to add or Tiva board is malfunctioning . Thanks
  • Hi cb1_mobile,
    Can you please use simple English to communicate.
  • Hello sonMEE,

    Please understand that we are not going to deviate from our support model just because it's 'small code'. Besides even if you claim it is small now, the project will grow in complexity and become impossible for us to support. You are doing yourself a disservice by rejecting using TivaWare when 100's before you have quickly succeeded with it. Sorry, but that is all I can say on the matter.
  • Here  is an example of doing the loop back using the TivaWare library and a single use of HWREG to enable to enable loop back mode.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #include "driverlib/pin_map.h"
    
    unsigned char u8DataTx[4] = {'A','B','C','D'};
    unsigned char u8DataRx[4];
    
    
    int
    main(void)
    {
        uint32_t ui32Index, ui32Data;
    
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
        // The SSI2 peripheral must be enabled for use.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
        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_6 | GPIO_PIN_5 | GPIO_PIN_6 |
                       GPIO_PIN_7);
        SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 1000000, 8);
        SSIEnable(SSI2_BASE);
    
        // Enable Loopback mode on SSI2
        // There is no Tivaware function for this
        HWREG(SSI2_BASE + SSI_O_CR1) |= 1u;
    
        // Send n bytes of data.
        //
        for(ui32Index = 0; ui32Index < 4; ui32Index++)
        {
            //
            // Send the data using the "blocking" put function.  This function
            // will wait until there is room in the send FIFO before returning.
            // This allows you to assure that all the data you send makes it into
            // the send FIFO.
            //
            SSIDataPut(SSI2_BASE, u8DataTx[ui32Index]);
            SSIDataGet(SSI2_BASE, &ui32Data);
            u8DataRx[ui32Index] = (unsigned char)ui32Data;
            if(u8DataTx[ui32Index] != u8DataRx[ui32Index])
            {
                while(1);  // Fail traps here
            }
        }
    
        while(1); // Pass traps here
    }
    

  • Bob, I'm grateful for your direct answer.
  • @ Bob,

    Highly strategic - yet (very) well illustrates the (rare) occasion (when & where) "DRM" may,  "Fill the (very) small gaps - which the API can not be expected to - fully/properly anticipate and/or resolve..."      (I'm searching for the "LIKE" - had a  "nightmare" - it  had been pulled...)

    May it be noted that,  "Another FAILED Verify" has (again) landed!     The chronic misuse of  "Verify/This Resolved"  NOW ... borders upon the "GUARANTEED!"     (What "upgrade?")