/*
 * config.h
 *
 *  Created on: Sep 5, 2021
 *      Author: david
 */

#ifndef INC_CONFIG_H_
#define INC_CONFIG_H_

/* TODO: add comments to everything */

/* EXAMPLE of USAGE */
/*
config_t new_config;
new_config.led_co2_alert_limit1 = 1000;
new_config.led_co2_alert_limit2 = 2000;
new_config.led_on = 1;
new_config.modbus_addr = 0x11;
config_write(&new_config);

config_t config;
config_read(&config);
*/

#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 CONFIG_DEFAULT_LED_ON					1
#define CONFIG_DEFAULT_LED_BRIGHTNESS			100 /* TODO: set according to the timers when this will be implemented */
#define CONFIG_DEFAULT_LED_ALERT1_LIMIT			1500
#define CONFIG_DEFAULT_LED_ALERT2_LIMIT			3000
#define CONFIG_DEFAULT_LED_SMOOTH				0
#define CONFIG_DEFAULT_SCD4x_T_OFFSET			0
#define CONFIG_DEFAULT_BAUDRATE_INDEX			0

#define	CONFIG_MODBUS_ADDR_LENGTH				2
#define CONFIG_BAUDRATE_INDEX_LENGTH			2
#define CONFIG_LED_ON_LENGTH					2
#define CONFIG_LED_BRIGHTNESS_LENGTH			2
#define CONFIG_LED_SMOOTH_LENGTH				2
#define CONFIG_LED_ALERT1_LENGTH				2
#define CONFIG_LED_ALERT2_LENGTH				2
#define CONFIG_LED_ALERT2_LENGTH				2
#define CONFIG_SCD4x_T_OFFSET_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 EEPROM_EMPTY_BYTE						0x00

#define EEPROM_ADDR_START 						((uint32_t)0x08080000)
#define EEPROM_ADDR_END 						((uint32_t)0x080801FF)

#define CONFIG_EEPROM_ADDR_MODBUS_ADDR			EEPROM_ADDR_START
#define CONFIG_EEPROM_ADDR_BAUDRATE_INDEX		(CONFIG_EEPROM_ADDR_MODBUS_ADDR 		+ CONFIG_MODBUS_ADDR_LENGTH)
#define CONFIG_EEPROM_ADDR_LED_ON				(CONFIG_EEPROM_ADDR_BAUDRATE_INDEX 		+ CONFIG_BAUDRATE_INDEX_LENGTH)
#define CONFIG_EEPROM_ADDR_LED_BRIGHTNESS		(CONFIG_EEPROM_ADDR_LED_ON				+ CONFIG_LED_ON_LENGTH)
#define CONFIG_EEPROM_ADDR_LED_SMOOTH			(CONFIG_EEPROM_ADDR_LED_BRIGHTNESS		+ CONFIG_LED_BRIGHTNESS_LENGTH)
#define CONFIG_EEPROM_ADDR_LED_ALERT1			(CONFIG_EEPROM_ADDR_LED_SMOOTH			+ CONFIG_LED_SMOOTH_LENGTH)
#define CONFIG_EEPROM_ADDR_LED_ALERT2			(CONFIG_EEPROM_ADDR_LED_ALERT1 			+ CONFIG_LED_ALERT1_LENGTH)
#define CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET		(CONFIG_EEPROM_ADDR_LED_ALERT2 			+ CONFIG_LED_ALERT2_LENGTH)

#define CONFIG_EEPROM_ADDR_VENDOR_NAME			(CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET 		+ CONFIG_SCD4x_T_OFFSET_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							((uint32_t)0x89ABCDEF)
#define FLASH_PEKEY2							((uint32_t)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

#define SYSTICK_FREQ_HZ							12000000
#define EEPROM_TIMEOUT_MAX_MS_INV				200

/*
 * Variables
 */

extern const uint32_t config_baudrates[];
extern const uint8_t config_baudrates_length;

/*
 * Type definitions
 */

typedef struct
{
	/* LED CONFIG */
	uint8_t led_on;
	uint16_t led_brightness;
	uint8_t led_smooth;
	uint16_t led_co2_alert_limit1;
	uint16_t led_co2_alert_limit2;

	/* SCD4x Temperature sensor offset */
	int16_t scd4x_t_offset;

	/* MODBUS CONFIG */
	uint16_t modbus_addr;
	uint32_t baudrate_index;
} config_t;


/* const uint32_t baudrates [] = {19200, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800, 115200}; */

int8_t config_read(config_t *config);
int8_t config_write(config_t *config);

#endif /* INC_CONFIG_H_ */

