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.

LM4F120 SSI to the CC1121 transceiver and L6470 motor controller

Other Parts Discussed in Thread: CC1121

I'm trying to interface with both the CC1121 and an L6470 motor controller via TI's SSI protocols. I've been working on this for a couple months now and at this point I can't figure out if I'm not getting anything back from the chips because my code is wrong or because I botched the hardware design somehow. The following code is to configure the CC11121 on SSI3 and the motor controllers on SSI1 & SSI2. I think I'm making all of the right API calls to configure the alternate functions correctly. The next part of the code just tries to send a command strobe to the CC1121 to see if it's alive and talking (because the idle status is denoted by 000....). I've taken out a lot of the #define s and some other GPIO code to try and make this shorter. Sorry for the poor formatting, I'm not sure what this textbox is doing. If anybody can see that I'm obviously not calling a critical function or that I'm trying to send data incorrectly so that the ARM or the CC1121 isn't recognizing the commands, please let me know. I'm pulling my hair out because I just can't see where I'm going wrong. In your reply, if you could include an example code of what you think I could change, that would be super helpful. Thanks everybody.

#include "inc/hw_gpio.h"

#include "inc/hw_memmap.h"

#include "inc/hw_sysctl.h"

#include "inc/hw_types.h"

#include "inc/hw_ints.h"

#include "driverlib/gpio.h"

#include "driverlib/sysctl.h"

#include "driverlib/ssi.h"

#include "driverlib/pin_map.h"

void main(void) {

SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

//START CONFIG CODE

// Enable GPIO and SSI 

//Pin 1 -> M_B_MISO -> PB6 //Pin 4 -> M_B_MOSI -> PB7 //Pin 57 -> M_B_CS (SSI2 Fss) -> PB5 //Pin 58 -> M_B_SCLK (SSI2) -> PB4

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//SSI2, Motor Control B

//Pin 61 -> CC_SCLK (SSI3) -> PD0 //Pin 62 -> CC_CS (SSI3 Fss) -> PD1 //Pin 63 -> CC_MISO -> PD2 //Pin 64 -> CC_MOSI -> PD3

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);//SSI3, CC1121

//Pin 28 -> M_A_MISO -> PF0 //Pin 29 -> M_A_MOSI -> PF1 //Pin 30 -> M_A_SCLK (SSI1) -> PF2 //Pin 31 -> M_A_CS (SSI1 Fss) -> PF3

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//SSI1, Motor Control A

GPIOPinConfigure(GPIO_PB4_SSI2CLK); GPIOPinConfigure(GPIO_PB5_SSI2FSS); GPIOPinConfigure(GPIO_PB6_SSI2RX); GPIOPinConfigure(GPIO_PB7_SSI2TX);

GPIOPinConfigure(GPIO_PD0_SSI3CLK); GPIOPinConfigure(GPIO_PD1_SSI3FSS); GPIOPinConfigure(GPIO_PD2_SSI3RX); GPIOPinConfigure(GPIO_PD3_SSI3TX);

GPIOPinConfigure(GPIO_PF0_SSI1RX); GPIOPinConfigure(GPIO_PF1_SSI1TX); GPIOPinConfigure(GPIO_PF2_SSI1CLK); GPIOPinConfigure(GPIO_PF3_SSI1FSS);

GPIOPinTypeSSI(GPIO_PORTB_BASE, 0x78); GPIOPinTypeSSI(GPIO_PORTD_BASE, 0x0F); GPIOPinTypeSSI(GPIO_PORTF_BASE, 0x0F);

SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 1000000, 8);

SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 1000000, 8);

SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);

SSIEnable(SSI1_BASE); SSIEnable(SSI2_BASE); SSIEnable(SSI3_BASE);

//END CONFIG CODE //START COMMS CODE

//CC1121 Command Strobes can be found in Table 6, page 15 of CC1121 User Guide

unsigned long CC_RX_MODE_STROBE = 0x34; //status byte should return 001

unsigned long ccStatus1 = 0xFFFF, ccStatus2 = 0xFFFF, ccStatus3 = 0xFFFF;

// Puts data in FIFO buffer to be sent/Reads data from receive FIFO buffer for the CC1121

SSIDataGetNonBlocking(SSI3_BASE, &ccStatus1); //checks status 

SSIDataPut(SSI3_BASE, CC_RX_MODE_STROBE); //suppose to change cc1121 into receive mode

SSIDataGetNonBlocking(SSI3_BASE, &ccStatus2); //checks status 

SSIDataGetNonBlocking(SSI3_BASE, &ccStatus3); //checks status

