/* * 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_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(_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; } // Reverse Scrolling no need, as bool is compared with equal to 0 if(_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(_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; } // Pause Light Enabled no need, as bool is compared with equal to 0 // Pause Light Color no need, as full range of UINT8 is valid if(_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(_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(_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(_EEPROM_Content.Jam_Light_Configuration.Duration_Max_s > DURATION_MAX_s) { _EEPROM_Content.Jam_Light_Configuration.Duration_Max_s = DURATION_MAX_s; } if(_EEPROM_Content.Jam_Light_Configuration.Duration_Min_s > _EEPROM_Content.Jam_Light_Configuration.Duration_Max_s || _EEPROM_Content.Jam_Light_Configuration.Duration_Min_s < DURATION_MIN_s) { _EEPROM_Content.Jam_Light_Configuration.Duration_Min_s = DURATION_MIN_s; } if(_EEPROM_Content.Jam_Light_Configuration.Duration_Max_s <= _EEPROM_Content.Jam_Light_Configuration.Duration_Min_s) { _EEPROM_Content.Jam_Light_Configuration.Duration_Max_s = 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(_EEPROM_Content.Jam_Light_Configuration.Color_Change > COLOR_CHANGE_MAX) { _EEPROM_Content.Jam_Light_Configuration.Color_Change = COLOR_CHANGE_MIN; } if(_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(_EEPROM_Content.Const_Light_Configuration.Fade_Speed > FADE_SPEED_MAX) { _EEPROM_Content.Const_Light_Configuration.Fade_Speed = FADE_SPEED_MIN; } if(_EEPROM_Content.Device_Configuration.Transition_Type >= 0) { _EEPROM_Content.Device_Configuration.Transition_Type = 0; } if(_EEPROM_Content.Device_Configuration.Transition_Frames == 0) { _EEPROM_Content.Device_Configuration.Transition_Frames = 16; } }