/* * main.c * * Created: Mon Nov 08 2021 14:06:53 * Author Chris */ // ============================================================================================ // Includes #include #include #include "pico/stdlib.h" #include "Core1.h" #include "Core1_LED_Enable.h" #include "I2C_Master.h" #include "Command.h" #include "UI_Control.h" #include "Mode_Manager.h" #include "INA260.h" #include "Switch.h" #include "Screens.h" #include "EEPROM_M24C64.h" #include "Rotary_Encoder.h" #include "Display.h" #include "Display_SPI.h" #include "Display_Image.h" #include "Display_Default_Configurations.h" #include "USB_Serial.h" #include "Serial_Command.h" // ============================================================================================ // Defines #define LEDG_PIN 12 #define LEDG_CONFIG gpio_init(LEDG_PIN); gpio_set_dir(LEDG_PIN, GPIO_OUT) #define LEDG_ON gpio_put(LEDG_PIN, 0) #define LEDG_OFF gpio_put(LEDG_PIN, 1) #define LEDG_TOGGLE gpio_put(LEDG_PIN, !gpio_get(LEDG_PIN)) #define LEDG_ANIMATION_1 LEDG_ON; sleep_ms(100); LEDG_OFF; sleep_ms(100); #define LEDG_ANIMATION_3 LEDG_ANIMATION_1; LEDG_ANIMATION_1; LEDG_ANIMATION_1 #define LEDR_PIN 11 #define LEDR_CONFIG gpio_init(LEDR_PIN); gpio_set_dir(LEDR_PIN, GPIO_OUT) #define LEDR_ON gpio_put(LEDR_PIN, 0) #define LEDR_OFF gpio_put(LEDR_PIN, 1) #define LEDR_TOGGLE gpio_put(LEDR_PIN, !gpio_get(LEDR_PIN)) #define TRIGGER_PIN 18 #define TRIGGER_CONFIG gpio_init(TRIGGER_PIN); gpio_set_dir(TRIGGER_PIN, GPIO_OUT) #define TRIGGER_ON gpio_put(TRIGGER_PIN, 1) #define TRIGGER_OFF gpio_put(TRIGGER_PIN, 0) // ============================================================================================ // Variables static bool _Timer_Fired = false; static struct repeating_timer _Timer; extern uint16_t _Image_Power_Critical_32x32[]; extern uint16_t _Image_Power_Overvoltage_32x32[]; extern uint16_t _Image_Power_Undervoltage_32x32[]; extern uint16_t _Image_Power_Unplugged_32x32[]; extern uint16_t _Image_Overcurrent_32x32[]; static uint32_t _Idle_Counter; // ============================================================================================ // Function Declarations void Check_For_Serial_Input(void); void Parse_Command(void); void Serial_Send_Configuration_Text(void); void Serial_Send_Configuration_Hex(void); void Serial_Return_Ping(void); void Serial_Write_Configuration_Byte(void); void Serial_Save_To_EEPROM(void); void Display_Start_Buffer_Readout(void); /******************************************************************* Interrupt Service Routines *******************************************************************/ bool ISR_Repeating_Timer(struct repeating_timer *t) { LEDR_TOGGLE; _Timer_Fired = true; return true; } /******************************************************************* Main Routine *******************************************************************/ int main(void) { // LED ================================================= LEDG_CONFIG; LEDR_CONFIG; LEDR_OFF; LEDG_ANIMATION_3; // Trigger ================================================= TRIGGER_CONFIG; TRIGGER_OFF; // Serial Command ============================================= Serial_Command_Init(); // USB Serial ================================================= USB_Serial_Init(); // I2C Master ============================================= I2CM_Init(I2C_NO_INTERNAL_PULLUP); // EEPROM ================================================= EEPROM_Init(); // INA 260 ================================================= INA260_Init(); // Core 1 ================================================= multicore_launch_core1(Core1_Main); // Command ================================================= Command_Init(); // UI Control ================================================= UI_Control_Init(); // Display ================================================= Display_Init(DISPLAY_COLOR_BLACK, true, false); Screen_Setup_Loading(); // Screen_Setup_Menu_Main(TRANSITION_NONE, TRANSITION_NONE, LINEAR, 0, false, 3); // Rotary Encoder ============================================= Rotary_Encoder_Init(); // Switch ================================================= Switch_Init(SWITCH_NO_INTERNAL_PULLUP); // Mode Manager ============================================= Mode_Manager_Init(); // Repeating Timer ============================================= add_repeating_timer_ms(40, ISR_Repeating_Timer, NULL, &_Timer); _Idle_Counter = 0; while (1) { if (_Timer_Fired == true) { _Timer_Fired = false; Display_Send_Buffer(); Display_Inc_Frame_Counter(); Display_Screen_Transition_Tick(); _Screen_Tick(); UI_Control_Acceleration_Update(CURRENT_TIME_ms); INA260_Update_Current_Threshold(); INA260_Read_BusVoltage(); INA260_Read_Current(); Command_Issue_Set_Request(MULTICORE_COMMAND_SET_INA260_BUSVOLTAGE, 0, INA260_Get_BusVoltage_mV()); if(_EEPROM_Content.Device_Configuration.Screen_Timeout > 0) { if(_Idle_Counter >= _EEPROM_Content.Device_Configuration.Screen_Timeout * (1000 / 40)) { if(_Screen_Idle_Active != true) { Screen_Setup_Idle(TRANSITION_UP, TRANSITION_UP, SCREEN_TRANSITION_DEFAULT_EASING, SCREEN_TRANSITION_DEFAULT_FRAMES); } } else if(_Screen_Idle_Counter_Disable == false) { _Idle_Counter++; } else if(_Screen_Idle_Counter_Disable == true) { _Idle_Counter = 0; } } } // Add functions here to execute during the DMA Transfer if(Display_SPI_DMA_Transfer_Ongoing()) { } if(Display_Send_Buffer_Completed()) { TRIGGER_ON; Mode_Manager_Tick(); EEPROM_Tick(); Command_Issue_Get_Request(MULTICORE_COMMAND_GET_LED_POWER_ERROR, 0); Display_Render_Objects(); LED_Power_Error Error = Command_Get_Request_Response_By_Command_Only(MULTICORE_COMMAND_GET_LED_POWER_ERROR, 100); uint16_t *Image = NULL; switch (Error) { case BUS_NO_SUPPLY: Image = _Image_Power_Unplugged_32x32; break; case BUS_UNDERVOLTAGE: Image = _Image_Power_Undervoltage_32x32; break; case BUS_OVERVOLTAGE: Image = _Image_Power_Overvoltage_32x32; break; case BUS_VOLTAGE_MEASUREMENT: Image = _Image_Power_Critical_32x32; break; case OVERCURRENT: Image = _Image_Overcurrent_32x32; break; } if(Image != NULL && Display_Screen_Transition_Ongoing() == false) { Display_Image_Draw_Color(DISPLAY_X_CENTER + 50, 30, Image); } TRIGGER_OFF; } else { Serial_Command_Check_For_Input(); if(Rotary_Encoder_Rotation_CW_Occurred()) { _Idle_Counter = 0; Display_Action_CW(); } if(Rotary_Encoder_Rotation_CCW_Occurred()) { _Idle_Counter = 0; Display_Action_CCW(); } if(Rotary_Encoder_Switch_Press_Occurred()) { _Idle_Counter = 0; Display_Action_SW(); } if(Switch_Press_Occurred()) { if(_Screen_Idle_Active == false) { _Idle_Counter = 0; } Mode_Manager_Cycle_Mode(); } } } }