Initial public release.

This commit is contained in:
Joe Kearney 2025-02-01 19:22:12 -06:00
parent 7b169e8116
commit dac4af8d25
255 changed files with 68595 additions and 2 deletions

105
2020TPCApp1.cydsn/NVM/NVM.h Normal file
View file

@ -0,0 +1,105 @@
/** \dir NVM
*
* \brief Non-Volatile Memory
*
* This directory/namespace contains all the software used to manage non-volatile memory for this CPU.
*
*/
/** \file
* \brief This file defines the interface to the NVM package.
*
* This file should be included by any file outside the NVM package wishing to make use
* of any of the NVM functionality.
*/
#ifndef NVM_H
#define NVM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
//! Enumeration of the various states of a nonvolatile memory entry.
typedef enum
{
//! This entry has not yet been initialized.
NVM_STATE_UNINITIALIZED = 0,
//! This entry has been read from nonvolatile memory, and the cyclic redundancy check failed.
NVM_STATE_CRC_FAILED,
//! No changes are pending for this entry.
NVM_STATE_IDLE,
//! A request has been made to save this entry to NVM.
NVM_STATE_SAVE_REQUESTED
} NVM_Entry_State_T;
typedef struct
{
// Size of the NVM data.
const size_t Size;
// Address of the NVM data in the EEPROM memory.
const uint16_t EE_Address;
// Address of the calculated CRC value in the EEPROM memory.
const uint16_t EE_CRC_Address;
// Address of the NVM data in RAM.
uint8_t * const Value;
// Address of the default data in ROM.
uint8_t const * const Default;
// Current state of this NVM entry
NVM_Entry_State_T State;
} NVM_EEPROMEntry_T;
/* Include Files */
#include "NVM_CRC.h"
#if (CONFIG__HAS_EXTERNAL_NVM)
#include "NVM_ExternalEEPROM.h"
#include "NVM_ExternalEEPROMEntries.h"
#endif // CONFIG__HAS_EXTERNAL_NVM
#if (CONFIG__HAS_INTERNAL_NVM)
#include "NVM_OnChipEEPROM.h"
#include "NVM_OnChipEEPROMEntries.h"
#endif // CONFIG__HAS_INTERNAL_NVM
/* Public Variables */
/* Public Functions */
inline bool IsNVMInitialized()
{
taskENTER_CRITICAL();
bool is_initialized =
#if (CONFIG__HAS_EXTERNAL_NVM)
NVM_IsExternalEEPROMInitialized &&
#endif // CONFIG__HAS_EXTERNAL_NVM
#if (CONFIG__HAS_INTERNAL_NVM)
NVM_IsOnChipEEPROMInitialized &&
#endif // CONFIG__HAS_INTERNAL_NVM
true;
taskEXIT_CRITICAL();
return is_initialized;
}
#ifdef __cplusplus
}
#endif
#endif // NVM_H

View file

