NUCLEO-L433 problem with USB

Hello,
I can’t get USB communication to work.

I am testing on NUCLEO-L433RC-P

In Embed studio I have a target NUCLEO-L433RC-P and I use the library mbed-os mbed-os-5.15 (I have the older version because of the MQTT communication libraries that work with this OS version)

I have the USB connected to the pins
D+ to pin PA12
D- to pin PA11
and of course the GND ground connected

I have tested all 3 versions of the sample programs from the link:

but in none of them did I get the computer to find the connected device.

Since the STM32L433 has an internal pull-up on the USB peripheral, I expect, that after connecting the USB cable to the PC, the device manager should at least find the unknown device…
It looks like the whole USB peripheral is not active for some reason.
I’ve checked the VDD_USB power pin, but it’s fine:
SWITCH SB25 VDDUSB power supply MCU pin48 = VDDUSB pin 48 powered by VDD_MCU

I also tried adding mbed_app.json and inserting the USB device into it

{
“target_overrides”: {
“*”: {
“target.device_has_add”: [ “USBDEVICE” ]
}
}
}

but then I got errors while compiling:
Compilation [ 97.9%]: USBPhy_STM32.cpp
[Error] USBPhy_STM32.cpp@46,31: no member named ‘DIEPTXF0_HNPTXFSIZ’ in ‘USB_TypeDef’
[Error] USBPhy_STM32.cpp@48,32: there is no member named ‘DIEPTXF’ in ‘USB_TypeDef’.
[Error] USBPhy_STM32.cpp@56,5: unknown type name ‘USB_OTG_GlobalTypeDef’
[Error] USBPhy_STM32.cpp@59,28: use of undeclared identifier ‘USBx_DEVICE’
[Error] USBPhy_STM32.cpp@59,48: use of undeclared identifier ‘USB_OTG_DSTS_FNSOF’
[Error] USBPhy_STM32.cpp@257,5: use of undeclared identifier ‘HAL_PCDEx_SetRxFiFo’; did you mean ‘HAL_PCDEx_GetTxFiFo’?
[Error] USBPhy_STM32.cpp@263,9: use of undeclared identifier ‘HAL_PCDEx_SetTxFiFo’
[ERROR] .\mbed-os\targets\TARGET_STM\USBPhy_STM32.cpp:46:31: error: no member named ‘DIEPTXF0_HNPTXFSIZ’ in ‘USB_TypeDef’

Do you have any idea how to do this correctly?
Thank you for your help.

Hello,

yeah, it seems like the USB was not supported for STM32L4 family in MbedOS 5
What old library? Maybe some can help.

BR, Jan

Dear Jan,
I have tried it with latest OS 6.17.0

Without mbed_app.json I have got answer in debuger:
– MbedOS Error Info –
This board does not have a hardware USB driver

With mbed_app.json where I added the USB device it works fine. PC found the CDC device and after some work with INF file I have got the result what i want.

The reason I wanted to use OS5.15 was that I have a previous project under this version where I use the libraries for Wiznet W5500 and MQTT. Under the new OS version these libraries are already reporting bugs, so I will either have to go through the whole thing and fix them or find others that will work with OS6.17.0. I wanted to save myself some of this time… :slight_smile:

Yeah, it have to be in mbed_app.json because usually all STM32 targets what do not have onboard USB port have this feature disabled.

I understand but this is a magic circle what killing this eco system. People usually want to be consumers instead of contributors.

Please share links to exact libraries that you use and we can look together how complicated would be to modified them to Mbed OS6.

BR, Jan

Thank you for your offer.
I usually turn to the forum only when I have exhausted all ideas on how to solve the problem. So I don’t want to take up your time. I’ll spend some time getting the existing libraries up and running and see: if I’m successful then I’ll share the libraries - I’m sure they’ll help others and if not I’ll contact you…
PS I’m guessing that most of the problem in these libraries will be mainly in time loops, where features that OS6 no longer supports will be used. This should be solvable fairly easily.
Thanks again.

1 Like

I’m here again. I didn’t get to MQTT because I’ve been struggling with USB for a few nights now.
I have moved from Nucleo to my board equipped with STM32L433RCT6.
In the MBED_APP.JSON configuration I only added a clock source (which shouldn’t be related to USB - the USB peripheral has its own)

{
"target_overrides": {
    "*": {
        "target.clock_source": "USE_PLL_HSI",
        "target.lse_available": 0,
        "target.device_has_add": ["USBDEVICE"]
        }
    }
}   

I created a simple test program:

#include "mbed.h"
#include "USBSerial.h"

// MBED OS 6.17.0
// clock source: HSI 16MHz

