Welcome Guest,Register Now
Log In

ANT Forum

Welcome guest, please Login or Register

   

Bare-metal, no API, Advanced Burst  

Rank

Total Posts: 3

Joined 2019-07-08

PM

Hi,

I was hoping the community could come to my aid as I've been stuck with the proper data flow control for Advanced Burst data in asynchronous tx only mode.

I've developed my own API from ground-up and my application is running on a bare-metal embedded environment. UART Tx/Rx and software-monitored RTS/CTS pins wired between my MCU and the nRF52 ANT SOC. My goal is to send out 120x161 bytes from my chip over ANT RF. The theoretical minimum time for this - taken 60kbps - is ~2.6sec, yet, I cannot go below 15sec which, as you see, is quite poor. Unfortunately the Ant Message Protocol And Usage, AN04 Burst Transfers, and Tech FAQ are not exactly useful in my particular case.

My main problem as you might guessed is with error handling - what happens when a transmission fails. In my API I have a function
void ANT_SendAdvancedBurstData(unsigned char channel, const void *dataeANT_BurstPacketType_t packetType){    
    
static int sequence 0;
    
struct __attribute__((packed)){
        unsigned char Channel        
5;
        
unsigned char SequenceNumber 2;
        
unsigned char IsLast         1;
        
unsigned char Data[ANT_ADVANCED_BURST_MAX_DATA_LEN];
    
} command;
    
    
// The very first packet will have a sequence number 0
    
if(packetType == ANT_BURST_PACKET_TYPE_FIRST)
        
sequence 0;
    
// The subsequent ones are numbered from 1 to 3.
    
else if(++sequence 3)
        
sequence 1;
    
// => Sequence number goes like 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3...

    
command.Channel         channel;
    
command.SequenceNumber  sequence;
    
command.IsLast          packetType == ANT_BURST_PACKET_TYPE_LAST;
    
memcpy(command.DatadataANT_ADVANCED_BURST_MAX_DATA_LEN);

    
ANT_ActionCommand(&command;, sizeof(command), ANT_MSG_ID_ADVANCED_BURST_DATA);

where
ANT_ActionCommand(..) 
fills in the SyncByte, MessageID, CommandLength, and Checksum fileds, then sends out the data over UART to the ANT SOC.

My question is then, how do I schedule in the successive calls to this function? I understand that in order to get the maximum throughput, I need to "prime" the ANT SOC with 2 messages to fill up its internal buffer. After that I need to monitor the RTS line and only send the next packet (sequence) when RTS is low.

However, if either packet fails, I need to restart the sequence from the sequence 0. Therefore, I not only have to monitor the RTS pin, but I also need to consider the channel response's error code to decide which sequence number to transmit next. Consequently, I need to wait for a response after each UART packet transmission - but under normal circumstances (where no error happens) I only receive a TX_START_0x0A and TX_DONE_0h05 messages; the "middle" messages not getting any replies. So if I wait X amount of time for a reply between each transmission, my throughput will suffer. If I just check for a channel response and not wait, I might fail to react to the TX_FAILED_0x06 message quickly enough, meaning that I'll get a SEQUENCE_ERROR_0x20. How do I get around this problem? Any help would be much appreciated.      
Rank

Total Posts: 3

Joined 2019-07-08

PM

For anyone having similar issues, the problem was that I was initiating new sequences too fast. (Advanced) burst negotiation between the Tx and Rx side takes around 10-15ms (Event Tx Start), therefore one cannot initiate (sequenceNumber[1:0] = 0b00) a burst transaction faster than this. Once the last burst is sent (sequenceNumber[2:0] = 0b1xx), the host must wait for the tx complete before initiating a new sequence. However, once the burst is initiated (and the queue on the ANT SOC fed according to the RTS/CTS pin requirements), the burst transaction becomes fast and stable. If all the hardware control flow is serviced well, the TX_START and TX_DONE events become irrelevant.