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.

Issue Setting Up SSI2 on TM4C123GH6PM to talk to MCP3008 ADC Peripheral

Other Parts Discussed in Thread: TM4C123GH6PM, EK-TM4C123GXL, LMFLASHPROGRAMMER

Hi All,

I'm trying to use the SSI2 module (PB4-7) to talk to the MCP3008 ADC peripheral via Freescale SPI. I am using the Keil Compiler/IDE. I used this youtube video to give me some guidance on how to set everything as well as the instructions from the datasheet (copied into my comments).

However, when I try to set up all the SSI registers in a debug session, certain ones exhibit error 65: no read/write permission seen here:

I followed the instructions exactly when writing the code (see below) as the datasheet said so I'm a bit confused as to what the problem could be. Any tips?

void SSI2_Init(void){ volatile unsigned long delay;

//For this example going to set up PB4-7 as Clock, FSS (Slave Select), RX, and TX respectively

//Initialization and Configuration
//To enable and initialize the SSI, the following steps are necessary:
//1. Enable the SSI module using the RCGCSSI register (see page 344).

SYSCTL_RCGCSSI_R=0x04;//Set bit 2 of RCGCSSI register, thus enabling Port B/Module 2 as an SSI port
Delay();

//2. Enable the clock to the appropriate GPIO module via the RCGCGPIO register (see page 338).
//To find out which GPIO port to enable, refer to Table 23-5 on page 1344.

SYSCTL_RCGC2_R |= 0x00000002; // 1) A clock (step 1)
delay = SYSCTL_RCGC2_R;


//3. Set the GPIO AFSEL bits for the appropriate pins (see page 668). To determine which GPIOs to
//configure, see Table 23-4 on page 1337.

GPIO_PORTB_AFSEL_R=0xF0;//allow alternate function of PB4-7 by setting these bits
GPIO_PORTB_AFSEL_R&=~(0x10);//****turn off AFSEL for PB5 since we need to control chip select functionality

//4. Configure the PMCn fields in the GPIOPCTL register to assign the SSI signals to the appropriate
//pins. See page 685 and Table 23-5 on page 1344.

//First go to page 1344, see that we need a value of 2 for each of the bitfields of PB4-7

GPIO_PORTB_PCTL_R =0x22220000;

///////////////PICK UP HEREEEEE youtu.be/VprofC5ssi4


//5. Program the GPIODEN register to enable the pin's digital function. In addition, the drive strength,
//drain select and pull-up/pull-down functions must be configured. Refer to “General-Purpose
//Input/Outputs (GPIOs)” on page 649 for more information.
//Note: Pull-ups can be used to avoid unnecessary toggles on the SSI pins, which can take the
//slave to a wrong state. In addition, if the SSIClk signal is programmed to steady state
//High through the SPO bit in the SSICR0 register, then software must also configure the
//GPIO port pin corresponding to the SSInClk signal as a pull-up in the GPIO Pull-Up
//Select (GPIOPUR) register.

GPIO_PORTB_DEN_R=0xF0; //enable digital for PB4-7
GPIO_PORTB_DIR_R=0x10;//make PB5 an output


//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_R&=0xD; //clear bit 1 (SSE bit) of the SSI2 Control Register 1
//^^^error 65: access violation at 0x4000A004: no 'read' permission


//2. Select whether the SSI is a master or slave:
//a. For master operations, set the SSICR1 register to 0x0000.0000
//b. For slave mode (output enabled), set the SSICR1 register to 0x0000.0004.
//c. For slave mode (output disabled), set the SSICR1 register to 0x0000.000C.

SSI2_CR1_R=0x00000000;//configure for master mode
//^^error 65: access violation at 0x4000A004: no 'write' permission
//3. Configure the SSI clock source by writing to the SSICC register.

SSI2_CC_R=0x0;//use system clock with divisor factor enabled
//error 65: access violation at 0x4000AFC8: no 'write' permission
//4. Configure the clock prescale divisor by writing the SSICPSR register.

//SSInClk = SysClk / (CPSDVSR * (1 + SCR))
SSI2_CPSR_R=0x08;//set prescaler for clock (assuming system clock is 16MHz) to start, scale down to 2MHz

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


//¦ Serial clock rate (SCR)
//¦ Desired clock phase/polarity, if using Freescale SPI mode (SPH and SPO)
//¦ The protocol mode: Freescale SPI, TI SSF, MICROWIRE (FRF)
//¦ The data size (DSS)
//15:8 SCR prescaler
//Want this set to 0 (no additional scaling): 0x00
//7 SPH (Serial Clock Phase) 0 captures on rising edge, 1 captures on falling edge
//want to capture on rising edge
//6 SPO (Serial Clock Polarity) 0 is idle low, 1 is idle high
//want idle low clock
//Want to run in 0,0 mode (capture rising edge, idle low)
//5:4 SSI Frame Format Select 0x0=Freescale SPI, 0x1=TI Protocol, 0x2=Microwire protocol
//3:0 data select size
//want 8 bit size since we will need to send 3 bytes (24 bits) during each transaction

SSI2_CR0_R=0x07; // all bits cleared except data size for 8 bits


//6. Optionally, configure the SSI module for µDMA use with the following steps:
//a. Configure a µDMA for SSI use. See “Micro Direct Memory Access (µDMA)” on page 585 for
//more information.
//b. Enable the SSI Module's TX FIFO or RX FIFO by setting the TXDMAE or RXDMAE bit in the
//SSIDMACTL register.

//*****Don't use for now but reevaluate whether I should when I start using interrupts****///

//7. Enable the SSI by setting the SSE bit in the SSICR1 register.
//As an example, assume the SSI must be configured to operate with the following parameters:
//¦ Master operation
//¦ Freescale SPI mode (SPO=1, SPH=1)
//¦ 1 Mbps bit rate
//¦ 8 data bits
//Assuming the system clock is 20 MHz, the bit rate calculation would be:
//SSInClk = SysClk / (CPSDVSR * (1 + SCR))
//1x106 = 20x106 / (CPSDVSR * (1 + SCR))
//In this case, if CPSDVSR=0x2, SCR must be 0x9.
//The configuration sequence would be as follows:
//1. Ensure that the SSE bit in the SSICR1 register is clear.
//2. Write the SSICR1 register with a value of 0x0000.0000.
//3. Write the SSICPSR register with a value of 0x0000.0002.
//4. Write the SSICR0 register with a value of 0x0000.09C7.
//5. The SSI is then enabled by setting the SSE bit in the SSICR1 register.

SSI2_CR1_R|=0x02;//set bitfield 1 (SSE enable bit)
GPIO_PORTB_DATA_R|=0x10;//set chip select high (idle high)

}

  • Hello Jim

    I have not seen such as an issue so far. Only thing I can think of is that the SSI clock enable has not been executed when the registers were being accessed. Can you check RCGCSSI bit for SSI-2 is set to 0x1 before the debug registers are accessed.
  • Hi Amit,

    I'm a bit confused about the wording of your request. As was pasted in my code above, I set SYSCTL_RCGCSSI_R=0x04; which should set bit 2 of that register. According to the datasheet (page 347) that is indeed the SSI enable bit for module 2 which is the module I am trying to use. Perhaps your theory could be applied to the next line when I tried to set the SYSCTL_RCGC2_R|=0x00000002 in order to give Port B a clock. I'm a bit confused about whether I should be using this one or SYSCTL_RCGCTIMER_R. Could you clarify that? I tried setting bit 2 on both and that doesn't seem to work either.

    Jim

  • Hello Jim,

    I would first not use the RCGC0, 1, 2 registers at all and instead use the RCGCGPIO, RCGCSSI and RCGCTIMER register. Second of all instead of using the DRM style of coding, move it to proven TivaWare.

    Since I have not seen the error earlier, I am curious to know if this is due to the Register debug window being opened when the peripheral is not enabled or being generated by IAR based on something that the code is doing?
  • Amit,

    I followed your advice and I tried setting up those three suggested registers and commented out the line where I set up RCGC2. The result I got was the following error in Keil: "Access to Port B without a clock. You must turn on bit 1 in RCGC2 and then wait 4 cycles".

    I am apprehensive about using TivaWare for this application because the peripheral I'm using has very specific requirements about the sequence it goes through in serial communication. I looked through the TivaWare software and it did not look like it had anything I could use.

    -Jim

  • Hello Jim

    First of all check the Register RCGCGPIO and make sue that the bit-1 is set for Port B access. Secondly, the TivaWare API follow the same sequence as you are doing and has additional checks also built, so I would not worry on that aspect.
  • Ok. I am following your advice and now I am trying to just do a simple example where I blink some LEDs just so I can figure out how to properly use the API. Here is literally all of my code:

    #include "tm4c123gh6pm.h"
    #include "driverlib/gpio.h"
    #include <stdint.h>

    void Delay(void);
    void
    GPIOPinWrite(uint32_t ui32Port,
    uint8_t ui8Pins,
    uint8_t ui8Val);
    void
    GPIOPinTypeGPIOOutput(uint32_t ui32Port,
    uint8_t ui8Pins);

    uint32_t GPIO_PORTB_BASE_ADDRESS=0x40005000;
    uint8_t GPIO_ALL_OUTPUTS=0xFF;
    uint8_t GPIO_ALL_HIGH=0xFF;
    uint8_t GPIO_ALL_LOW=0xFF;

    int main(void){
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE_ADDRESS, GPIO_ALL_OUTPUTS);//set all to outputs
    while (1){
    GPIOPinWrite(GPIO_PORTB_BASE_ADDRESS,GPIO_ALL_OUTPUTS,GPIO_ALL_HIGH);//set them high
    Delay();
    GPIOPinWrite(GPIO_PORTB_BASE_ADDRESS,GPIO_ALL_OUTPUTS,GPIO_ALL_HIGH);//set them low
    Delay();
    }

    }


    void Delay(void){unsigned long volatile time;
    time = 727240*200/91; // 0.1sec
    while(time){
    time--;
    }
    }

    I ran into a couple weird compiling errors  where uint32_t was not recognized in the gpio.h file that I alleviated by using #include <stdint.h> in the gpio.h file. I think I'm almost there but now I'm running into the following linking issue:

    Any advice you could give would be much appreciated.

    Thanks,

    Jim

  • Hello Jim,

    The precompiled driverlib has not been added to the linker stage
  • Forgive my ignorance, Amit but I am fairly new to this (clearly). What exactly do you mean "has not been added to the linker stage" and how would you recommend I resolve the issue in order to get code that compiles and accomplishes my goal?

    Thanks!
    Jim
  • Hello Jim

    The driverlib has a precompiled archive file under TivaWare installed path/driverlib/iar

    You need to add the same in the Project options under linker.
  • I don't see an IAR folder here:

  • Hello Jim,

    Under TivaWare as shown in the snapshot below.

  • Ok so now I'm taking your advice and trying to use TivaWare. As a starting point I used some sample code but I'm still struggling. The below code compiles but when I run it, it seems like some of the code is getting optimized out. Can you take a peak and see if anything pops out, especially in the SSI2_Init function? All I'm trying to do is read 3 consecutive 8bit bytes in accordance with what the MCP3008 expects. It seems like I'm not even able to read out the variables properly in my watch window.

    void SSI2_Init(void);


    ///Sample section//


    int
    main(void)
    {
    SSI2_Init();
    int numBytes=3;
    uint32_t pui32DataTx[numBytes];
    uint32_t pui32DataRx[numBytes];
    uint32_t ui32Index;



    while(1)
    {
    //Load TX up
    //Byte 1: 7 leading 0's and 1 start bit

    pui32DataTx[0]=0x01;
    //Byte 2: Only first 4 matter; Bit 7 set for single ended, cleared for differential. Select channel
    pui32DataTx[1]=0x80;
    //Byte 3: bits don't matter
    pui32DataTx[2]=0x00;

    //Pull CS low
    ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,0);
    //load TX data up and out
    for (ui32Index=0;ui32Index<numBytes;ui32Index++){
    SSIDataPut(SSI2_BASE,pui32DataTx[ui32Index]);
    }
    while(SSIBusy(SSI2_BASE)){}//wait until transfer done
    //pull in RX data
    for (ui32Index=0;ui32Index<numBytes;ui32Index++){
    SSIDataGet(SSI2_BASE, &pui32DataRx[ui32Index]);
    }


    //Put CS High again
    ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,GPIO_PIN_5);

    }
    return(0);
    }

    void SSI2_Init(void){
    //configure clock source

    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    uint32_t ui32SysClock;
    #endif

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_OSC), 25000000);
    #else
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);
    #endif

    //1. Enable the SSI Module
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);//enables SSI2
    ROM_SysCtlDelay(1);

    //2. Enable the clock to the appropriate GPIO module
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlDelay(1);

    //3.Configure Pin Muxing appropriately
    ROM_GPIOPinConfigure(GPIO_PB4_SSI2CLK);
    // ROM_GPIOPinConfigure(GPIO_PB5_SSI2FSS); //commented because I need to assume direct control to use MCP3008 with 24bit word scheme
    ROM_GPIOPinConfigure(GPIO_PB6_SSI2RX);
    ROM_GPIOPinConfigure(GPIO_PB7_SSI2TX);

    // 4. Configure the GPIO settings for the SSI pins. This function also gives
    // control of these pins to the SSI hardware. Consult the data sheet to
    // see which functions are allocated per pin.
    // The pins are assigned as follows:
    // PB7 - SSI2Tx
    // PB6 - SSI2Rx
    // PB5 - SSI2Fss
    // PB4 - SSI2CLK
    // TODO: change this to select the port/pin you are using.
    //
    ROM_GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_7 | GPIO_PIN_4 | GPIO_PIN_6);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_5);//assume direct control of PB5 Chip/Frame select
    ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_PIN_5);//IDLE HIGH CS

    // Configure and enable the SSI port for SPI master mode. Use SSI0,
    // system clock supply, idle clock level low and active low clock in
    // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
    // For SPI mode, you can set the polarity of the SSI clock when the SSI
    // unit is idle. You can also configure what clock edge you want to
    // capture data on. Please reference the datasheet for more information on
    // the different SPI modes.
    //
    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    SSIConfigSetExpClk(SSI2_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0,
    SSI_MODE_MASTER, 1000000, 8);
    #else
    SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);
    #endif

    //Enable SSI2
    SSIEnable(SSI2_BASE);

    }

  • Hello Jim

    It looks correct to me. Do note one thing is that the Read access is in a while loop. Some devices require a certain amount of wait time between CS deassertion and assertion. You may need to add a delay loop after the CS is made high.
  • Ok. I will keep tinkering.

    In the meantime, a new issue with debugging. Somehow during a debug session I had some kind of failure that locked out the device.Whenever I tried to download code I got the message "Error! Unable to initialize target. Power cycle the device and try again". At the behest of other threads, I was told to use the LM debugger tool to do a debug port unlock. Doing this allowed me to download code but now when I try to debug I get kicked out after a second or so. Any tips on how to resolve this issue??
  • Hello Jim,

    Normally this error occurs I have seen occuring

    (a) The JTAG pins are being affected either by explicit reprogramming of the GPIO Port C or Debug Disable (I am not suspecting the same in your case)
    (b) The system clock is such that it is way low for JTAG to work correctly. We can check for this when we execute the code by using breakpoints on key functions to see which function causes the issue.
  • I think rationale b makes the most sense. I used a divisor for the system clock of 64 while I was experimenting. I changed it back to 1 but I still see this issue.

    Any tips on how to reset it to the proper value so I can debug?

  • Hello Jim

    Reduce the JTAG clock frequency to 10-100 KHz. If the divide of 64 is there then it would put the system clock at 3.125MHz. If 1/10 of the system clock criteria is taken then JTAG must not be above 312.5KHz.
  • Amit,

    I attempted to change the JTAG frequency in the Keil "Options for Target" section. I moved it all the way down to 20kHz, 10kHz, and 5kHz and still experience the same problem. What would you recommend next?

    Jim

  • Hello Jim

    It is tough to say what the issue could be. Can you please attach the source project so that I can try the same on my launchpad.
  • codeAttempts.zip

    Amit,

    Attached in the zip file here are the programs I'm trying to run which were originally contained inside "C:\ti\TivaWare_C_Series-2.1.3.156\examples". Inside lies two projects, "SSIPrototype", where I attempt to communicate with an MCP3008 ADC IC and "project" which is a sample project that came with TivaWare which I only changed slightly to blink different GPIO outputs.

    Some notes:

    1. The IDE/Compiler I am using is Keil Microvision 4

    2. I am able to compile and download both programs to my microcontroller. The project.c code simply blinks an LED which is attached to a current amplifier circuit I designed. The SSIPrototype code has been verified via scope to output what appear to be proper CS and MOSI signals.

    3. The trouble began when I attempted to revise line 161 

    "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);" was changed to 

    SysCtlClockSet(SYSCTL_SYSDIV_64 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);"

    4. Even after using the LM Debugger tool to unlock debug,  and changing line 161 back to its original value, I am still experiencing the symptoms described above where I start a debug session and then I am immediately kicked off.

    The fact that the issue persists regardless of which program I use tells me that it has something to do with either the micro itself, the Keil microvision IDE, or some interaction between the two. Any help you could provide in recreating and tracking down the issue would be much appreciated.

    Thanks,

    Jim

  • Hello Jim

    Looking back at your use of clock and setting of the JTAG frequency, I ran an experiment where I changed the ICDI frequency in the ccxml file. as 1MHz, 100 KHz and 10 KHz and measure the JTAG TCK on the EK-TM4C123GXL. It seems that the TCK clock settings are not taken in the Stellaris ICDI as an option and it will continue to work at ~463KHz.

    The unlock sequence using LMFlashProgrammer if run correctly, should show the device Blank Erase Check as Pass.

    So I would suggest

    1. Run the unlock sequence and then run the blank check to ensure that the device is indeed erased
    2. Avoid using a divide of 64 on the Oscillator clock which could cause an issue with debug.

    As an additional step I did the same on my working board (i.e. changing the System clock to Crystal Frequency/64) and I am able to reproduce the issue. But a subsequent unlock sequence is able to recover my board.
  • Amit,

    I just followed your advice and got the following results:

    1. I did an unlock sequence which I assume you mean is under "other utilities" -->"debug port unlock"-->Fury, Dustdevil, TM4C, etc.-->Unlock. I completed the sequence with no errors

    2. I attempted to do a Blank Check Erase, which passed.

    3.  Iopened MicroVison Keil 4.

    4. I compiled code which had a division of 1 rather than 64 and downloaded it to the device successfully via Keil. Worthy of note is that this exact code was debuggable before the issues began.

    5. I launched a debug session from Microvision Keil 4.

    6. The same symptom from previously where the device starts the debug session then kicks me out immediately persists.

    Please advise.

    Jim

  • Additional questions:

    1. Were you able to compile/build my code initially?
    2. Were you able to debug my code initially?
    3. After recreating the issue and remedying it, were you able to build, compile and debug my code?
  • Hello Jim

    Yes. I was able to run compile and build your code with CCS and debug the same when using Division of 1. Also when I reproduced the issue, an Unlock operation, followed by correcting divide of 64 back to 1 it was working again.
  • Ok. What would you advise I do next?

    One theory I have is that the on board debugger is somehow damaged.

    If you can't solve this problem, please refer me to someone at TI who can.

    Jim

  • Hello Jim

    If the on-board debugger is damaged, then it can be checked by connecting an external debug probe as given in Section 4.5 of the JTAG application note

    www.ti.com/.../spma075.pdf

    An advantage of using external debug probe is that the JTAG TCK can be modified in the ccxml and it shall take effect.

    I have already reproduced the issue that you reported, isolated it to the system clock setting. I don't have your board (if the board has an issue). The last thing I can suggest is to import, compile and launch one of the working example code from TivaWare onto your board. If that still causes the issue to occur, then may be the board is the source of the problem.

    To isolate the IDE, you can download and install CCS and check the same example. If with both Keil and CCS the issue still persists then the board indeed is the source of the problem.
  • I am trying to isolate the IDE. What would you recommend as the best method to taking an existing microvision project and importing it into CCS? I am struggling with this and I am very surprised at how difficult this task has proven to be
  • Hello Jim,

    There is no direct method to import examples from one IDE to another IDE. You can perhaps use a simple example in CCS and copy the files over.
  • Amit,

    I finally have CCS running and properly debugging, which is great. Now I am trying to pick up where i left off and figure out how to talk to the MCP3008. However, when I run the following code, I get an issue:

    //*****************************************************************************
    //
    // blinky.c - Simple example to blink the on-board LED.
    //
    // Copyright (c) 2012-2016 Texas Instruments Incorporated. All rights reserved.
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    // This is part of revision 2.1.3.156 of the EK-TM4C123GXL Firmware Package.
    //
    //*****************************************************************************

    /////////TEST PROGRAM/////////////////////////////////////


    #include <stdbool.h>//
    #include <stdio.h>
    #include <stdint.h>//
    #include "inc/hw_memmap.h"//
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"//
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"//
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"


    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>Simple Project (project)</h1>
    //!
    //! A very simple example that can be used as a starting point for more complex
    //! projects. Most notably, this project is fully TI BSD licensed, so any and
    //! all of the code (including the startup code) can be used as allowed by that
    //! license.
    //!
    //! The provided code simply toggles a GPIO using the Tiva Peripheral Driver
    //! Library.
    //
    //*****************************************************************************

    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    /*
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    */
    //*****************************************************************************
    //
    // Toggle a GPIO.
    //
    //*****************************************************************************

    void SSI2_Init(void);


    ///Sample section//


    int
    main(void)
    {
    SSI2_Init();
    int numBytes=3;
    uint32_t pui32DataTx[numBytes];
    uint32_t pui32DataRx[numBytes];
    uint32_t ui32Index;

    while(1)
    {
    //Load TX up
    //Byte 1: 7 leading 0's and 1 start bit

    pui32DataTx[0]=0x01;
    //Byte 2: Only first 4 matter; Bit 7 set for single ended, cleared for differential. Select channel
    pui32DataTx[1]=0x80;
    //Byte 3: bits don't matter
    pui32DataTx[2]=0x00;

    //Pull CS low
    ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,0);
    // ROM_SysCtlDelay(5);
    //load TX data up and out
    for (ui32Index=0;ui32Index<numBytes;ui32Index++){
    SSIDataPut(SSI2_BASE,pui32DataTx[ui32Index]);
    }
    while(SSIBusy(SSI2_BASE)){}//wait until transfer done
    //pull in RX data
    for (ui32Index=0;ui32Index<numBytes;ui32Index++){
    SSIDataGet(SSI2_BASE, &pui32DataRx[ui32Index]);
    }


    //Put CS High again
    ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,GPIO_PIN_5);
    ROM_SysCtlDelay(5);

    }
    return(0);
    }

    void SSI2_Init(void){
    //configure clock source

    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    uint32_t ui32SysClock;
    #endif

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_OSC), 25000000);
    #else
    //changed Sys Div to make it super slow
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);
    #endif

    //1. Enable the SSI Module
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);//enables SSI2
    ROM_SysCtlDelay(1);

    //2. Enable the clock to the appropriate GPIO module
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlDelay(1);

    //3.Configure Pin Muxing appropriately
    ROM_GPIOPinConfigure(GPIO_PB4_SSI2CLK);
    // ROM_GPIOPinConfigure(GPIO_PB5_SSI2FSS); //commented because I need to assume direct control to use MCP3008 with 24bit word scheme
    ROM_GPIOPinConfigure(GPIO_PB6_SSI2RX);
    ROM_GPIOPinConfigure(GPIO_PB7_SSI2TX);

    // 4. Configure the GPIO settings for the SSI pins. This function also gives
    // control of these pins to the SSI hardware. Consult the data sheet to
    // see which functions are allocated per pin.
    // The pins are assigned as follows:
    // PB7 - SSI2Tx
    // PB6 - SSI2Rx
    // PB5 - SSI2Fss
    // PB4 - SSI2CLK
    // TODO: change this to select the port/pin you are using.
    //
    ROM_GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_7 | GPIO_PIN_4 | GPIO_PIN_6);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_5);//assume direct control of PB5 Chip/Frame select
    ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_PIN_5);//IDLE HIGH CS

    // Configure and enable the SSI port for SPI master mode. Use SSI0,
    // system clock supply, idle clock level low and active low clock in
    // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
    // For SPI mode, you can set the polarity of the SSI clock when the SSI
    // unit is idle. You can also configure what clock edge you want to
    // capture data on. Please reference the datasheet for more information on
    // the different SPI modes.
    //
    #if defined(TARGET_IS_TM4C129_RA0) || \
    defined(TARGET_IS_TM4C129_RA1) || \
    defined(TARGET_IS_TM4C129_RA2)
    SSIConfigSetExpClk(SSI2_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0,
    SSI_MODE_MASTER, 1000000, 8);
    #else
    SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);
    #endif

    //Enable SSI2
    SSIEnable(SSI2_BASE);

    }

    As soon as I try to hit "run" in debug, exit.c pops up and blocks the program. My screen looks like this:

    I am very perplexed because, before, when I compiled and downloaded to flash with Keil, I verified on oscilloscope that at the very least I was getting a clock output from PB5. However, now when I try to just let the program run, this happens. Does this information give you any clues as to what might be the problem? I'd really appreciate the help.

    Thanks for your help so far and I hope to hear from you.

    Jim

  • Hello Jim

    Put a while(1); statement at the end of the main so that the CCS does not compile in the exit routines for the CPU.