USBSerial USB_port(false, 0x1f00, 0x2012, 0x0001);          // USB port automaticky

bool USB_connected_flag = 0;

Ticker tick_1sec;                                           // casové priznaky
Ticker tick_60sec;

// vstupy a vystupy                                        
DigitalOut MCU_LEDG(PB_13);                                 // OK zelena LED
DigitalOut MCU_LEDR(PB_12);                                 // OK cervena LED
DigitalOut Rele(PB_5);                                      // OK rele (posun oproti MCU-P)
DigitalOut Beep(PA_15);                                     // OK pipak
DigitalOut RGB_Red(PC_2);                                   // RGB ledky
DigitalOut RGB_Green(PC_3);
DigitalOut RGB_Blue(PA_8);
DigitalIn Button(PB_14);                                    // OK tlacitko
DigitalIn USB_VCC(PA_0);                                    // detekce USB
DigitalOut MODBUS_EN(PC_12);                                // MODBUS prijem
                                                          

DigitalOut W_RST(PA_1);
DigitalOut W_CLK(PA_5);
DigitalIn W_MISO(PA_6);
DigitalOut W_MOSI(PA_7);
DigitalIn W_INT(PB_0);


// Procedury a funkce
void every_second();
void every_60sec();
void MCU_LEDR_Blink();


int main(void)
{
    Watchdog &watchdog = Watchdog::get_instance();
    watchdog.start(10000);
    
    W_RST = 0;                                              // drzim wiznet v resetu
    MCU_LEDR = 0;
    MCU_LEDG = 0;
    RGB_Red = 0;
    RGB_Green = 0;
    RGB_Blue = 0;
    Rele = 0;
    Beep = 0;
    W_RST = 1;                                              // poustim reset wiznetu

    tick_1sec.attach(&every_second, 1000ms);
    tick_60sec.attach(&every_60sec, 60000ms);
  
   
    while (1) 
    {
        watchdog.kick();

        if ((USB_VCC)&&(!USB_connected_flag))                   // detekuji USB_VCC a není jeste pripojeno
        {
            USB_port.connect();                                 // pokusim se pripojit USB
            //USB_port.wait_ready();                              // Block until ready
            USB_connected_flag=1;
        }
        if ((!USB_VCC)&&(USB_connected_flag))                   // neni USB_VCC a bylo pripojene
        {
            USB_port.disconnect();                              // odpojuji USB
            USB_connected_flag=0;
        }
    }  
}

void every_second() 
{
   if (USB_connected_flag)                                      // pripojeno USB
    {
        MCU_LEDG = 1;                                           // svitim LEDG
    }
    else
    {
        MCU_LEDG = !MCU_LEDG;                                   // neni pripojen - blikam
    }
}                                                                

void every_60sec()                                              // preruseni kazdou minutu
{
   MCU_LEDR_Blink();
   USB_port.printf("ABC");                                      // test 
}

void MCU_LEDR_Blink()
{
    MCU_LEDR = 1;
    wait_us(50000);
    MCU_LEDR = 0;
}

If I connect the board to the PC, the Device Manager finds my device correctly
and the green LED stops flashing - the “connection” flag
I open the corresponding virtual COM port in the terminal and wait for the test message “ABC”
So far everything is fine.

However, when the message arrives, the terminal only picks up the first character “A” and then the connection drops.
The board gets stuck and is only reset by the watchdog. Then it reconnects, but the terminal reports that the COM port does not exist.
(although the device is visible in the device report)

If I enable USB_port.wait_ready(); the board freezes and the watchdog resets it again.

I don’t foresee a hardware problem, given that

  • MCU USB peripheral is correctly powered with 3.3V
  • the computer is able to get data about the type of device
  • I am able to catch the first character of the test message
  • the same problem is on 2pcs of boards that I test and with different USB cables

Basically, I can’t think of much else…

The last attempt was to abandon USBserial and try USBCDC. It’s strange, but in this case I’m able to again catch the whole message and the connection is stable… One time!
After a while I went back and unplugged and reconnected the device I have the same problem as with the USBserial and I am no longer able to get the test message and stable connection. It seems to only work when first connection to the computer - once it recognizes the device, it doesn’t work.

I’m beginning to suspect that the problem is neither on my board nor in MBED, but in the Windows driver…

Last test: it really is in the windows or driver. If I uninstall driver and add it again, it works the first time I start it. Any further connection is not working…
(tried several drivers for VCP and all the same behavior)

Hello Lukas,

I see you are from same country :slight_smile:
USBSerial (not sure about CDC) you need manage DTR signal so it depends on your host APP if correctly manage it.

BR, Jan

Hello JohnnyK,

