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.

SPI Support in TiMAC

Other Parts Discussed in Thread: CC2530, TIMAC, MSP430F5438, CC2530EM, Z-STACK

Hello,

     I am attempting to use the CC2530EM system on a chip with the MSP-EXP430F5438 experimenter's board. I have successfully run sample applications using the SmartRF05 board with the CC2530 module, but I am now required to make information from the CC2530 radio available to an external processor, such as the MSP430F5438. I am currently using the TiMAC 1.3.1 software. Is this a valid hardware configuration? Previously, I was able to use the CC2530 with the MSP430 as a ZigBee device.

     I have looked through the TiMAC software and found SPI support for LCD and XNV devices only, and may be able to modify the LCD routines to communicate with the MSP430. Is this a valid approach considering I do not need the CC2530 to control an LCD directly? Are there any documents or sample applications that may help? I am not sure where to add the SPI functionality in the TiMAC software. What I would like the CC2530 to do is this:

  1. Carry out initializations (similar to data link sample application)
  2. Receive [TiMAC API] instructions from MSP430 over SPI
  3. Carry out instructions
  4. Return results over SPI

Any help would be greatly appreciated. Thank you,

Craig Verrill

  • Any thoughts on this topic?

    Thank you,

         Craig Verrill

  • Hi Craig,

    I'm not a big expert in TiMAC, however, I can suggest you a few things regarding SPI in CC2530.

    I've implemented my own SPI module as an additional module of HAL in my projects,

    though I did it in a complete version of TI's Zstack.

    You can start by doing as I did. Write your own module for SPI (i.e. HAL_SPI.c and HAL_SPI.h)

    and include this module in your project as a part of HAL.

    (I'll be using the "msa_cc2530" project as an example):

    The HAL_SPI.c module includes only two basic functions (as a first step): 

    1. Some initialization function for configuring the SPI port and GPIOs, this depends whether the SPI configured
      as master or slave. The call for this function should be somewhere inside the MSA_Init( ) function in msa.c
    2. Read/write function (readWriteSpi() ), which you can use for writing and reading data to/from SPI data
      buffer, that is the UxDBUF.

    Writing your own SPI module:

    1. A good place to start is by looking in DN113 document. If I remember this right, there is a mistake in
      SPI<->DMA configuration, however I don't remember what exactly is wrong. In case you'll decide that
      you want your SPI working with DMA, let me know, I'll look in my previous projects.
    2. cc253x user's guide is also a good place to refer from time to time.

    Carry out initialization, receive instructions from MSP430 over SPI, etc.:

    1. First of all you should decide who is the master and who is the slave in your MSP430<->CC2530 system.
    2. In case the cc2530 configured as master you can simply call to readWriteSpi( ) any time you got some
      information for the MSP430. The data from the MSP can be parsed and handled as a state machine,
      invoking transfer of data to the cc2530's radio and eventually to ZigBee network (just an example).
      OSAL API can be very helpful with timing and scheduling.
    3. The communication between those two devices through the SPI can be implemented by your own protocol
      (lets say, OPCODE driven).
    4. I've no good example in case the cc2530 acts like a slave, but i'm sure you can figure something out.

    Maybe there is a better and easier way to implement these functionalities, so please wait for an answer from TI experts before you take my suggestions.

     

    Anyway, I hope this helps.

    Br,

    Igor.

  • Hi Igor,

         Thanks for the suggestions. I have decided to implement SPI using the CC2530 as the master device and the MSP430 as the slave device. I have written the initialization function and ReadWriteSPI() based on the example in DN113.

     

    // Method 1; SSN kept low during the transfer of all bytes

    int* ReadWriteSPI(int length, int* txBufferMaster)

    {

                int i;

    SSN = LOW;

    for (i = 0; i <= length; i++)

    {

    U1DBUF = txBufferMaster[i];

    while (!(U1CSR && U1TX_BYTE));

    U1DBUF = rxBufferMaster[i];

    }

    SSN = HIGH;

    return rxBufferMaster;

    }

     

    I have also implemented a look-up table using OPCODEs to translate bytes passed over SPI to TiMAC function calls. It seems that I am very close on this project, but I am still confused in one area. TiMAC, like Z-stack is mostly task based. I don't know where or how to add the ReadWriteSPI task to the event queue. I have followed the program flow of TiMAC, and after all initializations are carried out, osal_start_system() is called, and the program goes into an infinite loop checking and handling tasks. I have attached a document describing what I believe to be the main program flow of TiMAC. If you could help me understand where and how to place an event into the event queue, I would be delighted and extremely grateful. (It looks to have something to do with the function HalSpiPoll() in Hal_ProcessPoll(), but this is a precompiled external function that is not available for me to see in the TiMAC source)

    8080.TIMAC program flow.pdf

    Thanks again,

         Craig Verrill

  • Hi Craig,

    The SPI module is a part of HAL, so you may consider to not make it a separate task, as your

    cc2530 is a master and you can handle the data transfer through the SPI in much easier way than

    creating additional task.


    Creating and adding new task (I'll be using the msa project as an example):

    1. Registering your new task in OSAL:
      1. Look in the msa_OSAL.c file, you'll notice the following array of event processing loops:
        // The order in this table must be identical to the task initialization calls below in osalInitTask.
        const pTaskEventHandlerFn tasksArr[] =
        {
        macEventLoop,
        MSA_ProcessEvent,
        Hal_ProcessEvent
        };

        By adding new event loop of your new task in the end of this array, you'r
        basically registering your new event in the OSAL.
        const pTaskEventHandlerFn tasksArr[] =
        {
        macEventLoop,
        MSA_ProcessEvent,
        Hal_ProcessEvent,
        MyNewTask_ProcessEvent 
        };
         
      2. You also need to add  MyNewTask_Init() function for your task in the 
        osalInitTasks() function, by replacing the Hal_Init( taskID ); with
        Hal_Init( taskID++ ); and adding MyNewTask_Init( taskID );
    2. Now you can reference to the msa.h and msa.c files:
      1. In the msa.c you can see an example of Init() and process_event() functions,
        also please notice the uint8 MSA_TaskId; declaration. The MSA_TaskID is an
        unique task ID within the OSAL.
      2. In the msa.h you'll notice that the MSA_TaskId declared as an external variable
        likewise the MSA_Init() and MSA_ProcessEvent() as an external functions for
        other tasks.
    3. Invoking some event in your new task
      1. You can use osal_set_event() (more details in the OSAL API document),
        to set a declared event that is a part of your task, by providing myTask_taskId
        and defined EVENT flag (you can define it in myTask.h). This is what you calling
        "adding task to OSAL's event queue". :) 
      2. You can invoke this event from your task or from any other task.

    I may be missing a thing or two, but in general I hope that this information was helpful.

    Br,

    Igor

  • Thanks Igor,

         This information was a major help. Much appreciated.

    Craig Verrill