/* ************************************* * Includes * *************************************/ #include "System.h" /* ************************************* * Defines * *************************************/ #define SYSTEM_MAX_TIMERS 8 #define check_bb_collision(x1,y1,w1,h1,x2,y2,w2,h2) (!( ((x1)>=(x2)+(w2)) || ((x2)>=(x1)+(w1)) || \ ((y1)>=(y2)+(h2)) || ((y2)>=(y1)+(h1)) )) /* ************************************* * Local Prototypes * *************************************/ //static void SystemCheckTimer(bool * timer, uint64_t * last_timer, uint8_t step); /* ************************************* * Local Variables * *************************************/ //Global timer (called by interrupt) static volatile uint64_t global_timer; //Tells whether rand seed has been set static bool rand_seed; //Timers static bool one_second_timer; static bool hundred_ms_timer; //Critical section is entered static bool system_busy; //Timer array static TYPE_TIMER timer_array[SYSTEM_MAX_TIMERS]; /* ************************************* * @name: void SystemInit(void) * @date: 19/05/2016 * @author: Xavier Del Campo * @brief: * *************************************/ void SystemInit(void) { //Reset global timer global_timer = 0; //Reset 1 second timer one_second_timer = 0; //Reset all user-handled timers SystemResetTimers(); //Initial value for system_busy system_busy = false; #if defined(USBCON) USBDevice.attach(); #endif } void SystemSetRandSeed(void) { if (rand_seed == false) { rand_seed = true; //Set random seed using global timer as reference srand((unsigned int)global_timer); } } bool SystemIsRandSeedSet(void) { return rand_seed; } void SystemIncreaseGlobalTimer(void) { global_timer++; } uint64_t SystemGetGlobalTimer(void) { return global_timer; } bool System1SecondTick(void) { return one_second_timer; } bool System100msTick(void) { return hundred_ms_timer; } void SystemRunTimers(void) { /* static uint64_t last_one_second_tick; static uint64_t last_100_ms_tick; SystemCheckTimer(&one_second_timer, &last_one_second_tick, REFRESH_FREQUENCY); SystemCheckTimer(&hundred_ms_timer, &last_100_ms_tick, 2); * */ } void SystemCheckTimer(bool * timer, uint64_t * last_timer, uint8_t step) { if (*timer == true) { *timer = false; *last_timer = global_timer; } if (global_timer >= (*last_timer + step) ) { *timer = true; } } void SystemWaitCycles(uint32_t cycles) { uint64_t currentTime = global_timer; while (global_timer < (currentTime + cycles) ); } uint32_t SystemRand(uint32_t min, uint32_t max) { return rand() % (max - min + 1) + min; } bool SystemIsBusy(void) { return system_busy; } bool SystemContains_u8(uint8_t value, uint8_t* buffer, size_t sz) { size_t i = 0; for (i = 0; i < sz; i++) { if (buffer[i] == value) { return true; } } return false; } bool SystemContains_u16(uint16_t value, uint16_t * buffer, size_t sz) { size_t i = 0; for (i = 0; i < sz; i++) { if (buffer[i] == value) { return true; } } return false; } TYPE_TIMER * SystemCreateTimer(uint32_t seconds, bool rf, void (*timer_callback)(void) ) { bool success = false; uint8_t i; if (seconds == 0) { return NULL; } for (i = 0; i < SYSTEM_MAX_TIMERS; i++) { if (timer_array[i].busy == false) { timer_array[i].Timeout_Callback = timer_callback; timer_array[i].time = seconds; timer_array[i].orig_time = seconds; timer_array[i].repeat_flag = rf; timer_array[i].busy = true; success = true; break; } } if (success == false) { return NULL; } return &timer_array[i]; } void SystemResetTimers(void) { uint8_t i; for (i = 0; i < SYSTEM_MAX_TIMERS; i++) { timer_array[i].Timeout_Callback = NULL; timer_array[i].busy = false; timer_array[i].repeat_flag = false; timer_array[i].time = 0; timer_array[i].orig_time = 0; } } void SystemUserTimersHandler(void) { uint8_t i; for (i = 0; i < SYSTEM_MAX_TIMERS; i++) { if (timer_array[i].busy == true) { if (System1SecondTick() == true) { timer_array[i].time--; if (timer_array[i].time == 0) { timer_array[i].Timeout_Callback(); if (timer_array[i].repeat_flag == true) { timer_array[i].time = timer_array[i].orig_time; } else { // Clean timer data timer_array[i].busy = false; timer_array[i].orig_time = 0; timer_array[i].Timeout_Callback = NULL; } } } } } } void SystemTimerRestart(TYPE_TIMER * timer) { timer->time = timer->orig_time; } void SystemTimerRemove(TYPE_TIMER * timer) { timer->time = 0; timer->orig_time = 0; timer->Timeout_Callback = NULL; timer->busy = false; timer->repeat_flag = false; } bool SystemArrayCompare(unsigned short * arr1, unsigned short * arr2, size_t sz) { size_t i; for (i = 0; i < sz; i++) { if (arr1[i] != arr2[i]) { return false; } } return true; } bool SystemCollisionCheck(TYPE_COLLISION_BLOCK c1, TYPE_COLLISION_BLOCK c2) { return (bool)check_bb_collision( c1.x, c1.y, c1.w, c1.h, c2.x, c2.y, c2.w, c2.h ); }