disk91 / stm32-it-sdk

Disk91 STM32 IoT SDK
https://www.disk91.com
GNU General Public License v3.0
45 stars 19 forks source link

Murata ABZ boot problem if disconnected UART #63

Closed zokl closed 3 years ago

zokl commented 3 years ago

Hello, I have a very special problem with Murata ABZ running on battery without connected UARTs. I use your SDK in a common way. For development and testing, I am using UART. Everything works. My code is done and I would like to use my board without connected UART. Now I have a problem with booting the device. Without connected UARTs device does not boot if I have the followed configuration in config.h:

#define ITSDK_WITH_UART             ( __UART_USART1 )       
#define ITSDK_WITH_UART_RXIRQ       ( __UART_USART1 )   
#define ITSDK_WITH_UART_RXIRQ_BUFSZ 32
#define ITSDK_WITH_RTC              __RTC_ENABLED
#define ITSDK_WITH_CLK_ADJUST       __ENABLE

If I disable ITSDK_WITH_CLK_ADJUST board boot.

I have tried to identify the breaking point. I found it in the function serial1_init() in uart_wrapper.c. The problem with CLK adjust occurs if is used this command - __HAL_UART_ENABLE_IT(_uart,UART_IT_RXNE);. After disabling everything works and the board boots with ITSDK_WITH_CLK_ADJUST enabled.

The other special issue is if I connect a cable about 20 cm with a free end to RX and TX board boots without upper modification. I have tried to use a configuration with/without pullup on RX but without success.

Do you know where could be a problem?

disk91 commented 3 years ago

Hello, UART 1 is use for STM32 boot operation in certain condition (take a look at BOOT pin also) This can cause the MCU to try using the serial bootloader to get a new firmware and prevent booting on the flash. When connected your serial line will have a state allowing to directly boot the normal way. You should be able to fix this with a pull-up/down, I don't remember on the RX line. Check all of this as I tell this from my memory. I've some issues like this and the solution was on this way. By reading more in detail your comment. I assume you have a IRQ storm on you RX line due to noise on the unconnected pin. Setup the RX pin with a pullup (by configuration is enought) should solve this problem. I don't know why clock adjust changed the behavior.

zokl commented 3 years ago

Hello, UART 1 is use for STM32 boot operation in certain condition (take a look at BOOT pin also) This can cause the MCU to try using the serial bootloader to get a new firmware and prevent booting on the flash. When connected your serial line will have a state allowing to directly boot the normal way. You should be able to fix this with a pull-up/down, I don't remember on the RX line. Check all of this as I tell this from my memory. I've some issues like this and the solution was on this way. By reading more in detail your comment. I assume you have a IRQ storm on you RX line due to noise on the unconnected pin. Setup the RX pin with a pullup (by configuration is enought) should solve this problem. I don't know why clock adjust changed the behavior.

Hello, thank you for your answer. I try to use pull-up and pull-down on the RX but without success. For now, only works disable this function __HAL_UART_ENABLE_IT(_uart,UART_IT_RXNE);.

disk91 commented 3 years ago

Do you have #define ITSDK_WITH_UART_RXIRQ __UART_USART2 (or equivalent) in your config.h

zokl commented 3 years ago

Do you have #define ITSDK_WITH_UART_RXIRQ __UART_USART2 (or equivalent) in your config.h

I use only USART1:

#define ITSDK_WITH_UART             ( __UART_USART1 )
#define ITSDK_WITH_UART_RXIRQ       ( __UART_USART1 )
#define ITSDK_WITH_UART_RXIRQ_BUFSZ 32

but in my other project, I use both of uarts and it has the same behavior.

disk91 commented 3 years ago

and the line you are removing is related to USART1 ? I think about an error if an interrupt occurs before the serial init. Can you try with modifying volatile uint8_t __serial1_bufferRd; volatile uint8_t __serial1_bufferWr; by volatile uint8_t __serial1_bufferRd = 0; volatile uint8_t __serial1_bufferWr = 0; in uart_wrapper.c ?

disk91 commented 3 years ago

if it works, can you try with:

void serial1_init() {
#if ( ITSDK_WITH_UART_RXIRQ & __UART_USART1 ) > 0 || ( ITSDK_WITH_UART_RXIRQ & __UART_LPUART1 ) > 0
    // Reset circular buffer
    __serial1_bufferRd = 0;
    __serial1_bufferWr = 0;
    #if ( ITSDK_WITH_UART_RXIRQ & __UART_LPUART1 ) > 0
        UART_HandleTypeDef * _uart = &hlpuart1;
    #elif  ( ITSDK_WITH_UART_RXIRQ & __UART_USART1 ) > 0
        UART_HandleTypeDef * _uart = &huart1;
    #endif
    __HAL_UART_ENABLE_IT(_uart,UART_IT_ERR);
    __HAL_UART_ENABLE_IT(_uart,UART_IT_RXNE);
    __HAL_UART_DISABLE_IT(_uart,UART_IT_TC);
    __HAL_UART_DISABLE_IT(_uart,UART_IT_TXE);
    // Clear pending interrupt & co
    HAL_UART_Receive_IT(_uart, __serial1_buffer, 1);
    _uart->Instance->RDR;
    _uart->Instance->ISR;
    _uart->Instance->ICR;
#endif
}
zokl commented 3 years ago

I have tried your proposed modifications but it does not work. I tried it with and without pull-up according to recomendation in https://www.st.com/resource/en/application_note/cd00167594-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf but without success.

The only working solution is removing __HAL_UART_ENABLE_IT(_uart,UART_IT_RXNE); if I use ITSDK_WITH_CLK_ADJUST enabled.

zokl commented 3 years ago

My schematic is very simple. PA9 and PA10 are used as a UART debug interface. Could it be a Murata and STM bug?

Screenshot 2020-11-11 at 07 56 08
disk91 commented 3 years ago

I don't really understand where it can come from, I have a relatively near setup but not this issue. If changing the code makes it working it should comes from something related to it. But why do you have a link with CLK_ADJUST is totally mad to me ; or the reason could be a timing reason as the CLK adjustment take a little while. Can you try to disable the Interruption on RXNE ( I assume cubemx activated them somewhere) to ensure there is no interrupt before having correctly setting up the buffers.

zokl commented 3 years ago

I don't really understand where it can come from, I have a relatively near setup but not this issue. If changing the code makes it working it should comes from something related to it. But why do you have a link with CLK_ADJUST is totally mad to me ; or the reason could be a timing reason as the CLK adjustment take a little while.

YES, this could be a problem. If I move itsdk_time_init(); after serial initialization everything works.

void itsdk_setup() {

//  itsdk_time_init();
    #if ITSDK_LOGGER_CONF > 0
    log_init(ITSDK_LOGGER_CONF);
    #endif
    #if ITSDK_WITH_WDG != __WDG_NONE && ITSDK_WDG_MS > 0
      wdg_setupWithMaxMs(ITSDK_WDG_MS);
    #endif
    serial1_init();
    serial2_init();
    itsdk_time_init(); 
zokl commented 3 years ago

So, the problem is really in the pull-up on the RX. My experiments were with an external resistor on a given pin. Finally, it helped activate the pull-up directly on the RX pin of the processor. Now the boot is no problem and needs no change in the SDK.

Thank you very much for your help!