279 lines
5.0 KiB
C
279 lines
5.0 KiB
C
/* *************************************
|
|
* 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 );
|
|
}
|