so I have successfully solved the USB. One problem was in the driver itself on the pC, the other in the call to the connect function, which is not needed at all, although it tempts you to use it.

Otherwise, exactly what I feared happened. By switching to OS6, I was unable to get the W5500 to work. There are a number of libraries designed for OS5 that, after modification (mainly waiting with the “wait” command), do not run under OS6, and after many tests I have to conclude that they actually do not run under OS5 combined with Nucleo L433 either.

Probably the furthest I got was with the WIZnetInterface-OS5 - For mbed OS-5 version for WIZnet Ethernet Interfa… | Mbed library, which was at least willing to share the PHY Link status with me after initialization, but I can only dream about connecting and getting an IP address. In addition, the connect function causes freezes despite the timeout parameter :slight_smile: And that’s another problem. Again, just to be safe, I switched from my board to Nucleo and a complete module with W5500 to rule out a possible HW bug.

My personal guess is that this is again somehow related to the TARGET configuration and environment, which is extremely opaque from my point of view with MBED. I am not sure what name (in mbed_app.json) of network interface is correct for my lbr… I have tested different names but without without visible change…

{
"config": {
    "network-interface":{
        "help": "options are ETHERNET, ETHERNET_WIZNET",
        "value": "WIZNETINTERFACE"
    }
},    
"target_overrides": {
    "*": {
        "target.clock_source": "USE_PLL_HSI",
        "target.lse_available": 0,
        "target.device_has_add": ["USBDEVICE"]
        }
    }
}    

Anyway, the rapid prototyping tool is becoming a time eating black hole for us. P.S. We are looking for a MBED programmer for occasional (paid) collaboration, do you know anyone? :slight_smile:

BR Lukas

Hello Lucas,

this is strange because how I see to the library uses just 4 things from Mbed

  • Timer
  • DigitalOut
  • SPI
  • wait functions

the rest seems to be Wiznet own implementation and I do not think these 4 APIs cause the problem.
But you are not alone - W5500 ethernet driver - #6 by xeenych

I do no know about any Mbed programmer and I can not call myself a professional programmer. But I can try help, then who know…

When we talk about W5500 module. What this mean? Original W5500 chip what you have on your PCB or about an Aliexpress clone? Can you share a link to exact product?

BR, Jan

Hello JohnnyK,
once again I spent a few late hours at the computer and did some tests to try to find a working library and verify my WIZ850io module…

1. Test
Test of the WIZ850io Ethernet module with the Bluepill board and source code from the Internet (GitHub - geekshow/mbed-os6-stm32-w5500-mqtt: Home MQTT ethernet controller using mbed os). For the source code I left the Wiznet and MQTT libraries and removed things related to sensors and display