@ -0,0 +1,72 @@
/**
* \file
* Functions and types for CRC checks.
*
* Generated on Sat Jun 15 14:34:15 2019
* by pycrc v0.9.2, https://pycrc.org
* using the configuration:
* - Width = 16
* - Poly = 0xed2f
* - XorIn = 0xbeef
* - ReflectIn = False
* - XorOut = 0x0000
* - ReflectOut = False
* - Algorithm = table-driven
*/
#include "NVM_CRC.h" /* include the header file generated with pycrc */
#include <stdlib.h>
#include <stdint.h>
/**
* Static table used for the table_driven implementation.
*/
static const NVM_CRC_t crc_table[256] = {
0x0000, 0xed2f, 0x3771, 0xda5e, 0x6ee2, 0x83cd, 0x5993, 0xb4bc,
0xddc4, 0x30eb, 0xeab5, 0x079a, 0xb326, 0x5e09, 0x8457, 0x6978,
0x56a7, 0xbb88, 0x61d6, 0x8cf9, 0x3845, 0xd56a, 0x0f34, 0xe21b,
0x8b63, 0x664c, 0xbc12, 0x513d, 0xe581, 0x08ae, 0xd2f0, 0x3fdf,
0xad4e, 0x4061, 0x9a3f, 0x7710, 0xc3ac, 0x2e83, 0xf4dd, 0x19f2,
0x708a, 0x9da5, 0x47fb, 0xaad4, 0x1e68, 0xf347, 0x2919, 0xc436,
0xfbe9, 0x16c6, 0xcc98, 0x21b7, 0x950b, 0x7824, 0xa27a, 0x4f55,
0x262d, 0xcb02, 0x115c, 0xfc73, 0x48cf, 0xa5e0, 0x7fbe, 0x9291,
0xb7b3, 0x5a9c, 0x80c2, 0x6ded, 0xd951, 0x347e, 0xee20, 0x030f,
0x6a77, 0x8758, 0x5d06, 0xb029, 0x0495, 0xe9ba, 0x33e4, 0xdecb,
0xe114, 0x0c3b, 0xd665, 0x3b4a, 0x8ff6, 0x62d9, 0xb887, 0x55a8,
0x3cd0, 0xd1ff, 0x0ba1, 0xe68e, 0x5232, 0xbf1d, 0x6543, 0x886c,
0x1afd, 0xf7d2, 0x2d8c, 0xc0a3, 0x741f, 0x9930, 0x436e, 0xae41,
0xc739, 0x2a16, 0xf048, 0x1d67, 0xa9db, 0x44f4, 0x9eaa, 0x7385,
0x4c5a, 0xa175, 0x7b2b, 0x9604, 0x22b8, 0xcf97, 0x15c9, 0xf8e6,
0x919e, 0x7cb1, 0xa6ef, 0x4bc0, 0xff7c, 0x1253, 0xc80d, 0x2522,
0x8249, 0x6f66, 0xb538, 0x5817, 0xecab, 0x0184, 0xdbda, 0x36f5,
0x5f8d, 0xb2a2, 0x68fc, 0x85d3, 0x316f, 0xdc40, 0x061e, 0xeb31,
0xd4ee, 0x39c1, 0xe39f, 0x0eb0, 0xba0c, 0x5723, 0x8d7d, 0x6052,
0x092a, 0xe405, 0x3e5b, 0xd374, 0x67c8, 0x8ae7, 0x50b9, 0xbd96,
0x2f07, 0xc228, 0x1876, 0xf559, 0x41e5, 0xacca, 0x7694, 0x9bbb,
0xf2c3, 0x1fec, 0xc5b2, 0x289d, 0x9c21, 0x710e, 0xab50, 0x467f,
0x79a0, 0x948f, 0x4ed1, 0xa3fe, 0x1742, 0xfa6d, 0x2033, 0xcd1c,
0xa464, 0x494b, 0x9315, 0x7e3a, 0xca86, 0x27a9, 0xfdf7, 0x10d8,
0x35fa, 0xd8d5, 0x028b, 0xefa4, 0x5b18, 0xb637, 0x6c69, 0x8146,
0xe83e, 0x0511, 0xdf4f, 0x3260, 0x86dc, 0x6bf3, 0xb1ad, 0x5c82,
0x635d, 0x8e72, 0x542c, 0xb903, 0x0dbf, 0xe090, 0x3ace, 0xd7e1,
0xbe99, 0x53b6, 0x89e8, 0x64c7, 0xd07b, 0x3d54, 0xe70a, 0x0a25,
0x98b4, 0x759b, 0xafc5, 0x42ea, 0xf656, 0x1b79, 0xc127, 0x2c08,
0x4570, 0xa85f, 0x7201, 0x9f2e, 0x2b92, 0xc6bd, 0x1ce3, 0xf1cc,
0xce13, 0x233c, 0xf962, 0x144d, 0xa0f1, 0x4dde, 0x9780, 0x7aaf,
0x13d7, 0xfef8, 0x24a6, 0xc989, 0x7d35, 0x901a, 0x4a44, 0xa76b
};
NVM_CRC_t NVM_CRC_update(NVM_CRC_t crc, const void *data, size_t data_len)
{
const unsigned char *d = (const unsigned char *)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = ((crc >> 8) ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc << 8)) & 0xffff;
d++;
}
return crc & 0xffff;
}

View file

@ -0,0 +1,115 @@
/**
* \file
* Functions and types for CRC checks.
*
* Generated on Sat Jun 15 14:34:05 2019
* by pycrc v0.9.2, https://pycrc.org
* using the configuration:
* - Width = 16
* - Poly = 0xed2f
* - XorIn = 0xbeef
* - ReflectIn = False
* - XorOut = 0x0000
* - ReflectOut = False
* - Algorithm = table-driven
*
* This file defines the functions NVM_CRC_init(), NVM_CRC_update() and NVM_CRC_finalize().
*
* The NVM_CRC_init() function returns the inital \c crc value and must be called
* before the first call to NVM_CRC_update().
* Similarly, the NVM_CRC_finalize() function must be called after the last call
* to NVM_CRC_update(), before the \c crc is being used.
* is being used.
*
* The NVM_CRC_update() function can be called any number of times (including zero
* times) in between the NVM_CRC_init() and NVM_CRC_finalize() calls.
*
* This pseudo-code shows an example usage of the API:
* \code{.c}
* NVM_CRC_t crc;
* unsigned char data[MAX_DATA_LEN];
* size_t data_len;
*
* crc = NVM_CRC_init();
* while ((data_len = read_data(data, MAX_DATA_LEN)) > 0) {
* crc = NVM_CRC_update(crc, data, data_len);
* }
* crc = NVM_CRC_finalize(crc);
* \endcode
*
* ## Additional Notes
*
* The CRC polynomial (0xED2F) was chosen based on the research published by Philip Koopman of Carnegie Mellon
* University [here](http://users.ece.cmu.edu/~koopman/crc/). Dr. Koopman claims this polynomial has a
* Hamming Distance of 10.
*
* The initial value, 0xBEEF, was chosen simply to avoid the most common EE values of 0xFFFF and 0x0000.
*
*/
#ifndef NVM_CRC_H
#define NVM_CRC_H
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The definition of the used algorithm.
*
* This is not used anywhere in the generated code, but it may be used by the
* application code to call algorithm-specific code, if desired.
*/
#define CRC_ALGO_TABLE_DRIVEN 1
/**
* The type of the CRC values.
*
* CRCs are sixteen bits wide.
*/
typedef uint16_t NVM_CRC_t;
/**
* Calculate the initial crc value.
*
* \return The initial crc value.
*/
static inline NVM_CRC_t NVM_CRC_init(void)
{
return 0xbeef;
}
/**
* Update the crc value with new data.
*
* \param[in] crc The current crc value.
* \param[in] data Pointer to a buffer of \a data_len bytes.
* \param[in] data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*/
NVM_CRC_t NVM_CRC_update(NVM_CRC_t crc, const void *data, size_t data_len);
/**
* Calculate the final crc value.
*
* \param[in] crc The current crc value.
* \return The final crc value.
*/
static inline NVM_CRC_t NVM_CRC_finalize(NVM_CRC_t crc)
{
return crc;
}
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
#endif /* NVM_CRC_H */

