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.

Cannot see data go out of the SPI transmit/receive data register in debugger

Hi, 

I am comparatively new to TIVA C series TM4C123GH6PMI launchpad, and I had a question about SPI.

I set up the SPI registers and everything, and I tried sending data through to another device. I hook up my launchpad to the PC and I want to check if the data is going off the pin. So I put a breakpoint on the line where I actually send the data out, but cannot see any data updated in the SPI2_DR_R register. I wonder what the matter is. Am I setting up SPI wrong? Here's my code:

// Initialize Hardware
void initHw()
{
// Configure HW to work with 16 MHz XTAL, PLL enabled, system clock of 40 MHz
SYSCTL_RCC_R = SYSCTL_RCC_XTAL_16MHZ | SYSCTL_RCC_OSCSRC_MAIN | SYSCTL_RCC_USESYSDIV | (4 << SYSCTL_RCC_SYSDIV_S);

// Set GPIO ports to use APB (not needed since default configuration -- for clarity)
// Note UART on port A must use APB
SYSCTL_GPIOHBCTL_R = 0;

// Enable GPIO port B and E peripherals
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOB | SYSCTL_RCGC2_GPIOE;

// Configure three backlight LEDs
GPIO_PORTB_DIR_R |= 0x20; // make bit5 an output
GPIO_PORTB_DR2R_R |= 0x20; // set drive strength to 2mA
GPIO_PORTB_DEN_R |= 0x20; // enable bit5 for digital
GPIO_PORTE_DIR_R |= 0x30; // make bits 4 and 5 outputs
GPIO_PORTE_DR2R_R |= 0x30; // set drive strength to 2mA
GPIO_PORTE_DEN_R |= 0x30; // enable bits 4 and 5 for digital

// Configure A0 and ~CS for graphics LCD
GPIO_PORTB_DIR_R |= 0x42; // make bits 1 and 6 outputs
GPIO_PORTB_DR2R_R |= 0x42; // set drive strength to 2mA
GPIO_PORTB_DEN_R |= 0x42; // enable bits 1 and 6 for digital

// Configure SSI2 pins for SPI configuration
SYSCTL_RCGCSSI_R |= SYSCTL_RCGCSSI_R2; // turn-on SSI2 clocking
GPIO_PORTB_DIR_R |= 0x90; // make bits 4 and 7 outputs
GPIO_PORTB_DR2R_R |= 0x90; // set drive strength to 2mA
GPIO_PORTB_AFSEL_R |= 0x90; // select alternative functions for MOSI, SCLK pins
GPIO_PORTB_PCTL_R = GPIO_PCTL_PB7_SSI2TX | GPIO_PCTL_PB4_SSI2CLK; // map alt fns to SSI2
GPIO_PORTB_DEN_R |= 0x90; // enable digital operation on TX, CLK pins

// Configure the SSI2 as a SPI master, mode 3, 8bit operation, 1 MHz bit rate
SSI2_CR1_R &= ~SSI_CR1_SSE; // turn off SSI2 to allow re-configuration
SSI2_CR1_R = 0; // select master mode
SSI2_CC_R = 0; // select system clock as the clock source
SSI2_CPSR_R = 40; // set bit rate to 1 MHz (if SR=0 in CR0)
SSI2_CR0_R = SSI_CR0_SPH | SSI_CR0_SPO | SSI_CR0_FRF_MOTO | SSI_CR0_DSS_8; // set SR=0, mode 3 (SPH=1, SPO=1), 8-bit
SSI2_CR1_R |= SSI_CR1_SSE; // turn on SSI2
}

//send command

void sendGraphicsLcdCommand(uint8_t command)
{
CS_NOT = 0; // assert chip select
__asm (" NOP"); // allow line to settle
__asm (" NOP");
__asm (" NOP");
__asm (" NOP");
A0 = 0; // clear A0 for commands
SSI2_DR_R = command; // write command
while (SSI2_SR_R & SSI_SR_BSY); //----> PUT BREAKPOINT HERE
CS_NOT = 1; // de-assert chip select
}

