If don't know if this is an issue that anyone cares about. I am also
not sure what the best way to solve it is either. I just thought I
would issue a pull request with this commit to bring the issue to light
and show a possible solution that I have tested on my mbed-1768 device.
Previously the serial_putc() API didn't make any use of the Tx FIFO
since the serial_writable() API it utilizes only returns true when the
FIFO is completely empty. This is due to the fact that the THRE bit of
the UART's LSR (Line Status Register) only goes high when the whole
FIFO is empty.
I noticed this when doing some performance testing with the network
stack. I went from calling printf() to output 3 bytes every 10 seconds
(with packet drop stats) to instead output 4 bytes every 10 seconds.
I thought these should easily fit in the 16 byte FIFO but outputting
one extra byte caused an additional three 550 byte UDP packets to be
dropped. This should only happen if the additional character being
sent to the UART was taking away extra CPU cycles from the network
stack.
My solution is to keep track of the number of bytes that have been
placed in the Tx FIFO since it was last detected as being completely
empty (via the THRE bit). Only once this count hits 16 does the code
then block, waiting for the THRE bit to go high. Each time the THRE
bit does go high, the count is reset to 0 again and it is incremented
for each byte that is loaded into the THR.
Because the LPC81X HAL implementation calls error(), which in turn calls
fprintf(), quite a bit of code is added to the image, which is not a good
idea on such resource constrained targets.
Because CT32B1 (P1_1, P1_2 and P1_3) is used by us_ticker.c for wait and ticker function. Since wait/ticker is commonly used by mbed code and I decided CT32B1 of LPC11XX should only be used for this function, not for PwmOut.
P1_6 and P1_7 are used by UART (USBTX/USBRX) and I think they should not be assigned to other function.
Fault is triggered by trying to read LPC_CAN1->IER when the peripheral is powered off. Fixed by checking the power control register before checking the IER register.
While fixing this issue in the various LPC* ports, I noticed a comment
pointing to this mbed forum post which summarizes this bug quite well:
https://mbed.org/forum/bugs-suggestions/topic/4473/
This bug was introduced in the following commit:
2662e105c4
The following code was added to serial_putc() as part of this commit:
uint32_t lsr = obj->uart->LSR;
lsr = lsr;
uint32_t thr = obj->uart->THR;
thr = thr;
As the forum post indicates, this causes the serial_putc() routine to
actually eat an inbound received byte if it exists since reading THR is
really reading the RBR, the Receiver Buffer Register. This code looks
like code that was probably added so that the developer could take a
snapshot of these registers and look at them in the debugger. It
probably got committed in error.
There were lots of overlaps in the code for LPC810 and LPC812, including
duplicated source files. This commit adds a TARGET_LPC81X_COMMON folder in
both HAL and CMSIS, this folder keeps common code for the targets.
This commit targets the LPC11U24 code, whereas a previous one
targetted similar issues in the LPC1768 mbed HAL code.
These changes were made to silence GCC warnings and fix potential bugs
where they would never be equal when the enumeration wasn't a 32-bit
type.
For example, pinmap.c used to contain this code:
if (pin == (uint32_t)NC) return;
I switched it to:
if (pin == (PinName)NC) return;
I wonder why this casting to uint32_t was done in the first place?
Maybe another supported compiler requires it?
The original code was:
if(LPC_CAN1->IER | LPC_CAN2->IER != 0) {
This would actually be interpreted as:
if(LPC_CAN1->IER | (LPC_CAN2->IER != 0)) {
I simplified it to:
if(LPC_CAN1->IER | LPC_CAN2->IER) {
With the comparison removed, the GCC warning no longer fires since the
user's intent is no longer unclear. However, the end result should be
the same.