View file

@ -0,0 +1,302 @@
/** \file
* \brief This file contains functions that manage the external EEPROM.
*
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
//! This is the same for both the MCP98243 and the CAT24C256.
#define EXTERNAL_EEPROM_I2C_ADDRESS 0x50
#define EXTERNAL_EEPROM_TEMP_SENSOR_I2C_ADDRESS 0x18
//! Read-only register used to identify the temperature sensor capability.
#define MCP98243_REGISTER_CAPABILITY 0x00
//! Sensor configuration register.
#define MCP98243_REGISTER_CONFIG 0x01
//! Upper temperature limit register.
#define MCP98243_REGISTER_T_UPPER 0x02
//! Lower temperature limit register.
#define MCP98243_REGISTER_T_LOWER 0x03
//! Critical temperature limit register.
#define MCP98243_REGISTER_T_CRIT 0x04
//! Ambient temperature register.
#define MCP98243_REGISTER_T_A 0x05
//! Read-only register used to identify the manufacturer of the device.
#define MCP98243_REGISTER_MANUFACTURER_ID 0x06
//! Read-only register indicating the device identification and device revision.
#define MCP98243_REGISTER_DEVICE_ID 0x07
//! Temperature sensor resolution register.
#define MCP98243_REGISTER_RESOLUTION 0x08
/* External Variables [Only if necessary!] */
/* External Function Prototypes [Only if necessary!] */
/* Public Variables */
//! Mutex controlling access to the EEPROM to ensure data/CRC integrity.
SemaphoreHandle_t xSemaphoreExternalEEPROMLock;
TaskHandle_t NVM_ExternalEEPROM_Task_Handle;
volatile bool NVM_IsExternalEEPROMInitialized = false;
/* Private Variables */
static QueueHandle_t xQueueExternalEEPROM;
//! Shared master transfer configuration variable.
static cy_stc_scb_i2c_master_xfer_config_t Master_Transfer_Config =
{
.slaveAddress = EXTERNAL_EEPROM_I2C_ADDRESS,
.buffer = NULL,
.bufferSize = 0U,
.xferPending = false
};
/* Private Function Prototypes */
/* Inline Functions */
//! Waits a given time for an I²C transfer to complete.
/*!
* \param timeout_in_ms The time (in milliseconds) to wait for the transfer to complete.
* \return #true if the transfer completed, or #false if the time ran out without
* a successful transfer.
*/
static inline bool Wait_For_Transfer_To_Complete(uint16_t timeout_in_ms)
{
bool success = false;
// Time to wait for an in-process transfer before looking again. This wait grows longer as time
// passes, until timeout_in_ms runs out.
uint16_t HOLDOFF_TIME_IN_ms = 1;
while ((success == false) && (timeout_in_ms > 0))
{
vTaskDelay(pdMS_TO_TICKS(HOLDOFF_TIME_IN_ms));
if (timeout_in_ms > HOLDOFF_TIME_IN_ms)
{
timeout_in_ms -= HOLDOFF_TIME_IN_ms;
// Wait a little longer next time.
HOLDOFF_TIME_IN_ms++;
}
else
{
timeout_in_ms = 0;
}
if ((I2C_MasterGetStatus() & CY_SCB_I2C_MASTER_BUSY) != CY_SCB_I2C_MASTER_BUSY)
{
success = true;
}
}
return success;
}
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
uint8_t xfer_buffer[5];
if (xSemaphoreTake(COMM_I2C_Bus_Mutex, portMAX_DELAY) == pdTRUE)
{
// Write the initial address to the EEPROM.
xfer_buffer[0] = (source >> 8);
xfer_buffer[1] = source & 0xFF;
Master_Transfer_Config.buffer = (uint8_t *)xfer_buffer;
Master_Transfer_Config.bufferSize = 2;
cy_en_scb_i2c_status_t errStatus = I2C_MasterWrite(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
// Read n bytes at EEPROM[source].
Master_Transfer_Config.buffer = (uint8_t *)destination;
Master_Transfer_Config.bufferSize = n;
errStatus = I2C_MasterRead(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
xSemaphoreGive(COMM_I2C_Bus_Mutex);
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
uint8_t xfer_buffer[4];
if (xSemaphoreTake(COMM_I2C_Bus_Mutex, portMAX_DELAY) == pdTRUE)
{
// Write the data one byte at a time.
for (uint8_t i = 0; i < n; i++)
{
uint16_t destination_address = destination + i;
xfer_buffer[0] = (destination_address >> 8);
xfer_buffer[1] = destination_address & 0xFF;
xfer_buffer[2] = *(source + i);
Master_Transfer_Config.buffer = (uint8_t *)xfer_buffer;
Master_Transfer_Config.bufferSize = 3;
cy_en_scb_i2c_status_t errStatus = I2C_MasterWrite(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
// The CAT24C256 has a nominal Write Cycle time (t_WR) of 5ms (no maximum specified).
// Wait 6ms between writes to have some margin (and avoid being NAKed).
vTaskDelay(pdMS_TO_TICKS(6));
}
xSemaphoreGive(COMM_I2C_Bus_Mutex);
}
}
/* Public Functions */
//! Sets up the external EEPROM, but does not read from it (yet).
void NVM_InitExternalEEPROM(void)
{
/// Create a mutex-type semaphore.
xSemaphoreExternalEEPROMLock = xSemaphoreCreateMutex();
if (xSemaphoreExternalEEPROMLock == NULL)
{
CY_ASSERT(0);
}
xQueueExternalEEPROM = xQueueCreate(5, sizeof(uint8_t));
}
//! Handles the ongoing external EEPROM tasks.
/*!
* First, it loops through all the external EEPROM entries, and reads them in to RAM.
* Then, it priodically loops through all the external EEPROM entries, and saves the ones that have been flagged.
*/
void NVM_ExternalEEPROMTask(void * pvParameters)
{
portBASE_TYPE xStatus;
static TickType_t xTicksToWait = pdMS_TO_TICKS(NVM_EXTERNAL_EEPROM_TASK_RATE_IN_ms);
for (uint8_t i = 0; i < NVM_N_EXTERNAL_EEPROM_ENTRIES; i++)
{
NVM_CRC_t calculated_crc;
NVM_CRC_t stored_crc = 0;
EEPROM_read_block(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->EE_Address, NVM_ExternalEEPROMEntries[i]->Size);
EEPROM_read_block((uint8_t *)&stored_crc, NVM_ExternalEEPROMEntries[i]->EE_CRC_Address, sizeof(NVM_CRC_t));
calculated_crc = NVM_CRC_init();
calculated_crc = NVM_CRC_update(calculated_crc, NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Size);
calculated_crc = NVM_CRC_finalize(calculated_crc);
if (calculated_crc == stored_crc)
{
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_IDLE;
}
else
{
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_CRC_FAILED;
COMM_Console_Print_String("[NVMEx ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Calculated/Stored CRCs: ");
COMM_Console_Print_UInt16((uint16_t) calculated_crc);
COMM_Console_Print_String("/");
COMM_Console_Print_UInt16((uint16_t) stored_crc);
COMM_Console_Print_String("\n");
COMM_Console_Print_String("[NVMEx ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Applying defaults.\n");
memcpy(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Default, NVM_ExternalEEPROMEntries[i]->Size);
// Auto-fix the CRC.
NVM_SaveExternalEEPROMEntry(NVM_ExternalEEPROMEntries[i]);
}
}
taskENTER_CRITICAL();
NVM_IsExternalEEPROMInitialized = true;
taskEXIT_CRITICAL();
while(true)
{
uint8_t dummy;
// Wait for a call to NVM_SaveExternalEEPROMEntry().
xStatus = xQueueReceive(xQueueExternalEEPROM, &dummy, xTicksToWait);
if (xStatus == pdPASS)
{
for (uint8_t i = 0; i < NVM_N_EXTERNAL_EEPROM_ENTRIES; i++)
{
NVM_CRC_t crc;
if (NVM_ExternalEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (xSemaphoreTake(xSemaphoreExternalEEPROMLock, portMAX_DELAY) == pdTRUE)
{
EEPROM_write_block(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->EE_Address, NVM_ExternalEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_ExternalEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreExternalEEPROMLock);
}
}
}
}
}
}
//! Flags the given external EEPROM entry to be saved next time the NVM_ExternalEEPROMTask() is run.
void NVM_SaveExternalEEPROMEntry(NVM_EEPROMEntry_T * const this)
{
if (xSemaphoreTake(xSemaphoreExternalEEPROMLock, portMAX_DELAY) == pdTRUE)
{
this->State = NVM_STATE_SAVE_REQUESTED;
xSemaphoreGive(xSemaphoreExternalEEPROMLock);
uint8_t dummy = 0;
xQueueSend(xQueueExternalEEPROM, &dummy, 0);
}
}
/* Private Functions */

View file

@ -0,0 +1,44 @@
/** \file
* \brief This file contains the public interface to the external EEPROM.
*
* On the 2020TPC, the external EEPROM is the Onsemi [CAT24C256](https://www.onsemi.com/pdf/datasheet/cat24c256-d.pdf).
*
*/
#ifndef NVM_EXTERNALEEPROM_H
#define NVM_EXTERNALEEPROM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define NVM_EXTERNAL_EEPROM_TASK_STACK_SIZE_in_bytes 256
//! The time between calls to NVM_ExternalEEPROMTask().
#define NVM_EXTERNAL_EEPROM_TASK_RATE_IN_ms 2000
/* Include Files */
/* Public Variables */
extern SemaphoreHandle_t xSemaphoreExternalEEPROMLock;
//! Handle of the NVM_ExternalEEPROMTask() given when the task was created.
extern TaskHandle_t NVM_ExternalEEPROM_Task_Handle;
extern volatile bool NVM_IsExternalEEPROMInitialized;
/* Public Functions */
void NVM_InitExternalEEPROM(void);
void NVM_ExternalEEPROMTask(void * pvParameters);
void NVM_SaveExternalEEPROMEntry(NVM_EEPROMEntry_T * const this);
/* Inline Functions */
#ifdef __cplusplus
}
#endif
#endif // NVM_EXTERNALEEPROM_H

View file

@ -0,0 +1,153 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file defines the External EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
/* Include Files */
#include "KTag.h"
/* EEPROM Entries */
/** \defgroup NVM_EXTERNAL_EEPROM NVM External EEPROM
*
* The External EEPROM is divided into logical "entries", represented by instances of the #NVM_EEPROMEntry_T type.
* At startup, these entries are loaded into their respective RAM copies by NVM_InitExternalEEPROM(). The application
* then updates the RAM copies directly, and requests that the NVM_ExternalEEPROMTask() save these back to the EEPROM
* when necessary.
* @{ */
static NVM_External_Test_T RAM_External_Test;
static const NVM_External_Test_T DEFAULT_External_Test =
{
//! Test Code 3
.External_Test_3 = UINT16_MAX,
//! Test Code 4
.External_Test_4 = UINT32_MAX,
};
NVM_EEPROMEntry_T NVM_External_Test =
{
//! Size == sizeof(NVM_External_Test_T)
.Size = 6,
.EE_Address = 0,
.EE_CRC_Address = 6,
.Value = (uint8_t *)&RAM_External_Test,
.Default = (uint8_t *)&DEFAULT_External_Test,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Info_T RAM_Info;
static const NVM_Info_T DEFAULT_Info =
{
//! Date this unit was first programmed.
.Date_Code_as_YYYYMMDD = 20200101,
};
NVM_EEPROMEntry_T NVM_Info =
{
//! Size == sizeof(NVM_Info_T)
.Size = 4,
.EE_Address = 8,
.EE_CRC_Address = 12,
.Value = (uint8_t *)&RAM_Info,
.Default = (uint8_t *)&DEFAULT_Info,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Hardware_Settings_T RAM_Hardware_Settings;
static const NVM_Hardware_Settings_T DEFAULT_Hardware_Settings =
{
//! Color order for the barrel Neopixels.
.Barrel_Color_Order = 2,
//! Color order for the receiver NeoPixels.
.Receiver_Color_Order = 0,
//! Color order for the display NeoPixels.
.Display_Color_Order = 2,
//! Color order for the effects NeoPixels.
.Effects_Color_Order = 2,
//! true if this unit is configured for a right-handed person; false if for a left-handed person.
.Is_Right_Handed = true,
//! Audio volume.
.Volume = 20,
};
NVM_EEPROMEntry_T NVM_Hardware_Settings =
{
//! Size == sizeof(NVM_Hardware_Settings_T)
.Size = 6,
.EE_Address = 14,
.EE_CRC_Address = 20,
.Value = (uint8_t *)&RAM_Hardware_Settings,
.Default = (uint8_t *)&DEFAULT_Hardware_Settings,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Game_Settings_T RAM_Game_Settings;
static const NVM_Game_Settings_T DEFAULT_Game_Settings =
{
//! Selected weapon.
.Weapon_ID = LASER_X_ID,
//! Player identification (is this used?)
.Player_ID = 0,
//! Selected team.
.Team_ID = 1,
};
NVM_EEPROMEntry_T NVM_Game_Settings =
{
//! Size == sizeof(NVM_Game_Settings_T)
.Size = 3,
.EE_Address = 22,
.EE_CRC_Address = 25,
.Value = (uint8_t *)&RAM_Game_Settings,
.Default = (uint8_t *)&DEFAULT_Game_Settings,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Hourmeter_T RAM_Hourmeter;
static const NVM_Hourmeter_T DEFAULT_Hourmeter =
{
//! Total number of startups for this unit.
.Hourmeter_Startups = 0,
};
NVM_EEPROMEntry_T NVM_Hourmeter =
{
//! Size == sizeof(NVM_Hourmeter_T)
.Size = 2,
.EE_Address = 27,
.EE_CRC_Address = 29,
.Value = (uint8_t *)&RAM_Hourmeter,
.Default = (uint8_t *)&DEFAULT_Hourmeter,
.State = NVM_STATE_UNINITIALIZED
};
/** @} */
NVM_EEPROMEntry_T * const NVM_ExternalEEPROMEntries[] =
{
&NVM_External_Test,
&NVM_Info,
&NVM_Hardware_Settings,
&NVM_Game_Settings,
&NVM_Hourmeter,
};
//! Size of the #NVM_ExternalEEPROMEntries array (i.e. the number of External EEPROM entries).
const uint8_t NVM_N_EXTERNAL_EEPROM_ENTRIES = (uint8_t) (sizeof(NVM_ExternalEEPROMEntries) / sizeof(NVM_EEPROMEntry_T *));

View file

@ -0,0 +1,135 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file declares the External EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
#ifndef NVM_EXTERNALEEPROMENTRIES_H
#define NVM_EXTERNALEEPROMENTRIES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
typedef struct __attribute__((packed))
{
//! Test Code 3
uint16_t External_Test_3;
//! Test Code 4
uint32_t External_Test_4;
} NVM_External_Test_T;
typedef struct __attribute__((packed))
{
//! Date this unit was first programmed.
uint32_t Date_Code_as_YYYYMMDD;
} NVM_Info_T;
typedef struct __attribute__((packed))
{
//! Color order for the barrel Neopixels.
uint8_t Barrel_Color_Order;
//! Color order for the receiver NeoPixels.
uint8_t Receiver_Color_Order;
//! Color order for the display NeoPixels.
uint8_t Display_Color_Order;
//! Color order for the effects NeoPixels.
uint8_t Effects_Color_Order;
//! true if this unit is configured for a right-handed person; false if for a left-handed person.
bool Is_Right_Handed;
//! Audio volume.
uint8_t Volume;
} NVM_Hardware_Settings_T;
typedef struct __attribute__((packed))
{
//! Selected weapon.
uint8_t Weapon_ID;
//! Player identification (is this used?)
uint8_t Player_ID;
//! Selected team.
uint8_t Team_ID;
} NVM_Game_Settings_T;
typedef struct __attribute__((packed))
{
//! Total number of startups for this unit.
uint16_t Hourmeter_Startups;
} NVM_Hourmeter_T;
/* Include Files */
/* Public Variables */
extern NVM_EEPROMEntry_T NVM_External_Test;
extern NVM_EEPROMEntry_T NVM_Info;
extern NVM_EEPROMEntry_T NVM_Hardware_Settings;
extern NVM_EEPROMEntry_T NVM_Game_Settings;
extern NVM_EEPROMEntry_T NVM_Hourmeter;
extern NVM_EEPROMEntry_T * const NVM_ExternalEEPROMEntries[];
extern const uint8_t NVM_N_EXTERNAL_EEPROM_ENTRIES;
// Shorthand macros, to save you time.
#define NVM_EXTERNAL_TEST_3 (((NVM_External_Test_T*)NVM_External_Test.Value)->External_Test_3)
#define NVM_EXTERNAL_TEST_3_ENTRY_PTR (&NVM_External_Test)
#define NVM_EXTERNAL_TEST_4 (((NVM_External_Test_T*)NVM_External_Test.Value)->External_Test_4)
#define NVM_EXTERNAL_TEST_4_ENTRY_PTR (&NVM_External_Test)
#define NVM_DATE_CODE_AS_YYYYMMDD (((NVM_Info_T*)NVM_Info.Value)->Date_Code_as_YYYYMMDD)
#define NVM_DATE_CODE_AS_YYYYMMDD_ENTRY_PTR (&NVM_Info)
#define NVM_BARREL_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Barrel_Color_Order)
#define NVM_BARREL_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_RECEIVER_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Receiver_Color_Order)
#define NVM_RECEIVER_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_DISPLAY_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Display_Color_Order)
#define NVM_DISPLAY_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_EFFECTS_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Effects_Color_Order)
#define NVM_EFFECTS_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_IS_RIGHT_HANDED (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Is_Right_Handed)
#define NVM_IS_RIGHT_HANDED_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_VOLUME (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Volume)
#define NVM_VOLUME_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_WEAPON_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Weapon_ID)
#define NVM_WEAPON_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_PLAYER_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Player_ID)
#define NVM_PLAYER_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_TEAM_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Team_ID)
#define NVM_TEAM_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_HOURMETER_STARTUPS (((NVM_Hourmeter_T*)NVM_Hourmeter.Value)->Hourmeter_Startups)
#define NVM_HOURMETER_STARTUPS_ENTRY_PTR (&NVM_Hourmeter)
#ifdef __cplusplus
}
#endif
#endif // NVM_EXTERNALEEPROMENTRIES_H

View file

@ -0,0 +1,260 @@
/** \file
* \brief This file contains functions that manage the on-chip EEPROM.
*
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/* External Variables [Only if necessary!] */
/* External Function Prototypes [Only if necessary!] */
/* Public Variables */
//! Mutex controlling access to the EEPROM to ensure data/CRC integrity.
SemaphoreHandle_t xSemaphoreOnChipEEPROMLock;
TaskHandle_t NVM_OnChipEEPROM_Task_Handle;
volatile bool NVM_IsOnChipEEPROMInitialized = false;
/* Private Variables */
static QueueHandle_t xQueueOnChipEEPROM;
#if CY_PSOC4
const uint8_t Emulated_EEPROM_Storage[On_Chip_Emulated_EEPROM_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
#endif // CY_PSOC4
/* Private Function Prototypes */
/* Inline Functions */
#if CY_PSOC4
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
On_Chip_Emulated_EEPROM_Read(source, destination, n);
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
On_Chip_Emulated_EEPROM_Write(destination, source, n);
}
#endif // CY_PSOC4
#if CY_PSOC5
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
for (uint_fast16_t i = 0; i < n; i++)
{
uint8_t temp = On_Chip_EEPROM_ReadByte(source + i);
*(destination + i) = temp;
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
for (uint_fast16_t i = 0; i < n; i++)
{
On_Chip_EEPROM_WriteByte(*(source + i), destination + i);
}
}
#endif // CY_PSOC5
#if CY_PSOC6
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
cy_en_em_eeprom_status_t result = On_Chip_EEPROM_Read(source, destination, n);
if (result != CY_EM_EEPROM_SUCCESS)
{
CY_ASSERT(0);
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
cy_en_em_eeprom_status_t result = On_Chip_EEPROM_Write(destination, source, n);
if (result != CY_EM_EEPROM_SUCCESS)
{
CY_ASSERT(0);
}
}
#endif // CY_PSOC6
/* Public Functions */
//! Sets up the on-chip EEPROM, but does not read from it (yet).
void NVM_InitOnChipEEPROM(void)
{
/// Create a mutex-type semaphore.
xSemaphoreOnChipEEPROMLock = xSemaphoreCreateMutex();
if (xSemaphoreOnChipEEPROMLock == NULL)
{
CY_ASSERT(0);
}
xQueueOnChipEEPROM = xQueueCreate(5, sizeof(uint8_t));
#if CY_PSOC4
On_Chip_Emulated_EEPROM_Init((uint32_t)Emulated_EEPROM_Storage);
#endif // CY_PSOC4
#if CY_PSOC5
On_Chip_EEPROM_Start();
#endif // CY_PSOC5
#if CY_PSOC6
// From the docs: "For PSoC 6, if Emulated EEPROM is selected for EEPROM storage, the start address will be
// overwritten to some address from Emulated EEPROM flash area."
On_Chip_EEPROM_Init(0);
#endif // CY_PSOC6
}
//! Handles the ongoing on-chip EEPROM tasks.
/*!
* First, it loops through all the on-chip EEPROM entries, and reads them in to RAM.
* Then, it priodically loops through all the on-chip EEPROM entries, and saves the ones that have been flagged.
*/
void NVM_OnChipEEPROMTask(void * pvParameters)
{
portBASE_TYPE xStatus;
static TickType_t xTicksToWait = pdMS_TO_TICKS(NVM_ON_CHIP_EEPROM_TASK_RATE_IN_ms);
for (uint8_t i = 0; i < NVM_N_ONCHIP_EEPROM_ENTRIES; i++)
{
NVM_CRC_t calculated_crc;
NVM_CRC_t stored_crc = 0;
EEPROM_read_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
EEPROM_read_block((uint8_t *)&stored_crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(NVM_CRC_t));
calculated_crc = NVM_CRC_init();
calculated_crc = NVM_CRC_update(calculated_crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
calculated_crc = NVM_CRC_finalize(calculated_crc);
if (calculated_crc == stored_crc)
{
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
}
else
{
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_CRC_FAILED;
COMM_Console_Print_String("[NVMOn ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Calculated/Stored CRCs: ");
COMM_Console_Print_UInt16((uint16_t) calculated_crc);
COMM_Console_Print_String("/");
COMM_Console_Print_UInt16((uint16_t) stored_crc);
COMM_Console_Print_String("\n");
COMM_Console_Print_String("[NVMOn ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Applying defaults.\n");
memcpy(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Default, NVM_OnChipEEPROMEntries[i]->Size);
// Auto-fix the CRC.
NVM_SaveOnChipEEPROMEntry(NVM_OnChipEEPROMEntries[i]);
}
}
taskENTER_CRITICAL();
NVM_IsOnChipEEPROMInitialized = true;
taskEXIT_CRITICAL();
while(true)
{
uint8_t dummy;
// Wait for a call to NVM_SaveOnChipEEPROMEntry().
xStatus = xQueueReceive(xQueueOnChipEEPROM, &dummy, xTicksToWait);
if (xStatus == pdPASS)
{
for (uint8_t i = 0; i < NVM_N_ONCHIP_EEPROM_ENTRIES; i++)
{
NVM_CRC_t crc;
#if (defined CY_PSOC4) || (defined CY_PSOC6)
if (NVM_OnChipEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
EEPROM_write_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
}
}
#endif // (defined CY_PSOC4) || (defined CY_PSOC6)
#if CY_PSOC5
// From the component datasheet:
// "[On_Chip_EEPROM_UpdateTemperature()] updates the store temperature value. This should
// be called anytime the EEPROM is active and temperature may have changed by more than
// 10°C."
if (On_Chip_EEPROM_UpdateTemperature() == CYRET_SUCCESS)
{
if (NVM_OnChipEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (On_Chip_EEPROM_Query() == CYRET_SUCCESS)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
EEPROM_write_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
}
}
}
}
else
{
vSerialPutString("ERROR: Couldn't update EEPROM temperature!", 80);
}
#endif // CY_PSOC5
}
}
}
}
//! Flags the given on-chip EEPROM entry to be saved next time the NVM_OnChipEEPROMTask() is run.
void NVM_SaveOnChipEEPROMEntry(NVM_EEPROMEntry_T * const this)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
this->State = NVM_STATE_SAVE_REQUESTED;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
uint8_t dummy = 0;
xQueueSend(xQueueOnChipEEPROM, &dummy, 0);
}
}
/* Private Functions */

View file

@ -0,0 +1,42 @@
/** \file
* \brief This file contains the public interface to the on-chip EEPROM driver.
*
*/
#ifndef NVM_ONCHIPEEPROM_H
#define NVM_ONCHIPEEPROM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define NVM_ON_CHIP_EEPROM_TASK_STACK_SIZE_in_bytes 256
//! The time between calls to NVM_OnChipEEPROMTask().
#define NVM_ON_CHIP_EEPROM_TASK_RATE_IN_ms 2000
/* Include Files */
/* Public Variables */
extern SemaphoreHandle_t xSemaphoreOnChipEEPROMLock;
//! Handle of the NVM_OnChipEEPROMTask() given when the task was created.
extern TaskHandle_t NVM_OnChipEEPROM_Task_Handle;
extern volatile bool NVM_IsOnChipEEPROMInitialized;
/* Public Functions */
void NVM_InitOnChipEEPROM(void);
void NVM_OnChipEEPROMTask(void * pvParameters);
void NVM_SaveOnChipEEPROMEntry(NVM_EEPROMEntry_T * const this);
/* Inline Functions */
#ifdef __cplusplus
}
#endif
#endif // NVM_ONCHIPEEPROM_H

