Renamed some definitions of the EEPROM addresses. Implemented Holding registers write and read

This commit is contained in:
David Žaitlík 2021-09-30 16:49:08 +02:00
parent e7f7077b8a
commit 9c6f88964f
3 changed files with 157 additions and 47 deletions

View File

@ -48,6 +48,10 @@ config_read(&config);
* Device description data can be accessed using direct readout from the memory * Device description data can be accessed using direct readout from the memory
* Device configuration data can be accessed using config_t struct. * Device configuration data can be accessed using config_t struct.
*/ */
#define CONFIG_DEFAULT_LED_ON 1
#define CONFIG_DEFAULT_LED_ALERT1_LIMIT 1000
#define CONFIG_DEFAULT_LED_ALERT2_LIMIT 2000
#define MODBUS_ADDR_LENGTH 2 #define MODBUS_ADDR_LENGTH 2
#define CONFIG_LED_ON_LENGTH 2 #define CONFIG_LED_ON_LENGTH 2
#define CONFIG_LED_ALERT1_LENGTH 2 #define CONFIG_LED_ALERT1_LENGTH 2
@ -58,21 +62,23 @@ config_read(&config);
#define REVISION_LENGTH 16 #define REVISION_LENGTH 16
#define SERIAL_NUMBER_LENGTH 64 #define SERIAL_NUMBER_LENGTH 64
#define EEPROM_EMPTY_BYTE 0x00
#define EEPROM_ADDR_START ((uint32_t)0x08080000) #define EEPROM_ADDR_START ((uint32_t)0x08080000)
#define EEPROM_ADDR_END ((uint32_t)0x080801FF) #define EEPROM_ADDR_END ((uint32_t)0x080801FF)
#define CONFIG_EEPROM_ADDR_MODBUS_ADDR EEPROM_ADDR_START #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_ON (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_ALERT1 (CONFIG_EEPROM_ADDR_LED_ON + 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_LED_ALERT2 (CONFIG_EEPROM_ADDR_LED_ALERT1 + CONFIG_LED_ALERT1_LENGTH)
#define CONFIG_EEPROM_ADDR_VENDOR_NAME CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR + CONFIG_LED_ALERT2_LENGTH #define CONFIG_EEPROM_ADDR_VENDOR_NAME (CONFIG_EEPROM_ADDR_LED_ALERT2 + CONFIG_LED_ALERT2_LENGTH)
#define CONFIG_EEPROM_ADDR_PRODUCT_CODE CONFIG_EEPROM_ADDR_VENDOR_NAME + VENDOR_NAME_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_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_REVISION (CONFIG_EEPROM_ADDR_PRODUCT_NAME + PRODUCT_NAME_LENGTH)
#define CONFIG_EEPROM_ADDR_SERIAL_NUMBER CONFIG_EEPROM_ADDR_REVISION + REVISION_LENGTH #define CONFIG_EEPROM_ADDR_SERIAL_NUMBER (CONFIG_EEPROM_ADDR_REVISION + REVISION_LENGTH)
#define FLASH_PEKEY1 0x89ABCDEF #define FLASH_PEKEY1 ((uint32_t)0x89ABCDEF)
#define FLASH_PEKEY2 0x02030405 #define FLASH_PEKEY2 ((uint32_t)0x02030405)
#define CONFIG_OK 0 #define CONFIG_OK 0
#define CONFIG_ERROR -1 #define CONFIG_ERROR -1

View File

@ -21,9 +21,17 @@ static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data);
int8_t config_read(config_t *config) int8_t config_read(config_t *config)
{ {
config->modbus_addr = *(uint16_t *) (CONFIG_EEPROM_ADDR_MODBUS_ADDR); config->modbus_addr = *(uint16_t *) (CONFIG_EEPROM_ADDR_MODBUS_ADDR);
config->led_on = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ON_ADDR); config->led_on = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ON);
config->led_co2_alert_limit1 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR); config->led_co2_alert_limit1 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT1);
config->led_co2_alert_limit2 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR); config->led_co2_alert_limit2 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT2);
/* Check if the EEPROM is initialized - do not check LED ON, that is 1 or 0 */
if ((config->modbus_addr == EEPROM_EMPTY_BYTE) ||
(config->led_co2_alert_limit1 == EEPROM_EMPTY_BYTE) ||
(config->led_co2_alert_limit2 == EEPROM_EMPTY_BYTE))
{
return CONFIG_ERROR;
}
return CONFIG_OK; return CONFIG_OK;
} }
@ -44,19 +52,19 @@ int8_t config_write(config_t *config)
} }
/* Write LED ON */ /* Write LED ON */
if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_ON_ADDR, config->led_on) != EEPROM_OK) if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_ON, config->led_on) != EEPROM_OK)
{ {
return EEPROM_WRITE_ERROR; return EEPROM_WRITE_ERROR;
} }
/* Write LED CO2 ALERT LIMIT 1 */ /* Write LED CO2 ALERT LIMIT 1 */
if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT1_ADDR, config->led_co2_alert_limit1) != EEPROM_OK) if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT1, config->led_co2_alert_limit1) != EEPROM_OK)
{ {
return EEPROM_WRITE_ERROR; return EEPROM_WRITE_ERROR;
} }
/* Write LED CO2 ALERT LIMIT 2 */ /* Write LED CO2 ALERT LIMIT 2 */
if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT2_ADDR, config->led_co2_alert_limit2) != EEPROM_OK) if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT2, config->led_co2_alert_limit2) != EEPROM_OK)
{ {
return EEPROM_WRITE_ERROR; return EEPROM_WRITE_ERROR;
} }

