Skip to content
globals.c 4 KiB
Newer Older
laurentc's avatar
laurentc committed
#include "stm32f3xx_hal.h"
#include "led_driver.h"
#include "globals.h"


uint32_t gSecondCounter = 0;
//uint32_t g100usSecondCounter = 0;
float speedRPS = 0;
float l_offsetX = 0; // modulo NB_COLUMNS
float startTimeOffset = 0;
extern TIM_HandleTypeDef htim6;	
// timers

/*

 F303
 TIM2 (64Mhz,APB?) pour le DMA vers LEDs. Count to 25 pour 0.4s
 TIM6 (basic 64Mhz, APB?) pour mesures de dlai  100 microseconde prs, fait un tour par seconde, utilis pour la base de temps principale
 TIM7 (basic,64Mhz, APB?) pour mesures de dlai  la microseconde
 
 F446
 TIM8 (180Mhz,APB2) pour le DMA vers LEDs. Count to 71 pour 0.4s
 TIM7 (basic,90Mhz, APB1) pour mesures de dlai  la microseconde
 TIM3 (90Mhz,APB1) pour des dlais de 1 seconde (dtection ON/OFF tlcommande). Pas utilis je crois
 TIM6 (basic 90Mhz, APB1) pour mesures de dlai  100 microseconde prs, fait un tour par seconde, utilis pour la base de temps principale
 TIM6 prescaler 9000, counter period 10000-1
 
 F746
 TIM8 (108Mhz,APB2) pour le DMA vers LEDs. Count to 42 pour 0.4s
 TIM7 (basic,54Mhz, APB1) pour mesures de dlai  la microseconde
 TIM3 (54Mhz,APB1) pour des dlais de 1 seconde (dtection ON/OFF tlcommande). Pas utilis je crois
 TIM6 (basic 54Mhz, APB1) pour mesures de dlai  100 microseconde prs, fait un tour par seconde, utilis pour la base de temps principale
 TIM6 prescaler 9000, counter period 10000-1
 
*/

// TIM1,8,9,10,11 sont sur APB2 (180Mhz)
// TIM2,3,4,5,6,7,12,13,14 est sur APB1(slow, 90Mhz)

// Precision of time in sec in a single precision float
// after 16777216 sec (4600 hours) gives only integer precision (too bad)
// after 167772.16 sec (46 hours) less than 1/100sec precision. Should not go beyond.

float getTime(void)
{ 
	uint16_t time6;
	uint32_t l_SecondCounter;
	
//	HAL_TIM_Base_Stop(&htim6);
	TIM6->CR1 &= ~TIM_CR1_CEN;
	time6 = TIM6->CNT;
	l_SecondCounter = gSecondCounter;
//	HAL_TIM_Base_Start(&htim6);
	TIM6->CR1 |= TIM_CR1_CEN;
	return l_SecondCounter + time6*0.0001f;
}

void setOffsetX(float X)
{
	//puts back in [0..1[
	if (X<=-1)
		X = 0;
	else
	{
		if (X>=1)
			X = 0;
		else if (X<0)
			X+=1;
	}
	l_offsetX = X*NB_COLUMNS;
	startTimeOffset = getTime();
}

// This function is supposed to be called at least before each frame display
float updateOffsetX(float time)
{
	if (speedRPS==0)
	{
		startTimeOffset = time;
		return l_offsetX;
  }		
	
	l_offsetX = l_offsetX + (time-startTimeOffset)*speedRPS;
	
	while (l_offsetX>=NB_COLUMNS)
	{
		l_offsetX-=NB_COLUMNS;
	}
	while (l_offsetX<0)
	{
		l_offsetX+=NB_COLUMNS;
	}
	startTimeOffset = time;
	
	return l_offsetX;
}

void setSpeedRPS(float RPS, float time)
{
	updateOffsetX(time); // update position with previous speed just before changing it.
	if (RPS>1)
		RPS = 1;
	if (RPS<-1)
		RPS = -1;
	speedRPS = RPS*NB_COLUMNS;
}



	
//#define quickWaitXus(x) {TIM6->CNT = 0;while(TIM6->CNT<x);}

void waitBlocking(uint16_t x)
{
	TIM7->CNT = 0;	
	while (TIM7->CNT<x);
}


void myWait1ms(int dtms)
{
	int i;

	for (i=0;i<dtms;i++)
			waitBlocking(T1_0);
}


// fait clignoter la led RUN avec un code lisible
// led run == PB8
void crash(uint8_t crash_code)
{
	int i,j;

	for(i=0;i<20;i++)
	{
		RunLedOn();
		myWait1ms(40);
		RunLedOff();
		myWait1ms(20);
		RunLedOn();
		myWait1ms(40);
		RunLedOff();
		myWait1ms(400);

		for (j=0;j<8;j++)
		{
			if (crash_code & (1<<(7-j)))
			{
				RunLedOn();
			}
			// 100ms
			myWait1ms(100);
			RunLedOff();
			myWait1ms(400);
		}
	}
	HAL_NVIC_SystemReset();
}

/*
Dure du clignotement:1 seconde
Transition:4 fois/seconde : T=0.25s
*/
void clig(void)
{
	int i;
	for (i=0;i<2;i++)
	{
		RunLedOn();
		myWait1ms(250);
		RunLedOff();
		myWait1ms(250);
	}
}

/*
Dure du clignotement:1 secondes
Transition:20 fois/seconde : T=0.05s
*/
void cligFast(void)
{ 
	int i;
	for (i=0;i<20;i++)
	{
	RunLedOn();
	myWait1ms(50);
	RunLedOff();
	myWait1ms(50);
	}
}


uint16_t clamp(uint16_t x, uint16_t min, uint16_t max)
{
	if (x<min)
		return min;
	if (x>max)
		return max;
	return x;
}

float linear(float x, int x1, int x2, int y1, int y2)
{
	return y1 + (1.0f*y2-y1)/(x2-x1)*(x-x1);
}