View file

@ -0,0 +1,63 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file defines the OnChip EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
/* Include Files */
#include "KTag.h"
/* EEPROM Entries */
/** \defgroup NVM_ONCHIP_EEPROM NVM OnChip EEPROM
*
* The OnChip EEPROM is divided into logical "entries", represented by instances of the #NVM_EEPROMEntry_T type.
* At startup, these entries are loaded into their respective RAM copies by NVM_InitOnChipEEPROM(). The application
* then updates the RAM copies directly, and requests that the NVM_OnChipEEPROMTask() save these back to the EEPROM
* when necessary.
* @{ */
static NVM_OnChip_Test_T RAM_OnChip_Test;
static const NVM_OnChip_Test_T DEFAULT_OnChip_Test =
{
//! Test Code 1
.OnChip_Test_1 = UINT16_MAX,
//! Test Code 2
.OnChip_Test_2 = UINT32_MAX,
};
NVM_EEPROMEntry_T NVM_OnChip_Test =
{
//! Size == sizeof(NVM_OnChip_Test_T)
.Size = 6,
.EE_Address = 0,
.EE_CRC_Address = 6,
.Value = (uint8_t *)&RAM_OnChip_Test,
.Default = (uint8_t *)&DEFAULT_OnChip_Test,
.State = NVM_STATE_UNINITIALIZED
};
/** @} */
NVM_EEPROMEntry_T * const NVM_OnChipEEPROMEntries[] =
{
&NVM_OnChip_Test,
};
//! Size of the #NVM_OnChipEEPROMEntries array (i.e. the number of OnChip EEPROM entries).
const uint8_t NVM_N_ONCHIP_EEPROM_ENTRIES = (uint8_t) (sizeof(NVM_OnChipEEPROMEntries) / sizeof(NVM_EEPROMEntry_T *));

