#include "include.h" extern bool b_ADC_Trigger_Ready; extern bool b_AD_Value_saved; extern uint8 ui8_ADC_Trigger_Channel; static uint8 ui8_OUT_rec_position[2]; // Position in the data to receive static uint8 ui8_OUT_rec_value[2]; // Holds the received logic level static uint8 ui8_IN_rec_position[2]; static uint8 ui8_IN_rec_bit[2]; static uint8 ui8_IN_rec_value[2] = {1, 1}; static uint8 ui8_Stop_Bit_Received[2]; static DaliMessageStruct s_Message[2]; static bool b_answer_edge[2] = {false, false}; static uint8 ui8_Temp_Value[2]; extern Com_Line_t* p_Lines[]; uint8 cpt=0; void RX_Interrupt_Handler(uint8 ui8_Line) { uint8 i = 0; sleep_disable(); Disable_Com_Line_Interrupt(ui8_Line); Switch_LEDs_On(0x04 << ui8_Line); if (ui8_switch_state == SWITCH_SETTING_CCB) { CCB_Start_Message_Reception(ui8_Line); } else { if (!(ui16_RX_TX_State & (CGL1_WAIT_ANSWER_ACTIVE << ui8_Line))) { s_Message[ui8_Line].ui8_Address = 0; s_Message[ui8_Line].ui8_Ext_Address = 0; s_Message[ui8_Line].ui8_Command = 0; s_Message[ui8_Line].b_Answer_Available = false; s_Message[ui8_Line].ui8_Line_1or2 = 2 - ui8_Line; s_Message[ui8_Line].s_Timestamp = s_Time; s_Message[ui8_Line].ui8_Answer = 0; // Clear answer s_Message[ui8_Line].b_Any_Answer = false; ui8_IN_rec_bit[ui8_Line] = 0; // No bit has been received ui8_IN_rec_value[ui8_Line] = 0x00; // Value is low when starting to receive ui8_Temp_Value[ui8_Line] = 0; ui8_IN_rec_position[ui8_Line] = 0; ui16_RX_TX_State |= (CGL1_REC_ACTIVE << ui8_Line); //rec_active = TRUE; // Activate the timer module to receive cpt=0; } else { ui8_OUT_rec_bit[ui8_Line] = 0; // No bit has been received ui8_OUT_rec_value[ui8_Line] = 0x00; // Value is low when starting to receive ui8_OUT_rec_position[ui8_Line] = 0; s_Message[ui8_Line].b_Any_Answer = true; b_answer_edge[ui8_Line] = true; ui16_RX_TX_State |= (CGL1_REC_ANSWER_ACTIVE << ui8_Line); ui16_RX_TX_State &= ~(CGL1_WAIT_ANSWER_ACTIVE << ui8_Line); } } } interrupt [PORTD_INT0_vect] void PORTD_0_ISR() { RX_Interrupt_Handler(0); } interrupt [PORTD_INT1_vect] void PORTD_1_ISR() { RX_Interrupt_Handler(1); } // Timer/counter TCC0 Overflow/Underflow interrupt service routine interrupt [TCC0_OVF_vect] void TCC0_Overflow_ISR() { static uint8 rtc_timer = 0; static uint16 ui16_Timer = 0; //Timer/counter interrupt is accessed every 104.166us sleep_disable(); if (ui8_switch_state == SWITCH_SETTING_CCB) { CCB_Receive_Message(); } else { ReceiveDaliMessage(); } rtc_timer++; if ((rtc_timer >= 97)) { disk_timerproc(); rtc_timer = 0; } if (ui16_Timer >= 20) { ui16_Timer = 0; if (b_AD_Value_saved == false) { ui8_allow_sleep &= ~ADC_SLEEP; b_ADC_Trigger_Ready = true; } else { if (!ui16_RX_TX_State || (ui16_RX_TX_State && (b_answer_edge[0] || b_answer_edge[1]))) { b_answer_edge[0] = false; b_answer_edge[1] = false; ui8_adc_counter++; if (ui8_adc_counter > 2 && !ui16_RX_TX_State) { ui8_ADC_Trigger_Channel++; ui8_adc_counter = 0; } if (ui16_RX_TX_State) { if (ui8_ADC_Trigger_Channel > 1) { ui8_ADC_Trigger_Channel = 0; } } if (ui8_ADC_Trigger_Channel >= 4) { ui8_ADC_Trigger_Channel = 2; } ui8_allow_sleep |= ADC_SLEEP; b_AD_Value_saved = false; ADC_Start_Conversion(ui8_ADC_Trigger_Channel); ui16_Timer = 15; } } if (ui16_RX_TX_State & (CGL1_REC_ACTIVE << 0)) { adca_del_extr(0); } if (ui16_RX_TX_State & (CGL1_REC_ACTIVE << 1)) { adca_del_extr(1); } } if ((b_AD_Value_saved == true) && (b_answer_edge[0] || b_answer_edge[1])) { ui16_Timer = 19; if (b_answer_edge[0]) { ui8_ADC_Trigger_Channel = 0; } if (b_answer_edge[1]) { ui8_ADC_Trigger_Channel = 1; } } ui16_Timer++; } uint8 g_tData[] = { //Reset test time 0,0,0,0,1,1,1,1, //-> start 0,0,0,0,1,1,1,1, //-> YB 0,0,0,0,1,1,1,1, //-> A5 0,0,0,0,1,1,1,1, //-> A4 1,1,1,1,0,0,0,0, //-> A3 1,1,1,1,0,0,0,0, //-> A2 1,1,1,1,0,0,0,0, //-> A1 0,0,0,0,1,1,1,1, //-> A0 0,0,0,0,1,1,1,1, //-> S 1,1,1,1,0,0,0,0, // CD7 0 1,1,1,1,0,0,0,0, // CD6 0 1,1,1,1,0,0,0,0, // CD5 0 1,1,1,1,0,0,0,0, // CD4 0 1,1,1,1,0,0,0,0, // CD3 0 1,1,1,1,0,0,0,0, // CD2 0 1,1,1,1,0,0,0,0, // CD1 0 1,1,1,1,0,0,0,0, // CD0 0 0,0,0,0,1,1,1,1, // A7 1,1,1,1,0,0,0,0, // A6 1,1,1,1,0,0,0,0, // A8 1,1,1,1,1,1,1,1, //stop 1,1,1,1,1,1,1,1 //stop }; void ReceiveDaliMessage() { uint8 ui8_Line; //******************* RX Anwort ********************************* for (ui8_Line = 0; ui8_Line < 2; ui8_Line++) { //ui8_Temp_Value[ui8_Line] = PORTD.IN & (1 << (ui8_Line)); if(ui8_Line==1 && cpt<176)ui8_Temp_Value[1]=g_tData[cpt++]; if ((ui16_RX_TX_State & (CGL1_REC_ANSWER_ACTIVE << ui8_Line))) { ui8_OUT_rec_position[ui8_Line]++; if (ui8_Temp_Value[ui8_Line] != ui8_OUT_rec_value[ui8_Line]) { // An edge has been detected switch (ui8_OUT_rec_bit[ui8_Line]) { case 0: // Start bit //PORTA.OUT |= 0x20; //PORTA.OUT &= ~0x20; //b_answer_edge[ui8Line] = true; ui8_OUT_rec_bit[ui8_Line]++; ui8_OUT_rec_position[ui8_Line] = 0; break; case 9: // First stop bit if (ui8_OUT_rec_position[ui8_Line] > 5) { // Stop bit error, no edge should exist, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 94; } break; case 10: // Second stop bit // Stop bit error, no edge should exist, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 86; break; default: // The address and command bits if (ui8_OUT_rec_position[ui8_Line] > 5) { //PORTA.OUT |= 0x20; //PORTA.OUT &= ~0x20; // Store the values if (ui8_Temp_Value[ui8_Line]) { s_Message[ui8_Line].ui8_Answer |= (1 << (8 - ui8_OUT_rec_bit[ui8_Line])); } ui8_OUT_rec_bit[ui8_Line]++; ui8_OUT_rec_position[ui8_Line] = 0; } break; } ui8_OUT_rec_value[ui8_Line] = ui8_Temp_Value[ui8_Line]; } else { // Signal level stable switch (ui8_OUT_rec_bit[ui8_Line]) { case 0: // Start bit if (ui8_OUT_rec_position[ui8_Line] == 8) { // Start bit error, too long delay before edge, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 166; } break; case 9: // First stop bit if (ui8_OUT_rec_position[ui8_Line] == 8) { if (ui8_Temp_Value[ui8_Line] == 0) { // Stop bit error, wrong level, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 94; } else { ui8_OUT_rec_bit[ui8_Line]++; ui8_OUT_rec_position[ui8_Line] = 0; } } break; case 10: // Second stop bit if (ui8_OUT_rec_position[ui8_Line] == 8) { // Receive ready s_Message[ui8_Line].b_Answer_Available = true; ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 86; } break; default: // The address and command bits if (ui8_OUT_rec_position[ui8_Line] >= 10) { // Data bit error, too long delay before edge, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ANSWER_ACTIVE << ui8_Line); //rec_active = FALSE; ui16_RX_TX_State |= (CGL1_WAIT_END << ui8_Line); ui8_TrueOrFalse[ui8_Line] = ((8 - ui8_OUT_rec_bit[ui8_Line]) * 8) + 86; } break; } } } //*******************RX Adr+ CMD ************************************ if (ui16_RX_TX_State & (CGL1_REC_ACTIVE << ui8_Line)) { // DEBUGPORT.OUTSET=DEBUG_PIN1; ui8_IN_rec_position[ui8_Line]++; if (ui8_Temp_Value[ui8_Line] != ui8_IN_rec_value[ui8_Line]) { // An edge has been detected switch (ui8_IN_rec_bit[ui8_Line]) { case 0: // Start bit //PORTA.OUT |= 0x20; //PORTA.OUT &= ~0x20; ui8_IN_rec_bit[ui8_Line]++; ui8_IN_rec_position[ui8_Line] = 0; break; case 20: // First stop bit 19Bit if (ui8_IN_rec_position[ui8_Line] == 8) { if (ui8_Temp_Value[ui8_Line] == 0) { //printf("ERROR: STOP19 EDGE"); Switch_LEDs_Off(0x04 << ui8_Line); // Stop bit error, wrong level, stop receiving ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); // rec_active = FALSE; Enable_Com_Line_Interrupt(ui8_Line); } else { ui8_IN_rec_bit[ui8_Line]++; ui8_IN_rec_position[ui8_Line] = 0; } } break; case 21: // Second stop bit // Stop bit error, no edge should exist, stop receiving //printf("ERROR: STOP20 EDGE"); Switch_LEDs_Off(0x04 << ui8_Line); ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); //rec_active = FALSE; Enable_Com_Line_Interrupt(ui8_Line); break; default: // The address and command bits if (ui8_IN_rec_position[ui8_Line] > 5) //6 //Wartezeit nach Epfang des Befehls //traduction:Délai après le début de la commande { //PORTA.OUT |= 0x20; //PORTA.OUT &= ~0x20; // Store the values if (ui8_Temp_Value[ui8_Line]) { // Check if address or command if (ui8_IN_rec_bit[ui8_Line] <= 8) { s_Message[ui8_Line].ui8_Address |= (1 << (8 - ui8_IN_rec_bit[ui8_Line])); } else { if (ui8_IN_rec_bit[ui8_Line] <= 16) { s_Message[ui8_Line].ui8_Command |= (1 << (16 - ui8_IN_rec_bit[ui8_Line])); } else if (ui8_IN_rec_bit[ui8_Line] <= 19) { // 3-bit extended address bits if (ui8_IN_rec_bit[ui8_Line] == 17) { s_Message[ui8_Line].ui8_Ext_Address |= (1 << 1); } if (ui8_IN_rec_bit[ui8_Line] == 18) { s_Message[ui8_Line].ui8_Ext_Address |= (1 << 0); } if (ui8_IN_rec_bit[ui8_Line] == 19) { s_Message[ui8_Line].ui8_Ext_Address |= (1 << 2); } } } } ui8_IN_rec_bit[ui8_Line]++; ui8_IN_rec_position[ui8_Line] = 0; ui8_Stop_Bit_Received[ui8_Line] = 0; } break; } ui8_IN_rec_value[ui8_Line] = ui8_Temp_Value[ui8_Line]; } else { // Signal level stable switch (ui8_IN_rec_bit[ui8_Line]) { case 0: // Start bit if (ui8_IN_rec_position[ui8_Line] == 8) { // Start bit error, too long delay before edge, stop receiving //printf("ERROR: STARTBIT"); ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); //rec_active = FALSE; Switch_LEDs_Off(0x04 << ui8_Line); Enable_Com_Line_Interrupt(ui8_Line); } break; case 17: // STOP_BIT1_NORMAL case 18: // STOP_BIT1_SINGLE_EXT_BIT case 19: // STOP_BIT1_DOUBLE_EXT_BIT if (ui8_IN_rec_position[ui8_Line] > 9) { if (ui8_Temp_Value[ui8_Line] != 0) //Second Stopbit 16 Byte { // Need 2 stop bits to signal new data if (ui8_Stop_Bit_Received[ui8_Line] == 1) { // Receive ready ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); ui16_RX_TX_State |= (CGL1_WAIT_ANSWER_ACTIVE << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 91; //Set Timer to wait for Answer Enable_Com_Line_Interrupt(ui8_Line); Switch_LEDs_Off(0x04 << ui8_Line); b_answer_edge[ui8_Line] = true; ui8_adc_counter = 0; } else { // first stop bit ui8_IN_rec_bit[ui8_Line]++; ui8_IN_rec_position[ui8_Line] = 0; ui8_Stop_Bit_Received[ui8_Line] = 1; } break; } } break; case 20: //STOP_BIT1_TRIPLE_EXT_BIT // First stop bit 18 Byte if (ui8_IN_rec_position[ui8_Line] > 5) { if (ui8_Temp_Value[ui8_Line] == 0) { //printf("ERROR: STOP_BIT LEVEL"); // Stop bit error, wrong level, stop receiving// ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); //rec_active = FALSE; Switch_LEDs_Off(0x04 << ui8_Line); Enable_Com_Line_Interrupt(ui8_Line); } else { ui8_IN_rec_bit[ui8_Line]++; ui8_IN_rec_position[ui8_Line] = 0; } } break; case 21: // STOP_BIT2_TRIPLE_EXT_BIT // Second stop bit 18 Byte if (ui8_IN_rec_position[ui8_Line] == 2) { // Receive ready ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); ui16_RX_TX_State |= (CGL1_WAIT_ANSWER_ACTIVE << ui8_Line); ui8_TrueOrFalse[ui8_Line] = 91; //Set Timer to wait for Answer Enable_Com_Line_Interrupt(ui8_Line); Switch_LEDs_Off(0x04 << ui8_Line); b_answer_edge[ui8_Line] = true; ui8_adc_counter = 0; } break; default: // The address and command bits if (ui8_IN_rec_position[ui8_Line] == 10) { //PORTA.OUT |= 0x20; //delay_us(200); //PORTA.OUT &= ~0x20; //printf("ERROR: ADDR,COMM %d!",ui8_IN_rec_bit[ui8Line]); // Data bit error, too long delay before edge, stop receiving Switch_LEDs_Off(0x04 << ui8_Line); ui16_RX_TX_State &= ~(CGL1_REC_ACTIVE << ui8_Line); Enable_Com_Line_Interrupt(ui8_Line); } break; } } } if (ui16_RX_TX_State & (CGL1_WAIT_END << ui8_Line)) { if (ui8_TrueOrFalse[ui8_Line]) { ui8_TrueOrFalse[ui8_Line]--; } else { ui16_RX_TX_State &= ~(CGL1_WAIT_END << ui8_Line); //if time for answer exceeded: Stop waiting if (b_DALI_OK[ui8_Line]) { Switch_LEDs_Off(0x04 << ui8_Line); } e_Queue(sizeof(DaliMessageStruct), &s_Message[ui8_Line]); Enable_Com_Line_Interrupt(ui8_Line); } } if ((PORTD.INTCTRL & (PORT_INT0LVL_HI_gc << (ui8_Line * 2)))) { if (ui8_TrueOrFalse[ui8_Line]) { ui8_TrueOrFalse[ui8_Line]--; } else { if ((ui16_RX_TX_State & (CGL1_WAIT_ANSWER_ACTIVE << ui8_Line))) { ui16_RX_TX_State &= ~(CGL1_WAIT_ANSWER_ACTIVE << ui8_Line); //if time for answer exceeded: Stop waiting if (b_DALI_OK[ui8_Line]) { Switch_LEDs_Off(0x04 << ui8_Line); } e_Queue(sizeof(DaliMessageStruct), &s_Message[ui8_Line]); } } } } }