Files
RP2350_MIDI_Lighter/Firmware/EEPROM_M24C64.c
Chris 89c875e38f - First complete version of firmware. Currently being tested in the rehearsal room
- Added bunch of screens, fonts and images
 - Added script to read out frame buffer (function currently disabled in Firmware)
2025-10-26 20:57:58 +01:00

239 lines
7.7 KiB
C

/*
* EEPROM_M24C64.c
*
* Created: Fri Dec 24 2021 12:24:26
* Author Chris
*/
// ============================================================================================
// Includes
#include "EEPROM_M24C64.h"
#include "I2C_Master.h"
#include "Hue.h"
#include "MIDI_Note_List.h"
// ============================================================================================
// Defines
#define EEPROM_I2C_ADDRESS 0b1010000
#define EEPROM_PAGE_SIZE 32
#define EEPROM_CONTENT_SIZE sizeof(EEPROM_Content_t)
#define EEPROM_READ_WRITE_STEPS (EEPROM_CONTENT_SIZE / EEPROM_PAGE_SIZE) + 1
// ============================================================================================
// Variables
volatile EEPROM_Content_t _EEPROM_Content;
volatile bool _Update_Triggered;
volatile uint8_t _Write_Status;
volatile uint _Read_Write_Counter;
// ============================================================================================
// Function Declarations
void EEPROM_Read_Data();
bool EEPROM_Write_Data(uint section);
void EEPROM_Check_Content_Valid();
/*******************************************************************
Interrupt Service Routines
*******************************************************************/
/*******************************************************************
Functions
*******************************************************************/
void EEPROM_Init(void)
{
_Update_Triggered = false;
_Write_Status = EEPROM_STATUS_NONE;
_Read_Write_Counter = 0;
EEPROM_Read_Data();
EEPROM_Check_Content_Valid();
}
void EEPROM_Tick(void)
{
if(_Update_Triggered == true) {
// Wait 1ms to let other I2C traffic to be completed
sleep_ms(1);
EEPROM_Write_Data(_Read_Write_Counter);
_Read_Write_Counter++;
if(_Read_Write_Counter == EEPROM_READ_WRITE_STEPS) {
_Update_Triggered = false;
}
}
}
void EEPROM_Trigger_Update()
{
_Read_Write_Counter = 0;
_Update_Triggered = true;
}
uint8_t EEPROM_Get_Write_Status()
{
uint8_t Return_Value = _Write_Status;
_Write_Status = EEPROM_STATUS_NONE;
return Return_Value;
}
uint EEPROM_Get_Content_Size()
{
return EEPROM_CONTENT_SIZE;
}
uint EEPROM_Get_Read_Write_Steps()
{
return EEPROM_READ_WRITE_STEPS;
}
/*******************************************************************
Internal Functions
*******************************************************************/
void EEPROM_Read_Data(void)
{
for(uint i=0;i<EEPROM_READ_WRITE_STEPS;i++)
{
uint16_t EEPROM_Read_Address = i * EEPROM_PAGE_SIZE;
uint8_t* Read_Address = ((uint8_t*)&_EEPROM_Content) + i * EEPROM_PAGE_SIZE;
uint8_t Read_Size = EEPROM_CONTENT_SIZE - i * EEPROM_PAGE_SIZE;
if(Read_Size > EEPROM_PAGE_SIZE) {
Read_Size = EEPROM_PAGE_SIZE;
}
I2CM_Packet_Receive(EEPROM_I2C_ADDRESS, EEPROM_Read_Address, sizeof(EEPROM_Read_Address), Read_Address, Read_Size);
}
}
bool EEPROM_Write_Data(uint section)
{
uint16_t EEPROM_Write_Address = section * EEPROM_PAGE_SIZE;
uint8_t* Write_Address = ((uint8_t*)&_EEPROM_Content) + section * EEPROM_PAGE_SIZE;
uint8_t Write_Size = EEPROM_CONTENT_SIZE - section * EEPROM_PAGE_SIZE;
if(Write_Size > EEPROM_PAGE_SIZE) {
Write_Size = EEPROM_PAGE_SIZE;
}
int Bytes_Written = I2CM_Packet_Transmit(EEPROM_I2C_ADDRESS, EEPROM_Write_Address, sizeof(EEPROM_Write_Address), Write_Address, Write_Size);
if(Bytes_Written == sizeof(EEPROM_Write_Address) + Write_Size) {
_Write_Status = EEPROM_STATUS_WRITE_OK;
return true;
}
_Write_Status = EEPROM_STATUS_WRITE_FAILED;
return false;
}
void EEPROM_Check_Content_Valid()
{
if((uint32_t)_EEPROM_Content.Device_Configuration.Idle_Screen > IDLE_SCREEN_MODE_ACTIVITY) {
_EEPROM_Content.Device_Configuration.Idle_Screen = IDLE_SCREEN_BLACK;
}
if(_EEPROM_Content.Device_Configuration.Screen_Timeout > SCREEN_TIMEOUT_MAX_s) {
_EEPROM_Content.Device_Configuration.Screen_Timeout = SCREEN_TIMEOUT_MAX_s;
}
if(_EEPROM_Content.Device_Configuration.Screen_Timeout < SCREEN_TIMEOUT_MIN_s) {
_EEPROM_Content.Device_Configuration.Screen_Timeout = SCREEN_TIMEOUT_MIN_s;
}
if((uint32_t)_EEPROM_Content.Device_Configuration.Reverse_List_Scrolling > 1) {
_EEPROM_Content.Device_Configuration.Reverse_List_Scrolling = 1;
}
if((uint32_t)_EEPROM_Content.Device_Configuration.Use_Color_Correction > 1) {
_EEPROM_Content.Device_Configuration.Use_Color_Correction = 1;
}
if((uint32_t)_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].MIDI_Channel > MIDI_CHANNEL_16) {
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].MIDI_Channel = MIDI_CHANNEL_1;
}
if( _EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Octave > _MIDI_Note_List[MIDI_NOTE_LIST_LENGTH-1].Octave ||
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Octave < _MIDI_Note_List[0].Octave) {
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Octave = _MIDI_Note_List[0].Octave;
}
// Note Colors no need, as full range of UINT8 is valid
if((uint32_t)_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Skip_Note_Off_Event > 1) {
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Skip_Note_Off_Event = 1;
}
if((uint32_t)_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Note_Reset_Enabled > 1) {
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Note_Reset_Enabled = 1;
}
if((uint32_t)_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Note_Reset_Timeout > 600) {
_EEPROM_Content.Channel_MIDI_Configuration[LED_Channel_1].Note_Reset_Timeout = 600;
}
if((uint32_t)_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Enabled > 1) {
_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Enabled = 1;
}
// Pause Light Color no need, as full range of UINT8 is valid
if((uint32_t)_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Timeout > PAUSE_LIGHT_DELAY_MAX_s) {
_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Timeout = PAUSE_LIGHT_DELAY_MIN_s;
}
if((uint32_t)_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Reset_Condition > CHANNEL_AND_EVENT_MATCH) {
_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Reset_Condition = ANY_TRAFFIC;
}
if((uint32_t)_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Fade_Speed > FADE_SPEED_MAX) {
_EEPROM_Content.Pause_Light_Configuration[LED_Channel_1].Fade_Speed = FADE_SPEED_MIN;
}
// Pause Light Timer and Active no need here
// Note Stack Enabled no need, as bool is compared with equal to 0
if((uint32_t)_EEPROM_Content.Jam_Light_Configuration.Durations.Max > DURATION_MAX_s) {
_EEPROM_Content.Jam_Light_Configuration.Durations.Max = DURATION_MAX_s;
}
if((uint32_t)_EEPROM_Content.Jam_Light_Configuration.Durations.Min > _EEPROM_Content.Jam_Light_Configuration.Durations.Max || _EEPROM_Content.Jam_Light_Configuration.Durations.Min < DURATION_MIN_s) {
_EEPROM_Content.Jam_Light_Configuration.Durations.Min = DURATION_MIN_s;
}
if(_EEPROM_Content.Jam_Light_Configuration.Durations.Max <= _EEPROM_Content.Jam_Light_Configuration.Durations.Min) {
_EEPROM_Content.Jam_Light_Configuration.Durations.Max = DURATION_MAX_s;
}
while(_EEPROM_Content.Jam_Light_Configuration.Hue_Angle_Start_Color < 0) {
_EEPROM_Content.Jam_Light_Configuration.Hue_Angle_Start_Color += HUE_MAX_ANGLE;
}
_EEPROM_Content.Jam_Light_Configuration.Hue_Angle_Start_Color %= HUE_MAX_ANGLE;
if((uint32_t)_EEPROM_Content.Jam_Light_Configuration.Color_Change > COLOR_CHANGE_MAX) {
_EEPROM_Content.Jam_Light_Configuration.Color_Change = COLOR_CHANGE_MIN;
}
if((uint32_t)_EEPROM_Content.Jam_Light_Configuration.Fade_Speed > FADE_SPEED_MAX) {
_EEPROM_Content.Jam_Light_Configuration.Fade_Speed = FADE_SPEED_MIN;
}
// Const Color no need, as full range of UINT8 is valid
if((uint32_t)_EEPROM_Content.Const_Light_Configuration.Fade_Speed > FADE_SPEED_MAX) {
_EEPROM_Content.Const_Light_Configuration.Fade_Speed = FADE_SPEED_MIN;
}
}