The line printf("%ld\r\n,count");
will always send "\r\n,count", which is 8 bytes, and likely not what you want.
You probably meant to write :
printf("%ld\r\n",count);
However, as Dave Tweed explained, it is unlikely the UART will run fast enough.
After the first millisecond, the count will be 4 digits, so that printf
will try to print at least 6 bytes, which would require 60Mbit/second.
Worse, TIM4_IRQHandler(void)
will be blocked waiting for the printf
to complete, so all lower priority interrupts will be blocked. The Nucleo F401-RE will be blocked inside the IRQ handler.
Turbo J points out, even if the UART could handle the data rate, the code of the printf
will consume more instruction cycles than available before the next interrupt happens.
BTW - What is receiving the characters from the UART? What data rate is it capable of receiving? A lot of ordinary USB to UART converters will struggle to get much above 1MByte/second.
Either a fixed length format, or a format which only uses one bit to signal end of 'packet' would be more efficient. A god choice also depends on the receivers capabilities. Write directly to the UART buffer, avoid using printf
. It won't be doing anything useful to a binary protocol (unless it internally used DMA).
Possible approaches:
4 byte fixed 'packet'.
Edit3:
Assuming a sendByte(byte)
function is available to stuff bytes directly int the UART buffer:
sendbyte((count>>24)&0xff);
sendbyte((count>>16)&0xff);
sendbyte((count>>8)&0xff);
sendbyte((count)&0xff);
Would send the 4 bytes of the count. However the receiver might lose synchronisation. This wouldn't be a big problem for the first few seconds as the top byte would always be zero. Further, the receiver could always see which byte is changing most quickly. However, if losing bytes is a problem, this might not be enough.
To help avoid losing synchronisation, reserve the top bit of each byte to mark the start or end of the packet. So using a maximum 28bit count, and setting the top bit of the first byte of the 4 byte packet to a '1' and the top bit of the following three bytes to '0'.
Use printable characters, for simplicity use 6 bits, with the top bit of the first byte set (so it is above ASCII) but the rest using ASCII. This would lose another bit from each byte, so you might want to transmit 30 bits in a 5 byte packet. These messages would be printable, which might help you debug it.
If you kept the data rate to a rate the receiver could handle (maybe 4Mbit/s or less?), and sent slowly enough to give a reasonable amount of processing time to the rest of the application, it should be okay.
That would suggest a byte every 2µseconds, and for the 5 byte protocol, a timestamp every 10µs.
You could use DMA to send the bytes. The timer IRQ would set up the bytes for transfer, initialise the DMA, and it would all happen in the background. However, this is much more complex to set up, so get the transfer working before attempting to use DMA.
Edit:
At a baudrate of 115200, that is only 14,400 bytes/second.
A count of 1,000,000,000 will take 30 bits, or at least 4 bytes.
So the maximum number of counts that could be transferred is 3,600/second, i.e. a timestamp each 277µs.
I strongly recommend you explain the actual problem you are trying to solve, maybe in a new question, as it currently seems orders of magnitude away from feasible.
Edit2:
I've failed to find them, but I believe FTDI published some benchmark numbers for their USB-to-UART using 12Mbits USB transfers a few years ago. I believe, under benchmark conditions (which they designed) they got just under 700kBytes/second (abut 670kB/s, I think). Without more detail, I would regard this as unachievable in general situations, and an absolute maximum.
There is a somewhat interesting set of USB 'read' benchmarks by PJRC comparing various USB-equiped microcontrollers. The results for Maple (an STM32F103) was 234,114 Bytes/second directly over 12Mbit/s USB. PJRC's Teensy 3.0 managed 683,689 under the same constraints. Paul Stoffregen seems to be very talented, so I would use that as very good throughput for read. It also is close enough to my recollection of the FTDI benchmark (I thought 670k) that I would reduce that by 20%, say 500kB/s, and use that as my maximum.
Best Answer
It was: __HAL_TIM_GET_COUNTER
I should RTFM better