diff --git a/due_obd2/due_obd2.ino b/due_obd2/due_obd2.ino index d838457..712f91a 100644 --- a/due_obd2/due_obd2.ino +++ b/due_obd2/due_obd2.ino @@ -28,32 +28,112 @@ extern uint8_t SmallFont[]; char should_clear = 1; char led_state = LOW; char flag = 0; +char counter_temp = 0; +char main_color = 0; +char init_text_i = 0; +int init_text_x = 100; +char init_text[] = "Initialising..."; +char text_temp[2] = {'a','\0'}; + +void on_init_enter(); +void on_init_run(); +void on_init_exit(); +void on_main_enter(); +void on_main_run(); +void __state_none(){ /* do nothing */} + +state_t init_state = + { + .id = STATE_INIT, + .next = STATE_CAR_INFO, + .on_enter = &on_init_enter, + .on_run = &on_init_run, + .on_exit = &on_init_exit}; + +state_t main_state = + { + .id = STATE_CAR_INFO, + .next = STATE_CAR_INFO, + .on_enter = &on_main_enter, + .on_run = &on_main_run, + .on_exit = &__state_none}; /* Set the pins for the display and dev board */ /* Standard Arduino Mega/Due shield : ,38,39,40,41 */ -UTFT display(ILI9486,38,39,40,41); +UTFT display(ILI9486, 38, 39, 40, 41); -void setup() { - randomSeed(analogRead(0)); +void on_init_enter() +{ + display.clrScr(); + Serial.println("Entering init state!"); +} - #if (DEBUG == 1) - Serial.begin(9600); - #endif - /* Serial1 is bluetooth module, pin 18 and 19. */ - Serial1.begin(115200); +void on_init_run() +{ + Serial.println("Running!"); + if (!flag) + { + flag = 1; + main_color = ~main_color; + // display.clrScr(); + if (main_color) + { + display.setColor(VGA_RED); + display.fillCircle(10,20,100); + } else + { + display.setColor(VGA_TEAL); + display.fillCircle(30,50,131); + } + display.setColor(VGA_AQUA); + display.setBackColor(0,0,0); + text_temp[0] = init_text[init_text_i]; + display.print(text_temp, init_text_x, LCD_H / 2); + init_text_x += display.getFontXsize(); + init_text_i++; + if (init_text_i > 14) + { + init_text_i = 0; + display.clrScr(); + } + } - /* Init display */ - display.InitLCD(); - display.setFont(BigFont); +} - #if (DEBUG == 1) - Serial.println("Starting"); - #endif +void on_init_exit() +{ + Serial.println("Exiting init state!"); + flag = 0; + main_color = 0; + display.clrScr(); +} - pinMode(LED_BUILTIN, OUTPUT); - - obd2_timer_init(); +void on_main_enter() +{ + obd2_timer_reset(); + Serial.println("Entering main loop"); + obd2_timer_set_period(800); +} +void on_main_run() +{ + if (!flag) + { + led_state = ~led_state; + digitalWrite(LED_BUILTIN, led_state); + flag = 1; + main_color = ~main_color; + if (main_color) + display.setColor(255, 0, 166); + else + display.setColor(78, 181, 72); + display.fillRect(LCD_W / 2 - 200, LCD_H / 2 - 100, LCD_W / 2 + 200, LCD_H / 2 + 100); + display.setColor(0, 247, 255); + display.print("OBD2 display yeet", CENTER, LCD_H / 2); +#if (DEBUG == 1) + Serial.println("switching led"); +#endif + } } void RTT_Handler() @@ -62,33 +142,60 @@ void RTT_Handler() obd2_timer_reset(); } -void loop() { - // put your main code here, to run repeatedly: - while (Serial1.available()) { - char rec = Serial1.read(); - #if (DEBUG == 1) - Serial.println(rec); - #endif - } +void setup() +{ + randomSeed(analogRead(0)); - if (should_clear) - { - display.clrScr(); - display.setColor(255, 0, 166); - display.fillRect(LCD_W/2-200,LCD_H/2-100,LCD_W/2+200,LCD_H/2+100); - display.setColor(0, 247, 255); - display.print("OBD2 display yeet",CENTER,LCD_H/2); - delay(10); - should_clear = 0; - } +#if (DEBUG == 1) + Serial.begin(9600); +#endif + /* Serial1 is bluetooth module, pin 18 and 19. */ + Serial1.begin(115200); - if (!flag) - { - led_state = ~led_state; - digitalWrite(LED_BUILTIN, led_state); - flag = 1; - #if (DEBUG == 1) - Serial.println("switching led"); - #endif - } + /* Init display */ + display.InitLCD(); + display.setFont(BigFont); + +#if (DEBUG == 1) + Serial.println("Starting"); +#endif + + pinMode(LED_BUILTIN, OUTPUT); + + obd2_timer_init(); + statemachine_register_state(&init_state, STATE_INIT); + statemachine_register_state(&main_state, STATE_CAR_INFO); + statemachine_init(); +} + +void loop() +{ + + statemachine_loop(); + + counter_temp++; + if (counter_temp == 50) + { + statemachine_next(); + } + + delay(100); + // while (Serial1.available()) + // { + // char rec = Serial1.read(); + // #if (DEBUG == 1) + // Serial.println(rec); + // #endif + // } + + // if (should_clear) + // { + // display.clrScr(); + // display.setColor(255, 0, 166); + // display.fillRect(LCD_W / 2 - 200, LCD_H / 2 - 100, LCD_W / 2 + 200, LCD_H / 2 + 100); + // display.setColor(0, 247, 255); + // display.print("OBD2 display yeet", CENTER, LCD_H / 2); + // delay(10); + // should_clear = 0; + // } } diff --git a/due_obd2/obd2_display.h b/due_obd2/obd2_display.h index 5c5a3a3..fe36be7 100644 --- a/due_obd2/obd2_display.h +++ b/due_obd2/obd2_display.h @@ -2,7 +2,8 @@ #define OBD2_DISPLAY_H #ifdef __cplusplus - extern "C" { +extern "C" +{ #endif /* display size */ diff --git a/due_obd2/obd2_timer.c b/due_obd2/obd2_timer.c index d5d7f67..6b05b16 100644 --- a/due_obd2/obd2_timer.c +++ b/due_obd2/obd2_timer.c @@ -1,23 +1,32 @@ +#include "sam3xa/include/sam3x8e.h" +#include "sam3xa/include/component/component_rtt.h" // #include "sam3xa/include/component/component_rtt.h" // #include "sam3xa/include/sam3x8e.h" #include "obd2_timer.h" void obd2_timer_init(void) { - /* enable the timer: reset the RTT, enable the alarm interrupt, set the prescaler value equal to the processor clock speed*/ - RTT->RTT_MR = RTT_MR_RTTRST | RTT_MR_ALMIEN | RTT_MR_RTPRES(32768/2); - /* set the alarm value to 0*/ - RTT->RTT_AR = 0; - /* enable the interrupt*/ - NVIC_EnableIRQ(RTT_IRQn); + /* enable the timer: reset the RTT + RTT->RTT_MR = RTT_MR_RTTRST; + /* set the alarm value to 0*/ + RTT->RTT_AR = 0; +} + +void obd2_timer_enable() +{ + /* enable the alarm interrupt*/ + RTT->RTT_MR |= RTT_MR_ALMIEN; + + /* enable the interrupt*/ + NVIC_EnableIRQ(RTT_IRQn); } void obd2_timer_reset() { - /* To prevent several executions of the interrupt handler, - the interrupt must be disabled in the interrupt handler - and re-enabled when the status register is cleared. - */ + /* To prevent several executions of the interrupt handler, + the interrupt must be disabled in the interrupt handler + and re-enabled when the status register is cleared. +*/ /* disable interrupts */ RTT->RTT_MR &= ~RTT_MR_ALMIEN; /* clear the status register (reading it clears it) @@ -30,5 +39,10 @@ void obd2_timer_reset() RTT->RTT_MR |= RTT_MR_ALMIEN; /* reset the RTT*/ RTT->RTT_MR |= RTT_MR_RTTRST; - +} + +void obd2_timer_set_period(__UINT32_TYPE__ period) +{ + /* set the prescaler value equal to the clock speed divided by how many milliseconds*/ + RTT->RTT_MR |= RTT_MR_RTPRES(CLOCK_FREQ / (1000/period)); } diff --git a/due_obd2/obd2_timer.h b/due_obd2/obd2_timer.h index 495181d..f8a34fe 100644 --- a/due_obd2/obd2_timer.h +++ b/due_obd2/obd2_timer.h @@ -1,7 +1,9 @@ #ifndef OBD2_TIMER_H +#define OBD2_TIMER_H #ifdef __cplusplus - extern "C" { +extern "C" +{ #endif #include "Arduino.h" @@ -10,6 +12,8 @@ void obd2_timer_init(); void obd2_timer_reset(); +void obd2_timer_enable(); +void obd2_timer_set_period(__UINT32_TYPE__ period); #ifdef __cplusplus } diff --git a/due_obd2/statemachine.c b/due_obd2/statemachine.c index 86bbb62..a3a8ea5 100644 --- a/due_obd2/statemachine.c +++ b/due_obd2/statemachine.c @@ -1,19 +1,60 @@ #include "statemachine.h" -state_t none_state = -{ - .id = 0, - .on_enter = &__state_none, - .on_run = &__state_none, - .on_exit = &__state_none, +int current_state_id = 0; +state_t states[STATE_AMOUNT] = {NULL, NULL}; +__UINT8_TYPE__ next = 0; +__UINT8_TYPE__ statemachine_register_state(state_t *state, int index) +{ + if (index >= STATE_AMOUNT) + { + return 0; + } + if (state->id != index) + { + return 0; + } + states[index] = *state; + return 1; } -statemachine_t statemachine = -{ - .current_state = -}; -void statemachine_init() +__UINT8_TYPE__ statemachine_init() { + for (int i = 0; i < STATE_AMOUNT; i++) + { + if (states[i].id < 0 || states[i].next < 0 || states[i].on_enter == NULL || states[i].on_run == NULL || states[i].on_exit == NULL) + { + return 0; + } + } + current_state_id = 0; + states[current_state_id].on_enter(); +} +void statemachine_loop() +{ + if (next) + { + next = 0; + + if (states[current_state_id].on_exit != NULL) + { + states[current_state_id].on_exit(); + } + if (states[current_state_id].next >= 0 && states[current_state_id].next != current_state_id) + { + current_state_id = states[current_state_id].next; + } + states[current_state_id].on_enter(); + } + + if (states[current_state_id].on_run != NULL) + { + states[current_state_id].on_run(); + } +} + +void statemachine_next() +{ + next = 1; } \ No newline at end of file diff --git a/due_obd2/statemachine.h b/due_obd2/statemachine.h index 57e2ab4..0bd97ea 100644 --- a/due_obd2/statemachine.h +++ b/due_obd2/statemachine.h @@ -1,11 +1,17 @@ #ifndef STATEMACHINE_H #define STATEMACHINE_H #ifdef __cplusplus - extern "C" { +extern "C" +{ #endif #include "Arduino.h" +#define STATE_INIT 0 +#define STATE_CAR_INFO 1 + +#define STATE_AMOUNT 2 /* change when more states are added */ + /* two displays: - initialisation display, shows the state of booting up - main display, shows the data from the OBD2 scanner @@ -16,44 +22,39 @@ /** * @brief State struct. Contains the id of the state, and the functions that are called when the state is entered, running and exited. -*/ + */ typedef struct SM_STATE { int id; + int next; void (*on_enter)(); void (*on_run)(); void (*on_exit)(); } state_t; -/** - * @brief Transition struct. Contains the id of the state it transitions to, and the next state. -*/ -typedef struct SM_TRANSITION -{ - int state_id; - state_t *next_state; -} transition_t; - -/** - * @brief State machine struct. Contains the current state and the transitions. -*/ -typedef struct SM_STATE_MACHINE -{ - state_t *current_state; - transition_t *transitions; /* Transitions between states. Every state's ID is also it's position in the array.*/ - -} statemachine_t; - /** * @brief Initialises the state machine. Initializes the statemachine struct. */ -void statemachine_init(); -void __state_none() -{ - /* do nothing*/ -} +__UINT8_TYPE__ statemachine_init(); +/** + * @brief Main loop of the state machine. executes the on_run function of the current state. + */ +void statemachine_loop(); + +/** + * @brief Changes the state of the state machine to the next state. Calls the exit function of the current state and the enter function of the next state. + */ +void statemachine_next(); + +/** + * @brief Registers a state in the state machine. + * @param state The state to add + * @param index The index of the state in the array. Must be the same as the id of the state. + * @return 1 if the state was added successfully, 0 if not. + */ +__UINT8_TYPE__ statemachine_register_state(state_t *state, int index); #ifdef __cplusplus - } - #endif +} +#endif #endif // !STATEMACHINE_H