This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Possible bug / missing feature in CMSIS UART Driver for LPC1769

I have made some changes to the RTE_Device.h that are necessary for my UART transmission to work properly. Unfortunately I cannot set this via the API in Driver_USART.h. Will these changes be overwritten or will I have to write functions to implement these changes to the RTE_Device.h?

Actually I think it is a bug or missing feature that this cannot be set. The FCR register of the LPC1769 cannot be written to. When I change values of the registers in the drop down menu in Periphals --> UART0, it goes back to the initial value. I had to manually write to this register in the RTE_Device.h and now it works. All the other registers can be set here without issues. 

There is a function getCapabilites() to read the capabilites of the driver, but there is no possibility to set these capabilites. Maybe I am missing something. I have searched everywhere.

  • getCapabilities() reports the capabilities defined in and by the driver source (UART_17xx.c), which should be visible in your project as a read-only file. The driver has limited ability to change behavior (DMA vs. non-DMA, for example), but that's it. That means you can't change how it handles FCR (as an example) unless you write a new driver (which is not impossible).

    I don't know why you would need to modify RTE_Driver.h (I can guess, but you didn't explain). If you're trying to change the trigger level, define the level you want in your build script using the pre-processor. This is explained in the UART_17xx.c file. There's no rule preventing you from modifying registers outside driver functions. But it could upset the driver state, so be careful. 

    As for weird behavior with changing FCR from the peripheral view -- well, sometimes the code that implements the peripheral viewer has bugs. If you think there's a valid bug there, raise it with ARM support and it'll get fixed, eventually. Meanwhile, the workaround is to do what you did and explicitly update FCR, either from code or from a memory window.

  • I have extended the RTE_Device.h by

    // <o> Trigger Level <0x00U=>1 bit <0x40U=>4 bits <0x80U=>8 bits<0xC0U=>14 bits 
    #define USART0_TRIG_LVL 0xC0U

    for all four UARTs. These correspond to 

    // USART TX FIFO trigger level
    #define USART_TRIG_LVL_1 (0x00U)
    #define USART_TRIG_LVL_4 (0x40U)
    #define USART_TRIG_LVL_8 (0x80U)
    #define USART_TRIG_LVL_14 (0xC0U)

    inside the UART_LPC17xx.h. This way I can now set the trigger level of the UART TX FIFO. This is needed for the Character Timeout, because it is disabled when the trigger level is set to 1 bit. I don't know why this function is not implemented. Maybe there is a reason for it. Nonetheless, the behavior of the FCR register in the periphal view is indeed weird, as you have also realized. I don't want to file a bug, when there is no reason to, but this has solved my problem. The register is RW and setting it is possible and needed according to the manual fo the LPC17xx family. 

    Maybe I just implemented it in the wrong file, but other registers are set in the RTE_Device.h as well. Pre-processor definitions are #ifdefs as far as I understand, so I could just set this in my main.h file I guess. This way I would also make sure that the settings don't get lost during an update.

  • RTE_Device.h doesn't set registers directly -- it defines macros that are used elsewhere to enable code and create values that are loaded into registers.

    As you noted, customizing RTE_Device.h can work, but unless you take over the pack (you can make your own), then you could have problems in future if/when the pack is updated. 

    You can avoid that hassle by defining the appropriate timeout macro in the C/C++ options. You can do that at the project level or for individual files. It's still part of the project, easy to find, and easy to implement.