|
#include "include.h"
|
|
|
|
|
|
#define BUFFER_SIZE 256 // must be 2^n (8, 16, 32, 64 ...)
|
|
#define BUFFER_MASK (BUFFER_SIZE-1) //
|
|
Never forget parentheses
|
|
|
|
uint8 ui8_tx_buffer[BUFFER_SIZE];
|
|
uint8 ui8_tx_buffer_read = 0; // points to the field with the oldest content
|
|
uint8 ui8_tx_buffer_write = 0; // always points to an empty field
|
|
|
|
//doit etre de 2^n (8, 16, 32, 64 ...)
|
|
#define BUFFER_MASK (BUFER_SIZE-1) // Ne jamais oublier les parenth?ses
|
|
|
|
uint8 ui8_tx_buffer[BUFFER_SIZE];
|
|
uint8 ui8_tx_buffer_read = 0; // pointe vers le champ avec le contenu le plus ancien
|
|
uint8 ui8_tx_buffer_write = 0; // toujours sur un champ vide
|
|
|
|
//1000Byte buffer because sometimes SD-Card is very slow
|
|
uint8 ui8_buffer[1500];
|
|
uint16 ui16_free_space = 1500;
|
|
uint16 ui16_entry_pointer[MAX_QUEUE_ENTRIES];
|
|
uint8 ui8_entry_length[MAX_QUEUE_ENTRIES];
|
|
uint8 ui8_first_entry;
|
|
uint8 ui8_next_entry;
|
|
|
|
uint8 ui8_UART_sec;
|
|
uint8 ui8_UART_min;
|
|
uint8 ui8_UART_hrs;
|
|
uint8 ui8_UART_cnt = 0;
|
|
|
|
|
|
|
|
//****************** Timestamp **********************************
|
|
//max. 999 millisec, 999 microsec
|
|
void IncreaseTimestamp(uint16 millisec, uint16 microsec, uint16 nanosec)
|
|
{
|
|
s_Time.ui16_Time_nsec += nanosec;
|
|
s_Time.ui16_Time_usec += microsec;
|
|
s_Time.ui16_Time_msec += millisec;
|
|
|
|
if (s_Time.ui16_Time_nsec >= 1000)
|
|
{
|
|
s_Time.ui16_Time_usec++;
|
|
s_Time.ui16_Time_nsec -= 1000;
|
|
}
|
|
|
|
if (s_Time.ui16_Time_usec >= 1000)
|
|
{
|
|
s_Time.ui16_Time_msec++;
|
|
s_Time.ui16_Time_usec -= 1000;
|
|
}
|
|
|
|
if (s_Time.ui16_Time_msec >= 1000)
|
|
{
|
|
s_Time.ui8_Time_sec++;
|
|
s_Time.ui16_Time_msec -= 1000;
|
|
}
|
|
|
|
if (s_Time.ui8_Time_sec >= 60)
|
|
{
|
|
s_Time.ui8_Time_min++;
|
|
s_Time.ui8_Time_sec -= 60;
|
|
}
|
|
|
|
if (s_Time.ui8_Time_min >= 60)
|
|
{
|
|
s_Time.ui8_Time_hrs++;
|
|
s_Time.ui8_Time_min -= 60;
|
|
}
|
|
|
|
if (s_Time.ui8_Time_hrs >= 24)
|
|
{
|
|
s_Time.ui8_Time_hrs -= 24;
|
|
}
|
|
}
|
|
|
|
void set_Time(uint8 hrs, uint8 min, uint8 sec)
|
|
{
|
|
s_Time.ui16_Time_nsec = 0;
|
|
s_Time.ui16_Time_usec = 0;
|
|
s_Time.ui16_Time_msec = 0;
|
|
s_Time.ui8_Time_sec = sec;
|
|
s_Time.ui8_Time_min = min;
|
|
s_Time.ui8_Time_hrs = hrs;
|
|
}
|
|
|
|
void eep_set_Time(void)
|
|
{
|
|
ui16_EEPROM_Write(EEP_UI16_NANOSECONDS, s_Time.ui16_Time_nsec);
|
|
ui16_EEPROM_Write(EEP_UI16_MICROSECONDS, s_Time.ui16_Time_usec);
|
|
ui16_EEPROM_Write(EEP_UI16_MILLISECONDS, s_Time.ui16_Time_msec);
|
|
ui8_EEPROM_Write(EEP_UI8_SECONDS, s_Time.ui8_Time_sec);
|
|
ui8_EEPROM_Write(EEP_UI8_MINUTES, s_Time.ui8_Time_min);
|
|
ui8_EEPROM_Write(EEP_UI8_HOURS, s_Time.ui8_Time_hrs);
|
|
ui8_EEPROM_Write(EEP_UI8_TIMESET, 1);
|
|
delay_ms(10);
|
|
}
|
|
|
|
void eep_get_Time(void)
|
|
{
|
|
if (ui8_EEPROM_Read(EEP_UI8_TIMESET) == 1)
|
|
{
|
|
s_Time.ui16_Time_nsec = ui16_EEPROM_Read(EEP_UI16_NANOSECONDS);
|
|
s_Time.ui16_Time_usec = ui16_EEPROM_Read(EEP_UI16_MICROSECONDS);
|
|
s_Time.ui16_Time_msec = ui16_EEPROM_Read(EEP_UI16_MILLISECONDS);
|
|
s_Time.ui8_Time_sec = ui8_EEPROM_Read(EEP_UI8_SECONDS);
|
|
s_Time.ui8_Time_min = ui8_EEPROM_Read(EEP_UI8_MINUTES);
|
|
s_Time.ui8_Time_hrs = ui8_EEPROM_Read(EEP_UI8_HOURS);
|
|
delay_ms(10);
|
|
ui8_EEPROM_Write(EEP_UI8_TIMESET, 0);
|
|
IncreaseTimestamp(652, 0, 0);
|
|
}
|
|
|
|
#asm("sei")
|
|
}
|
|
|
|
void set_Time_from_UART(void)
|
|
{
|
|
char c;
|
|
c = getchar();
|
|
|
|
if (c == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (c < 48 || c > 58) //c is ASCII-Code, 0-9 = ASCII 48-57, : = ASCII 58
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_cnt++;
|
|
|
|
switch (ui8_UART_cnt)
|
|
{
|
|
case 1: //1st char of hours
|
|
if (c > 50)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_hrs = 10 * (c - 48);
|
|
break;
|
|
|
|
case 2: //2nd char of hours
|
|
if (ui8_UART_hrs > 10)
|
|
{
|
|
//first char of hour > 20 then 2nd can only be 0-4
|
|
if (c > 51)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//first char of hour < 20 then 2nd can be 0-9
|
|
if (c > 57)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
ui8_UART_hrs += (c - 48);
|
|
break;
|
|
|
|
case 3: //1st colon (:)
|
|
if (c != 58)
|
|
{
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
ui8_UART_cnt = 0;
|
|
return;
|
|
}
|
|
|
|
break;
|
|
|
|
case 4: //1st char of mins
|
|
if (c > 53)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_min = 10 * (c - 48);
|
|
break;
|
|
|
|
case 5: //2nd char of mins
|
|
if (c > 57)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_min += (c - 48);
|
|
break;
|
|
|
|
case 6: //2nd colon (:)
|
|
if (c != 58)
|
|
{
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
ui8_UART_cnt = 0;
|
|
return;
|
|
}
|
|
|
|
break;
|
|
|
|
case 7: //1st char of sec
|
|
if (c > 53)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_sec = 10 * (c - 48);
|
|
break;
|
|
|
|
case 8: //2nd char of sec
|
|
if (c > 57)
|
|
{
|
|
ui8_UART_cnt = 0;
|
|
|
|
while (getchar() != 0); //empty USART-Receiver-Buffer
|
|
|
|
printf("Please enter current time in 24h-format HH:MM:SS\r\n");
|
|
return;
|
|
}
|
|
|
|
ui8_UART_sec += (c - 48);
|
|
set_Time(ui8_UART_hrs, ui8_UART_min, ui8_UART_sec);
|
|
printf("Clock was set to: ");
|
|
PrintTimestamp(s_Time);
|
|
printf("\r\n");
|
|
ui8_UART_cnt = 0;
|
|
return;
|
|
break;
|
|
|
|
default:
|
|
ui8_UART_cnt = 0;
|
|
#asm("cli")
|
|
rx_counter_usarte0 = 0; //empty USART-Receiver-Buffer
|
|
#asm("sei")
|
|
return;
|
|
break;
|
|
}
|
|
|
|
set_Time_from_UART();
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* Brief calculate checksum
|
|
*
|
|
* This function calculates the checksum of any one
|
|
* Data packet. The checksum is the checksum, limited to 1 byte,
|
|
* returned.
|
|
*
|
|
* \ param p_data Pointer to the starting point of any data packet
|
|
* \ param ui8_size Length of the data packet
|
|
* \ return The determined checksum (checksum)
|
|
//calculer la somme ? payer
|
|
*
|
|
* Cette fonction calcule la somme de contr?le de n?importe quel
|
|
* Paquets de donn?es La somme de contr?le est limit?e ? 1 octet,
|
|
* rendu en retour.
|
|
*
|
|
* param p_data pointeur vers le point de d?part d?un paquet de donn?es quelconque
|
|
* paramui8_taille du paquet de donn?es
|
|
* Retour sur la somme de contr?le d?termin?e (total crois?)
|
|
*
|
|
*/
|
|
uint8 ui8_CalculateChecksum(void* p_data, uint8 ui8_size)
|
|
{
|
|
uint8 ui8_counter;
|
|
uint8 ui8_checksum = 0;
|
|
|
|
for (ui8_counter = 0; ui8_counter < ui8_size; ui8_counter++)
|
|
{
|
|
ui8_checksum += *((uint8*)p_data + ui8_counter);
|
|
}
|
|
|
|
return ui8_checksum;
|
|
}
|
|
|
|
/**
|
|
* \ brief hysteresis function
|
|
*
|
|
* This is a universal hysteresis function. Using the function parameters, a
|
|
* condition to be checked, a hysteresis variable and the maximum deceleration are specified. is
|
|
* the condition FALSE, the hysteresis variable is reduced by 1. If it reaches the value "0", see above
|
|
* "-1" is returned. If the condition is TRUE, the value of the variable is increased and at
|
|
* Reached the maximum delay "1" returned. As long as the value of the hysteresis variable
|
|
* between the limits, "0" is returned
|
|
*
|
|
* \ param ui8_condition The condition to be checked
|
|
* \ param p_ui8_delay_counter A uint8 pointer to a delay variable
|
|
* \ param ui8_hysteresis The maximum delay value
|
|
* \ return See above
|
|
*// Il s?agit d?une fonction d?hyst?r?sis universelle qui permet
|
|
* la condition ? v?rifier, une variable d?hyst?r?sis et la d?c?l?ration maximale sont indiqu?es
|
|
* la condition FALSE, la variable d?hyst?r?sis est r?duite de 1 et lorsqu?elle atteint la valeur "0",
|
|
* Renvoie "-1" Si la condition TRUE est remplie, la valeur de la variable est augment?e et
|
|
* R?alisation de la d?c?l?ration maximale "1" tant que la valeur de la variable d?hyst?r?sis
|
|
* situ?e entre les limites, est renvoy? "0"
|
|
*
|
|
* paramui8_condition La condition ? contr?ler
|
|
* param p_ui8_delay_counter Un uint8 vers une variable de retard
|
|
* paramui8_hyst?r?sis La valeur de retard maximale
|
|
*/
|
|
HysteresisStateEnum e_GetHysteresisState(uint8 ui8_condition, uint8* p_ui8_delay_counter, uint8 ui8_hysteresis)
|
|
{
|
|
if (ui8_condition)
|
|
{
|
|
if (*p_ui8_delay_counter < ui8_hysteresis)
|
|
{
|
|
(*p_ui8_delay_counter)++;
|
|
}
|
|
else
|
|
{
|
|
return UPPER_BOUNDARY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((*p_ui8_delay_counter) != 0)
|
|
{
|
|
(*p_ui8_delay_counter)--;
|
|
}
|
|
else
|
|
{
|
|
return LOWER_BOUNDARY;
|
|
}
|
|
}
|
|
|
|
return TRANSITION;
|
|
}
|
|
|
|
uint16 ui16_GetFreeQueueSpace()
|
|
{
|
|
return ui16_free_space;
|
|
}
|
|
|
|
uint8 ui8_BufferIn(uint8 ui8_data)
|
|
{
|
|
uint8 ui8_next;
|
|
// TX-Complete-Interrupt sperren
|
|
//UCSR0B = 0x08;
|
|
ui8_next = ((ui8_tx_buffer_write + 1) & BUFFER_MASK);
|
|
|
|
if (ui8_tx_buffer_read == ui8_next)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
ui8_tx_buffer[ui8_tx_buffer_write & BUFFER_MASK] = ui8_data;
|
|
ui8_tx_buffer_write = ui8_next;
|
|
// TX-Complete-Interrupt freigeben
|
|
//UCSR0B = 0x48;
|
|
return 1;
|
|
}
|
|
|
|
uint8 ui8_BufferOut(uint8* p_ui8_data)
|
|
{
|
|
if (ui8_tx_buffer_read == ui8_tx_buffer_write)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
*p_ui8_data = ui8_tx_buffer[ui8_tx_buffer_read];
|
|
ui8_tx_buffer_read = (ui8_tx_buffer_read + 1) & BUFFER_MASK;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* \ letter queue for any data // File d?attente de donn?es arbitraires
|
|
*
|
|
* \ param ui8_length Number of bytes to be transferred
|
|
* [0] The oldest entry is transferred to the output buffer
|
|
* [1-254] record length, at [3], p_data [0] -p_data [3] are queued
|
|
* [255] Oldest entry is marked as processed
|
|
* \ param p_data Pointer to the data stream
|
|
* \ return [QUEUE_OVERFLOW] Queue full
|
|
* [QUEUE_FILLED] Line filled
|
|
* [QUEUE_EMPTY] Queue empty - nothing to do
|
|
* [QUEUE_PROCESSED] queue entry processed, data was in the output buffer
|
|
* copied
|
|
*//Nombre d?octets ? transmettre
|
|
* [0] L?entr?e la plus ancienne est transmise au tampon de sortie
|
|
* [1-254] Longueur des enregistrements ? [3] mise en file d?attente, p_data[0]-p_data[3]
|
|
* [255] l?entr?e la plus ancienne est indiqu?e comme termin?e
|
|
* param p_data pointeur sur le flux de donn?es
|
|
* return [QUE_OVERFLOW] Serpent plein
|
|
* [QUE_FILED] Serpentin farci
|
|
* [QUE_EMPTY] File vide - ne rien faire
|
|
* [QUE_PROCESSED] entr?e de serpent trait?e, donn?es dans le tampon de sortie
|
|
* copi?
|
|
*/
|
|
QueueStatusEnum e_Queue(uint8 ui8_length, void* p_data)
|
|
{
|
|
//uint16 ui16_free_space;
|
|
|
|
// Puffer f?llen
|
|
if (ui8_length && (ui8_length != 255))
|
|
{
|
|
//maximum number of data records already exist
|
|
if (ui8_next_entry >= MAX_QUEUE_ENTRIES - 1)
|
|
{
|
|
printf("QUEUE_OVERFLOW 1");
|
|
return QUEUE_OVERFLOW;
|
|
}
|
|
|
|
ui16_free_space = sizeof(ui8_buffer);
|
|
ui16_free_space -= ui16_entry_pointer[ui8_next_entry];
|
|
|
|
//free space at the end of the buffer is sufficient// Espace libre ? la fin du tampon suffisant
|
|
if (ui16_free_space >= ui8_length)
|
|
{
|
|
ui8_entry_length[ui8_next_entry] = ui8_length;
|
|
memcpy(&ui8_buffer[ui16_entry_pointer[ui8_next_entry]], p_data, ui8_length);
|
|
ui8_next_entry++;
|
|
ui16_entry_pointer[ui8_next_entry] = ui16_entry_pointer[ui8_next_entry - 1] + ui8_length;
|
|
return QUEUE_FILLED;
|
|
}
|
|
// free space at the end of the buffer is insufficient// Espace libre ? la fin du tampon insuffisant
|
|
else
|
|
{
|
|
printf("QUEUE_OVERFLOW 2");
|
|
return QUEUE_OVERFLOW;
|
|
}
|
|
}
|
|
else if (ui8_length == 255)
|
|
{
|
|
// Oldest entry completed, then on to the next// l??l?ment le plus ancien est r?gl?, puis passe ? l??l?ment suivant
|
|
memset(&ui8_buffer[ui16_entry_pointer[ui8_first_entry]], 0x00, ui8_entry_length[ui8_first_entry]);
|
|
ui8_first_entry++;
|
|
}
|
|
else // process buffer //
|
|
{
|
|
// reached the end of the queue// Fin de la queue atteinte
|
|
if (ui8_first_entry == ui8_next_entry)
|
|
{
|
|
if (ui8_first_entry)
|
|
{
|
|
ui8_first_entry = 0;
|
|
ui8_next_entry = 0;
|
|
}
|
|
|
|
return QUEUE_EMPTY;
|
|
}
|
|
|
|
//Copy the queue entry to the output buffer //Copier l?entr?e en serpent dans le tampon de sortie
|
|
memcpy(p_data, &ui8_buffer[ui16_entry_pointer[ui8_first_entry]], ui8_entry_length[ui8_first_entry]);
|
|
return QUEUE_PROCESSED;
|
|
}
|
|
|
|
return QUEUE_IDLE;
|
|
}
|
|
|
|
|
|
void Handle_Message_Queue()
|
|
{
|
|
CCB_Message_t s_ccb_message;
|
|
DaliMessageStruct s_dali_message;
|
|
|
|
if (ui8_switch_state == SWITCH_SETTING_CCB)
|
|
{
|
|
if (e_Queue(0, &s_ccb_message) == QUEUE_PROCESSED)
|
|
{
|
|
e_Queue(255, &s_ccb_message);
|
|
|
|
if (eep_language == SETTING_GERMAN)
|
|
{
|
|
Ger_PrintCcbMessage(&s_ccb_message);
|
|
}
|
|
else if (eep_language == SETTING_FRANCE)
|
|
{
|
|
Fra_PrintCcbMessage(&s_ccb_message);
|
|
}
|
|
else
|
|
{
|
|
CCB_Print_Message(&s_ccb_message);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (e_Queue(0, &s_dali_message) == QUEUE_PROCESSED)
|
|
{
|
|
e_Queue(255, &s_dali_message);
|
|
//PrintDaliMessage(&s_dali_message);
|
|
file_number = s_dali_message.ui8_Line_1or2;
|
|
//file_number = 1;
|
|
//else file_number = 2;
|
|
|
|
if (eep_language == SETTING_GERMAN)
|
|
{
|
|
Ger_PrintDaliMessage(&s_dali_message);
|
|
}
|
|
else if (eep_language == SETTING_FRANCE)
|
|
{
|
|
Fra_PrintDaliMessage(&s_dali_message);
|
|
}
|
|
else
|
|
{
|
|
PrintDaliMessage(&s_dali_message);
|
|
}
|
|
}
|
|
}
|
|
}
|