7 years, 9 months ago.

Porting MODSERIAL to Nucleo-L476RG

Hello,

I need a buffered serial library with interrupt capability for my Nucleo-L476RG application. That is why I have to port MODSERIAL to mentioned Nucleo platform.

According to the instructions in "AddingDevice.h" I did the following:

MACROS.h

...
#include "MODSERIAL_NUCLEO_L476RG.h"
...

MODSERIAL_NUCLEO_L476RG.h

#if defined(TARGET_NUCLEO_L476RG)

#define MODSERIAL_IRQ_REG ((USART_TypeDef*)_base)->CR1
#define DISABLE_TX_IRQ MODSERIAL_IRQ_REG &= ~USART_CR1_TXEIE
#define DISABLE_RX_IRQ MODSERIAL_IRQ_REG &= ~USART_CR1_RXNEIE
#define ENABLE_TX_IRQ MODSERIAL_IRQ_REG |= USART_CR1_TXEIE
#define ENABLE_RX_IRQ MODSERIAL_IRQ_REG |= USART_CR1_RXNEIE

#define MODSERIAL_READ_REG ((USART_TypeDef*)_base)->RDR
#define MODSERIAL_WRITE_REG ((USART_TypeDef*)_base)->TDR
#define MODSERIAL_READABLE ((((USART_TypeDef*)_base)->ISR & USART_ISR_RXNE) != 0)
#define MODSERIAL_WRITABLE ((((USART_TypeDef*)_base)->ISR & USART_ISR_TXE) != 0)

#define RESET_TX_FIFO while(0 == 1)
#define RESET_RX_FIFO while(MODSERIAL_READABLE) char dummy = MODSERIAL_READ_REG

#define RX_IRQ_ENABLED ((MODSERIAL_IRQ_REG & USART_CR1_RXNEIE) != 0)
#define TX_IRQ_ENABLED ((MODSERIAL_IRQ_REG & USART_CR1_TXEIE) != 0)

#endif

MODSERIAL_NUCLEO_L476RG.cpp

#ifdef TARGET_NUCLEO_L476RG
#include "MODSERIAL.h"

void MODSERIAL::setBase(void ) {
switch( _serial.index ) {
        case 0: _base = USART1; _IRQ = USART1_IRQn; break;
        case 1: _base = USART2; _IRQ = USART2_IRQn; break;
        case 2: _base = USART3; _IRQ = USART3_IRQn; break;
        default: _base = NULL; _IRQ = (IRQn_Type)NULL; break;
    }
}

void MODSERIAL::initDevice(void) {};

bool MODSERIAL::txIsBusy( void ) 
{ 
    return ( (((USART_TypeDef*)_base)->ISR & ( 1UL << 6 )) == 0 ) ? true : false; 
} 

#endif

When testing the library with below simple mbed code (even without interrupts), the code compiles but my serial terminal shows nothing:

Main.cpp

#include "mbed.h"
#include "MODSERIAL.h"

#define BUFFER_LENGTH 512
MODSERIAL pc(USBTX, USBRX, BUFFER_LENGTH);
//Serial pc(USBTX, USBRX);

int main()
{
     pc.baud(921600);
     pc.printf("\r\nStarting...\r\n");
}

By switching to "Serial pc(USBTX, USBRX);" instead of MODSERIAL the serial communication works fine.

I am attaching some screenshots from the reference manual of STM32L4x6 No. RM0351. /media/uploads/petermeter69/mbed_cr1.png /media/uploads/petermeter69/mbed_isr.png /media/uploads/petermeter69/mbed_rdr_tdr.png

Since I am new to mbed, I have no idea how to investigate into this. Please help me what I am doing wrong!

I have messaged Erik the current maintainer of MODSERIAL and he can't reproduce the problem on his F401 board. If you try your code without the .baud line it will work . The problem is the baud causes a reinitialisation of the st driver and something is going wrong.

posted by David Fisher 04 May 2017

By commenting out the line where the baud rate is set, the above MODSERIAL library indeed starts working on my Nucleo-L476RG at the default baud rate of 9600! The only problem that remains is that this is quite slow... Anyway thanks for this tip!

posted by Peter Molnar 04 May 2017

1 Answer

7 years ago.

I have the same problem with porting to Nucleo F767ZI did you ever solve the problem ?

I think the problem is in the SetBase function.

Sorry, I didnt solve it! Also sorry for the late answer!

posted by Peter Molnar 20 Apr 2017

The problem seems to be there is no underlying hardware serial port being made in the Serial class and so there is no index to select the serial port in MODSERIAL SetBase. I tried selecting the correct uart in SetBase and it didn't work I think because the hardware serial port hasn't been created. I came up with the same .h file you did. Sorry for the late answer :)

posted by David Fisher 27 Apr 2017

Erik has pushed a new version of MODSERIAL which fixes some warnings. It didn't solve the problem for me but I'd be interested to know if it solved it for you.

posted by David Fisher 08 May 2017