/*
 * platform_eeprom_header.h
 *
 *  Created on: 24 Jun 2020
 *      Author: Nick Pelling
 */

#ifndef PLATFORM_EEPROM_HEADER_H_
#define PLATFORM_EEPROM_HEADER_H_

#include <stdint.h>
#include <stdbool.h>

#define PLATFORM_EEPROM_HEADER_MAGIC	0x31415927U

#define PLATFORM_EEPROM_HEADER_OFFSET	0x0000		// Memory offset where header begins

#define PLATFORM_HOSTNAME_MAXLEN		16			// Keep this a multiple of 4!
#define PLATFORM_SERIAL_LEN             16          // Keep this a multiple of 4!

typedef struct
{
	uint32_t	uiHeaderMagic;			///< 00 Must be PLATFORM_EEPROM_HEADER_MAGIC
	uint32_t	uiChecksum;				///< 04 32-bit additive (negated) checksum of this header
	char        achSerialNumber[PLATFORM_SERIAL_LEN]; // 08 Defined in factory - 16 characters with no trailing zero.
	uint16_t	u16HeaderLength;		///< 24 Length of this header (must be multiple of 4!)
	uint16_t	u16DeviceIndex;			///< 26 i.e. 12369 etc
	uint8_t		au8CoAPIPAddress[4];	///< 28 CoAP multicast IP address
	uint8_t		au8StaticIPAddress[4];	///< 32 Static IP address
	uint8_t		au8StaticNetMask[4];	///< 36 Static netmask
	uint8_t		au8StaticGateway[4];	///< 40 Static gateway
	uint8_t		au8MACAddress[6];		///< 44 Top three bytes should be 00:0E:BF (Remsdaq OUI)
	uint8_t		u8UseDHCP;				///< 50 Set to 1 if you want to use DHCP
	uint8_t		au8Reserved1[1];		///< 51 Reserve final byte, rounds size up to multiple of 4
	uint8_t		achHostName[PLATFORM_HOSTNAME_MAXLEN];	///< 52 Hostname
	// 68 For compatibility, add new fields after this, don't insert above!
} stEEPROM_Header_t;

/**
 * @brief Calculate a config header checksum
 *
 * @param[in] pvBase        Base address of configuration block
 * @param[in] uiNumBytes    Length (in bytes) of the configuration
 * @return                  32-bit additive checksum value
 *
 * Calculate the checksum of a platform configuration EEPROM header
 */
uint32_t eeprom_header_calc_checksum(void *pvBase, uint32_t uiNumBytes);

/**
 * @brief Read an EEPROM platform configuration block
 * @param[in] pstHeader Header to read bytes into
 * @retval true         All went well
 * @retval false        Problem encountered
 *
 * Read a platform configuration block in from the EEPROM
 */
bool eeprom_header_read(stEEPROM_Header_t * pstHeader);

/**
 * @brief Write a platform configuration block out to the EEPROM
 * @param[in] pstHeader Header to read bytes from
 * @retval true         All went well
 * @retval false        Problem encountered
 *
 * Write a platform configuration block out to the EEPROM
 */
bool eeprom_header_write(const stEEPROM_Header_t * pstHeader);

/**
 * @brief Initialise the I2C master clock
 *
 * Initialise the I2C master clock (shared by all I2C buses)
 */
void InitialiseI2CMasterClock(void);

/**
 * @brief Initialise the I2C2 device
 *
 * Initialise the I2C2 device
 */
void InitialiseI2C2(void);
#endif /* PLATFORM_EEPROM_HEADER_H_ */