SSI2_DR_R REGISTER is never updated with any value other than 0000.

Thanks!

  • May I commend you for a very well organized and attractively presented post?   Shows care and thoughtfulness - both point toward your success.

    That said - your post employs Direct Register and some (brief/closing) ASM.   There's nothing wrong with that - yet please realize that Direct Register places far more demands upon your forum helpers - be they vendor or outsiders!   Most here must "reach for the MCU manual" and then "dial in" each/every register - you've accessed.   That's a lot of work - mais oui?

    Predecessor firm produced a highly detailed API - all in "C" (even interrupt service routines may be entirely in "C") - and that was a key driver in this vendor's acquisition.   There exist multiple, detailed code examples which exercise most every MCU peripheral.  And SPI is well included.  (find under xxxWare/examples/peripherals/ssi/"ssi_master.c" is just one example.

    Beauty of the API is its long use and test by thousands here.   While not perfect - it's damn close - and your API usage greatly speeds, eases, & enhances the efforts of your remote "helpers."   Direct Register codings - in comparison - almost always are "one off" - have no history of successful usage - and demand great time/effort investment to insure that, "all is well."

    I like your logical approach - write here for your consideration.   I'm small, tech biz owner - almost never would I allow staff to write in Direct Register unless that code portion proved especially critical (execution speed & code-size sensitive.)   (the set-up of SPI meets neither of those considerations - btw...)

    Confess that it's been awhile since I looked in detail @ "SSI2_DR_R REGISTER" but I seem to recall that values therein were "transient" - you may never see them.   Scope attached to MOSI is a far more normal/customary means to confirm data output - suggest you add that to your test protocol...

  • Thank you cb1, unless you were sarcastic of course. I will improve my posts in the future if you were. Having said that, I failed to get what "Direct Register" means.
  • My friend - I'm small biz owner - we cannot be "sarcastic." Again - as I detailed - your post is quite logical. I'm @ client site now - net goes "in/out" I send my post in stages so that (all) is not lost.

    Direct Register is illustrated by your coding: "GPIO_PORTB_DEN_R" and all similar.

    Your review of the driver library will review literally thousands of code examples - all in C - and employing the vendor's API format. It's much simpler - and tested - and documented - and greatly eases the review of your posted code.

    BTW - I find nothing in my initial post even remotely touching on "sarcasm."   Might you illustrate how/why you though that?   I put time/effort in that composition - it was intended to be 100% constructive - bit shocking that you (appear) to have missed that...

  • One more point - possibly explaining your use of Direct Register.   (rather than much preferred vendor API)

    The MCU Manual - as issued first by LMI - later by this vendor - contain (mostly - perhaps exclusively) very brief code examples - those implemented in Direct Register.   Notably - to compound that sin - no mention (whatsoever) is made of vendor's rich API - w/in the 1000+ pg. MCU Manual.   That's a significant oversight - is it not?   (and why must outsiders note - bring to the table?)

    This issue flies beyond poster's subject - yet may well explain his difficulty - and the complications which Direct Register force upon (hapless) forum helpers...

  • So you are saying review driver library? Where do I find it?

  • The answer to your question is really basic - my "feeding" it to you will "not" best serve you. (clearly - you need to become much more familiar w/the resources and "nooks/crannies" here)

    What did you find "sarcastic" in my answering post?
  • Hello Varad,

    The setting of the Main Oscillator is not as simple as the line below....

    SYSCTL_RCC_R = SYSCTL_RCC_XTAL_16MHZ | SYSCTL_RCC_OSCSRC_MAIN | SYSCTL_RCC_USESYSDIV | (4 << SYSCTL_RCC_SYSDIV_S);

    The driverlib are part of the TivaWare download and installation.

    Regards
    Amit