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.

RTOS/CC2640R2F: Thread synchronization for time critical SPI transfer?

Part Number: CC2640R2F

Tool/software: TI-RTOS

Hello,

I am developing my BLE application around the simple_peripheral example and I am having an issue reliably reading in data from my SPI peripheral. I have an external SPI CAN bus controller that interrupts when a message is received into one of its two buffers and I must read this message over SPI immediately. I have added a can task with an interrupt handler for this that has a higher priority than the simple_peripheral task, but lower than the ICall_createRemoteTasks() and the GAPRole_createTask().

I need to be able to receive a large packet (of around 10 messages) back to back after I issue a data request to another device on the CAN bus. This works for most of the time, however, there are times when the can task is preempted by the higher priority tasks and it misses several of the messages (does not read them before another comes in and overwrites the buffer on the external controller). 

I have been looking into using the Task_disable() and enable functions around this critical transfer since I have control over and know when the transfer will occur but I can't seem to get it to work properly. It seems to crash the entire program like it is not ever re-enabling. Is it ok to use these functions in this manner with the ICall_createRemoteTasks() and the GAPRole_createTask() tasks? Is this the best way to go about solving this problem or is there a better solution I should be looking at?

Thanks!

  • Hi,
    I have assigned this thread to our BLE/CAN expert. Stay tuned.
  • Hello,

    Joshua Hess said:
    I am developing my BLE application around the simple_peripheral example and I am having an issue reliably reading in data from my SPI peripheral

    What are the connection parameters that you are using (ex. connection interval)? And how much data are sending over the air?

    Joshua Hess said:
    I have an external SPI CAN bus controller that interrupts when a message is received into one of its two buffers and I must read this message over SPI immediately

    Which SPI CAN controller are you using? Also what speed are you running SPI and CAN?

    Joshua Hess said:
    I need to be able to receive a large packet (of around 10 messages) back to back after I issue a data request to another device on the CAN bus

    How frequent are you planning to receive these packets?

    Joshua Hess said:
    Is this the best way to go about solving this problem or is there a better solution I should be looking at?

    Instead of disabling the tasks, I would ratter change the priority of your CAN task to the highest and then when it's done put it back to their default priority, but depending on how often you will receive CAN data, your connection interval and how much data you are sending over the air, this might not be a good solution. Unless that you time this in between your connection intervals.

    The correct implementation will be to have a queue or some kind of mailbox on the CC264x and use the SPI DMA to transfer the frames from the CAN controller into these mailboxes. And then have another task to process the message received.

     Hopefully this helps.

       David

  • Hello David,
    Thank you for your reply. Let me start by answering your questions:

    1. I am using a small connection interval, the min and max are both set to 10 (12.5ms). I am currently only sending a single 20byte characteristic every 30ms from the central side to the peripheral. However, the received CAN data will be packatized and sent over another characteristic at a slower interval, say every 100ms once I get notifications working.

    2. I am using the MCP2515 CAN controller. The SPI is set at 10M (max it can be) and the CAN is operating at 500Kbs.

    3. I am currently requesting these packets every 20ms and it should remain this way. I might be able to expand this to 30ms if needed.

    Gathering from what you were saying about "sqeezing" the can task to a higher priority between the connection intervals, I would guess that that might not be a good solution here since the connection interval is less than the CAN receiving rate. Is this accurate? Also, what would happen in a condition where the highest priority BLE tasks were prempted?

    I am using mutiple queues between and in my tasks for message sending and processing. Is this the same type of queue you are referring to? I have breifely looked at the SPI DMA functionality but there are some issues with using it as well. One problem with this solution is that the INT pin on the MCP2515 can indicate things other than just a received message in the buffer such as erros or transmit status. Additionally, upon the INT pin going low due to a message in the buffer, I must read a register to determine if the message is in buffer one or buffer two. There are two other INT pins that indicate only a state change of the rx buffers, but it would be extremly inconvinient to use these because I have used up all the GPIO pins on my CC2640r2 for other critical things.

    Idealy, I think the best solution would be to ensure smooth uninterrupted exicution of the CAN task only during this time. I suppose I could look at increasing the connection interval to avoid collision and squeeze this transfer in between them. The actual CAN transfer of the data from request to last frame received is less than 3.5ms so maybe this would be possible.

    Let me know your thoughts on what you think would be best for this situation. I really appreciate your help!

    Thank you so much,
    Josh
  • Hi Josh,

     Were you able to test this?

    Joshua Hess said:
    increasing the connection interval to avoid collision and squeeze this transfer in between them

     Did that work?

      Please let us know if you need any help from our side.

       Best regards,

       David