diff --git a/examples/Boards/STM32L475VG-DISCOVERY-IOT/BTLE_sensors_TimeOfFlight_demo/BTLE_sensors_TimeOfFlight_demo.ino b/examples/Boards/STM32L475VG-DISCOVERY-IOT/BTLE_sensors_TimeOfFlight_demo/BTLE_sensors_TimeOfFlight_demo.ino index db6a8da..f5914d9 100644 --- a/examples/Boards/STM32L475VG-DISCOVERY-IOT/BTLE_sensors_TimeOfFlight_demo/BTLE_sensors_TimeOfFlight_demo.ino +++ b/examples/Boards/STM32L475VG-DISCOVERY-IOT/BTLE_sensors_TimeOfFlight_demo/BTLE_sensors_TimeOfFlight_demo.ino @@ -346,12 +346,15 @@ void setup() { // Initlialize components. HumTemp = new HTS221Sensor (dev_i2c); + HumTemp->begin(); HumTemp->Enable(); PressTemp = new LPS22HBSensor(dev_i2c); + PressTemp->begin(); PressTemp->Enable(); - sensor_vl53l0x = new VL53L0X(dev_i2c, PC6, PC7); + sensor_vl53l0x = new VL53L0X(dev_i2c, PC6); + sensor_vl53l0x->begin(); sensor_vl53l0x->VL53L0X_Off(); ret = sensor_vl53l0x->InitSensor(0x10); if(ret) { diff --git a/examples/Boards/STM32L475VG-DISCOVERY-IOT/WiFi_MQTT_Adafruit.io/WiFi_MQTT_Adafruit.io.ino b/examples/Boards/STM32L475VG-DISCOVERY-IOT/WiFi_MQTT_Adafruit.io/WiFi_MQTT_Adafruit.io.ino index 0c42ccf..a5e5cb3 100644 --- a/examples/Boards/STM32L475VG-DISCOVERY-IOT/WiFi_MQTT_Adafruit.io/WiFi_MQTT_Adafruit.io.ino +++ b/examples/Boards/STM32L475VG-DISCOVERY-IOT/WiFi_MQTT_Adafruit.io/WiFi_MQTT_Adafruit.io.ino @@ -80,6 +80,7 @@ void setup() { // Initlialize components. HumTemp = new HTS221Sensor (dev_i2c); + HumTemp->begin(); HumTemp->Enable(); } diff --git a/examples/NonReg/BufferedEEPROM/BufferedEEPROM.ino b/examples/NonReg/BufferedEEPROM/BufferedEEPROM.ino index 83e91d9..63c3d97 100644 --- a/examples/NonReg/BufferedEEPROM/BufferedEEPROM.ino +++ b/examples/NonReg/BufferedEEPROM/BufferedEEPROM.ino @@ -1,48 +1,58 @@ -#include "Arduino.h" -#include +#include +#if defined(DATA_EEPROM_BASE) +#warning "STM32 devices have an integrated EEPROM. No buffered API available." + +void setup() { +} + +void loop() { +} + +#else /** - * Most STM32 devices don't have an integrated EEPROM. - * To emulate a EEPROM, the STM32 Arduino core emulated - * the operation of an EEPROM with the help of the embedded - * flash. - * - * Writing to a flash is very expensive operation, since a - * whole flash page needs to be written, even if you only - * want to access the flash byte-wise. - * - * The STM32 Arduino core provides a buffered access API - * to the emulated EEPROM. The library has allocated the - * buffer even if you don't use the buffered API, so - * it's strongly suggested to use the buffered API anyhow. - */ + Most STM32 devices don't have an integrated EEPROM. + To emulate a EEPROM, the STM32 Arduino core emulated + the operation of an EEPROM with the help of the embedded + flash. + + Writing to a flash is very expensive operation, since a + whole flash page needs to be written, even if you only + want to access the flash byte-wise. + + The STM32 Arduino core provides a buffered access API + to the emulated EEPROM. The library has allocated the + buffer even if you don't use the buffered API, so + it's strongly suggested to use the buffered API anyhow. +*/ #define DATA_LENGTH E2END void setup() { - Serial.begin(115200); + Serial.begin(115200); } void loop() { - // Fill the EEPROM buffer in memory with data - for (uint16_t i = 0; i < DATA_LENGTH; i++) { - eeprom_buffered_write_byte(i, i % 256); - } + // Fill the EEPROM buffer in memory with data + for (uint16_t i = 0; i < DATA_LENGTH; i++) { + eeprom_buffered_write_byte(i, i % 256); + } - // Copy the data from the buffer to the flash - eeprom_buffer_flush(); + // Copy the data from the buffer to the flash + eeprom_buffer_flush(); - // Clear the buffer for demonstration purpose - for (uint16_t i = 0; i < DATA_LENGTH; i++) { - eeprom_buffered_write_byte(i, 0); - } + // Clear the buffer for demonstration purpose + for (uint16_t i = 0; i < DATA_LENGTH; i++) { + eeprom_buffered_write_byte(i, 0); + } - // Print the 254th byte of the current buffer (should be 0) - Serial.println(eeprom_buffered_read_byte(254)); + // Print the 254th byte of the current buffer (should be 0) + Serial.println(eeprom_buffered_read_byte(254)); - // Copy the data from the flash to the buffer - eeprom_buffer_fill(); + // Copy the data from the flash to the buffer + eeprom_buffer_fill(); - // Print the 254th byte of the current buffer (should be 254) - Serial.println(eeprom_buffered_read_byte(254)); + // Print the 254th byte of the current buffer (should be 254) + Serial.println(eeprom_buffered_read_byte(254)); } +#endif diff --git a/examples/NonReg/CheckVariant/CheckVariant.ino b/examples/NonReg/CheckVariant/CheckVariant.ino new file mode 100644 index 0000000..7f494f1 --- /dev/null +++ b/examples/NonReg/CheckVariant/CheckVariant.ino @@ -0,0 +1,131 @@ +/* + This sketch check: + - digital and analog pins defined in the variant + - peripheral instances associated to wire (I2C), serial (UART) and SPI +*/ + +#include "utils.h" + +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01090000) +#error "This sketch is not compatible with core version prior to 2.0.0" +#endif + +#define PORTx(pn) (char)('A' + STM_PORT(pn)) +#define PINx(pn) STM_PIN(pn) + +#ifndef LED_BUILTIN +#define LED_BUILTIN PNUM_NOT_DEFINED +#endif + +/* + Initial check of Serial to be sure we can further print on serial + Returns true in case of test passed + Returns false in case of test failed +*/ +bool checkSerial(void) { + bool testPassed = true; +#if defined(PinMap_UART_RX) && defined(PinMap_UART_TX) + USART_TypeDef *uart_rx = (USART_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SERIAL_RX), PinMap_UART_RX); + USART_TypeDef *uart_tx = (USART_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SERIAL_TX), PinMap_UART_TX); + if (uart_rx == NP) { + /* PIN_SERIAL_RX (%d) doesn't match a valid UART peripheral */ + testPassed = false; + } + if (uart_tx == NP) { + /* PIN_SERIAL_TX doesn't match a valid UART peripheral */ + testPassed = false; + } + if (uart_rx != uart_tx) { + /* PIN_SERIAL_RX (%d) doesn't match PIN_SERIAL_TX peripheral */ + testPassed = false; + } +#endif + return testPassed; +} + +/* + Prints Pin name + pname: Pin of type PinName (PY_n) + asPN: true display as a PinName, false as a pin number (PYn) + val: display value or not + ln: carriage return or not +*/ +void printPinName(PinName pname, bool asPN, bool val, bool ln) { + Serial.print("P"); + Serial.print(PORTx(pname)); + if (asPN) { + Serial.print("_"); + } + Serial.print(PINx(pname)); + if (val) { + Serial.print(" ("); + Serial.print(asPN ? (uint32_t)pname : pinNametoDigitalPin(pname)); + Serial.print(")"); + } + if (ln) { + Serial.println(); + } +} + +void setup() { + /* Check first whether Serial is valid and we can further print on Serial */ + if (!checkSerial()) { + uint32_t blinkDelay = 200; + while (1) { + /* blink led quickly and forever in case of error */ + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on + delay(blinkDelay); + digitalWrite(LED_BUILTIN, LOW); // turn the LED off + delay(blinkDelay); + } + } + + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + + bool testPassed = true; + String testStatus; + uint32_t blinkDelay; + + Serial.println("#####"); + Serial.printf("NUM_DIGITAL_PINS = %i\n", NUM_DIGITAL_PINS); + Serial.printf("NUM_ANALOG_INPUTS = %i\n", NUM_ANALOG_INPUTS); + + /* Run the different tests */ + if (!checkDigitalPins()) { + testPassed = false; + } + if (!checkAnalogPins()) { + testPassed = false; + } + if (!checkIPInstance()) { + testPassed = false; + } + + /* Display test result */ + if (testPassed) { + testStatus = "PASSED"; + blinkDelay = 1000; + } else { + testStatus = "FAILED"; + blinkDelay = 200; + } + Serial.println(""); + Serial.println("########################################"); + Serial.printf("#### Test %s\n", testStatus.c_str()); + Serial.println("########################################"); + + /* Blink Led forever, slowly for test passed, and quickly for test failed */ + while (1) { + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) + delay(blinkDelay); + digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW + delay(blinkDelay); + } +} diff --git a/examples/NonReg/CheckVariant/analogPinsTest.ino b/examples/NonReg/CheckVariant/analogPinsTest.ino new file mode 100644 index 0000000..efc1041 --- /dev/null +++ b/examples/NonReg/CheckVariant/analogPinsTest.ino @@ -0,0 +1,49 @@ +/* + Check Analog pins + Return true in case of test passed + Return false in case of test failed +*/ +bool checkAnalogPins(void) { + bool testPassed = true; + + Serial.println("#####"); + Serial.println("Checking analog pins definition..."); + + for ( uint32_t i = 0; i < (NUM_ANALOG_INPUTS); i++) { + uint8_t res = 0; + // i is the index in the analogInputPin array + uint32_t pinnum_array = analogInputPin[i]; + uint32_t pinnum_aTD_i = analogInputToDigitalPin(i); + uint32_t pinnum_aTD_Ax = analogInputToDigitalPin(A0 + i); + + PinName pn_dTpn_Ax = digitalPinToPinName(A0 + i); + PinName pn_aTpn_Ax = analogInputToPinName(A0 + i); + + + if ((pinnum_array != pinnum_aTD_i) || (pinnum_array != pinnum_aTD_Ax) || (pinnum_aTD_i == NC)) { + res = 1; + } + if (!digitalpinIsAnalogInput(pinnum_array) || !digitalpinIsAnalogInput(pinnum_aTD_i) || !digitalpinIsAnalogInput(pinnum_aTD_Ax)) { + res |= 2; + } + if ((pn_dTpn_Ax != pn_aTpn_Ax) || (pinnum_aTD_i == NC)) { + res |= 4; + } + if (digitalPinToAnalogInput(pinnum_aTD_i) != i) { + + res |= 8; + } + + if (res) { + Serial.printf("A%i defined as %i with pin name: ", i, A0 + i); + printPinName(pn_aTpn_Ax, true, true, false); + Serial.print(" and pin number: "); + printPinName(pn_aTpn_Ax, false, true, false); + Serial.printf(" --> %i\n", res); + Serial.printf(" --> digitalPinToAnalogInput(%i) = %i\n", pinnum_aTD_i, digitalPinToAnalogInput(pinnum_aTD_i)); + testPassed = false; + } + } + Serial.println("End check analog pins"); + return testPassed; +} diff --git a/examples/NonReg/CheckVariant/checkIPInstanceTest.ino b/examples/NonReg/CheckVariant/checkIPInstanceTest.ino new file mode 100644 index 0000000..d2ede8d --- /dev/null +++ b/examples/NonReg/CheckVariant/checkIPInstanceTest.ino @@ -0,0 +1,190 @@ +/* + Checks Wire instances (I2C) + Returns true in case of test passed + Returns false in case of test failed +*/ +bool checkI2CInstance(void) { + bool testPassed = true; + +#if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL) + I2C_TypeDef *i2c_sda = (I2C_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_WIRE_SDA), PinMap_I2C_SDA); + I2C_TypeDef *i2c_scl = (I2C_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_WIRE_SCL), PinMap_I2C_SCL); + if (i2c_sda == NP) { + Serial.printf("PIN_WIRE_SDA (%d) doesn't match a valid I2C peripheral\n", PIN_WIRE_SDA); + testPassed = false; + } + if (i2c_scl == NP) { + Serial.printf("PIN_WIRE_SCL (%d) doesn't match a valid I2C peripheral\n", PIN_WIRE_SCL); + testPassed = false; + } + if (i2c_sda != i2c_scl) { + Serial.printf("PIN_WIRE_SCL (%d) doesn't match PIN_WIRE_SDA (%d) peripheral\n", PIN_WIRE_SCL, PIN_WIRE_SDA); + testPassed = false; + } +#endif + return testPassed; +} + +#if defined(SERIAL_UART_INSTANCE) +/* + Returns USART_TypeDef corresponding to SERIAL_UART_INSTANCE +*/ +USART_TypeDef* getSerialInstance(void) { +#if SERIAL_UART_INSTANCE == 0 || SERIAL_UART_INSTANCE == 101 + return LPUART1; +#elif SERIAL_UART_INSTANCE == 1 + return USART1; +#elif SERIAL_UART_INSTANCE == 2 + return USART2; +#elif SERIAL_UART_INSTANCE == 3 + return USART3; +#elif SERIAL_UART_INSTANCE == 4 +#if defined(UART4_BASE) + return UART4; +#else + return USART4; +#endif +#elif SERIAL_UART_INSTANCE == 5 +#if defined(UART5_BASE) + return UART5; +#else + return USART5; +#endif +#elif SERIAL_UART_INSTANCE == 6 + return USART6; +#elif SERIAL_UART_INSTANCE == 7 +#if defined(UART7_BASE) + return UART7; +#else + return USART7; +#endif +#elif SERIAL_UART_INSTANCE == 8 +#if defined(UART8_BASE) + return UART8; +#else + return USART8; +#endif +#elif SERIAL_UART_INSTANCE == 9 + return USART9; +#elif SERIAL_UART_INSTANCE == 10 +#if defined(UART10_BASE) + return UART10; +#else + return USART10; +#endif +#else + return NULL; +#endif +} +#endif /* SERIAL_UART_INSTANCE */ + +/* + Checks Serial instances (UART) + Returns true in case of test passed + Returns false in case of test failed +*/ +bool checkSerialInstance(void) { + bool testPassed = true; + +#if defined(PIN_SERIAL_RX) && defined(PIN_SERIAL_TX) + USART_TypeDef *uart_rx = (USART_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SERIAL_RX), PinMap_UART_RX); + USART_TypeDef *uart_tx = (USART_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SERIAL_TX), PinMap_UART_TX); + if (uart_rx == NP) { + Serial.printf("PIN_SERIAL_RX (%d) doesn't match a valid UART peripheral\n", PIN_SERIAL_RX); + testPassed = false; + } + if (uart_tx == NP) { + Serial.printf("PIN_SERIAL_TX (%d) doesn't match a valid UART peripheral\n", PIN_SERIAL_TX); + testPassed = false; + } + if (uart_rx != uart_tx) { + Serial.printf("PIN_SERIAL_RX (%d) doesn't match PIN_SERIAL_TX (%d) peripheral\n", PIN_SERIAL_RX, PIN_SERIAL_TX); + testPassed = false; + } + +#if defined(SERIAL_UART_INSTANCE) + USART_TypeDef* usart = getSerialInstance(); + if (usart != uart_tx) { + Serial.printf("SERIAL_UART_INSTANCE (%d) doesn't match PIN_SERIAL_TX (%d) peripheral\n", SERIAL_UART_INSTANCE, PIN_SERIAL_TX); + testPassed = false; + } +#endif + +#endif /* PIN_SERIAL_RX && PIN_SERIAL_TX */ + + return testPassed; +} + +/* + Checks SPI instances + Returns true in case of test passed + Returns false in case of test failed +*/ +bool checkSPIInstance(void) { + bool testPassed = true; + +#if defined(PIN_SPI_MOSI) && defined(PIN_SPI_MISO) + SPI_TypeDef *spi_mosi = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SPI_MOSI), PinMap_SPI_MOSI); + SPI_TypeDef *spi_miso = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SPI_MISO), PinMap_SPI_MISO); + if (spi_mosi == NP) { + Serial.printf("PIN_SPI_MOSI (%d) doesn't match a valid SPI peripheral\n", PIN_SPI_MOSI); + testPassed = false; + } + if (spi_miso == NP) { + Serial.printf("PIN_SPI_MISO (%d) doesn't match a valid SPI peripheral\n", PIN_SPI_MISO); + testPassed = false; + } + if (spi_mosi != spi_miso) { + Serial.printf("PIN_SPI_MOSI (%d) doesn't match PIN_SPI_MISO (%d) peripheral\n", PIN_SPI_MOSI, PIN_SPI_MISO); + testPassed = false; + } + +#if defined(PIN_SPI_SCK) + SPI_TypeDef *spi_sck = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(PIN_SPI_SCK), PinMap_SPI_SCLK); + if (spi_sck == NP) { + Serial.printf("PIN_SPI_SCK (%d) doesn't match a valid SPI peripheral\n", PIN_SPI_SCK); + testPassed = false; + } + if (spi_sck != spi_mosi) { + Serial.printf("PIN_SPI_SCK (%d) doesn't match PIN_SPI_MISO (%d) peripheral\n", PIN_SPI_SCK, PIN_SPI_MISO); + testPassed = false; + } +#endif + +#endif /* PIN_SPI_MOSI && PIN_SPI_MISO */ + +#if defined(PIN_SPI_SS) + /* PIN_SPI_SS may be used as software chip select (and not hardware) any pin is valid + thus not possible to check this pin agianst PinMap_SPI_SSEL */ + if (!digitalPinIsValid(PIN_SPI_SS)) { + Serial.printf("PIN_SPI_SS (%d) doesn't match PIN_SPI_MISO (%d) peripheral\n", PIN_SPI_SS, PIN_SPI_MISO); + testPassed = false; + } +#endif + + return testPassed; +} + +/* + Check IP instances (I2C, UART, SPI) + Return true in case of test passed + Return false in case of test failed +*/ +bool checkIPInstance(void) { + bool testPassed = true; + + Serial.println("#####"); + Serial.println("Checking IP instances (I2C, UART, SPI)..."); + + if (!checkI2CInstance()) { + testPassed = false; + } + if (!checkSerialInstance()) { + testPassed = false; + } + if (!checkSPIInstance()) { + testPassed = false; + } + Serial.println("End check IP instances (I2C, UART, SPI)"); + return testPassed; +} diff --git a/examples/NonReg/CheckVariant/digitalPinsTest.ino b/examples/NonReg/CheckVariant/digitalPinsTest.ino new file mode 100644 index 0000000..5f5487e --- /dev/null +++ b/examples/NonReg/CheckVariant/digitalPinsTest.ino @@ -0,0 +1,592 @@ + +#define PNUM(Port, Pin) P ## Port ## Pin +#define PNAME(Port, Pin) P ## Port ## _ ## Pin +#define DECLTESTPNUM(Port, Pin) checkPinNumber(XSTR(PNAME(Port, Pin)), PNAME(Port, Pin), "P"#Port#Pin, PNUM(Port, Pin)) + +/* + Check Pin number + Return true in case of test passed + Return false in case of test failed +*/ +bool checkPinNumber(const char* spname, PinName pname, const char* spnum, uint32_t pnum) { + PinName pnamex = digitalPinToPinName(pnum); + if (pnamex != pname) { + Serial.print("Pin number: "); + Serial.printf("%s(%i) indexes PinName:", spnum); + if (pnamex == NC) { + Serial.print("NC"); + } else { + printPinName(pnamex, true, true, false); + } + Serial.print(" --> "); + uint32_t pnumx = pinNametoDigitalPin(pname); + if (pnumx != NUM_DIGITAL_PINS) { + Serial.printf("%s should be %i\n", spnum, pnumx); + } else { + Serial.printf("%s is not in digitalPin[], so %i should not be defined.\n", spname, spnum); + } + return false; + } + return true; +} + +/* + Check Digital pins + Return true in case of test passed + Return false in case of test failed +*/ +bool checkDigitalPins(void) { + bool testPassed = true; + Serial.println("#####"); + Serial.println("Checking digital pins..."); + // Serial.println("\tPin number definition..."); +#ifdef PA0 + if (!DECLTESTPNUM(A, 0)) testPassed = false; +#endif +#ifdef PA1 + if (!DECLTESTPNUM(A, 1)) testPassed = false; +#endif +#ifdef PA2 + if (!DECLTESTPNUM(A, 2)) testPassed = false; +#endif +#ifdef PA3 + if (!DECLTESTPNUM(A, 3)) testPassed = false; +#endif +#ifdef PA4 + if (!DECLTESTPNUM(A, 4)) testPassed = false; +#endif +#ifdef PA5 + if (!DECLTESTPNUM(A, 5)) testPassed = false; +#endif +#ifdef PA6 + if (!DECLTESTPNUM(A, 6)) testPassed = false; +#endif +#ifdef PA7 + if (!DECLTESTPNUM(A, 7)) testPassed = false; +#endif +#ifdef PA8 + if (!DECLTESTPNUM(A, 8)) testPassed = false; +#endif +#ifdef PA9 + if (!DECLTESTPNUM(A, 9)) testPassed = false; +#endif +#ifdef PA10 + if (!DECLTESTPNUM(A, 10)) testPassed = false; +#endif +#ifdef PA11 + if (!DECLTESTPNUM(A, 11)) testPassed = false; +#endif +#ifdef PA12 + if (!DECLTESTPNUM(A, 12)) testPassed = false; +#endif +#ifdef PA13 + if (!DECLTESTPNUM(A, 13)) testPassed = false; +#endif +#ifdef PA14 + if (!DECLTESTPNUM(A, 14)) testPassed = false; +#endif +#ifdef PA15 + if (!DECLTESTPNUM(A, 15)) testPassed = false; +#endif +#ifdef PB0 + if (!DECLTESTPNUM(B, 0)) testPassed = false; +#endif +#ifdef PB1 + if (!DECLTESTPNUM(B, 1)) testPassed = false; +#endif +#ifdef PB2 + if (!DECLTESTPNUM(B, 2)) testPassed = false; +#endif +#ifdef PB3 + if (!DECLTESTPNUM(B, 3)) testPassed = false; +#endif +#ifdef PB4 + if (!DECLTESTPNUM(B, 4)) testPassed = false; +#endif +#ifdef PB5 + if (!DECLTESTPNUM(B, 5)) testPassed = false; +#endif +#ifdef PB6 + if (!DECLTESTPNUM(B, 6)) testPassed = false; +#endif +#ifdef PB7 + if (!DECLTESTPNUM(B, 7)) testPassed = false; +#endif +#ifdef PB8 + if (!DECLTESTPNUM(B, 8)) testPassed = false; +#endif +#ifdef PB9 + if (!DECLTESTPNUM(B, 9)) testPassed = false; +#endif +#ifdef PB10 + if (!DECLTESTPNUM(B, 10)) testPassed = false; +#endif +#ifdef PB11 + if (!DECLTESTPNUM(B, 11)) testPassed = false; +#endif +#ifdef PB12 + if (!DECLTESTPNUM(B, 12)) testPassed = false; +#endif +#ifdef PB13 + if (!DECLTESTPNUM(B, 13)) testPassed = false; +#endif +#ifdef PB14 + if (!DECLTESTPNUM(B, 14)) testPassed = false; +#endif +#ifdef PB15 + if (!DECLTESTPNUM(B, 15)) testPassed = false; +#endif +#if defined GPIOC_BASE +#ifdef PC0 + if (!DECLTESTPNUM(C, 0)) testPassed = false; +#endif +#ifdef PC1 + if (!DECLTESTPNUM(C, 1)) testPassed = false; +#endif +#ifdef PC2 + if (!DECLTESTPNUM(C, 2)) testPassed = false; +#endif +#ifdef PC3 + if (!DECLTESTPNUM(C, 3)) testPassed = false; +#endif +#ifdef PC4 + if (!DECLTESTPNUM(C, 4)) testPassed = false; +#endif +#ifdef PC5 + if (!DECLTESTPNUM(C, 5)) testPassed = false; +#endif +#ifdef PC6 + if (!DECLTESTPNUM(C, 6)) testPassed = false; +#endif +#ifdef PC7 + if (!DECLTESTPNUM(C, 7)) testPassed = false; +#endif +#ifdef PC8 + if (!DECLTESTPNUM(C, 8)) testPassed = false; +#endif +#ifdef PC9 + if (!DECLTESTPNUM(C, 9)) testPassed = false; +#endif +#ifdef PC10 + if (!DECLTESTPNUM(C, 10)) testPassed = false; +#endif +#ifdef PC11 + if (!DECLTESTPNUM(C, 11)) testPassed = false; +#endif +#ifdef PC12 + if (!DECLTESTPNUM(C, 12)) testPassed = false; +#endif +#ifdef PC13 + if (!DECLTESTPNUM(C, 13)) testPassed = false; +#endif +#ifdef PC14 + if (!DECLTESTPNUM(C, 14)) testPassed = false; +#endif +#ifdef PC15 + if (!DECLTESTPNUM(C, 15)) testPassed = false; +#endif +#endif +#if defined GPIOD_BASE +#ifdef PD0 + if (!DECLTESTPNUM(D, 0)) testPassed = false; +#endif +#ifdef PD1 + if (!DECLTESTPNUM(D, 1)) testPassed = false; +#endif +#ifdef PD2 + if (!DECLTESTPNUM(D, 2)) testPassed = false; +#endif +#ifdef PD3 + if (!DECLTESTPNUM(D, 3)) testPassed = false; +#endif +#ifdef PD4 + if (!DECLTESTPNUM(D, 4)) testPassed = false; +#endif +#ifdef PD5 + if (!DECLTESTPNUM(D, 5)) testPassed = false; +#endif +#ifdef PD6 + if (!DECLTESTPNUM(D, 6)) testPassed = false; +#endif +#ifdef PD7 + if (!DECLTESTPNUM(D, 7)) testPassed = false; +#endif +#ifdef PD8 + if (!DECLTESTPNUM(D, 8)) testPassed = false; +#endif +#ifdef PD9 + if (!DECLTESTPNUM(D, 9)) testPassed = false; +#endif +#ifdef PD10 + if (!DECLTESTPNUM(D, 10)) testPassed = false; +#endif +#ifdef PD11 + if (!DECLTESTPNUM(D, 11)) testPassed = false; +#endif +#ifdef PD12 + if (!DECLTESTPNUM(D, 12)) testPassed = false; +#endif +#ifdef PD13 + if (!DECLTESTPNUM(D, 13)) testPassed = false; +#endif +#ifdef PD14 + if (!DECLTESTPNUM(D, 14)) testPassed = false; +#endif +#ifdef PD15 + if (!DECLTESTPNUM(D, 15)) testPassed = false; +#endif +#endif +#if defined GPIOE_BASE +#ifdef PE0 + if (!DECLTESTPNUM(E, 0)) testPassed = false; +#endif +#ifdef PE1 + if (!DECLTESTPNUM(E, 1)) testPassed = false; +#endif +#ifdef PE2 + if (!DECLTESTPNUM(E, 2)) testPassed = false; +#endif +#ifdef PE3 + if (!DECLTESTPNUM(E, 3)) testPassed = false; +#endif +#ifdef PE4 + if (!DECLTESTPNUM(E, 4)) testPassed = false; +#endif +#ifdef PE5 + if (!DECLTESTPNUM(E, 5)) testPassed = false; +#endif +#ifdef PE6 + if (!DECLTESTPNUM(E, 6)) testPassed = false; +#endif +#ifdef PE7 + if (!DECLTESTPNUM(E, 7)) testPassed = false; +#endif +#ifdef PE8 + if (!DECLTESTPNUM(E, 8)) testPassed = false; +#endif +#ifdef PE9 + if (!DECLTESTPNUM(E, 9)) testPassed = false; +#endif +#ifdef PE10 + if (!DECLTESTPNUM(E, 10)) testPassed = false; +#endif +#ifdef PE11 + if (!DECLTESTPNUM(E, 11)) testPassed = false; +#endif +#ifdef PE12 + if (!DECLTESTPNUM(E, 12)) testPassed = false; +#endif +#ifdef PE13 + if (!DECLTESTPNUM(E, 13)) testPassed = false; +#endif +#ifdef PE14 + if (!DECLTESTPNUM(E, 14)) testPassed = false; +#endif +#ifdef PE15 + if (!DECLTESTPNUM(E, 15)) testPassed = false; +#endif +#endif +#if defined GPIOF_BASE +#ifdef PF0 + if (!DECLTESTPNUM(F, 0)) testPassed = false; +#endif +#ifdef PF1 + if (!DECLTESTPNUM(F, 1)) testPassed = false; +#endif +#ifdef PF2 + if (!DECLTESTPNUM(F, 2)) testPassed = false; +#endif +#ifdef PF3 + if (!DECLTESTPNUM(F, 3)) testPassed = false; +#endif +#ifdef PF4 + if (!DECLTESTPNUM(F, 4)) testPassed = false; +#endif +#ifdef PF5 + if (!DECLTESTPNUM(F, 5)) testPassed = false; +#endif +#ifdef PF6 + if (!DECLTESTPNUM(F, 6)) testPassed = false; +#endif +#ifdef PF7 + if (!DECLTESTPNUM(F, 7)) testPassed = false; +#endif +#ifdef PF8 + if (!DECLTESTPNUM(F, 8)) testPassed = false; +#endif +#ifdef PF9 + if (!DECLTESTPNUM(F, 9)) testPassed = false; +#endif +#ifdef PF10 + if (!DECLTESTPNUM(F, 10)) testPassed = false; +#endif +#ifdef PF11 + if (!DECLTESTPNUM(F, 11)) testPassed = false; +#endif +#ifdef PF12 + if (!DECLTESTPNUM(F, 12)) testPassed = false; +#endif +#ifdef PF13 + if (!DECLTESTPNUM(F, 13)) testPassed = false; +#endif +#ifdef PF14 + if (!DECLTESTPNUM(F, 14)) testPassed = false; +#endif +#ifdef PF15 + if (!DECLTESTPNUM(F, 15)) testPassed = false; +#endif +#endif +#if defined GPIOG_BASE +#ifdef PG0 + if (!DECLTESTPNUM(G, 0)) testPassed = false; +#endif +#ifdef PG1 + if (!DECLTESTPNUM(G, 1)) testPassed = false; +#endif +#ifdef PG2 + if (!DECLTESTPNUM(G, 2)) testPassed = false; +#endif +#ifdef PG3 + if (!DECLTESTPNUM(G, 3)) testPassed = false; +#endif +#ifdef PG4 + if (!DECLTESTPNUM(G, 4)) testPassed = false; +#endif +#ifdef PG5 + if (!DECLTESTPNUM(G, 5)) testPassed = false; +#endif +#ifdef PG6 + if (!DECLTESTPNUM(G, 6)) testPassed = false; +#endif +#ifdef PG7 + if (!DECLTESTPNUM(G, 7)) testPassed = false; +#endif +#ifdef PG8 + if (!DECLTESTPNUM(G, 8)) testPassed = false; +#endif +#ifdef PG9 + if (!DECLTESTPNUM(G, 9)) testPassed = false; +#endif +#ifdef PG10 + if (!DECLTESTPNUM(G, 10)) testPassed = false; +#endif +#ifdef PG11 + if (!DECLTESTPNUM(G, 11)) testPassed = false; +#endif +#ifdef PG12 + if (!DECLTESTPNUM(G, 12)) testPassed = false; +#endif +#ifdef PG13 + if (!DECLTESTPNUM(G, 13)) testPassed = false; +#endif +#ifdef PG14 + if (!DECLTESTPNUM(G, 14)) testPassed = false; +#endif +#ifdef PG15 + if (!DECLTESTPNUM(G, 15)) testPassed = false; +#endif +#endif +#if defined GPIO_HBASE +#ifdef PH0 + if (!DECLTESTPNUM(H, 0)) testPassed = false; +#endif +#ifdef PH1 + if (!DECLTESTPNUM(H, 1)) testPassed = false; +#endif +#ifdef PH2 + if (!DECLTESTPNUM(H, 2)) testPassed = false; +#endif +#ifdef PH3 + if (!DECLTESTPNUM(H, 3)) testPassed = false; +#endif +#ifdef PH4 + if (!DECLTESTPNUM(H, 4)) testPassed = false; +#endif +#ifdef PH5 + if (!DECLTESTPNUM(H, 5)) testPassed = false; +#endif +#ifdef PH6 + if (!DECLTESTPNUM(H, 6)) testPassed = false; +#endif +#ifdef PH7 + if (!DECLTESTPNUM(H, 7)) testPassed = false; +#endif +#ifdef PH8 + if (!DECLTESTPNUM(H, 8)) testPassed = false; +#endif +#ifdef PH9 + if (!DECLTESTPNUM(H, 9)) testPassed = false; +#endif +#ifdef PH10 + if (!DECLTESTPNUM(H, 10)) testPassed = false; +#endif +#ifdef PH11 + if (!DECLTESTPNUM(H, 11)) testPassed = false; +#endif +#ifdef PH12 + if (!DECLTESTPNUM(H, 12)) testPassed = false; +#endif +#ifdef PH13 + if (!DECLTESTPNUM(H, 13)) testPassed = false; +#endif +#ifdef PH14 + if (!DECLTESTPNUM(H, 14)) testPassed = false; +#endif +#ifdef PH15 + if (!DECLTESTPNUM(H, 15)) testPassed = false; +#endif +#endif +#if defined GPIOI_BASE +#ifdef PI0 + if (!DECLTESTPNUM(I, 0)) testPassed = false; +#endif +#ifdef PI1 + if (!DECLTESTPNUM(I, 1)) testPassed = false; +#endif +#ifdef PI2 + if (!DECLTESTPNUM(I, 2)) testPassed = false; +#endif +#ifdef PI3 + if (!DECLTESTPNUM(I, 3)) testPassed = false; +#endif +#ifdef PI4 + if (!DECLTESTPNUM(I, 4)) testPassed = false; +#endif +#ifdef PI5 + if (!DECLTESTPNUM(I, 5)) testPassed = false; +#endif +#ifdef PI6 + if (!DECLTESTPNUM(I, 6)) testPassed = false; +#endif +#ifdef PI7 + if (!DECLTESTPNUM(I, 7)) testPassed = false; +#endif +#ifdef PI8 + if (!DECLTESTPNUM(I, 8)) testPassed = false; +#endif +#ifdef PI9 + if (!DECLTESTPNUM(I, 9)) testPassed = false; +#endif +#ifdef PI10 + if (!DECLTESTPNUM(I, 10)) testPassed = false; +#endif +#ifdef PI11 + if (!DECLTESTPNUM(I, 11)) testPassed = false; +#endif +#ifdef PI12 + if (!DECLTESTPNUM(I, 12)) testPassed = false; +#endif +#ifdef PI13 + if (!DECLTESTPNUM(I, 13)) testPassed = false; +#endif +#ifdef PI14 + if (!DECLTESTPNUM(I, 14)) testPassed = false; +#endif +#ifdef PI15 + if (!DECLTESTPNUM(I, 15)) testPassed = false; +#endif +#endif +#if defined GPIOJ_BASE +#ifdef PJ0 + if (!DECLTESTPNUM(J, 0)) testPassed = false; +#endif +#ifdef PJ1 + if (!DECLTESTPNUM(J, 1)) testPassed = false; +#endif +#ifdef PJ2 + if (!DECLTESTPNUM(J, 2)) testPassed = false; +#endif +#ifdef PJ3 + if (!DECLTESTPNUM(J, 3)) testPassed = false; +#endif +#ifdef PJ4 + if (!DECLTESTPNUM(J, 4)) testPassed = false; +#endif +#ifdef PJ5 + if (!DECLTESTPNUM(J, 5)) testPassed = false; +#endif +#ifdef PJ6 + if (!DECLTESTPNUM(J, 6)) testPassed = false; +#endif +#ifdef PJ7 + if (!DECLTESTPNUM(J, 7)) testPassed = false; +#endif +#ifdef PJ8 + if (!DECLTESTPNUM(J, 8)) testPassed = false; +#endif +#ifdef PJ9 + if (!DECLTESTPNUM(J, 9)) testPassed = false; +#endif +#ifdef PJ10 + if (!DECLTESTPNUM(J, 10)) testPassed = false; +#endif +#ifdef PJ11 + if (!DECLTESTPNUM(J, 11)) testPassed = false; +#endif +#ifdef PJ12 + if (!DECLTESTPNUM(J, 12)) testPassed = false; +#endif +#ifdef PJ13 + if (!DECLTESTPNUM(J, 13)) testPassed = false; +#endif +#ifdef PJ14 + if (!DECLTESTPNUM(J, 14)) testPassed = false; +#endif +#ifdef PJ15 + if (!DECLTESTPNUM(J, 15)) testPassed = false; +#endif +#endif +#if defined GPIOK_BASE +#ifdef PK0 + if (!DECLTESTPNUM(K, 0)) testPassed = false; +#endif +#ifdef PK1 + if (!DECLTESTPNUM(K, 1)) testPassed = false; +#endif +#ifdef PK2 + if (!DECLTESTPNUM(K, 2)) testPassed = false; +#endif +#ifdef PK3 + if (!DECLTESTPNUM(K, 3)) testPassed = false; +#endif +#ifdef PK4 + if (!DECLTESTPNUM(K, 4)) testPassed = false; +#endif +#ifdef PK5 + if (!DECLTESTPNUM(K, 5)) testPassed = false; +#endif +#ifdef PK6 + if (!DECLTESTPNUM(K, 6)) testPassed = false; +#endif +#ifdef PK7 + if (!DECLTESTPNUM(K, 7)) testPassed = false; +#endif +#ifdef PK8 + if (!DECLTESTPNUM(K, 8)) testPassed = false; +#endif +#ifdef PK9 + if (!DECLTESTPNUM(K, 9)) testPassed = false; +#endif +#ifdef PK10 + if (!DECLTESTPNUM(K, 10)) testPassed = false; +#endif +#ifdef PK11 + if (!DECLTESTPNUM(K, 11)) testPassed = false; +#endif +#ifdef PK12 + if (!DECLTESTPNUM(K, 12)) testPassed = false; +#endif +#ifdef PK13 + if (!DECLTESTPNUM(K, 13)) testPassed = false; +#endif +#ifdef PK14 + if (!DECLTESTPNUM(K, 14)) testPassed = false; +#endif +#ifdef PK15 + if (!DECLTESTPNUM(K, 15)) testPassed = false; +#endif +#endif + + Serial.println("End check digital pins"); + return testPassed; +} diff --git a/examples/NonReg/HardwareTimer/HardwareTimer_OutputInput_test/HardwareTimer_OutputInput_test.ino b/examples/NonReg/HardwareTimer/HardwareTimer_OutputInput_test/HardwareTimer_OutputInput_test.ino index 3ee3d0d..1dc20d3 100644 --- a/examples/NonReg/HardwareTimer/HardwareTimer_OutputInput_test/HardwareTimer_OutputInput_test.ino +++ b/examples/NonReg/HardwareTimer/HardwareTimer_OutputInput_test/HardwareTimer_OutputInput_test.ino @@ -8,9 +8,9 @@ Designed to work on Nucleo_L476RG TIM1 ch1N and ch2 are used for output generation (TIM1_CH1N_PIN, and TIM1_CH2_PIN). It is important that both channel are on the same timer, in order to check influence on channel dependant API. - Management of interruption is done with variable incrementation. - TIM8 ch1/ch2 are used to measure frequence and duty cycle of TIM1_CH1N output generated signal - TIM8 ch3/ch4 are used to measure frequence and duty cycle of TIM1_CH2 output generated signal + Management of interruption is done with variable increment. + TIM8 ch1/ch2 are used to measure frequency and duty cycle of TIM1_CH1N output generated signal + TIM8 ch3/ch4 are used to measure frequency and duty cycle of TIM1_CH2 output generated signal Regular channel and complementary channel (TIM1_CH1N) are tested. @@ -32,6 +32,11 @@ /*************************************** ** Defines ***************************************/ +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01090000) +#error "Due to API change, this sketch is compatible with STM32_CORE_VERSION >= 0x01090000" +#endif + + #if !defined(ARDUINO_NUCLEO_L476RG) #error "Sketch is applicable to NUCLEO_L476RG" #endif @@ -44,11 +49,11 @@ #define Output2_channel 2 // TIM input -#define TIM8_CH1_PIN PC6 // CN10 pin 4 Use also channel2 for freq/duty measurement +#define TIM8_CH1_PIN PC_6_ALT1 // CN10 pin 4 Use also channel2 for freq/duty measurement #define Freq1_channelRising 1 #define Freq1_channelFalling 2 -#define TIM8_CH3_PIN PC8 // CN10 pin 2 Use also channel4 for freq/duty measurement +#define TIM8_CH3_PIN PC_8_ALT1 // CN10 pin 2 Use also channel4 for freq/duty measurement #define Freq2_channelRising 3 #define Freq2_channelFalling 4 @@ -56,7 +61,7 @@ #define OUTPUT_DUTY1 20 // percentage #define OUTPUT_DUTY2 30 // percentage -#define TEMPO_BEFORE_MEASUREMENT 500 // milisecondes +#define TEMPO_BEFORE_MEASUREMENT 500 // millisecondes #define TOLERANCE 10 // Percentage #define EXPECTED_INTERRUPT_COUNT ((TEMPO_BEFORE_MEASUREMENT * OUTPUT_FREQUENCY) / 1000) @@ -102,23 +107,23 @@ uint32_t test_Status = PASSED; ** Interrupt callback ***************************************/ /******** Output *****/ -void output_Update_IT_callback(HardwareTimer *) +void output_Update_IT_callback(void) { Output_Update++; } -void Output_Compare1_IT_callback(HardwareTimer *) +void Output_Compare1_IT_callback(void) { Output_Compare1++; } -void Output_Compare2_IT_callback(HardwareTimer *) +void Output_Compare2_IT_callback(void) { Output_Compare2++; } /******** Input 1 *****/ -void Input_Capture1_Rising_IT_callback(HardwareTimer *) +void Input_Capture1_Rising_IT_callback(void) { Current1_Capture = MyTim_input->getCaptureCompare(Freq1_channelRising); /* frequency computation */ @@ -138,7 +143,7 @@ void Input_Capture1_Rising_IT_callback(HardwareTimer *) rolloverCompare1Count = 0; } -void Input_Capture1_Falling_IT_callback(HardwareTimer *) +void Input_Capture1_Falling_IT_callback(void) { /* prepare DutyCycle computation */ Current1_Capture = MyTim_input->getCaptureCompare(Freq1_channelFalling); @@ -155,7 +160,7 @@ void Input_Capture1_Falling_IT_callback(HardwareTimer *) } /******** Input 2 *****/ -void Input_Capture2_Rising_IT_callback(HardwareTimer *) +void Input_Capture2_Rising_IT_callback(void) { Current2_Capture = MyTim_input->getCaptureCompare(Freq2_channelRising); /* frequency computation */ @@ -175,7 +180,7 @@ void Input_Capture2_Rising_IT_callback(HardwareTimer *) rolloverCompare2Count = 0; } -void Input_Capture2_Falling_IT_callback(HardwareTimer *) +void Input_Capture2_Falling_IT_callback(void) { /* prepare DutyCycle computation */ Current2_Capture = MyTim_input->getCaptureCompare(Freq2_channelFalling); @@ -194,7 +199,7 @@ void Input_Capture2_Falling_IT_callback(HardwareTimer *) /******** Input rollover *****/ /* In case of timer rollover, frequency is to low to be measured set values to 0 To reduce minimum frequency, it is possible to increase prescaler. But this is at a cost of precision. */ -void Rollover_IT_callback(HardwareTimer *) +void Rollover_IT_callback(void) { rolloverCompare1Count++; rolloverCompare2Count++; @@ -375,7 +380,6 @@ void loop() /********* Output test ***/ test_step++; - MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE, NC); MyTim_output->setOverflow((1000000 / OUTPUT_FREQUENCY), MICROSEC_FORMAT); MyTim_output->attachInterrupt(output_Update_IT_callback); MyTim_output->resume(); @@ -392,6 +396,7 @@ void loop() Verify_output_interrupts(0, 0, 0); test_step++; + MyTim_output->pause(); MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE_PWM1, TIM1_CH1N_PIN); MyTim_output->setOverflow((1000000 / OUTPUT_FREQUENCY), MICROSEC_FORMAT); MyTim_output->setCaptureCompare(Output1_channel, OUTPUT_DUTY1, PERCENT_COMPARE_FORMAT); @@ -400,24 +405,28 @@ void loop() Verify_output(2, 0, 0); test_step++; + MyTim_output->pause(); MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE_TOGGLE, TIM1_CH1N_PIN); MyTim_output->resume(); Verify_output(1, OUTPUT_FREQUENCY / 2, 50); // in PWM2, output is the complementary of PW1 Verify_output(2, 0, 0); test_step++; + MyTim_output->pause(); MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE_PWM2, TIM1_CH1N_PIN); MyTim_output->resume(); Verify_output(1, OUTPUT_FREQUENCY, 100 - OUTPUT_DUTY1); // in PWM2, output is the complementary of PW1 Verify_output(2, 0, 0); test_step++; + MyTim_output->pause(); MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE_PWM1, TIM1_CH1N_PIN); MyTim_output->resume(); Verify_output(1, OUTPUT_FREQUENCY, OUTPUT_DUTY1); Verify_output(2, 0, 0); test_step++; + MyTim_output->pause(); MyTim_output->setMode(Output2_channel, TIMER_OUTPUT_COMPARE_PWM1, TIM1_CH2_PIN); MyTim_output->setCaptureCompare(Output2_channel, OUTPUT_DUTY2, PERCENT_COMPARE_FORMAT); MyTim_output->resumeChannel(Output2_channel); @@ -444,7 +453,7 @@ void loop() test_step++; MyTim_output->pauseChannel(Output1_channel); - MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_COMPARE); + MyTim_output->setMode(Output1_channel, TIMER_OUTPUT_DISABLED); MyTim_output->resumeChannel(Output1_channel); Verify_output(1, 0, 0); // in PWM2, output is the complementary of PW1 Verify_output(2, OUTPUT_FREQUENCY, OUTPUT_DUTY2); @@ -567,6 +576,7 @@ void loop() } test_step++; + MyTim_output->pause(); MyTim_output->setPWM(Output1_channel, TIM1_CH1N_PIN, OUTPUT_FREQUENCY, OUTPUT_DUTY1); Verify_output(1, OUTPUT_FREQUENCY, OUTPUT_DUTY1); test_step++; diff --git a/examples/NonReg/RTC/RTC_Tests/RTC_Config.ino b/examples/NonReg/RTC/RTC_Tests/RTC_Config.ino index be59a78..a41fa60 100644 --- a/examples/NonReg/RTC/RTC_Tests/RTC_Config.ino +++ b/examples/NonReg/RTC/RTC_Tests/RTC_Config.ino @@ -34,4 +34,5 @@ void rtc_setTime(const char* date, const char* time) { // you can use also //rtc.setTime(hours, minutes, seconds); //rtc.setDate(weekDay, day, month, year); -} + delay(100); +} \ No newline at end of file diff --git a/examples/NonReg/RTC/RTC_Tests/RTC_Tests.ino b/examples/NonReg/RTC/RTC_Tests/RTC_Tests.ino index 0e34267..d034413 100644 --- a/examples/NonReg/RTC/RTC_Tests/RTC_Tests.ino +++ b/examples/NonReg/RTC/RTC_Tests/RTC_Tests.ino @@ -18,27 +18,31 @@ STM32RTC& rtc = STM32RTC::getInstance(); /* Change these values to set the current initial time - * - * format: date: "Dec 31 2017" and time: "23:59:56" - * by default use built date and time - */ + + format: date: "Dec 31 2017" and time: "23:59:56" + by default use built date and time +*/ static const char* mydate = __DATE__; static const char* mytime = __TIME__; //static const char* mydate = "Dec 31 2017"; //static const char* mytime = "23:59:56"; /* Change these values to set user (a)synchronous prescalers - * value to test. - * - * Default 99/9999 are for RTCCLK = 1MHz - * Example for DISCO_F746NG with a HSE of 25MHz - * HSE divider will be 25 and RTCCLK will be 1MHz. (HSE/HSEdiv) - * - * To have a calendar clock of 1 Hz: - * clk = RTCCLK / ((predA +1) * (predS +1)) - * clk = 1000000 / ((99 +1) * (9999+1)) = 1 Hz - */ + value to test. + + Default 99/9999 are for RTCCLK = 1MHz + Example for DISCO_F746NG with a HSE of 25MHz + HSE divider will be 25 and RTCCLK will be 1MHz. (HSE/HSEdiv) + + To have a calendar clock of 1 Hz: + clk = RTCCLK / ((predA +1) * (predS +1)) + clk = 1000000 / ((99 +1) * (9999+1)) = 1 Hz +*/ +#if defined(STM32F1xx) +static uint32_t userPredA = 99; +#else static int8_t userPredA = 99; +#endif /* STM32F1xx */ static int16_t userPredS = 9999; /* */ @@ -64,7 +68,7 @@ static STM32RTC::Alarm_Match DHHMMSS_MATCH = STM32RTC::MATCH_DHHMMSS; void setup() { Serial.begin(115200); - while(!Serial) {} + while (!Serial) {} } void loop() @@ -88,7 +92,7 @@ void loop() Serial.println("Invalid input"); continue; } - switch(c) { + switch (c) { case '1': default: Serial.println("Test will use LSI_CLOCK"); @@ -106,36 +110,37 @@ void loop() break; } +#if defined(STM32F1xx) + Serial.println("Testing only asynchronous prescaler setting"); + uint32_t a; +#else Serial.println("Testing asynchronous and synchronous prescaler setting"); int8_t a; - int16_t s; +#endif /* STM32F1xx */ + int16_t s = 0; rtc.getPrediv(&a, &s); Serial.print("Async/Sync for default LSI clock: "); - Serial.print(a); Serial.print('/'); Serial.println(s); + Serial.printf("%i/%i\n", a, s); rtc_config(clkSource, rtc.HOUR_24, mydate, mytime); Serial.print("Async/Sync for selected clock: "); rtc.getPrediv(&a, &s); - Serial.print(a); Serial.print('/'); Serial.println(s); + Serial.printf("%i/%i\n", a, s); rtc.end(); - if(clkSource == rtc.HSE_CLOCK) { - Serial.print("User Async/Sync set to "); - Serial.print(userPredA); - Serial.print("/"); - Serial.print(userPredS); - Serial.print(": "); + if (clkSource == rtc.HSE_CLOCK) { + Serial.printf("User Async/Sync set to %i/%i:", userPredA, userPredS); rtc.setPrediv(userPredA, userPredS); rtc_config(clkSource, rtc.HOUR_24, mydate, mytime); rtc.getPrediv(&a, &s); - Serial.print(a); Serial.print('/'); Serial.println(s); + Serial.printf("%i/%i\n", a, s); printDateTime(10, 1000, false); } - Serial.print("User Async/Sync reset use the computed one: "); + Serial.print("User Async/Sync reset to use the computed one: "); rtc.setPrediv(-1, -1); rtc_config(clkSource, rtc.HOUR_24, mydate, mytime); rtc.getPrediv(&a, &s); - Serial.print(a); Serial.print('/'); Serial.println(s); + Serial.printf("%i/%i\n", a, s); // Check date change Serial.println("Testing date and time"); @@ -158,22 +163,25 @@ void loop() Serial.println("Using Epoch API, set to Jan 1, 2016"); rtc.setEpoch(1451606400); // Jan 1, 2016 - for (uint32_t i=0; i<8; i++) { - Serial.print("Unix time = "); - Serial.println(rtc.getEpoch()); - Serial.print("Seconds since Jan 1 2000 = "); - Serial.println(rtc.getY2kEpoch()); + for (uint32_t i = 0; i < 8; i++) { + Serial.printf("Unix time = %u\n", rtc.getEpoch()); + Serial.printf("Seconds since Jan 1 2000 = %u\n", rtc.getY2kEpoch()); printDateTime(1, 1000, false); } Serial.println("\nTesting alarm"); rtc_config(clkSource, rtc.HOUR_24, mydate, mytime); - byte alarmSeconds = ((seconds+5)<60) ? seconds+5 : 5; - byte alarmMinutes = ((seconds+5)<60) ? minutes : ((minutes+1)<60) ? minutes+1 : 0; - byte alarmHours = ((seconds+5)<60) ? hours : ((minutes+1)<60) ? hours : ((hours+1)<24) ? hours+1 : 0; - byte alarmDay = (hours==alarmHours)? day: ((day+1)<=31) ? day+1 : 1; + byte alarmSeconds = ((seconds + 5) < 60) ? seconds + 5 : 5; + byte alarmMinutes = ((seconds + 5) < 60) ? minutes : ((minutes + 1) < 60) ? minutes + 1 : 0; + byte alarmHours = ((seconds + 5) < 60) ? hours : ((minutes + 1) < 60) ? hours : ((hours + 1) < 24) ? hours + 1 : 0; + byte alarmDay = (hours == alarmHours) ? day : ((day + 1) <= 31) ? day + 1 : 1; + +#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000) + rtc.setAlarmSubSeconds(123); +#endif #ifndef STM32F1xx + Serial.println("\nEvery minute"); rtc.attachInterrupt(alarmMatch, (void*)&SS_MATCH); rtc.setAlarmSeconds(alarmSeconds); rtc.enableAlarm(rtc.MATCH_SS); @@ -203,7 +211,11 @@ void loop() Serial.println("\nEvery month"); rtc_setTime(mydate, mytime); rtc.attachInterrupt(alarmMatch, (void*)&DHHMMSS_MATCH); +#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000) + rtc.setAlarmTime(alarmHours, alarmMinutes, alarmSeconds, 123); +#else rtc.setAlarmTime(alarmHours, alarmMinutes, alarmSeconds); +#endif rtc.setAlarmDay(alarmDay); rtc.enableAlarm(rtc.MATCH_DHHMMSS); printDateTime(20, 1000, true); @@ -219,33 +231,33 @@ void alarmMatch(void *data) { STM32RTC::Alarm_Match m = *(STM32RTC::Alarm_Match*)data; - Serial.print("Alarm Match "); - switch(m) { - case STM32RTC::MATCH_OFF: - Serial.println("MATCH_OFF could not happen"); - break; - case STM32RTC::MATCH_YYMMDDHHMMSS://kept for compatibility - case STM32RTC::MATCH_MMDDHHMMSS: //kept for compatibility - case STM32RTC::MATCH_DHHMMSS: - Serial.println("MATCH_DHHMMSS"); - rtc.setMonth(((rtc.getMonth()+1)<13)? rtc.getMonth()+1: 1); - rtc.setEpoch(rtc.getEpoch()- 10); - break; - case STM32RTC::MATCH_HHMMSS: - Serial.println("MATCH_HHMMSS"); - rtc.setEpoch(rtc.getEpoch()+86395); - break; - case STM32RTC::MATCH_MMSS: - Serial.println("MATCH_MMSS"); - rtc.setEpoch(rtc.getEpoch()+3595); - break; - case STM32RTC::MATCH_SS: - Serial.println("MATCH_SS"); - rtc.setEpoch(rtc.getEpoch()+55); - break; - default: - Serial.println("Unknown STM32RTC::Alarm_Match type"); + Serial.print("Alarm Match at "); + printDateTime(1, 0, false); + switch (m) { + case STM32RTC::MATCH_OFF: + Serial.println("MATCH_OFF could not happen"); + break; + case STM32RTC::MATCH_YYMMDDHHMMSS://kept for compatibility + case STM32RTC::MATCH_MMDDHHMMSS: //kept for compatibility + case STM32RTC::MATCH_DHHMMSS: + Serial.println("MATCH_DHHMMSS"); + rtc.setMonth(((rtc.getMonth() + 1) < 13) ? rtc.getMonth() + 1 : 1); + rtc.setEpoch(rtc.getEpoch() - 10); + break; + case STM32RTC::MATCH_HHMMSS: + Serial.println("MATCH_HHMMSS"); + rtc.setEpoch(rtc.getEpoch() + 86395); + break; + case STM32RTC::MATCH_MMSS: + Serial.println("MATCH_MMSS"); + rtc.setEpoch(rtc.getEpoch() + 3595); + break; + case STM32RTC::MATCH_SS: + Serial.println("MATCH_SS"); + rtc.setEpoch(rtc.getEpoch() + 55); + break; + default: + Serial.println("Unknown STM32RTC::Alarm_Match type"); break; } } - diff --git a/examples/NonReg/RTC/RTC_Tests/RTC_utils.ino b/examples/NonReg/RTC/RTC_Tests/RTC_utils.ino index 957314d..c4b7ee9 100644 --- a/examples/NonReg/RTC/RTC_Tests/RTC_utils.ino +++ b/examples/NonReg/RTC/RTC_Tests/RTC_utils.ino @@ -6,13 +6,6 @@ static uint8_t conv2d(const char* p) { return 10 * v + *++p - '0'; } -void print2digits(int number) { - if (number < 10) { - Serial.print("0"); // print a 0 before if the number is < than 10 - } - Serial.print(number); -} - // sample input: date = "Dec 26 2009", time = "12:34:56" void initDateTime (const char* date, const char* time) { year = conv2d(date + 9); @@ -41,41 +34,31 @@ void initDateTime (const char* date, const char* time) { // d: delay between each print // a: display alarm void printDateTime(uint32_t t, uint32_t d, bool a) { - for (uint32_t i=0; i KO <--"); nbTestKO++; } @@ -126,14 +126,14 @@ void test_uart(int val) void setup() { SERIAL_PORT_MONITOR.begin(115200); - while(!SERIAL_PORT_MONITOR); + while (!SERIAL_PORT_MONITOR); SERIAL_PORT_MONITOR.print("SerialLoop test on "); SERIAL_PORT_MONITOR.println(XSTR(SERIAL_PORT_TESTED)); SERIAL_PORT_MONITOR.print(configNb); SERIAL_PORT_MONITOR.println(" configs to test."); SERIAL_PORT_MONITOR.print(speedNb); SERIAL_PORT_MONITOR.println(" speed to test."); - start_time=millis(); + start_time = millis(); } void loop() { @@ -147,7 +147,7 @@ void loop() { SERIAL_PORT_MONITOR.print("Test duration (ms): "); SERIAL_PORT_MONITOR.print(millis() - start_time); - while(1); // End test + while (1); // End test } SERIAL_PORT_MONITOR.println("########################"); @@ -156,19 +156,18 @@ void loop() { SERIAL_PORT_MONITOR.print(" (0x"); SERIAL_PORT_MONITOR.print(serialConfig[configCur].config, HEX); SERIAL_PORT_MONITOR.println(")"); - for (uint32_t s=0; s= 0x01090000" +#endif + #define pin D2 uint32_t channelRising, channelFalling; @@ -20,7 +29,7 @@ HardwareTimer *MyTim; @brief Input capture interrupt callback : Compute frequency and dutycycle of input signal */ -void TIMINPUT_Capture_Rising_IT_callback(HardwareTimer*) +void TIMINPUT_Capture_Rising_IT_callback(void) { CurrentCapture = MyTim->getCaptureCompare(channelRising); /* frequency computation */ @@ -42,7 +51,7 @@ void TIMINPUT_Capture_Rising_IT_callback(HardwareTimer*) /* In case of timer rollover, frequency is to low to be measured set values to 0 To reduce minimum frequency, it is possible to increase prescaler. But this is at a cost of precision. */ -void Rollover_IT_callback(HardwareTimer*) +void Rollover_IT_callback(void) { rolloverCompareCount++; @@ -57,7 +66,7 @@ void Rollover_IT_callback(HardwareTimer*) @brief Input capture interrupt callback : Compute frequency and dutycycle of input signal */ -void TIMINPUT_Capture_Falling_IT_callback(HardwareTimer*) +void TIMINPUT_Capture_Falling_IT_callback(void) { /* prepare DutyCycle computation */ CurrentCapture = MyTim->getCaptureCompare(channelFalling); diff --git a/examples/Peripherals/HardwareTimer/InputCapture/InputCapture.ino b/examples/Peripherals/HardwareTimer/InputCapture/InputCapture.ino index 23200f1..561c4f3 100644 --- a/examples/Peripherals/HardwareTimer/InputCapture/InputCapture.ino +++ b/examples/Peripherals/HardwareTimer/InputCapture/InputCapture.ino @@ -6,6 +6,15 @@ Measured frequency is displayed on Serial Monitor. */ +/* + Note: Please verify that 'pin' used for PWM has HardwareTimer capability for your board + This is specially true for F1 serie (BluePill, ...) +*/ + +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01090000) +#error "Due to API change, this sketch is compatible with STM32_CORE_VERSION >= 0x01090000" +#endif + #define pin D2 uint32_t channel; @@ -14,7 +23,7 @@ uint32_t input_freq = 0; volatile uint32_t rolloverCompareCount = 0; HardwareTimer *MyTim; -void InputCapture_IT_callback(HardwareTimer*) +void InputCapture_IT_callback(void) { CurrentCapture = MyTim->getCaptureCompare(channel); /* frequency computation */ @@ -31,7 +40,7 @@ void InputCapture_IT_callback(HardwareTimer*) /* In case of timer rollover, frequency is to low to be measured set value to 0 To reduce minimum frequency, it is possible to increase prescaler. But this is at a cost of precision. */ -void Rollover_IT_callback(HardwareTimer*) +void Rollover_IT_callback(void) { rolloverCompareCount++; diff --git a/examples/Peripherals/HardwareTimer/PWM_FullConfiguration/PWM_FullConfiguration.ino b/examples/Peripherals/HardwareTimer/PWM_FullConfiguration/PWM_FullConfiguration.ino index 3765a03..6deed28 100644 --- a/examples/Peripherals/HardwareTimer/PWM_FullConfiguration/PWM_FullConfiguration.ino +++ b/examples/Peripherals/HardwareTimer/PWM_FullConfiguration/PWM_FullConfiguration.ino @@ -8,27 +8,36 @@ Once configured, there is only CPU load for callbacks executions. */ -// 'pin' PWM will be mangaed automatically by hardware whereas 'pin2' PWM will be managed by software through interrupt callback -#if defined(LED_BUILTIN) -#define pin LED_BUILTIN +/* + Note: Please verify that 'pin' used for PWM has HardwareTimer capability for your board + This is specially true for F1 serie (BluePill, ...) +*/ -#if LED_BUILTIN == D3 -#error LED_BUILTIN == D3 -#else -#define pin2 D3 +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01090000) +#error "Due to API change, this sketch is compatible with STM32_CORE_VERSION >= 0x01090000" #endif +// 'pin' PWM will be managed automatically by hardware whereas 'pin2' PWM will be managed by software through interrupt callback +#if defined(LED_BUILTIN) + #define pin LED_BUILTIN + + #if LED_BUILTIN == D3 + #define pin2 D2 + #else + #define pin2 D3 + #endif + #else -#define pin D2 -#define pin2 D3 + #define pin D2 + #define pin2 D3 #endif -void Update_IT_callback(HardwareTimer*) +void Update_IT_callback(void) { // Update event correspond to Rising edge of PWM when configured in PWM1 mode digitalWrite(pin2, LOW); // pin2 will be complementary to pin } -void Compare_IT_callback(HardwareTimer*) +void Compare_IT_callback(void) { // Compare match event correspond to falling edge of PWM when configured in PWM1 mode digitalWrite(pin2, HIGH); } @@ -63,4 +72,4 @@ void setup() void loop() { /* Nothing to do all is done by hardware. Even no interrupt required. */ -} \ No newline at end of file +} diff --git a/examples/Peripherals/HardwareTimer/Timebase_callback/Timebase_callback.ino b/examples/Peripherals/HardwareTimer/Timebase_callback/Timebase_callback.ino index 4d57fa6..5bb7186 100644 --- a/examples/Peripherals/HardwareTimer/Timebase_callback/Timebase_callback.ino +++ b/examples/Peripherals/HardwareTimer/Timebase_callback/Timebase_callback.ino @@ -5,13 +5,17 @@ Once configured, there is only CPU load for callbacks executions. */ +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01090000) +#error "Due to API change, this sketch is compatible with STM32_CORE_VERSION >= 0x01090000" +#endif + #if defined(LED_BUILTIN) #define pin LED_BUILTIN #else #define pin D2 #endif -void Update_IT_callback(HardwareTimer*) +void Update_IT_callback(void) { // Toggle pin. 10hz toogle --> 5Hz PWM digitalWrite(pin, !digitalRead(pin)); } @@ -31,7 +35,6 @@ void setup() // configure pin in output mode pinMode(pin, OUTPUT); - MyTim->setMode(2, TIMER_OUTPUT_COMPARE); // In our case, channekFalling is configured but not really used. Nevertheless it would be possible to attach a callback to channel compare match. MyTim->setOverflow(10, HERTZ_FORMAT); // 10 Hz MyTim->attachInterrupt(Update_IT_callback); MyTim->resume(); diff --git a/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino b/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino new file mode 100644 index 0000000..4c34061 --- /dev/null +++ b/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino @@ -0,0 +1,52 @@ +/* + Timebase callback + This example shows how to configure HardwareTimer to execute a callback with some parameter at regular interval. + Callback toggles pin. + Once configured, there is only CPU load for callbacks executions. +*/ + +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION < 0x01090000) +#error "Due to API change, this sketch is compatible with STM32_CORE_VERSION >= 0x01090000" +#endif + +#if defined(LED_BUILTIN) +#define pin LED_BUILTIN +#else +#define pin D2 +#endif + + +uint32_t MyData = 1; // Parameter used for callback is arbitrarily a pointer to uint32_t, it could be of other type. + +// Every second, print on serial MyData. And increment it. +void Update_IT_callback(uint32_t* data) +{ + Serial.println(*data); + *data = *data + 1; +} + +void setup() +{ + Serial.begin(9600); +#if defined(TIM1) + TIM_TypeDef *Instance = TIM1; +#else + TIM_TypeDef *Instance = TIM2; +#endif + + // Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup() function is finished. + HardwareTimer *MyTim = new HardwareTimer(Instance); + + // configure pin in output mode + pinMode(pin, OUTPUT); + + MyTim->setOverflow(1, HERTZ_FORMAT); // 1 Hz + MyTim->attachInterrupt(std::bind(Update_IT_callback, &MyData)); // bind argument to callback: When Update_IT_callback is called MyData will be given as argument + MyTim->resume(); +} + + +void loop() +{ + /* Nothing to do all is done by hardware. Even no interrupt required. */ +} \ No newline at end of file diff --git a/examples/Peripherals/Registers/Reset_reason/Reset_reason.ino b/examples/Peripherals/Registers/Reset_reason/Reset_reason.ino new file mode 100644 index 0000000..15179d0 --- /dev/null +++ b/examples/Peripherals/Registers/Reset_reason/Reset_reason.ino @@ -0,0 +1,123 @@ +/* Last Reset Reason Sketch +* This sketch will determine what caused the last reset on the STM32 MCU. Most microcontrollers +* have a register dedicated to storing the last reason of the chip, weather being from a +* low power condition, software caused or brown-out. Test it by resetting the MCU via holding the USER button, +* which triggers the Reset_my_MCU() function or unplug the USB cable and repluggit back. Adjust your +* UART, USER Button pin and registers accordingly. Use the MCU's datasheet and/or stm32yyyxxx.h for reference. +* The code is provided "as is" with no liability. +*/ + +#include "stm32yyxx_ll_rcc.h" +#include "IWatchdog.h" +// #include "STM32LowPower.h" + +#define USER_BTN_PIN USER_BTN // Adjust this for your board + +// Enumerator for combining reset flag bits into one byte then display them +enum reset_reason { + UNKNOWN_RESET = 0, + BROWN_OUT = 1 << 0, + NRST_PIN = 1 << 1, + SOFTWARE_RST = 1 << 2, + INDEPENDENT_WDG = 1 << 3, + WINDOW_WDG = 1 << 4, + LOW_POWER = 1 << 5, + OPTION_BYTE_LOADER = 1 << 6, + POWER_ON_DOWN = 1 << 7, + STANDBY = 1 << 8, + WAKEUP = 1 << 9 +}; + +reset_reason last_reset_reason = UNKNOWN_RESET; //is initially 0 or unknown +static int default_button_state = LOW; + +void Reset_My_MCU() { + // There are a few reset conditions. Keep the one you wish to use and comment out the others. + + // Below is the WakeUp reset condition (needs STM32LowPower.h library) + // LowPower.shutdown(1000); + + // Below is the Software reset condition + // NVIC_SystemReset(); + + // Below is the Watchdog Timer reset condition + IWatchdog.begin(1000); //1ms tick then reset + while (1) + ; // Wait for reset +} + +void setup() { + pinMode(USER_BTN_PIN, INPUT); + default_button_state = digitalRead(USER_BTN_PIN); + Serial.begin(115200); + while (!Serial) + ; // Wait for Serial + +#ifdef RCC_CSR_BORRSTF + if (LL_RCC_IsActiveFlag_BORRST()) last_reset_reason = (reset_reason)(last_reset_reason | BROWN_OUT); +#endif + if (LL_RCC_IsActiveFlag_PINRST()) last_reset_reason = (reset_reason)(last_reset_reason | NRST_PIN); + if (LL_RCC_IsActiveFlag_SFTRST()) last_reset_reason = (reset_reason)(last_reset_reason | SOFTWARE_RST); +#if defined(RCC_RSR_IWDG1RSTF) + if (LL_RCC_IsActiveFlag_IWDG1RST()) last_reset_reason = (reset_reason)(last_reset_reason | INDEPENDENT_WDG); +#else + if (LL_RCC_IsActiveFlag_IWDGRST()) last_reset_reason = (reset_reason)(last_reset_reason | INDEPENDENT_WDG); +#endif +#if defined(RCC_RSR_WWDG1RSTF) + if (LL_RCC_IsActiveFlag_WWDG1RST()) last_reset_reason = (reset_reason)(last_reset_reason | WINDOW_WDG); +#else + if (LL_RCC_IsActiveFlag_WWDGRST()) last_reset_reason = (reset_reason)(last_reset_reason | WINDOW_WDG); +#endif + if (LL_RCC_IsActiveFlag_LPWRRST()) last_reset_reason = (reset_reason)(last_reset_reason | LOW_POWER); +#if defined(RCC_CSR_OBLRSTF) || defined(RCC_CSR2_OBLRSTF) + if (LL_RCC_IsActiveFlag_OBLRST()) last_reset_reason = (reset_reason)(last_reset_reason | OPTION_BYTE_LOADER); +#endif +#ifdef RCC_CSR_PORRSTF + if (LL_RCC_IsActiveFlag_PORRST()) last_reset_reason = (reset_reason)(last_reset_reason | POWER_ON_DOWN); +#endif +#if defined(PWR_CSR_SBF) || defined(PWR_SR_SBF) || defined(PWR_SR1_SBF) || defined(PWR_CSR1_SBF) || defined(PWR_PMSR_SBF) + if (LL_PWR_IsActiveFlag_SB()) last_reset_reason = (reset_reason)(last_reset_reason | STANDBY); +#endif +#if defined(PWR_CSR_WUF) + if (LL_PWR_IsActiveFlag_WU()) last_reset_reason = (reset_reason)(last_reset_reason | WAKEUP); +#endif + + + // Clear internal reset flags after they were captured + LL_RCC_ClearResetFlags(); +#if defined(PWR_SCR_CSBF) || defined(PWR_CR1_CSBF) || defined(PWR_PMCR_CSSF) || defined(PWR_SR_CSSF) +#if defined(STM32U0xx) + LL_PWR_ClearFlag_CSB(); +#else + LL_PWR_ClearFlag_SB(); +#endif +#endif +#if defined(PWR_CSR_WUF) + LL_PWR_ClearFlag_WU(); +#endif +} + +void loop() { + Serial.println("Last reset reason:"); + + if (last_reset_reason & BROWN_OUT) Serial.println(" - Brown-out reset"); + if (last_reset_reason & SOFTWARE_RST) Serial.println(" - Software reset"); + if (last_reset_reason & INDEPENDENT_WDG) Serial.println(" - Independent Watchdog reset"); + if (last_reset_reason & WINDOW_WDG) Serial.println(" - Window Watchdog reset"); + if (last_reset_reason & LOW_POWER) Serial.println(" - Low-power reset"); + if (last_reset_reason & OPTION_BYTE_LOADER) Serial.println(" - Option byte loader reset"); + if (last_reset_reason & STANDBY) Serial.println(" - Standby mode reset"); + if (last_reset_reason & WAKEUP) Serial.println(" - WakeUp flag reset (Pin or RTC)"); + if (last_reset_reason & POWER_ON_DOWN) Serial.println(" - Power on or power down reset"); + if (last_reset_reason & NRST_PIN) Serial.println(" - Pin reset (NRST or software)"); //last case so the rest take precedence before issuing NRST + if (last_reset_reason == UNKNOWN_RESET) Serial.println(" - Unknown or no flags set"); + + // Trigger software reset on button press + if (digitalRead(USER_BTN_PIN) != default_button_state) { + Serial.println("Button pressed → Triggering reset..."); + delay(300); // Debounce + Reset_My_MCU(); + } + + delay(1000); +} diff --git a/examples/Peripherals/Registers/UID_Retrieve/UID_Retrieve.ino b/examples/Peripherals/Registers/UID_Retrieve/UID_Retrieve.ino new file mode 100644 index 0000000..605502a --- /dev/null +++ b/examples/Peripherals/Registers/UID_Retrieve/UID_Retrieve.ino @@ -0,0 +1,53 @@ +/* UID Retrieve sketch +* UID (Universal Identifier) is a ID that's etched to each MCU at factory release +* so it's uniquely identifiable. This can help traceability and addressing devices +* without having to craft a database yourself. This sketch retrieves UID, MAC, Device +* and Revision ID of each MCU. Refer to the relevant datasheet to know where are these +* values are stored in the registers. +* The code is provided "as is" with no liability. +*/ + +void setup() { + Serial.begin(115200); + while (!Serial) + ; // Wait for Serial to be ready + + Serial.printf("%s Device Identifiers:\n", BOARD_NAME); + + // Unique Device ID (96 bits / 12 bytes) + uint32_t uid0 = HAL_GetUIDw0(); + uint32_t uid1 = HAL_GetUIDw1(); + uint32_t uid2 = HAL_GetUIDw2(); + + Serial.print("UID: "); + Serial.print(uid2, HEX); + Serial.print("-"); + Serial.print(uid1, HEX); + Serial.print("-"); + Serial.println(uid0, HEX); + + // MAC Address: typically stored in UID for STM32U series + // Use the lower 6 bytes of the 96-bit UID (commonly used) + uint8_t mac[6] = { + (uint8_t)(uid0 >> 0), + (uint8_t)(uid0 >> 8), + (uint8_t)(uid0 >> 16), + (uint8_t)(uid1 >> 0), + (uint8_t)(uid1 >> 8), + (uint8_t)(uid1 >> 16) + }; + + Serial.print("MAC Address: "); + for (int i = 0; i < 6; i++) { + if (mac[i] < 0x10) Serial.print("0"); + Serial.print(mac[i], HEX); + if (i < 5) Serial.print(":"); + } + Serial.println(); + Serial.printf("Device ID: 0x%x\n", HAL_GetDEVID()); + Serial.printf("Revision ID: 0x%x\n", HAL_GetREVID()); +} + +void loop() { + // Nothing here +} diff --git a/library.properties b/library.properties index 4cf6c1f..be51ffb 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=STM32duino Examples -version=1.0.5 +version=1.2.7 author=several maintainer=stm32duino sentence=Provides several examples for the Arduino core for STM32 MCUs.