Changed the data structure of the struct. Implemented writing and reading config. Defined addresses for the data. NOT TESTED.

This commit is contained in:
David Žaitlík 2021-09-10 21:51:29 +02:00
parent 17286806fb
commit 7e256ff282
3 changed files with 111 additions and 85 deletions

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -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 */