View file

@ -0,0 +1,60 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file declares the OnChip EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
#ifndef NVM_ONCHIPEEPROMENTRIES_H
#define NVM_ONCHIPEEPROMENTRIES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
typedef struct __attribute__((packed))
{
//! Test Code 1
uint16_t OnChip_Test_1;
//! Test Code 2
uint32_t OnChip_Test_2;
} NVM_OnChip_Test_T;
/* Include Files */
/* Public Variables */
extern NVM_EEPROMEntry_T NVM_OnChip_Test;
extern NVM_EEPROMEntry_T * const NVM_OnChipEEPROMEntries[];
extern const uint8_t NVM_N_ONCHIP_EEPROM_ENTRIES;
// Shorthand macros, to save you time.
#define NVM_ONCHIP_TEST_1 (((NVM_OnChip_Test_T*)NVM_OnChip_Test.Value)->OnChip_Test_1)
#define NVM_ONCHIP_TEST_1_ENTRY_PTR (&NVM_OnChip_Test)
#define NVM_ONCHIP_TEST_2 (((NVM_OnChip_Test_T*)NVM_OnChip_Test.Value)->OnChip_Test_2)
#define NVM_ONCHIP_TEST_2_ENTRY_PTR (&NVM_OnChip_Test)
#ifdef __cplusplus
}
#endif
#endif // NVM_ONCHIPEEPROMENTRIES_H