- profile in mbed_app.json I left the original "requires": ["bare-metal"],
- I set the target as NUCLEO-F103RB (I know it's Bluepill compatible)
- the compilation went fine, only for
	DHCPClient.cpp
	TCPSocketServer.cpp
	W5500.cpp
	MQTTmbed.h
I got several [Warning]: 'read_ms' is deprecated......
- I threw a USB converter on the debug UART pins

obrazek

The result is that the WIZ850io module with the bluepilll works just fine and gets the IP address without any problems. (and after I set up the broker it also connected to the broker)

2. Test
I connected the same LAN module to Nucleo-L433 and moved the same program I tested on Bluepill to Nucleo-L433:

- I left the original "requires": ["bare-metal"] profile in mbed_app.json,
- I set the target as NUCLEO-L433RC-P 
- I modified the pins where I have the LAN module connected to
	EthernetInterface wiz(PA_7, PA_6, PA_5, PA_4, PA_1);
- the compilation went fine, only at
	DHCPClient.cpp
	TCPSocketServer.cpp
	W5500.cpp
	MQTTmbed.h
I got several [Warning] as before: 'read_ms' is deprecated......

During the test, the board attempts to initialize the LAN module

obrazek

But then it freezes and the watchdog resets board. The debug returns the following:

obrazek

Error decoder says:
HardFault exception
Cortex-M HardFault exception has occurred.

This suggests that the problem is definitely not in the HW and not necessarily in the Wiznet library, but rather in the combination of the Target with this library. In this combination, MBED OS simply approaches either SPI or some timing in loops differently…

As you wrote: library uses just 4 things from Mbed
- Timer
- DigitalOut
- SPI
- wait functions
but from my point of view it looks like the problem is somewhere in these 4 things and because the board freezes I would guess Wait functions or Timers.

Do you have any ideas on how to spot the problem better?

P.S. I am using original WIZ850io module with W5500 IC from Wiznet.

Best regards Lukas

Did you try to debug? For exact line where the code stops.

BR, Jan

Hello JohnnyK,
another tests with debug.
It frozen because the SPI communication is not working correctly- no valid answer from LAN module.
(and the connect function don’t have timeout in this case)

When I am using on Nucleo-L433 SPI1 on these pins - it is not working!

EthernetInterface wiz(PA_7, PA_6, PA_5, PA_4, PA_1);

But I have tried to reconnect the LAN module to another pins with SPI1 (below) and it is working without problem !!

EthernetInterface wiz(PB_5, PA_11, PB_3, PA_15, PA_1);

Now I know, it is the SPI problem .

I have also checked the mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralPins.c
and problematic pins are with note about SMPS:

MBED_WEAK const PinMap PinMap_SPI_MOSI[] = {
    {PA_7,       SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, // Connected to SMPS_SW [TS3A44159PWR_IN1_2]
    {PA_12,      SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)},
    {PB_5,       SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL.....

a collision with SMPS may be the reason on Nucleo L433.

My PCB is designed to use SPI1 on pins PA_7, PA_6, PA_5, PA_4, PA_1, but not using external SMPS. So it might work - I will test it after weekend…

Best regards Lukas

Hi,

Good to know my guess was close and Wiznet lib is working.

The external Smps is equipped on the Nucleo boards with -p suffix like on Nucleo-L433RC-P. According to user manual UM2206 there is a onboard jumper which will deactivate the Smps. So you can try to do it and test if the SPI_1 will work after that.

Back to your MCU. Do you have TM32L433RCT6 or TM32L433RCT6P? Because same like above, just MCU with suffix P has modified pinout for external SMPS.

BR, Jan

So I’m definitely done for the day. For 2 months I have not been able to make a stable LAN and MQTT connection on MBED. Ignoring the fact that I had to fix about 100 bugs in the libraries that are available (why if they are not functional), it is still unstable and the system crashes. Today when I finally lost a project worth more than a million I sincerely regret the day I started with MBED. I must say that the idea of MBED is good, but overall it is a waste of time… I’m going to look for another environment :frowning:

Hello Lukas,

I’m sorry for your situation and good luck in the future.

BR, Jan

Thank you very much. I’m really flustrated. Especially about things that I think should be reliable by now. What I’m observing:

  • Conflicts between timers in the library and tickers in the main program. Wiznet and MQTT use internal timers for timeouts, if a ticker (or more) is defined in the main program, the internal library timer can change it or turn it off completely randomly. As a result, the part of the program in the main loop that is to be executed based on the ticker flag is then skipped, or leads to a complete freeze. This is completely random and there is no cure for it - what timers are in collision is virtually impossible to trace… If thread sleep is added, disaster is guaranteed.
  • The undefined behavior varies depending on the BUILD profile. For example, under Develop the program runs, under Release it freezes already, without being able to determine what is the exact cause
  • libraries for some functions, such as wiznet and MQTT, are tragic and difficult to port between operating system versions. Of course this is not the fault of MBED OS, however it would be really nice if at least some library for a given OS version was revised, tested and released as a reference example (I see this on forums where, for example, the topic of MQTT is common and people spend time digging through various dubious libraries that are non-transferable and bent for some unique configuration)

For what it’s worth, I’m sure everyone would really appreciate if you could contribute back these fixes. Even if you don’t want to make PRs or maintain a fork, if you could at least push up the fixed versions to a repo somewhere, I’m sure someone on Mbed CE could find the time to go through what you changed and see about integrating the fixes.

And yeah, you have a good point here! MQTT and Wiznet ethernet chips are both very popular, and frankly they should be supported by Mbed. Mbed already has the infrastructure to allow swapping out IP stacks, so it shouldn’t have to be that hard to use the Wiznet one instead.

Anyway, I’m sorry for what happened, and do know that the Mbed CE project team and I are working bit by bit to try and work through exactly these sorts of issues… it will just take us a while to get through and clean up all these features and libraries.

Thank you for your feedback. I will be happy to publish the edits and make them available to all users. However, I can do that when I am sure that everything is working as it should, which is not currently the case. I would hate to contribute something that I am currently complaining about :slight_smile:

2 Likes

Hello,
MBED still keeps me up at night. After being depressed for a while, I threw myself into work - I can’t walk away from an unresolved problem. Despite the problems with libraries, I still believe that the MBED concept is a good one, and if I can solve it, maybe it will help others…
I have made progress since last time.

Summary:
- I am working on my own board with STM32L433RC
- MCU is working with HSI clock (configured in mbed_app.json, others clock configurations are default)
- I use 3x UART and 1x LPUSART
- SPI to where the Wiznet W5500 IC is connected
- HW USB port to receive info messages
- I compile in MBED studio
- MBED OS 6.17
- I have the target set to Nucleo-L433RC-P (except for the different addresses of some pins that I don’t use the RC-P should have the same core as my RC)

So far the test program works by forwarding data to the USB when it receives data on the UART. In addition, once a minute it tries to connect to the LAN and MQTT broker and if connected sends a test message to the broker.

#include "TCPSocketConnection.h"
#include "mbed.h"
#include "USBSerial.h"
#include "EthernetInterface.h"
#include "MQTTClient.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "cmsis.h"
#include <cstdio>

#define DEVICE_NAME "QRF reader"
#define DEVICE_ID "1707130195"
#define CLIENT_ID "17"
#define DEVICE_VERSION "v1.01"

#define MQTT_BROKER "192.168.0.103"
#define MQTT_PORT 1883

#define WATCHDOG_TIMEOUT_MS 20000   // 20 sekund
#define LOOP_SLEEP_MS 99
#define MQTT_KEEPALIVE 6000              // 100 minut udrzuje spojeni
#define NET_TIMEOUT_MS 2000
#define MAXIMUM_RX_BUFFER_SIZE 64

#define CARD_ID "123123123"
#define CARD_SOURCE "RFID reader"


// KONFIGURACE HW A PROPUSTNOSTI ZPRAV
bool RFID_reader_enabled = 1;           // RFID reader je povolen prijem
bool QR_reader_enabled = 1;             // QR reader je povolen prijem

bool Enable_USB = 1;                    // povoleni USB
   bool connected_USB = 1;                 // 
   bool USB_Header_flag = 1;               // posilani zprav s hlavickou
   bool Enable_USBconfigMess = 1;          // povoleni pomocných zpráv na USB
bool Enable_Ethernet = 1;               // povoleni ethernetu
bool Enable_MQTT = 1;                   // povoleni MQTT 
bool Enable_MODBUS = 0;                 // povoleni 485 MODBUS
bool Enable_IQRF = 0;                   // povoleni IQRF
   uint8_t  IQRF_NtwAdr = 0;               // adresa IQRF zarizeni

// PRACOVNI PRIZNAKY
bool flag_publish_QRFinfo = 0;          // priznak posilani pravidelneho info
bool flag_publish_info;
bool Button_flag = 0;                   // priznak stisku tlacitka
bool Block_front_LEDs_flag = 0;         // blokovani LED na celnim panelu

char systemUSBmessage[] = "";           // pro USB zpravy

Watchdog &wd = Watchdog::get_instance();

uint8_t mac_addr[6]={0x00, 0x00, 0x00, 0xBE, 0xEF, 0x99};
const char* mqtt_broker = MQTT_BROKER;
const int mqtt_port = MQTT_PORT;
char const *topic_sub = "QRF/request/"DEVICE_ID;
char const *topic_cmnd = "cmnd/"DEVICE_ID"/";
char const *topic_pub = "QRF/response/"DEVICE_ID;
char lwt_topic[] = "QRF/"DEVICE_ID"/online";
char lwt_msg[] = "0";
char mqtt_clientid[] = CLIENT_ID;

unsigned long uptime_sec = 0;
bool connected_net = false;

bool connected_mqtt = false;
uint8_t conn_failures = 0;

USBSerial USB_port(false, 0x1f00, 0x2012, 0x0001);              // USB port

//static BufferedSerial IQRF_port(PC_1, PC_0);                    // LPUART - IQRF reader port
BufferedSerial RFID_port(PA_9, PA_10);                 // UART1 - RFID reader port
//static BufferedSerial QR_port(PA_2, PA_3);                      // UART2 - QR reader port
                                                                // UART3 - 485  

char RXbufferUSB[MAXIMUM_RX_BUFFER_SIZE] = {0};                 // buffry pro zpravy
char TXbufferUSB[MAXIMUM_RX_BUFFER_SIZE] = {0};
char RXbufferRFID[MAXIMUM_RX_BUFFER_SIZE] = {0};
char RXbufferQR[MAXIMUM_RX_BUFFER_SIZE] = {0};
char RXbufferIQRF[MAXIMUM_RX_BUFFER_SIZE] = {0};

uint8_t USB_buffer_RX_length = 0;
uint8_t USB_buffer_TX_length = 0;                               // aktuální velikost buffru zprav
uint8_t RFID_buffer_length = 0;
uint8_t QR_buffer_length = 0;
uint8_t IQRF_buffer_RX_length = 0;

bool USB_RX_flag = 0;                                           // priznaky prichozich zprav
bool RFID_RX_flag = 0;
bool QR_RX_flag = 0;
bool IQRF_RX_flag = 0;

bool flag_every_500ms = 0;                                      // timer - nahrada za attach
bool flag_every_1s = 0;
bool flag_every_60s = 0;
int Times500ms = 0;
uint8_t Times1s = 0;
uint8_t Times60s = 0;


// vstupy a vystupy                                        
// wiznet QRF     PA_7, PA_6, PA_5, PA_4, PA_1
DigitalOut MCU_LEDG(PB_13);                                     // OK zelena LED
DigitalOut MCU_LEDR(PB_12);                                     // OK cervena LED
DigitalOut Rele(PB_5);                                          // OK rele (posun oproti MCU-P)
DigitalOut Beep(PA_15);                                         // OK pipak
DigitalOut RGB_Red(PC_2);                                       // RGB ledky
DigitalOut RGB_Green(PC_3);
DigitalOut RGB_Blue(PA_8);
DigitalIn Button(PB_14);                                        // OK tlacitko
DigitalOut MODBUS_EN(PC_12);                                    // MODBUS
DigitalIn W_INT(PB_0);
DigitalIn QR_INT(PA_0);


void USB_SendSystemMessage();
bool networking_init(EthernetInterface &wiz);
bool mqtt_init(MQTTNetwork &mqttNet, MQTT::Client<MQTTNetwork, Countdown> &client);
void message_handler(MQTT::MessageData& md);
int publish(MQTT::Client<MQTTNetwork, Countdown> &client, const char* msg_type, const char* point, const char* payload, size_t payload_len, bool retain, MQTT::QoS qos);
int publish_value(MQTT::Client<MQTTNetwork, Countdown> &client, const char *topic, const char *buf, bool retain);            
void publish_QRFinfo(MQTT::Client<MQTTNetwork, Countdown> &client); 
void publish_QRFdata(MQTT::Client<MQTTNetwork, Countdown> &client);
void Rx_USB_Interrupt();
void Beeper();
void OpenGate();
void MCU_LEDR_Blink();


int main(void)
{
    wd.start(WATCHDOG_TIMEOUT_MS);
    
    MCU_LEDR = 0;
    MCU_LEDG = 0;
    RGB_Red = 0;
    RGB_Green = 0;
    RGB_Blue = 0;
    Rele = 0;
    Beep = 0;

    RGB_Red = 1;                                                // test signalizacnich LED
    wait_us(3000000);
    RGB_Red = 0;
    RGB_Green = 1;
    wait_us(3000000);
    RGB_Green = 0;
    RGB_Blue = 1;
    wait_us(3000000);
    RGB_Blue = 0;
    
    sprintf(systemUSBmessage, "Devive: %s\n", DEVICE_NAME); USB_SendSystemMessage();
    sprintf(systemUSBmessage, "Device ver.: %s\n\n", DEVICE_VERSION);  USB_SendSystemMessage();

     EthernetInterface wiz(PA_7, PA_6, PA_5, PA_4, PA_1);        
    
    MQTTNetwork mqttNetwork(&wiz);
    MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork, NET_TIMEOUT_MS);
    
    USB_port.set_blocking(false);
    
    //IQRF_port.set_baud(19200);                                      // IQRF
    //IQRF_port.set_format(8,SerialBase::None,1);                     // byte, parita, stop bit
    //IQRF_port.attach(&Rx_IQRF_Interrupt, SerialBase::RxIrq);
    // system clock musi byt 3x - 4096x baudrate, 
    // pro 80MHz je povoleny baudrate 19531 - 26666666 bds

    // test pro unbufered
    //RFID_port.attach(&Rx_RFID_Interrupt, SerialBase::RxIrq);
    //RFID_port.baud(9600);                                       // RFID reader konfig
    //RFID_port.format(8,SerialBase::None,1);                     // byte, parita, stop bit
    //NVIC_SetPriority(USART1_IRQn, 240);
    //RFID_port.set_blocking(false);
    //test pro buffered
    RFID_port.set_baud(9600);                                       // RFID reader konfig
    RFID_port.set_format(8,SerialBase::None,1);                     // byte, parita, stop bit
    NVIC_SetPriority(USART1_IRQn, 240);
    RFID_port.set_blocking(false);
        
    //QR_port.set_baud(9600);                                         // QR reader konfig
    //QR_port.set_format(8,SerialBase::None,1);                       // byte, parita, stop bit
    //QR_port.attach(&Rx_QR_Interrupt, SerialBase::RxIrq);

    wd.kick();
    
    while(1) 
    {
        wait_us(10);
        Times500ms++;                                           // ticker 500ms, 1s, 60s
        if (Times500ms == 50000)                               
        {
            flag_every_500ms = 1;
            Times500ms = 0;
            Times1s++;
            if (Times1s == 2)
            {
                flag_every_1s = 1;
                Times1s = 0;
                Times60s++;
                if (Times60s == 60)
                {
                    flag_every_60s = 1;
                    Times60s = 0;
                }
            }  
        }
       
        if(flag_every_500ms)                                // every 500ms
        {
            flag_every_500ms = 0;
            
            if(!connected_net && !connected_mqtt) 
            {
                MCU_LEDG = !MCU_LEDG;
            }
        }

        if(flag_every_1s)                                // every 1s
        {
            flag_every_1s = 0;
            if(connected_net && !connected_mqtt) 
            {
                 MCU_LEDG = !MCU_LEDG;
            }
            else if(connected_net && connected_mqtt) 
            {
                MCU_LEDG = 1;
            }

            if (!Block_front_LEDs_flag)                                     // pokud neni blokovano
            {
                RGB_Blue = !RGB_Blue;                                   // blikam pripravenost na celnim panelu
            }
            wd.kick();
        }
        
        if(flag_every_60s)                                // every 60s
        {
             flag_every_60s = 0;
             int LAN_link = wiz.link();
             sprintf(systemUSBmessage,  "Link: %d, LAN: %d, MQTT: %d\n", LAN_link, connected_net, connected_mqtt);  USB_SendSystemMessage();
             
             if(LAN_link !=1)
             {
                 connected_net = 0;
                 connected_mqtt = 0; 
             }
             else if (!connected_net && Enable_Ethernet) 
             {
                 connected_net = networking_init(wiz);      
             }
             if (connected_net && !connected_mqtt) 
             {
                 connected_mqtt = mqtt_init(mqttNetwork, client);
             }
             if (connected_net && connected_mqtt)           // pravidelny publish test
             {
                 publish_QRFinfo(client);
                 publish_QRFdata(client);
                 client.yield(200); 
             }
                //sprintf(systemUSBmessage,  "ReInit UART\n");  USB_SendSystemMessage();
                //BufferedSerial RFID_port(PA_9, PA_10);
                //RFID_port.set_baud(9600);                                       // RFID reader konfig
                //RFID_port.set_format(8,SerialBase::None,1);                     // byte, parita, stop bit
                //RFID_port.set_blocking(false);
                wd.kick();
        }    


        if ((Button) && (!Button_flag))                             // stisk tlacitka
        {
            Button_flag = 1;
            OpenGate();
        }    
        if ((!Button) && (Button_flag))                             // pustění tlačítka
        {
            Button_flag = 0;
        } 

        
        if (RFID_port.readable())           // prijem zpravy od RFID
        {                          
           wait_us(100000);                 // spoydeni pro celou zpravu do buffru
           while ((RFID_port.readable()) && (RFID_buffer_length < MAXIMUM_RX_BUFFER_SIZE))
            {
                RFID_port.read(&RXbufferRFID[RFID_buffer_length],1);
                ++ RFID_buffer_length;
            }
            RFID_RX_flag = 1;
        }
        
        
        if ((RFID_RX_flag)||(QR_RX_flag))                       // pri prijmu zpravy z RFID nebo QR
        {
           if (connected_USB)                                   // je pripojeno USB?  POSILAM
           {
                MCU_LEDR_Blink();
                if (USB_Header_flag)                            // zprava s headrem?
                {
                    TXbufferUSB[0] = 0xAA;                      // hlavicka
                    TXbufferUSB[1] = 0x00;    
                    if (RFID_RX_flag)                           // je to od RFID?
                    {
                        RFID_RX_flag = 0;
                        TXbufferUSB[2] = 0x01;                  // RFID
                        for (int i=0; i<RFID_buffer_length; i++)
                        {
                            TXbufferUSB[i+3] = RXbufferRFID[i];             // data z RFID
                        }                                                   // paticka premazava posledni znak 0D
                        TXbufferUSB[(RFID_buffer_length + 2)] = 0xAA;       // paticka
                        USB_buffer_TX_length = RFID_buffer_length + 3;      // pak o jednu mene
                        RFID_buffer_length = 0;
                    }
                    if (QR_RX_flag)
                    {
                        QR_RX_flag = 0;
                        TXbufferUSB[2] = 0x02;                  //QR
                        for (int i=0; i<QR_buffer_length; i++)
                        {
                            TXbufferUSB[i+3] = RXbufferQR[i];               // data z QR
                        }
                        TXbufferUSB[(QR_buffer_length + 3)] = 0xAA;         // paticka
                        USB_buffer_TX_length = QR_buffer_length + 4;
                        QR_buffer_length = 0;
                    }
                }
                else                                            // bez hlavicky a paticky
                {
                    if (RFID_RX_flag)
                    {
                        RFID_RX_flag = 0;
                        for (int i=0; i<(RFID_buffer_length-1); i++)        // minus posledni znak 0D
                        {
                            TXbufferUSB[i] = RXbufferRFID[i];               // data z RFID
                        }
                        USB_buffer_TX_length = RFID_buffer_length;
                        RFID_buffer_length = 0;
                    }
                    else if (QR_RX_flag)
                    {
                        QR_RX_flag = 0;
                        for (int i=0; i<QR_buffer_length; i++)
                        {
                            TXbufferUSB[i] = RXbufferQR[i];                 // data z QR
                        }
                        USB_buffer_TX_length = QR_buffer_length;
                        QR_buffer_length = 0;
                    }
                }
                USB_port.write(&TXbufferUSB, USB_buffer_TX_length);   // tady je chyba - stridam buffry
                sprintf(systemUSBmessage, " \n");  USB_SendSystemMessage();
            }
               
            USB_buffer_TX_length = 0;                                       // az po odeslani vsech zprav
        }
        
    //ThisThread::sleep_for(10ms);    
    }    
}



// posila na USB systemove informace 
void USB_SendSystemMessage()
{
    if (Enable_USBconfigMess)
    {
        USB_port.write((uint8_t *)systemUSBmessage, strlen(systemUSBmessage));
    }    
}
// and all others functions and procedures....

Wiznet and MQTT are already working well and without any failures - sending data every minute.
The UART only works fine for the first 60 seconds before the flag_every_60s is called. If data comes in on the UART after that the board crashes immediately and after 20s the watchdog restarts it.

obrazek

  • at first I suspected wiznet and MQTT, but the board crashes when receiving UART message even though the 60s part is completely empty (I don’t call LAN connection at all)
if(flag_every_60s)                                // every 60s
        {}  // empty
  • it’s also not related to time - I can extend the loop to 180s for example and then it crashes after receiving the UART message only after 180s

  • I have tried several combinations to work with UART

    • Buffred serial, attach or sigio (crashes anyway after 60s on first reception)
    • Unbuffered serial, attach or sigio (crashes equally after 60s on first reception)
    • I also implemented RAWSerial (does not crash after 60s on first reception, but does not receive after that)
    • I tried to lower the IRQ priority for the UART (no effect)
    • I tried reinitializing the UART at the end of the 60s sequence (it doesn’t crash after 60s on first reception, but doesn’t receive at all)

Similarly, I do the time loop on the 500ms, 1s and 60s flags completely inappropriately in main. If I use Ticker, then it crashes the very first time I receive a message on the UART.

Overall, it looks to me like the individual parts are working, but the problem is maybe somewhere in some Mutex/ISR collision although I don’t see it anywhere.

The problem is that I don’t have a single free serial port to send a crash report to and know more information.
Is there any way to send this information to the HW USB port, which is the only one I have available?

I tried to solve this problem by creating my own Custom Target, promising myself that I could then get messages over the ST-link I use to record. Unfortunately I was unable to create a custom custom target :frowning:

The last thing is that I’m not at all sure if I have configured correctly the mbed_app.json and all necessary libraries are enabled. I’m using bare-metal profile and the MBED documentation says mutex is enable for example, so I believe it… Is it OK?

{
    "requires": ["bare-metal", "events", "drivers-usb"],
    "target_overrides": {
      "*": {
        "target.clock_source": "USE_PLL_HSI",
        "target.lse_available": 0,
        "target.default_lib": "small", 
        "target.printf_lib": "minimal-printf",
        "platform.minimal-printf-enable-floating-point": true,
        "platform.stdio-minimal-console-only": true,
        "platform.stdio-baud-rate": 115200,
        "platform.stdio-buffered-serial": 1,
        "target.console-uart": false,
    	"target.console-uart-flow-control": null,
        "target.device_has_add": ["USBDEVICE"]
      }
    }
}

I’m even less sure about the other configuration than this one I got from the demo example.
Also, the documentation mentions that: “arm microlib doesn’t support returning from main(); attempting to return from main() causes a bare metal application to crash. Here we show two ways to prevent this…”. It almost looks like my case, but I honestly don’t really understand what exactly is meant by that?

In principle, I don’t necessarily need the smallest possible configuration - I have 256k flash and I certainly won’t use it, so I can easily go to another configuration with more code and it doesn’t have to be bare-metal or microlib, if that solves my problem :slight_smile:

P.S. JohnnyK won’t be at Embedded world in Nuremberg next week by any chance?

BR Lukas