View File

@ -77,12 +77,30 @@ enum {
REGISTER_NUM_RH_SCD4x = 30014, REGISTER_NUM_RH_SCD4x = 30014,
REGISTER_NUM_T_SHT4x_SIGNED = 30015, REGISTER_NUM_T_SHT4x_SIGNED = 30015,
REGISTER_NUM_T_SCD4x_SIGNED = 30016 REGISTER_NUM_T_SCD4x_SIGNED = 30016
} register_numbers; } data_registers_numbers;
enum {
REGISTER_NUM_LED_ON = 40001,
REGISTER_NUM_CO2_ALERT_LIMIT1 = 40002,
REGISTER_NUM_CO2_ALERT_LIMIT2 = 40003,
REGISTER_NUM_MODBUS_ADDR = 40004
} config_registers_numbers;
enum {
REGISTER_NUM_VENDOR_NAME = 30010,
REGISTER_NUM_PRODUCT_CODE = 30011,
REGISTER_NUM_REVISION = 30012,
REGISTER_NUM_PRODUCT_NAME = 30013,
REGISTER_NUM_SERIAL_NUMBER = 30014
} identification_registers_numbers;
/* Variables to store the measured data */ /* Variables to store the measured data */
int CO2, T_SCD4x, RH_SCD4x; int CO2, T_SCD4x, RH_SCD4x;
int T_SHT4x, RH_SHT4x; int T_SHT4x, RH_SHT4x;
uint16_t sps30_measured_data[10]; uint16_t sps30_measured_data[10];
/* Struct to store the sensor config */
config_t sensor_config;
/* USER CODE END PV */ /* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
@ -100,35 +118,104 @@ void LPUART1_TX_Buffer(uint8_t* buffer_tx, uint8_t buffer_tx_len);
int8_t modbus_slave_callback(modbus_transaction_t *transaction) int8_t modbus_slave_callback(modbus_transaction_t *transaction)
{ {
uint16_t register_number = transaction->register_number; uint16_t register_number = transaction->register_number;
if (transaction->function_code == MODBUS_READ_INPUT_REGISTERS) { switch (transaction->function_code)
for (int i = 0; i < transaction->register_count; i++, register_number++) { {
switch (register_number) { case MODBUS_READ_INPUT_REGISTERS:
case REGISTER_NUM_CO2: for (int i = 0; i < transaction->register_count; i++, register_number++)
transaction->input_registers[i] = (uint16_t)CO2; {
break; switch (register_number)
case REGISTER_NUM_T_SHT4x: {
transaction->input_registers[i] = (uint16_t)T_SHT4x; case REGISTER_NUM_CO2:
break; transaction->input_registers[i] = (uint16_t)CO2;
case REGISTER_NUM_RH_SHT4x: break;
transaction->input_registers[i] = (uint16_t)RH_SHT4x; case REGISTER_NUM_T_SHT4x:
break; transaction->input_registers[i] = (uint16_t)T_SHT4x;
case REGISTER_NUM_T_SCD4x: break;
transaction->input_registers[i] = (uint16_t)T_SCD4x; case REGISTER_NUM_RH_SHT4x:
break; transaction->input_registers[i] = (uint16_t)RH_SHT4x;
case REGISTER_NUM_RH_SCD4x: break;
transaction->input_registers[i] = (uint16_t)RH_SCD4x; case REGISTER_NUM_T_SCD4x:
break; transaction->input_registers[i] = (uint16_t)T_SCD4x;
case REGISTER_NUM_T_SHT4x_SIGNED: break;
transaction->input_registers_signed[i] = (int16_t)T_SHT4x; case REGISTER_NUM_RH_SCD4x:
break; transaction->input_registers[i] = (uint16_t)RH_SCD4x;
case REGISTER_NUM_T_SCD4x_SIGNED: break;
transaction->input_registers_signed[i] = (int16_t)T_SCD4x; case REGISTER_NUM_T_SHT4x_SIGNED:
break; transaction->input_registers_signed[i] = (int16_t)T_SHT4x;
default: break;
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED; case REGISTER_NUM_T_SCD4x_SIGNED:
transaction->input_registers_signed[i] = (int16_t)T_SCD4x;
break;
default:
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
}
} }
} return MODBUS_OK;
return MODBUS_OK; case MODBUS_READ_HOLDING_REGISTERS:
for (int i = 0; i < transaction->register_count; i++, register_number++)
{
switch (register_number)
{
case REGISTER_NUM_LED_ON:
transaction->holding_registers[i] = (uint16_t)(sensor_config.led_on);
break;
case REGISTER_NUM_CO2_ALERT_LIMIT1:
transaction->holding_registers[i] = (uint16_t)(sensor_config.led_co2_alert_limit1);
break;
case REGISTER_NUM_CO2_ALERT_LIMIT2:
transaction->holding_registers[i] = (uint16_t)(sensor_config.led_co2_alert_limit2);
break;
case REGISTER_NUM_MODBUS_ADDR:
transaction->holding_registers[i] = (uint16_t)(sensor_config.modbus_addr);
break;
default:
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
}
}
return MODBUS_OK;
case MODBUS_WRITE_SINGLE_REGISTER:
switch (register_number)
{
case REGISTER_NUM_LED_ON:
sensor_config.led_on = (uint8_t) transaction->holding_registers[0];
break;
case REGISTER_NUM_CO2_ALERT_LIMIT1:
sensor_config.led_co2_alert_limit1 = (uint16_t) transaction->holding_registers[0];
break;
case REGISTER_NUM_CO2_ALERT_LIMIT2:
sensor_config.led_co2_alert_limit2 = (uint16_t) transaction->holding_registers[0];
break;
case REGISTER_NUM_MODBUS_ADDR:
sensor_config.modbus_addr = (uint16_t) transaction->holding_registers[0];
break;
default:
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
}
return MODBUS_OK;
case MODBUS_WRITE_MULTIPLE_REGISTERS:
for (int i = 0; i < transaction->register_count; i++, register_number++)
{
switch (register_number)
{
case REGISTER_NUM_LED_ON:
sensor_config.led_on = (uint8_t) transaction->holding_registers[i];
break;
case REGISTER_NUM_CO2_ALERT_LIMIT1:
sensor_config.led_co2_alert_limit1 = (uint16_t) transaction->holding_registers[i];
break;
case REGISTER_NUM_CO2_ALERT_LIMIT2:
sensor_config.led_co2_alert_limit2 = (uint16_t) transaction->holding_registers[i];
break;
case REGISTER_NUM_MODBUS_ADDR:
sensor_config.modbus_addr = (uint16_t) transaction->holding_registers[i];
break;
default:
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
}
}
return MODBUS_OK;
default:
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
} }
/* Catch-all error */ /* Catch-all error */
return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED; /* nothing implemented yet! TODO */ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED; /* nothing implemented yet! TODO */
@ -196,7 +283,16 @@ int main(void)
i2c_context.i2c = I2C1; i2c_context.i2c = I2C1;
i2c_init(&i2c_context); i2c_init(&i2c_context);
modbus_slave_set_address(0x11); /* Read config from EEPROM - if unsuccessful, set the default values*/
int8_t config_read_status = config_read(&sensor_config);
if (config_read_status != CONFIG_OK)
{
sensor_config.modbus_addr = MODBUS_DEFAULT_SLAVE_ADDRESS;
sensor_config.led_co2_alert_limit1 = CONFIG_DEFAULT_LED_ALERT1_LIMIT;
sensor_config.led_co2_alert_limit2 = CONFIG_DEFAULT_LED_ALERT2_LIMIT;
sensor_config.led_on = CONFIG_DEFAULT_LED_ON;
}
modbus_slave_set_address(sensor_config.modbus_addr);
scd4x_start_periodic_measurement(); scd4x_start_periodic_measurement();
uint8_t scd4x_is_connected = 1; uint8_t scd4x_is_connected = 1;