View file

@ -0,0 +1,125 @@
/** \file
* \brief This file contains functions that implement the settings interface for SystemK.
*
*/
/* Include Files */
#include "KTag.h"
SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t * value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
*value = NVM_IS_RIGHT_HANDED;
break;
case SYSTEMK_SETTING_AUDIO_VOLUME:
*value = NVM_VOLUME;
break;
case SYSTEMK_SETTING_TEAMID:
*value = NVM_TEAM_ID;
break;
case SYSTEMK_SETTING_PLAYERID:
*value = NVM_PLAYER_ID;
break;
case SYSTEMK_SETTING_WEAPONID:
*value = NVM_WEAPON_ID;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
NVM_IS_RIGHT_HANDED = value;
break;
case SYSTEMK_SETTING_AUDIO_VOLUME:
NVM_VOLUME = value;
break;
case SYSTEMK_SETTING_TEAMID:
NVM_TEAM_ID = value;
break;
case SYSTEMK_SETTING_PLAYERID:
NVM_PLAYER_ID = value;
break;
case SYSTEMK_SETTING_WEAPONID:
NVM_WEAPON_ID = value;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t * value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_T_START_GAME_in_ms:
*value = CONFIG_KTAG_T_DEFAULT_START_GAME_in_ms;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_T_START_GAME_in_ms:
result = SYSTEMK_RESULT_NOT_IMPLEMENTED;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_Save(void)
{
#if (CONFIG__HAS_EXTERNAL_NVM)
NVM_SaveExternalEEPROMEntry(&NVM_Hardware_Settings);
NVM_SaveExternalEEPROMEntry(&NVM_Game_Settings);
#else // CONFIG__HAS_EXTERNAL_NVM
NVM_SaveOnChipEEPROMEntry(&NVM_Hardware_Settings);
NVM_SaveOnChipEEPROMEntry(&NVM_Game_Settings);
#endif // CONFIG__HAS_EXTERNAL_NVM
return SYSTEMK_RESULT_SUCCESS;
}