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 *data, eANT_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.Data, data, ANT_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.