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.

HalUARTWriteSPI() hangs

Other Parts Discussed in Thread: CC2540, ADS1118, CC2541

My environment is the following:

1.CC2540 USB Dongle running -1.4.0 application

2.USART0:P0_2-5=MI/MO/SS/C as SPI

3. Defined Symbols

HALNODEBUG
OSAL_CBTIMER_NUM_TASKS=1
xPOWER_SAVING
HAL_AES_DMA=TRUE
HAL_DMA=TRUE
HAL_UART_DMA=0
HAL_UART_ISR=0
HAL_UART=TRUE
HAL_UART_SPI=1
HAL_SPI_MASTER=TRUE
HAL_UART_PORT=TRUE
HAL_UART_USB=0
HAL_SPI_QUEUED_TX=TRUE
HAL_KEY=FALSE
HAL_LCD=FALSE
HAL_LED=TRUE

Execution hangs here, in HalUARTWriteSPI():

 while((!SPI_RDY_IN()) && (!spiRdyIsr) );

because SPI_RDY_IN is defined as:

#define SPI_RDY_IN()           (SPI_RDYIn == 0)

and SPI_RDYIn =0x01

Here's the assembly code.  Why is P0_1 being used for SPI_RDY_IN?

while((!SPI_RDY_IN()) && (!spiRdyIsr) );
02DC3C A2 81 MOV C,P0.P0_1
02DC3E 50 06 JNC 0x2DC46
02DC40 90 04 B5 MOV DPTR,#0x04B5
02DC43 E0 MOVX A,@DPTR
02DC44 60 F6 JZ 0x2DC3C
HAL_DMA_MAN_TRIGGER(HAL_SPI_CH_TX);
02DC46 75 D7 10 MOV DMAREQ,#0x10

  • TI is assuming you have a 5 wire SPI setup: SCLK, MOSI, MISO, CS, and DRY (data ready). TI assumes DRY is on P0_1.  Its odd because TI makes chips that don't conform to this standard. Take the ADS1118 for example. It multiplexes the DRY signal with MISO, and we should complain about that.

    You'll have to change the code if the chip you're using doesn't have a dedicated DRY pin. I rewrote the SPI without the DMA or DRY involved. Not too hard

  • Peter Borenstein said:

    TI is assuming you have a 5 wire SPI setup: SCLK, MOSI, MISO, CS, and DRY (data ready). TI assumes DRY is on P0_1.  Its odd because TI makes chips that don't conform to this standard. Take the ADS1118 for example. It multiplexes the DRY signal with MISO, and we should complain about that.

    You'll have to change the code if the chip you're using doesn't have a dedicated DRY pin. I rewrote the SPI without the DMA or DRY involved. Not too hard

    Thanks, Peter!

    Is there any reason why I shouldn't just remove the DRY check and use the TO code as is, with DMA?  From what I understand, DMA transfers are preferred over polled or ISR transfers.

    I plan to test the hardware interface, first, by configuring the driver as a SPI master, then re-configuring it as a Port 0 slave.  I don't believe in rewriting code if I already have something that works, but I'll rewrite it if you recommend replacing HALUartWriteSPI().

  • The DMA is useful because it reads/writes data into an SRAM buffer without needing the core to be on. This doesn't benefit my needs much so I don't take advantage of it. 

    I had to rewrite because I couldn't change the polarity of the clock or the data rate on the fly. I have two chips with different requirements. I looked at all this a long time ago so I'm hesitant to give details. I'm pretty sure a header gets added to any data you try to send. And some pin gets set as a DRYout in addition to the DRYin you mentioned in your first post. A bunch of "extra" stuff that would've messed up my communication.

    I hope a genius post here about TI's SPI intent. What serial communication standards are they trying to conform to?

  • I tried modifying _hal_uart_spi.c to not use the SPI_RDY pin.  Now I see a lot of SCLKs occurring even when MOSI is not being driven.  Also, it looks like GPIO  interrupts are triggered on the SPI_RDY input:

    /* Setup GPIO for interrupts by falling edge on SPI_RDY_IN */
    PxIEN |= SPI_RDYIn_BIT;
    PICTL |= PICTL_BIT;

    I'm also confused about the use of DMA_PAD in this code.  What is it?

    There must be a good example of a DMA-based SPI driver for this chip.  Do I really need to hack this TI version or build my own?

  • Hi Richard, Peter

    The file  _hal_uart_spi.c is a software component used in our network processor applications where the communication protocol needs more than regular SPI due to power modes being enabled on the slave side (CC25XX devices).

    To use SPI communication towards other devices I would recommend using e.g. the example in the KeyFobDemo (bma250.c) which is a simple accelerometer being communicated to through SPI.

    Regards,
    Svend

  • Thanks, Svend!

    I know I've seen this code before, but I can't find it now.  Please send me a link to the latest KeyFobDemo source code.

    Best regards, Richard

  • It is a part of the BLE stack, found under Projects\ble\KeyFob\Source.

    Regards,
    Svend

  • Thanks, Svend.

    I re-installed the 1.4.0 software and found the KeyFob project.  Unfortunately this does not help me.  I already have a simple polled driver similar to spiWriteByte() and spiReadByte().  I'm looking for an example of a DMA-based driver to keep up with the DMA-based driver used on SPI master subsystem.

    The HAL driver uses DMA, but it also has additional complexity associated with the RDY lines.

    Any other suggestions are very welcome.

  • Hi Richard,

    Any news on the SPI-DMA? Did you achieve any good results? I guess I'll start cleaning that _hal_uart_spi.c too. The ability to receive data from an external device w/o using the CC2541 core is really a point of interest with this technology.
    I would like your feedback -- just so I don't blow all my time in something that's not worth the effort, and since SPI triggered by an ISR is a given..

    I'm just not so sure about all those DMA functions as to what they're doing. Also it is pretty unclear what happens to the buffer that is passed, e.g., to HalUARTRead -- Should the buffer be passed with the register address to be read? Contrary to all the other libs in the 1.4 ble, SPI-DMA is pretty lame.. Hope the TI guys do something about it since this -> processors.wiki.ti.com/.../CC254x_SPI_Driver_User_Guide is really nothing.

    Thanks