//END COMMS CODE

}//end main

  • Matt,

    Are the parts you're using  TI Part CC1121 Active High Performance Low Power RF Transceiver , and the ST Microcontrollers L6470 dSPIN: Fully integrated microstepping motor driver with motion engine and SPI ?

    I need to be sure before I try to replicate your issue.


    -Austin


  • Yes, those are the parts that I am using along with the LM4F120H5QR. I'm using the 32MHz crystal for the CC1121 and a 16MHz crystal for the ARM, along with a 32.xxx kHz for a RTC. I haven't been able to get responses on any of the SPI lines, I can show more of my code for writing to the L6470, though it's not much different from what I'm using on the CC1121. I transplanted the ARM from the Launchpad onto my own PCB so that I can have access to some of the other GPIO ports. I also have a schematic from KiCAD if that will help. Thank you for trying to help.

  • Matt, your code appears to be correct. I was able to run it on my system and have it function (thus verifying the initialization). Might i suggest a few things though,

    1) add a UART connection for debugging, I found it very useful to have the UART print back each thing that was received right after it was received so i could debug it in real time.

    2) why are you using two channels for the motor controller? From what I can tell it only requires one.

    3) beware of SSI channel overlaps, for example SSI1 and SSI3 both can run on PD0-3 just with different AFSEL selectors, make sure that yours are set up correctly, also note that B7 and D1, as well as B6 and D0 are connected via a 0ohm resistor. (its in the data sheet)

    4 try using the regular get and puts instead of their nonblocking bretherin.

    -Austin

  • The command strobe worked also? Do the results show up in the variables I initialized and if so could you post the values read from them so that I have something to reference? The reason I am using all three SSI ports is because I am actually using two separate L6470 controllers and the CC1121. I put them on separate SSI busses (or what I thought were separate, somehow I missed the zero ohm resistors) in an attempt to reduce the complexity of any potential debug as far as chip select and talking to multiple peripherals simultaneously. On power up, I want to be talking to all three devices, will the zero ohm resistors interfere with that? If so what steps would you recommend to enable this functionality. The program was hanging/going into FaultISR when I was using the non-blocking versions, which is why I switched.

    If my initialization code is functioning properly, then I should be able to use the following code to talk to the dSPIN and continue using the same format to send the CC1121 transmit data, along with transmit configurations, correct? As you can see I've hard coded the commands in hex because I have been unable to find a library to import for the dSPIN, is there a library and header file for it?

    unsigned long L6470_NOP = 0x00;

    unsigned long L6470_RUN = 0x51003CFA; //Moves forward at specified speed

    unsigned long motorStatus1 = 0xFF00, motorStatus2 = 0xFF00;

    //Motor_A  SSIDataPut(SSI1_BASE, L6470_RUN);  

    SSIDataPut(SSI1_BASE, L6470_NOP);  

    SSIDataPut(SSI1_BASE, L6470_NOP);  

    SSIDataPut(SSI1_BASE, L6470_GET_STATUS); 

    SSIDataGet(SSI1_BASE, &motorStatus1);

     

    Something I just realized for the motor controllers, in my setup I have the controllers powered at 5V and the ARM at 3.3V. I know the GPIO on the ARM is 5V tolerant and the SPI input on the controllers is 3.3-5V TTL controlled, but I was wondering if the hardware SSI on the ARM is also 5V tolerant. The only pin this would be an issue on would be the MISO on the ARM.

     

     

  • Also, I'm sure I could figure this out fairly easily, but if you could paste in the code for your UART setup, that would be a supreme time saver. Thank you for all of your assistance this far Austin. You have been quite the help.

  • Matt,

    I tested your initialization, I do not have the other hardware so I couldn't test that. I did however verify that using your initialization code you should be able to read and write to and from the pins you intend to.

    I would recommend using  SSI1 on PF0-3, SSI0 on PA2-5, and SSI3 on PD0-3 to avoid possible issues (because SSI2 seems like it would muck with things). (make sure you set the AFSEL bits right)

    Hm, interesting about the regualr ones causing a fault ISR, the difference between them is the regular R/W functions do not return untill something is read, you may want to track down why its going into the fault ISR as this seems to be indicative of a deeper problem.

    Two things i just noticed

    1) in SSIConfigSetExpClk() you set the width of the data you are sending (you set it to 8), when you send anything larger than 8 bits the rest of the data is discarded, so when you are trying to send 0x51003CFA all that is being sent is FA, take a look at the source for SSIDataPut() and you'll see the note in the comments above it.(note you can only send up to 16 bits at a time as a limitation)

    2) make sure you are using the correct transfer protocol, ie is the motor controller really using MOTO_MODE_0 or 3 as the case may be.

    I'll post the uart code next

    -Austin

  • UART CODE

    ---------------------------------------------------------

    #include "utils/uartstdio.h"

    main{

    ......

        //UART init
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioInit(0);

    ......

    UARTprintf("whatever you want to print");

    UARTprintf("for example a number variable %d", NumberVariableName);

    .....

    }

    --------------------------------------------------------------

    I used this to continually write data and print it to the UART as i wrote it, you could easily adapt it to print all data received. 

        UARTprintf("Device Initiated Lets send some data\n");
        
        lIdx = 0;
        while(1){
            while(pcChars[lIdx])
            {
                SSIDataPut(SSI1_BASE, pcChars[lIdx]);
                UARTprintf("%c",pcChars[lIdx]);
                lIdx++;
            }
            UARTprintf("\nSSI Done\n");
            lIdx = 0;
        }

    ---------------------------------------------------------------------

    Good luck,

    -Austin

  • Again, thanks for your help, this will definitely be very helpful, and at least I know now the configuration is right. Last question, do you know of a library that TI has that I can import into my main file to communicate with the L6470 and the CC1121? From the L6470 data sheet it sounded like there was one, but I haven't been able to find anything.

  • Hi Matt.

    I was wondering whether you manged to use the L6470 motor driver with the LM4F120 controller. since I am starting a project that involve the two components. and I encounter some problems with it. And it will be a great help to know that someone has one it before.

    Thanks, Asi.