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.

CC2530 ZNP mini

Other Parts Discussed in Thread: CC2530, Z-STACK

Hello,

I'm using the Simple Application Demo for the CC2530 ZNP and IAR. I'm trying to use the SPI SDRY interrupt to detect new incoming ZNP messages. I have followed the steps sugested in the code to do so. When I try to use SpiPoll( ) to read the incoming message the execution blocks waiting for an incoming message. Is there something wrong with using SpiPoll( ) within the interrupt routine?

Much thanks,

Mathew Turnell

  • Also if anyone could send me the datasheet describing the messages structure and application interface between the ZNP and the MSP430. I found this one for the CC2480. 7026.cc2480.pdf

  • The document you're looking for is called "CC2530ZNP Interface Specification" and to get it you'll need to download the ZAP package, from here:

    http://focus.ti.com/docs/toolsw/folders/print/z-stack.html?DCMP=HPA_RFIC_General&HQS=Other+OT+z-stack

    Download:

    ZStack-ZAP-MSP430-1.0.3.exe

    Once you install it, the doc is located in:

    C:\Texas Instruments\ZAP-MSP430-1.0.3\Documents

     

    As you've probably noticed, it's very similar to the CC2480, but better.

    Cheers,

    Derek

  • You'll have to disable the SRDY interrupt during a spiPoll because SRDY is also used back and forth in normal communication.

     

    --Derek

  • I disabled the SRDY interrupt but the program still blocks waiting for a character to be received trough SPI. To be more precise it blocks in the following function after I call SpiPoll( ) within the interrupt:

     

    void spiWrite(unsigned char *bytes, unsigned char numBytes)
    {
        while (numBytes--)
        { 
            UCB0TXBUF = *bytes;
            while (!(IFG2 & UCB0RXIFG)) ;     //WAIT for a character to be received, if any
            *bytes++ = UCB0RXBUF;             //read bytes
        }
    }

    Any clues?

  • Also I just found out that the printf function of the msp430 doesnt handle floats??? printf(%f,floatVariable) doesnt work! weird!

  • In the example code I had to fit everything into IAR's kickstart (4kB) code limit, so we use a very tiny printf implementation that doesn't support much. However, it's easy to just use stdio.h instead, just change the #include "printf.h" or whatever it is. One other note about printf: IAR has a few different options for how much printf support you need. Look in project options : compiler : libraries or something like that. The "full" printf library supports everything.

    And of course if you're doing serious development, don't use IAR kickstart. :)

    Oh, there's a problem in your code. You need quotation marks around the %f. It should be:

    printf("%f", floatVariable);

     

    Regards,

    Derek

  • Hmmm. I don't have any ideas. One thought would be to not call spiWrite in the ISR, but instead have the ISR set a flag that gets read in your main application loop. Then, in the main state machine if the flag is set then disable SRDY interrupt, call spiWrite, and re-enable the SRDY interrupt.

    Also take a look at the signals (including SRDY) with a logic analyzer so you can verify that you're getting the right signals. SRDY is tricky because hi/lo changes meaning depending on what you're doing.

    --Derek

  •  

    Hi,

     

    I think you should check to see when exactly an interrupt is generated, in your version you assume that an interrupt is generated when the first bit has arrived and that you have to poll the SPI interface to check that the whole byte has been shifted in and out. 

    It could also be that the interrupt is generated at the time when the whole byte has been shifted in/out, check the manual of the device please. It means that when the interrupt is generated at the end that, that is my guess, a SpiPoll() is not required because the byte is available to be read from the register.

     

    I also have seen cases where a byte needs to be read every time an interrupt is generated, the incoming bytes doesn't "overwrite" the contents of the receiver byte if the receiver byte has not been read, this could be confirm the SPI standard but I am not a 100% sure if it applies to the 2530, again checking de manual will help you also on this potential issue.

    In general polling and interrupt driven I/O are 2 completely different approaches and should never be mixed ideally unless the manual specifies specificly this scenario.

    I am not on expert on Spi (yet) but I do have experience with polling and fully interrupt driven I/O.

     

    Just a few hints that might be able to help you towards your goal.

    please let me know what you have figured out because I have to tackle this problem too at some point in time.

     

    -- André

  •  

    and an other possible hints is that you can't again mix polling driven I/O within an ISR: what you are doing is writing a complete buffer by writing a byte and waiting for the read to complete. This is not the optimal approach when using pure interrupt driven I/O.

    The approach in general is (I don't know the exact detail but let's assume that there is a interrupt that the Tx buffer is empty, the code would be:

     

    unsigned char *bytes;

    unsigned char numBytes;


    void TxBufferEmptyISR() {

    unsigned char lastChar;

    if  (numBytes--)  {  

    // not sure if you have to read the incoming byte per-se first, check manual?

    lastChar = UCB0RXBUF;             //read bytes

            // write the current byte into the transmit register

    UCB0TXBUF = *bytes;

            // and advance the read/write pointer

    *bytes++ = lastChar ;             //store the received char in the buffer
        }
    }

    You see my point: for every byte written an interrupt will be generated and no polling is required because the interrupts are generated when the designated condition occurs.

    I have to be honest, I don't know a lot about the TI hardware yet but again this is the preferred general approach when using pure interrupt driven I/O.

     

    Good luck.

     

    -- André