Time to get serious, time to start with the microcontroller and with the first part of the project, clone the stm32 template, then remove the .git folder to remove the source control that comes with the template. Remember if you have a different board than the stm32g0 you can take a look at AN005
$ git clone https://github.com/ModularMX/template-g0 casiotron
$ cd casiotron
$ rm -r .git
REQ-201
The message processing implementation should be implemented in a single piece of code written in files serial.h and serial.c, those files shall be place in the folder app
REQ-202
The interfaces to implement that communicate with other pieces of software should be only the following two
void Serial_Init( void );
void Serial_MainFunction( void );
Where Serial_Init
is the function to initialize all the required memory regions (variables) and peripherals to start working with the Serial port and the messages reception processing. And Serial_MainFunction
is going to implement the state machine in charge of messages processing.
REQ-203
The header file serial.h should look like this
#ifndef __SERIAL_H__
#define __SERIAL_H__
void Serial_Init( void );
void Serial_MainFunction( void );
#endif
REQ-204
While the source file serial.c looks something like this
// Add more includes as needed
#include "bsp.h"
#include "serial.h"
// Add more global variables, definitons, and/or prototipes as needed
void Serial_Init( void )
{
...
}
void Serial_MainFunction( void )
{
...
}
//Add more axuliary private functions as needed
The functions can be called from main.c like this
#include "bsp.h"
#include "serial.h"
//Add more includes as needed
int main( void )
{
HAL_Init();
Serial_Init();
//Add more initilizations as needed
for(;;)
{
Serial_MainFunction();
//Add another task as needed
}
}
REQ-205
The messages to process, and their corresponding answers are those described in the project requirements
REQ-206
The serial messages will be received by the UART rx interrupt one character at the time. And the invisible character \r
will represent the end of any message. You can take as reference some of the examples like UART: Reception using Interrupts
REQ-206
The information shall validate if time and date are correct plus calculate day of the week and take into consideration leap years, you can copy and paste the functions you made previously and added in serial.c file as static functions.
static uint8_t Serial_ValidateTime( uint8_t hour, uint8_t minutes, uint8_t seconds );
static uint8_t Serial_ValidateDate( uint8_t days, uint8_t month, uint16_t year );
static uint8_t Serial_ValidateLeapYear( uint32_t year );
static uint8_t Serial_GetWeekDay( uint8_t days, uint8_t month, uint16_t year );
REQ-207
Once the information is processed and accepted should be placed in the following structure
typedef struct _APP_MsgTypeDef
{
uint8_t msg; /*!< Store the message type to send */
APP_TmTypeDef tm; /*!< time and date in stdlib tm format */
}APP_MsgTypeDef;
REQ-208
time and date time structure as defined by the following structure
typedef struct _APP_TmTypeDef
{
uint32_t tm_sec; /* seconds, range 0 to 59 */
uint32_t tm_min; /* minutes, range 0 to 59 */
uint32_t tm_hour; /* hours, range 0 to 23 */
uint32_t tm_mday; /* day of the month, range 1 to 31 */
uint32_t tm_mon; /* month, range 0 to 11 */
uint32_t tm_year; /* years in rage 1900 2100 */
uint32_t tm_wday; /* day of the week, range 0 to 6 */
uint32_t tm_yday; /* day in the year, range 0 to 365 */
uint32_t tm_isdst; /* daylight saving time */
}APP_TmTypeDef;
REQ-209
The messages type shall be defined using the following enum
REQ-210
A macro like function should be defined to convert data from BCD to and 8 bit integer. The macro will accept a 8 bit BCD number and return a 8 bit unsigned integer number
#define BCD_TO_BIN( x ) ...
...
num = BCD_TO_BIN( 0x19 )
//num will value 19 in decimal or 0x13 in hex format
REQ-211
enums and structures definitions APP_Messages
, APP_TmTypeDef
, APP_MsgTypeDef
shall be place at bsp.h
REQ-212
The state machine design shall follow the next UML State Machine diagram where each state should be represented with a case statement from the switch sentence. The state machine implementation should be made using a single switch statement inside the function Serial_MainFunction

To test the code, use the debugger, set a breakpoint right where the structure is set with valid values (OK state), send a message through a serial app, and when the program execution stops at the breakpoint watch the structure's content using the same debugger.