diff --git a/fw/Core/Inc/config.h b/fw/Core/Inc/config.h index 2e47aab..d75e37f 100644 --- a/fw/Core/Inc/config.h +++ b/fw/Core/Inc/config.h @@ -2,7 +2,7 @@ * config.h * * Created on: Sep 5, 2021 - * Author: dukenuc + * Author: david */ #ifndef INC_CONFIG_H_ @@ -12,54 +12,78 @@ #include "stdint.h" #include "stm32l0xx.h" +/* DESCRIPTION OF THE DATA STRUCTURE */ +/* + * Data are divided into two groups: + * A) DEVICE DESCRIPTION + * Can not be changed by the user. + * These data can be only read. + * These data are: + * * VENDOR NAME + * * PRODUCT CODE + * * PRODUCT NAME + * * REVISION + * * SERIAL NUMBER + * B) DEVICE CONFIGURATION + * Can be changed by the user. + * These data are: + * * MODBUS ADDRESS - Modbus Address of the device. Default is 254 + * * LED ON - Whether the CO2 Level Indication LED should be on or off + * * LED CO2 ALERT LIMIT 1 - CO2 Level when the LED color changes Green<->Yellow + * * LED CO2 ALERT LIMIT 2 - CO2 Level when the LED color changes Yellow<->Red + * + * Device description data can be accessed using direct readout from the memory + * Device configuration data can be accessed using config_t struct. + */ +#define MODBUS_ADDR_LENGTH 2 +#define CONFIG_LED_ON_LENGTH 1 +#define CONFIG_LED_ALERT1_LENGTH 2 +#define CONFIG_LED_ALERT2_LENGTH 2 +#define VENDOR_NAME_LENGTH 64 +#define PRODUCT_CODE_LENGTH 64 +#define PRODUCT_NAME_LENGTH 64 +#define REVISION_LENGTH 16 +#define SERIAL_NUMBER_LENGTH 64 -#define VENDOR_NAME_LENGTH 64 -#define PRODUCT_CODE_LENGTH 64 -#define PRODUCT_NAME_LENGTH 64 -#define REVISION_LENGTH 16 -#define SERIAL_NUMBER_LENGTH 64 +#define EEPROM_ADDR_START ((uint32_t)0x08080000) +#define EEPROM_ADDR_END ((uint32_t)0x080801FF) -#define DATA_EEPROM_BASE_ADDR ((uint32_t)0x08080000) /* Data EEPROM base address */ -#define DATA_EEPROM_END_ADDR ((uint32_t)0x080801FF) /* Data EEPROM end address */ +#define CONFIG_EEPROM_ADDR_MODBUS_ADDR EEPROM_ADDR_START +#define CONFIG_EEPROM_ADDR_LED_ON_ADDR CONFIG_EEPROM_ADDR_MODBUS_ADDR + MODBUS_ADDR_LENGTH +#define CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR CONFIG_EEPROM_ADDR_LED_ON_ADDR + CONFIG_LED_ON_LENGTH +#define CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR + CONFIG_LED_ALERT1_LENGTH +#define CONFIG_EEPROM_ADDR_VENDOR_NAME CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR + CONFIG_LED_ALERT2_LENGTH +#define CONFIG_EEPROM_ADDR_PRODUCT_CODE CONFIG_EEPROM_ADDR_VENDOR_NAME + VENDOR_NAME_LENGTH +#define CONFIG_EEPROM_ADDR_PRODUCT_NAME CONFIG_EEPROM_ADDR_PRODUCT_CODE + PRODUCT_CODE_LENGTH +#define CONFIG_EEPROM_ADDR_REVISION CONFIG_EEPROM_ADDR_PRODUCT_NAME + PRODUCT_NAME_LENGTH +#define CONFIG_EEPROM_ADDR_SERIAL_NUMBER CONFIG_EEPROM_ADDR_REVISION + REVISION_LENGTH -#define FLASH_PEKEY1 0x89ABCDEF -#define FLASH_PEKEY2 0x02030405 - -#define CONFIG_OK 0 -#define CONFIG_ERROR -1 - -#define EEPROM_OK 0 -#define EEPROM_ERROR -1 -#define EEPROM_UNLOCK_ERROR -2 -#define EEPROM_LOCK_ERROR -3 -#define EEPROM_WRITE_ERROR -4 +#define FLASH_PEKEY1 0x89ABCDEF +#define FLASH_PEKEY2 0x02030405 +#define CONFIG_OK 0 +#define CONFIG_ERROR -1 +#define EEPROM_OK 0 +#define EEPROM_ERROR -1 +#define EEPROM_UNLOCK_ERROR -2 +#define EEPROM_LOCK_ERROR -3 +#define EEPROM_WRITE_ERROR -4 +#define EEPROM_ADDR_ERROR -5 typedef struct { - /* DEVICE ID */ - uint8_t vendor_name[VENDOR_NAME_LENGTH]; - uint8_t product_code[PRODUCT_CODE_LENGTH]; - uint8_t product_name[PRODUCT_NAME_LENGTH]; - uint8_t revision[REVISION_LENGTH]; - uint8_t serial_number[SERIAL_NUMBER_LENGTH]; - - /* DEVICE SPECIFIC CONFIG */ + /* DEVICE CONFIG */ uint8_t led_on; uint16_t led_co2_alert_limit1; uint16_t led_co2_alert_limit2; + + /* MODBUS CONFIG */ + uint16_t modbus_addr; } config_t; int8_t config_read(config_t *config); - int8_t config_write(config_t *config); -static int8_t eeprom_lock(void); -static int8_t eeprom_unlock(void); -static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data); -static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data); -static int8_t eeprom_program_word(uint32_t addr, uint32_t ee_data); - #endif /* INC_CONFIG_H_ */ diff --git a/fw/Core/Src/config.c b/fw/Core/Src/config.c index 4348c4c..cee056c 100644 --- a/fw/Core/Src/config.c +++ b/fw/Core/Src/config.c @@ -2,13 +2,28 @@ * config.c * * Created on: Sep 5, 2021 - * Author: dukenuc + * Author: david */ #include "config.h" +/* Function to lock the EEPROM */ +static int8_t eeprom_lock(void); +/* Function to unlock the EEPROM */ +static int8_t eeprom_unlock(void); +/* Function to write one byte to the EEPROM */ +/* IMPORTANT: EEPROM must be unlocked first */ +static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data); +/* Function to write two bytes to the EEPROM */ +/* IMPORTANT: EEPROM must be unlocked first */ +static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data); + int8_t config_read(config_t *config) { + config->modbus_addr = *(uint16_t *) CONFIG_EEPROM_ADDR_MODBUS_ADDR; + config->led_on = *(uint8_t *) CONFIG_EEPROM_ADDR_LED_ON_ADDR; + config->led_co2_alert_limit1 = *(uint16_t *) CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR; + config->led_co2_alert_limit2 = *(uint16_t *) CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR; return CONFIG_OK; } @@ -21,26 +36,32 @@ int8_t config_write(config_t *config) } /* Reset the ERASE and DATA bits in the FLASH_PECR register to disable any residual erase */ FLASH->PECR = FLASH->PECR & ~(FLASH_PECR_ERASE | FLASH_PECR_DATA); - if (eeprom_program_byte(DATA_EEPROM_BASE_ADDR, 0xab) != EEPROM_OK) + + /* Write MODBUS ADDRESS */ + if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_MODBUS_ADDR, config->modbus_addr) != EEPROM_OK) { return EEPROM_WRITE_ERROR; } - if (eeprom_program_halfword(DATA_EEPROM_BASE_ADDR+2, 0x4321) != EEPROM_OK) + /* Write LED ON */ + if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_ON_ADDR, config->led_on) != EEPROM_OK) { return EEPROM_WRITE_ERROR; } - if (eeprom_program_word(DATA_EEPROM_BASE_ADDR + (4), 0x12345678) != EEPROM_OK) + /* Write LED CO2 ALERT LIMIT 1 */ + if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR, config->led_co2_alert_limit1) != EEPROM_OK) { return EEPROM_WRITE_ERROR; } - for (uint8_t i = 0; i < 16; i ++) + /* Write LED CO2 ALERT LIMIT 2 */ + if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR, config->led_co2_alert_limit2) != EEPROM_OK) { - eeprom_program_byte(DATA_EEPROM_BASE_ADDR + 8 + i, i+1); + return EEPROM_WRITE_ERROR; } + /* Lock EEPROM*/ if (eeprom_lock() != EEPROM_OK) { return EEPROM_LOCK_ERROR; @@ -61,8 +82,6 @@ static int8_t eeprom_lock(void) return EEPROM_OK; } -/* Unlock the EEPROM: */ - static int8_t eeprom_unlock(void) { while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */ @@ -76,49 +95,40 @@ static int8_t eeprom_unlock(void) FLASH->PEKEYR = FLASH_PEKEY2; /* PEKEY2 */ } FLASH->PECR = FLASH->PECR | (FLASH_PECR_ERRIE | FLASH_PECR_EOPIE); /* enable flash interrupts */ - return EEPROM_OK; } -/** -* Brief This function programs a word of data EEPROM. -* The ERASE bit and DATA bit are cleared in PECR at the beginning -* words are automatically erased if required before programming -* Param addr is the 32-bit EEPROM address to program, data is the 32 bit word to program -* Retval None -*/ - -/* NOTE: The EEPROM must be unlocked and the flash interrupts must have been enabled prior to calling this function.*/ - static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data) { - *(uint8_t *)(addr) = ee_data; /* write data to EEPROM */ - //__WFI(); - if (*(uint8_t *)(addr) != ee_data) + if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 1)) { - return EEPROM_WRITE_ERROR; + *(uint8_t *)(addr) = ee_data; /* write data to EEPROM */ + /* TODO: Why is not the WFI triggering on FLASH Interrupt if it is supposed to be enabled? */ + //__WFI(); + if (*(uint8_t *)(addr) != ee_data) + { + return EEPROM_WRITE_ERROR; + } + return EEPROM_OK; + } else + { + return EEPROM_ADDR_ERROR; } - return EEPROM_OK; } static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data) { - *(uint16_t *)(addr) = ee_data; /* write data to EEPROM */ - //__WFI(); - if (*(uint16_t *)(addr) != ee_data) - { - return EEPROM_WRITE_ERROR; - } - return EEPROM_OK; -} - - -static int8_t eeprom_program_word(uint32_t addr, uint32_t ee_data) -{ - *(uint32_t *)(addr) = ee_data; /* write data to EEPROM */ - //__WFI(); - if (*(uint32_t *)(addr) != ee_data) - { - return EEPROM_WRITE_ERROR; - } - return EEPROM_OK; + if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 2)) + { + *(uint16_t *)(addr) = ee_data; /* write data to EEPROM */ + /* TODO: Why is not the WFI triggering on FLASH Interrupt if it is supposed to be enabled? */ + //__WFI(); + if (*(uint16_t *)(addr) != ee_data) + { + return EEPROM_WRITE_ERROR; + } + return EEPROM_OK; + } else + { + return EEPROM_ADDR_ERROR; + } } diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c index d736673..82e98f4 100644 --- a/fw/Core/Src/main.c +++ b/fw/Core/Src/main.c @@ -196,14 +196,6 @@ int main(void) scd4x_start_periodic_measurement(); uint8_t scd4x_is_connected = 1; uint8_t sps30_is_connected = 0; - - - config_t dummy_config; - int8_t config_write_err = config_write(&dummy_config); - - uint32_t eeprom_dato1 = *(uint8_t *)(DATA_EEPROM_BASE_ADDR); - uint32_t eeprom_dato2 = *(uint16_t *)(DATA_EEPROM_BASE_ADDR+2); - uint32_t eeprom_dato3 = *(uint32_t *)(DATA_EEPROM_BASE_ADDR+4); /* USER CODE END 2 */ /* Infinite loop */