|
#include "include.h"
|
|
|
|
bool b_Line1_Active = false;
|
|
bool b_Line2_Active = false;
|
|
static uint8 cgline1_cnt = 0;
|
|
static uint8 cgline2_cnt = 0;
|
|
register uint8 ui8_tick_2ms = 0;
|
|
bool sdcard_switch = 0;
|
|
|
|
// System Clocks initialization
|
|
void system_clocks_init(void)
|
|
{
|
|
unsigned char n, s;
|
|
// Optimize for speed
|
|
#pragma optsize-
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
// External 32,768 kHz oscillator initialization
|
|
// External 32.768 kHz crystal oscillator low power mode: Off
|
|
OSC.XOSCCTRL = OSC_XOSCSEL_32KHz_gc;
|
|
// Enable the external oscillator
|
|
OSC.CTRL |= OSC_XOSCEN_bm;
|
|
|
|
// Wait for the external oscillator to stabilize
|
|
while ((OSC.STATUS & OSC_XOSCRDY_bm) == 0);
|
|
|
|
// Internal 32 MHz RC oscillator initialization
|
|
// Enable the internal 32 MHz RC oscillator
|
|
OSC.CTRL |= OSC_RC32MEN_bm;
|
|
// System Clock prescaler A division factor: 1
|
|
// System Clock prescalers B & C division factors: B:1, C:1
|
|
// ClkPer4: 32000,000 kHz
|
|
// ClkPer2: 32000,000 kHz
|
|
// ClkPer: 32000,000 kHz
|
|
// ClkCPU: 32000,000 kHz
|
|
n = (CLK.PSCTRL & (~(CLK_PSADIV_gm | CLK_PSBCDIV1_bm | CLK_PSBCDIV0_bm))) |
|
|
CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc;
|
|
CCP = CCP_IOREG_gc;
|
|
CLK.PSCTRL = n;
|
|
// Internal 32 MHz RC osc. calibration reference clock source: 32.768 kHz Ext. Crystal Osc.
|
|
OSC.DFLLCTRL = (OSC.DFLLCTRL & (~(OSC_RC32MCREF_gm | OSC_RC2MCREF_bm))) | OSC_RC32MCREF_XOSC32K_gc;
|
|
|
|
// Use of the runtime calibration of the oscillator for the most accurate bus timing possible for the DALI bus //
|
|
// to get.///
|
|
// Goal: A frequency should be selected that is as close as possible to 32 MHz (normal "working frequency" of the //
|
|
// oscillator) and at the same time a multiple of 9600 Hz (sample frequency of the DALI bus lines) //
|
|
// is. Selected factor: 3336. Calculation: // Facteur choisi ?: 3336 Calcul
|
|
// 9600 Hz * 3336 = 32.025.600 Hz
|
|
// So the target frequency is 32.025 MHz.//
|
|
// To set the runtime calibration to the corresponding target frequency, the COMP register ////
|
|
le registre COMP doit
|
|
/ be described with a value that represents the ratio of the desired frequency to the reference frequency //
|
|
// represents. The external 32.768 kHz quartz was chosen as the reference source; The reference frequency gives //
|
|
// divide by 32: 1024 Hz.// se divise en 32: 1024 Hz.
|
|
// Below are some setting examples, which are taken from the XMEGA manual, page 100, table 7-11 //
|
|
// are: /// sont les suivants:
|
|
// desired frequency| Reference frequency | COMP-Wert
|
|
// ---------------------+--------------------+------------- // Fr?quence souhait?e | Fr?quence de r?f?rence | Valeur COMP
|
|
// 30 MHz | 1024 Hz | 0x7270
|
|
// 32 MHz (Standard) | 1024 Hz | 0x7A12
|
|
// 34 MHz | 1024 Hz | 0x81B3
|
|
//
|
|
// Calculation of the value we need:// Calcul de la valeur dont nous avons besoin?:
|
|
// 32.025.600 Hz / 1024 Hz = 31275 = 0x7A2B
|
|
DFLLRC32M.COMP1 = 0x2B;
|
|
DFLLRC32M.COMP2 = 0x7A;
|
|
// Enable the auto-calibration of the internal 32 MHz RC oscillator
|
|
DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
|
|
|
|
// Wait for the internal 32 MHz RC oscillator to stabilize
|
|
while ((OSC.STATUS & OSC_RC32MRDY_bm) == 0);
|
|
|
|
// Select the system clock source: 32 MHz Internal RC Osc.
|
|
n = (CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_RC32M_gc;
|
|
CCP = CCP_IOREG_gc;
|
|
CLK.CTRL = n;
|
|
// Disable the unused oscillators: 2 MHz, internal 32 kHz, PLL
|
|
OSC.CTRL &= ~(OSC_RC2MEN_bm | OSC_RC32KEN_bm | OSC_PLLEN_bm);
|
|
// ClkPer output: Disabled bit 4
|
|
PORTCFG.CLKEVOUT = (PORTCFG.CLKEVOUT & (~(PORTCFG_CLKEVPIN_bm | PORTCFG_CLKOUTSEL_gm | PORTCFG_CLKOUT_gm))) |
|
|
PORTCFG_CLKEVPIN_bm | PORTCFG_CLKOUTSEL_CLK1X_gc | PORTCFG_CLKOUT_OFF_gc;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
// Restore optimization for size if needed
|
|
#pragma optsize_default
|
|
}
|
|
|
|
// Ports initialization
|
|
void ports_init(void)
|
|
{
|
|
// PORTA initialization
|
|
// OUT register
|
|
PORTA.OUT = 0x00;
|
|
// Pin0: Input
|
|
// Pin1: Input
|
|
// Pin2: Input
|
|
// Pin3: Output
|
|
// Pin4: Input
|
|
// Pin5: Input
|
|
// Pin6: Input
|
|
// Pin7: Input
|
|
PORTA.DIR = 0x38;
|
|
// Pin0 Output/Pull configuration: Totempole/No
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTA.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/No
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTA.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin2 Output/Pull configuration: Totempole/No
|
|
// Pin2 Input/Sense configuration: Sense both edges
|
|
// Pin2 Inverted: Off
|
|
// Pin2 Slew Rate Limitation: Off
|
|
PORTA.PIN2CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin3 Output/Pull configuration: Totempole/No
|
|
// Pin3 Input/Sense configuration: Sense both edges
|
|
// Pin3 Inverted: Off
|
|
// Pin3 Slew Rate Limitation: Off
|
|
PORTA.PIN3CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin4 Output/Pull configuration: Pullup/No
|
|
// Pin4 Input/Sense configuration: Sense both edges
|
|
// Pin4 Inverted: Off
|
|
// Pin4 Slew Rate Limitation: Off
|
|
PORTA.PIN4CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin5 Output/Pull configuration: Totempole/No
|
|
// Pin5 Input/Sense configuration: Sense both edges
|
|
// Pin5 Inverted: Off
|
|
// Pin5 Slew Rate Limitation: Off
|
|
PORTA.PIN5CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin6 Output/Pull configuration: Totempole/No
|
|
// Pin6 Input/Sense configuration: Sense both edges
|
|
// Pin6 Inverted: Off
|
|
// Pin6 Slew Rate Limitation: Off
|
|
PORTA.PIN6CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin7 Output/Pull configuration: Totempole/No
|
|
// Pin7 Input/Sense configuration: Sense both edges
|
|
// Pin7 Inverted: Off
|
|
// Pin7 Slew Rate Limitation: Off
|
|
PORTA.PIN7CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Interrupt 0 level: Disabled
|
|
// Interrupt 1 level: Disabled
|
|
PORTA.INTCTRL = (PORTA.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc;
|
|
// Pin0 Pin Change interrupt 0: Off
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
// Pin2 Pin Change interrupt 0: Off
|
|
// Pin3 Pin Change interrupt 0: Off
|
|
// Pin4 Pin Change interrupt 0: Off
|
|
// Pin5 Pin Change interrupt 0: Off
|
|
// Pin6 Pin Change interrupt 0: Off
|
|
// Pin7 Pin Change interrupt 0: Off
|
|
PORTA.INT0MASK = 0x00;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: Off
|
|
// Pin2 Pin Change interrupt 1: Off
|
|
// Pin3 Pin Change interrupt 1: Off
|
|
// Pin4 Pin Change interrupt 1: Off
|
|
// Pin5 Pin Change interrupt 1: Off
|
|
// Pin6 Pin Change interrupt 1: Off
|
|
// Pin7 Pin Change interrupt 1: Off
|
|
PORTA.INT1MASK = 0x00;
|
|
// PORTB initialization
|
|
// OUT register
|
|
PORTB.OUT = 0x00;
|
|
// Pin0: Input
|
|
// Pin1: Output
|
|
// Pin2: Output
|
|
// Pin3: Output
|
|
PORTB.DIR = 0x0E;
|
|
// Pin0 Output/Pull configuration: Totempole/No
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTB.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/No
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTB.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin2 Output/Pull configuration: Totempole/No
|
|
// Pin2 Input/Sense configuration: Sense both edges
|
|
// Pin2 Inverted: Off
|
|
// Pin2 Slew Rate Limitation: Off
|
|
PORTB.PIN2CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin3 Output/Pull configuration: Totempole/No
|
|
// Pin3 Input/Sense configuration: Sense both edges
|
|
// Pin3 Inverted: Off
|
|
// Pin3 Slew Rate Limitation: Off
|
|
PORTB.PIN3CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Interrupt 0 level: Disabled
|
|
// Interrupt 1 level: Disabled
|
|
PORTB.INTCTRL = (PORTB.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc;
|
|
// Pin0 Pin Change interrupt 0: Off
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
// Pin2 Pin Change interrupt 0: Off
|
|
// Pin3 Pin Change interrupt 0: Off
|
|
PORTB.INT0MASK = 0x00;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: Off
|
|
// Pin2 Pin Change interrupt 1: Off
|
|
// Pin3 Pin Change interrupt 1: Off
|
|
PORTB.INT1MASK = 0x00;
|
|
// PORTC initialization
|
|
// OUT register
|
|
PORTC.OUT = 0x00;
|
|
// Pin0: Input
|
|
// Pin1: Output
|
|
// Pin2: Input
|
|
// Pin3: Input
|
|
// Pin4: Input
|
|
// Pin5: Output
|
|
// Pin6: Input
|
|
// Pin7: Output
|
|
PORTC.DIR = 0xA2;
|
|
// Pin0 Output/Pull configuration: Totempole/No
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTC.PIN0CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/No
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTC.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin2 Output/Pull configuration: Totempole/Pull-up (on input)
|
|
// Pin2 Input/Sense configuration: Sense both edges
|
|
// Pin2 Inverted: Off
|
|
// Pin2 Slew Rate Limitation: Off
|
|
PORTC.PIN2CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin3 Output/Pull configuration: Totempole/Pull-down (on input)
|
|
// Pin3 Input/Sense configuration: Sense both edges
|
|
// Pin3 Inverted: Off
|
|
// Pin3 Slew Rate Limitation: Off
|
|
PORTC.PIN3CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin4 Output/Pull configuration: Totempole/Pull-up (on input)
|
|
// Pin4 Input/Sense configuration: Sense both edges
|
|
// Pin4 Inverted: Off
|
|
// Pin4 Slew Rate Limitation: Off
|
|
PORTC.PIN4CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin5 Output/Pull configuration: Totempole/No
|
|
// Pin5 Input/Sense configuration: Sense both edges
|
|
// Pin5 Inverted: Off
|
|
// Pin5 Slew Rate Limitation: Off
|
|
PORTC.PIN5CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin6 Output/Pull configuration: Totempole/No
|
|
// Pin6 Input/Sense configuration: Sense both edges
|
|
// Pin6 Inverted: Off
|
|
// Pin6 Slew Rate Limitation: Off
|
|
PORTC.PIN6CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin7 Output/Pull configuration: Totempole/No
|
|
// Pin7 Input/Sense configuration: Sense both edges
|
|
// Pin7 Inverted: Off
|
|
// Pin7 Slew Rate Limitation: Off
|
|
PORTC.PIN7CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// PORTC Peripheral Output Remapping
|
|
// OC0A Output: Pin 0
|
|
// OC0B Output: Pin 1
|
|
// OC0C Output: Pin 2
|
|
// OC0D Output: Pin 3
|
|
// USART0 XCK: Pin 1
|
|
// USART0 RXD: Pin 2
|
|
// USART0 TXD: Pin 3
|
|
// SPI MOSI: Pin 7
|
|
// SPI SCK: Pin 5
|
|
PORTC.REMAP = (0 << PORT_SPI_bp) | (0 << PORT_USART0_bp) | (0 << PORT_TC0D_bp) | (0 << PORT_TC0C_bp) | (0 << PORT_TC0B_bp) | (0 << PORT_TC0A_bp);
|
|
// Interrupt 0 level: Disabled
|
|
// Interrupt 1 level: Disabled
|
|
PORTC.INTCTRL = (PORTC.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc;
|
|
// Pin0 Pin Change interrupt 0: Off
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
// Pin2 Pin Change interrupt 0: Off
|
|
// Pin3 Pin Change interrupt 0: Off
|
|
// Pin4 Pin Change interrupt 0: Off
|
|
// Pin5 Pin Change interrupt 0: Off
|
|
// Pin6 Pin Change interrupt 0: Off
|
|
// Pin7 Pin Change interrupt 0: Off
|
|
PORTC.INT0MASK = 0x00;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: Off
|
|
// Pin2 Pin Change interrupt 1: Off
|
|
// Pin3 Pin Change interrupt 1: Off
|
|
// Pin4 Pin Change interrupt 1: Off
|
|
// Pin5 Pin Change interrupt 1: Off
|
|
// Pin6 Pin Change interrupt 1: Off
|
|
// Pin7 Pin Change interrupt 1: Off
|
|
PORTC.INT1MASK = 0x00;
|
|
// PORTD initialization
|
|
// OUT register
|
|
PORTD.OUT = 0x00;
|
|
// Pin0: Input
|
|
// Pin1: Input
|
|
// Pin2: Output
|
|
// Pin3: Input
|
|
// Pin4: Input
|
|
// Pin5: Input
|
|
// Pin6: Input
|
|
// Pin7: Input
|
|
PORTD.DIR = 0x04;
|
|
// Pin0 Output/Pull configuration: Totempole/Pull-up (on input)
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTD.PIN0CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/Pull-up (on input)
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTD.PIN1CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin2 Output/Pull configuration: Totempole/No
|
|
// Pin2 Input/Sense configuration: Sense both edges
|
|
// Pin2 Inverted: Off
|
|
// Pin2 Slew Rate Limitation: Off
|
|
PORTD.PIN2CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin3 Output/Pull configuration: Totempole/Pull-down (on input)
|
|
// Pin3 Input/Sense configuration: Sense both edges
|
|
// Pin3 Inverted: Off
|
|
// Pin3 Slew Rate Limitation: Off
|
|
PORTD.PIN3CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin4 Output/Pull configuration: Totempole/Pull-down (on input)
|
|
// Pin4 Input/Sense configuration: Sense both edges
|
|
// Pin4 Inverted: Off
|
|
// Pin4 Slew Rate Limitation: Off
|
|
PORTD.PIN4CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin5 Output/Pull configuration: Totempole/Pull-down (on input)
|
|
// Pin5 Input/Sense configuration: Sense both edges
|
|
// Pin5 Inverted: Off
|
|
// Pin5 Slew Rate Limitation: Off
|
|
PORTD.PIN5CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin6 Output/Pull configuration: Totempole/Pull-down (on input)
|
|
// Pin6 Input/Sense configuration: Sense both edges
|
|
// Pin6 Inverted: Off
|
|
// Pin6 Slew Rate Limitation: Off
|
|
PORTD.PIN6CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin7 Output/Pull configuration: Totempole/No
|
|
// Pin7 Input/Sense configuration: Sense both edges
|
|
// Pin7 Inverted: Off
|
|
// Pin7 Slew Rate Limitation: Off
|
|
PORTD.PIN7CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Interrupt 0 level: Low
|
|
// Interrupt 1 level: Low
|
|
PORTD.INTCTRL = (PORTD.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_HI_gc | PORT_INT0LVL_HI_gc;
|
|
// Pin0 Pin Change interrupt 0: On
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
// Pin2 Pin Change interrupt 0: Off
|
|
// Pin3 Pin Change interrupt 0: Off
|
|
// Pin4 Pin Change interrupt 0: Off
|
|
// Pin5 Pin Change interrupt 0: Off
|
|
// Pin6 Pin Change interrupt 0: Off
|
|
// Pin7 Pin Change interrupt 0: Off
|
|
PORTD.INT0MASK = 0x01;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: On
|
|
// Pin2 Pin Change interrupt 1: Off
|
|
// Pin3 Pin Change interrupt 1: Off
|
|
// Pin4 Pin Change interrupt 1: Off
|
|
// Pin5 Pin Change interrupt 1: Off
|
|
// Pin6 Pin Change interrupt 1: Off
|
|
// Pin7 Pin Change interrupt 1: Off
|
|
PORTD.INT1MASK = 0x02;
|
|
// PORTE initialization
|
|
// OUT register
|
|
PORTE.OUT = 0x08;
|
|
// Pin0: Input
|
|
// Pin1: Input
|
|
// Pin2: Input
|
|
// Pin3: Output
|
|
PORTE.DIR = 0x08;
|
|
// Pin0 Output/Pull configuration: Totempole/No
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTE.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/No
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTE.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin2 Output/Pull configuration: Totempole/No
|
|
// Pin2 Input/Sense configuration: Sense both edges
|
|
// Pin2 Inverted: Off
|
|
// Pin2 Slew Rate Limitation: Off
|
|
PORTE.PIN2CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin3 Output/Pull configuration: Totempole/No
|
|
// Pin3 Input/Sense configuration: Sense both edges
|
|
// Pin3 Inverted: Off
|
|
// Pin3 Slew Rate Limitation: Off
|
|
PORTE.PIN3CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Interrupt 0 level: Disabled
|
|
// Interrupt 1 level: Disabled
|
|
PORTE.INTCTRL = (PORTE.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc;
|
|
// Pin0 Pin Change interrupt 0: Off
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
// Pin2 Pin Change interrupt 0: Off
|
|
// Pin3 Pin Change interrupt 0: Off
|
|
PORTE.INT0MASK = 0x00;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: Off
|
|
// Pin2 Pin Change interrupt 1: Off
|
|
// Pin3 Pin Change interrupt 1: Off
|
|
PORTE.INT1MASK = 0x00;
|
|
// PORTR initialization
|
|
// OUT register
|
|
PORTR.OUT = 0x00;
|
|
// Pin0: Input
|
|
// Pin1: Input
|
|
PORTR.DIR = 0x00;
|
|
// Pin0 Output/Pull configuration: Totempole/No
|
|
// Pin0 Input/Sense configuration: Sense both edges
|
|
// Pin0 Inverted: Off
|
|
// Pin0 Slew Rate Limitation: Off
|
|
PORTR.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Pin1 Output/Pull configuration: Totempole/No
|
|
// Pin1 Input/Sense configuration: Sense both edges
|
|
// Pin1 Inverted: Off
|
|
// Pin1 Slew Rate Limitation: Off
|
|
PORTR.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
// Interrupt 0 level: Disabled
|
|
// Interrupt 1 level: Disabled
|
|
PORTR.INTCTRL = (PORTR.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) |
|
|
PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc;
|
|
// Pin0 Pin Change interrupt 0: Off
|
|
// Pin1 Pin Change interrupt 0: Off
|
|
PORTR.INT0MASK = 0x00;
|
|
// Pin0 Pin Change interrupt 1: Off
|
|
// Pin1 Pin Change interrupt 1: Off
|
|
PORTR.INT1MASK = 0x00;
|
|
}
|
|
|
|
|
|
// Function used to read the calibration byte from the
|
|
// signature row, specified by 'index'
|
|
#pragma optsize-
|
|
unsigned char read_calibration_byte(unsigned char index)
|
|
{
|
|
unsigned char r;
|
|
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
|
|
r = *((flash unsigned char*) index);
|
|
// Clean up NVM command register
|
|
NVM.CMD = NVM_CMD_NO_OPERATION_gc;
|
|
return r;
|
|
}
|
|
#pragma optsize_default
|
|
|
|
|
|
// Disable a Timer/Counter type 0
|
|
void tc0_disable(TC0_t* ptc)
|
|
{
|
|
// Timer/Counter off
|
|
ptc->CTRLA = (ptc->CTRLA & (~TC0_CLKSEL_gm)) | TC_CLKSEL_OFF_gc;
|
|
// Issue a reset command
|
|
ptc->CTRLFSET = TC_CMD_RESET_gc;
|
|
}
|
|
|
|
|
|
// Timer/Counter TCC0 initialization
|
|
void tcc0_init(void)
|
|
{
|
|
unsigned char s;
|
|
unsigned char n;
|
|
// Note: the correct PORTC direction for the Compare Channels outputs
|
|
// is configured in the ports_init function
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
// Disable and reset the timer/counter just to be sure
|
|
tc0_disable(&TCC0);
|
|
// Clock source: ClkPer/1
|
|
TCC0.CTRLA = (TCC0.CTRLA & (~TC0_CLKSEL_gm)) | TC_CLKSEL_DIV1_gc;
|
|
// Mode: Normal Operation, Overflow Int./Event on TOP
|
|
// Compare/Capture on channel A: Off
|
|
// Compare/Capture on channel B: Off
|
|
// Compare/Capture on channel C: Off
|
|
// Compare/Capture on channel D: Off
|
|
TCC0.CTRLB = (TCC0.CTRLB & (~(TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm | TC0_WGMODE_gm))) |
|
|
TC_WGMODE_NORMAL_gc;
|
|
// Capture event source: None
|
|
// Capture event action: None
|
|
TCC0.CTRLD = (TCC0.CTRLD & (~(TC0_EVACT_gm | TC0_EVSEL_gm))) |
|
|
TC_EVACT_OFF_gc | TC_EVSEL_OFF_gc;
|
|
// Overflow interrupt: High Level
|
|
// Error interrupt: Disabled
|
|
TCC0.INTCTRLA = (TCC0.INTCTRLA & (~(TC0_ERRINTLVL_gm | TC0_OVFINTLVL_gm))) |
|
|
TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_HI_gc;
|
|
// Compare/Capture channel A interrupt: Disabled
|
|
// Compare/Capture channel B interrupt: Disabled
|
|
// Compare/Capture channel C interrupt: Disabled
|
|
// Compare/Capture channel D interrupt: Disabled
|
|
TCC0.INTCTRLB = (TCC0.INTCTRLB & (~(TC0_CCDINTLVL_gm | TC0_CCCINTLVL_gm | TC0_CCBINTLVL_gm | TC0_CCAINTLVL_gm))) |
|
|
TC_CCDINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_OFF_gc;
|
|
// High resolution extension: Off
|
|
HIRESC.CTRLA &= ~HIRES_HREN0_bm;
|
|
// Advanced Waveform Extension initialization
|
|
// Optimize for speed
|
|
#pragma optsize-
|
|
// Disable locking the AWEX configuration registers just to be sure
|
|
n = MCU.AWEXLOCK & (~MCU_AWEXCLOCK_bm);
|
|
CCP = CCP_IOREG_gc;
|
|
MCU.AWEXLOCK = n;
|
|
// Restore optimization for size if needed
|
|
#pragma optsize_default
|
|
// Pattern generation: Off
|
|
// Dead time insertion: Off
|
|
AWEXC.CTRL &= ~(AWEX_PGM_bm | AWEX_CWCM_bm | AWEX_DTICCDEN_bm | AWEX_DTICCCEN_bm | AWEX_DTICCBEN_bm | AWEX_DTICCAEN_bm);
|
|
// Fault protection initialization
|
|
// Fault detection on OCD Break detection: On
|
|
// Fault detection restart mode: Latched Mode
|
|
// Fault detection action: None (Fault protection disabled)
|
|
AWEXC.FDCTRL = (AWEXC.FDCTRL & (~(AWEX_FDDBD_bm | AWEX_FDMODE_bm | AWEX_FDACT_gm))) |
|
|
AWEX_FDACT_NONE_gc;
|
|
// Fault detect events:
|
|
// Event channel 0: Off
|
|
// Event channel 1: Off
|
|
// Event channel 2: Off
|
|
// Event channel 3: Off
|
|
// Event channel 4: Off
|
|
// Event channel 5: Off
|
|
// Event channel 6: Off
|
|
// Event channel 7: Off
|
|
AWEXC.FDEVMASK = 0b00000000;
|
|
// Make sure the fault detect flag is cleared
|
|
AWEXC.STATUS |= AWEXC.STATUS & AWEX_FDF_bm;
|
|
// Clear the interrupt flags
|
|
TCC0.INTFLAGS = TCC0.INTFLAGS;
|
|
// Set counter register
|
|
TCC0.CNT = 0x0000;
|
|
// Set period register
|
|
// TCC0.PER=0x04FF;
|
|
TCC0.PER = 3336;
|
|
// Set channel A Compare/Capture register
|
|
TCC0.CCA = 0x0000;
|
|
// Set channel B Compare/Capture register
|
|
TCC0.CCB = 0x0000;
|
|
// Set channel C Compare/Capture register
|
|
TCC0.CCC = 0x0000;
|
|
// Set channel D Compare/Capture register
|
|
TCC0.CCD = 0x0000;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
#asm("sei")
|
|
}
|
|
|
|
|
|
// USARTE0 initialization
|
|
void usarte0_init(void)
|
|
{
|
|
// Note: The correct PORTE direction for the RxD, TxD and XCK signals
|
|
// is configured in the ports_init function.
|
|
// Transmitter is enabled
|
|
// Set TxD=1
|
|
PORTE.OUTSET = 0x08;
|
|
// Communication mode: Asynchronous USART
|
|
// Data bits: 8
|
|
// Stop bits: 1
|
|
// Parity: Disabled
|
|
USARTE0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;
|
|
// Receive complete interrupt: Low Level
|
|
// Transmit complete interrupt: Low Level
|
|
// Data register empty interrupt: Disabled
|
|
USARTE0.CTRLA = (USARTE0.CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
|
|
USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc | USART_DREINTLVL_OFF_gc;
|
|
// Required Baud rate: 115200
|
|
// Real Baud Rate: 115211,5 (x1 Mode), Error: 0,0 %
|
|
USARTE0.BAUDCTRLA = 0x2E;
|
|
USARTE0.BAUDCTRLB = ((0x09 << USART_BSCALE_gp) & USART_BSCALE_gm) | 0x08;
|
|
// Receiver: On
|
|
// Transmitter: On
|
|
// Double transmission speed mode: Off
|
|
// Multi-processor communication mode: Off
|
|
USARTE0.CTRLB = (USARTE0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
|
|
USART_RXEN_bm | USART_TXEN_bm;
|
|
}
|
|
|
|
|
|
|
|
// USARTE0 Receiver interrupt service routine
|
|
interrupt [USARTE0_RXC_vect] void usarte0_rx_isr(void)
|
|
{
|
|
unsigned char status;
|
|
char data;
|
|
sleep_disable();
|
|
|
|
if (ui8_allow_sleep & CLOCK_SLEEP)
|
|
{
|
|
ui8_allow_sleep |= USART_RX_SLEEP;
|
|
status = USARTE0.STATUS;
|
|
data = USARTE0.DATA;
|
|
|
|
if ((status & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0)
|
|
{
|
|
rx_buffer_usarte0[rx_wr_index_usarte0++] = data;
|
|
#if BUFFER_SIZE_USARTE0 == 256
|
|
|
|
// special case for receiver buffer size=256
|
|
if (++rx_counter_usarte0 == 0)
|
|
{
|
|
rx_buffer_overflow_usarte0 = 1;
|
|
}
|
|
|
|
#else
|
|
|
|
if (rx_wr_index_usarte0 == BUFFER_SIZE_USARTE0)
|
|
{
|
|
rx_wr_index_usarte0 = 0;
|
|
}
|
|
|
|
if (++rx_counter_usarte0 == BUFFER_SIZE_USARTE0)
|
|
{
|
|
rx_counter_usarte0 = 0;
|
|
rx_buffer_overflow_usarte0 = 1;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
if (rx_wr_index_usarte0 >= 8)
|
|
{
|
|
set_Time_from_UART();
|
|
}
|
|
|
|
ui8_allow_sleep &= ~USART_RX_SLEEP;
|
|
}
|
|
}
|
|
|
|
|
|
// USARTE0 Transmitter interrupt service routine
|
|
interrupt [USARTE0_TXC_vect] void usarte0_tx_isr(void)
|
|
{
|
|
sleep_disable();
|
|
|
|
if (tx_counter_usarte0)
|
|
{
|
|
--tx_counter_usarte0;
|
|
USARTE0.DATA = tx_buffer_usarte0[tx_rd_index_usarte0++];
|
|
#if BUFFER_SIZE_USARTE0 != 256
|
|
|
|
if (tx_rd_index_usarte0 == BUFFER_SIZE_USARTE0)
|
|
{
|
|
tx_rd_index_usarte0 = 0;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
ui8_allow_sleep &= ~USART_TX_SLEEP;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Handle_Inputs(void)
|
|
{
|
|
uint8 ui8_Temp_Input;
|
|
ui16_Input_Select++;
|
|
|
|
if (!ui16_RX_TX_State)
|
|
{
|
|
if (PORTD.IN & (0x01))
|
|
{
|
|
if (cgline1_cnt > 100)
|
|
{
|
|
b_Line1_Active = true;
|
|
}
|
|
else
|
|
{
|
|
cgline1_cnt++;
|
|
}
|
|
}
|
|
else if (cgline1_cnt)
|
|
{
|
|
cgline1_cnt--;
|
|
}
|
|
else
|
|
{
|
|
b_Line1_Active = false;
|
|
}
|
|
|
|
if (PORTD.IN & (0x02))
|
|
{
|
|
if (cgline2_cnt > 100)
|
|
{
|
|
b_Line2_Active = true;
|
|
}
|
|
else
|
|
{
|
|
cgline2_cnt++;
|
|
}
|
|
}
|
|
else if (cgline2_cnt)
|
|
{
|
|
cgline2_cnt--;
|
|
}
|
|
else
|
|
{
|
|
b_Line2_Active = false;
|
|
}
|
|
}
|
|
|
|
if ((PORTD.OUT & 0x04)) // Rotation-Switch
|
|
{
|
|
if ((0xF0 & ui8_Input_Content) != ((PORTD.IN & 0x78) << 1))
|
|
{
|
|
ui16_Input_Cnt[0]++;
|
|
|
|
if (ui16_Input_Cnt[0] > 400)
|
|
{
|
|
ui16_Input_Cnt[0] = 0;
|
|
ui8_Input_Content = (((PORTD.IN & 0x78) << 1) | (ui8_Input_Content & 0x0F));
|
|
ui8_Temp_Input = ((ui8_Input_Content & 0xF0) >> 4);
|
|
|
|
switch (ui8_Temp_Input)
|
|
{
|
|
//If rotation-switch changed value, you can write here your code to do sth.
|
|
case 0:
|
|
//Write here the code for value 0
|
|
break;
|
|
|
|
case 1:
|
|
//Write here the code for value 1
|
|
break;
|
|
|
|
// ... //
|
|
case 15:
|
|
//value 15: F on rotation-switch
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//Write here a print-command to display the new config of rotation-switch
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ui16_Input_Cnt[0] = 0;
|
|
}
|
|
}
|
|
else //DIP-Switch
|
|
{
|
|
if ((0x0F & ui8_Input_Content) != ((PORTD.IN & 0x78) >> 3))
|
|
{
|
|
ui16_Input_Cnt[1]++;
|
|
|
|
if (ui16_Input_Cnt[1] > 400)
|
|
{
|
|
ui16_Input_Cnt[1] = 0;
|
|
ui8_Input_Content = (((PORTD.IN & 0x78) >> 3) | (ui8_Input_Content & 0xF0));
|
|
ui8_Temp_Input = (ui8_Input_Content & 0x0F);
|
|
|
|
switch (ui8_Temp_Input)
|
|
{
|
|
case 14:
|
|
ui8_switch_state = SWITCH_SETTING_DALI;
|
|
break;
|
|
|
|
case 12:
|
|
ui8_switch_state = SWITCH_SETTING_CCB;
|
|
break;
|
|
|
|
default:
|
|
ui8_switch_state = SWITCH_SETTING_CGLINE;
|
|
break;
|
|
}
|
|
|
|
Print_Config();
|
|
sdcard_switch = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ui16_Input_Cnt[1] = 0;
|
|
}
|
|
}
|
|
|
|
if (ui16_Input_Select > 800)
|
|
{
|
|
if (PORTD.OUT & 0x04)
|
|
{
|
|
PORTD.OUT &= ~(0x04);
|
|
}
|
|
else
|
|
{
|
|
PORTD.OUT |= (0x04);
|
|
}
|
|
|
|
ui16_Input_Select = 0;
|
|
}
|
|
|
|
// SD-Card initialization
|
|
if (sdcard_switch && ui16_Input_Cnt[3] > 1000)
|
|
{
|
|
if (eep_output > 0 && !b_sdcard_active)
|
|
{
|
|
if (!(PORTA.IN & 0x10))
|
|
{
|
|
sdcard_init();
|
|
}
|
|
}
|
|
|
|
if ((PORTA.IN & 0x10))
|
|
{
|
|
b_sdcard_active = false;
|
|
}
|
|
}
|
|
|
|
if ((ui8_USB_SD_switch & 0x10) != (PORTA.IN & 0x10))
|
|
{
|
|
if (ui16_Input_Cnt[3] < 1001)
|
|
{
|
|
ui16_Input_Cnt[3]++;
|
|
}
|
|
else
|
|
{
|
|
ui8_USB_SD_switch |= (PORTA.IN & 0x10);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ui16_Input_Cnt[3] = 0;
|
|
}
|
|
|
|
//If SD-Card is plugged in or out while operating -> reset controller
|
|
if (((ui8_USB_SD_switch & 0x01) != (PORTC.IN & 0x01)) || ((ui8_USB_SD_switch & 0x80) != (PORTD.IN & 0x80)))
|
|
{
|
|
ui16_Input_Cnt[2]++;
|
|
|
|
if (ui16_Input_Cnt[2] > 1500)
|
|
{
|
|
#asm("cli")
|
|
eep_set_Time();
|
|
CCP = CCP_IOREG_gc;
|
|
RST.CTRL = 0x01;
|
|
}
|
|
}
|
|
else if (ui16_Input_Cnt[2] > 0)
|
|
{
|
|
ui16_Input_Cnt[2]--;
|
|
}
|
|
}
|
|
|
|
// Write a character to the USARTE0 Transmitter buffer
|
|
// USARTE0 is used as the default output device by the 'putchar' function
|
|
//
|
|
#define _ALTERNATE_PUTCHAR_
|
|
#pragma used+
|
|
void putchar(char c)
|
|
{
|
|
while (tx_counter_usarte0 == BUFFER_SIZE_USARTE0);
|
|
|
|
if (b_uart_on)
|
|
{
|
|
ui8_allow_sleep |= USART_TX_SLEEP;
|
|
USARTE0.CTRLA &= ~(USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc);
|
|
|
|
if (tx_counter_usarte0 || ((USARTE0.STATUS & USART_DREIF_bm) == 0))
|
|
{
|
|
tx_buffer_usarte0[tx_wr_index_usarte0++] = c;
|
|
#if BUFFER_SIZE_USARTE0 != 256
|
|
|
|
if (tx_wr_index_usarte0 == BUFFER_SIZE_USARTE0)
|
|
{
|
|
tx_wr_index_usarte0 = 0;
|
|
}
|
|
|
|
#endif
|
|
++tx_counter_usarte0;
|
|
}
|
|
else
|
|
{
|
|
USARTE0.DATA = c;
|
|
}
|
|
}
|
|
|
|
if (b_sdcard_active && b_sdcard_on)
|
|
{
|
|
put_sdcard(c);
|
|
}
|
|
|
|
USARTE0.CTRLA |= (USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc);
|
|
}
|
|
#pragma used-
|
|
|
|
// Receive a character from USARTE0
|
|
// USARTE0 is used as the default input device by the 'getchar' function
|
|
#define _ALTERNATE_GETCHAR_
|
|
#pragma used+
|
|
char getchar(void)
|
|
{
|
|
char data;
|
|
|
|
if (rx_counter_usarte0 == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
data = rx_buffer_usarte0[rx_rd_index_usarte0++];
|
|
#if BUFFER_SIZE_USARTE0 != 256
|
|
|
|
if (rx_rd_index_usarte0 == BUFFER_SIZE_USARTE0)
|
|
{
|
|
rx_rd_index_usarte0 = 0;
|
|
}
|
|
|
|
#endif
|
|
#asm("cli")
|
|
--rx_counter_usarte0;
|
|
#asm("sei")
|
|
return data;
|
|
}
|
|
#pragma used-
|
|
|
|
// RTC initialization
|
|
void rtcxm_init(void)
|
|
{
|
|
unsigned char s;
|
|
// RTC clock source: 32.768 kHz from 32.768 kHz Crystal Osc. on TOSC
|
|
// Note: The external 32.768 kHz crystal oscillator is
|
|
// initialized in the system_clocks_init function.
|
|
// Select the clock source and enable the RTC clock
|
|
CLK.RTCCTRL = (CLK.RTCCTRL & (~CLK_RTCSRC_gm)) | CLK_RTCSRC_TOSC32_gc | CLK_RTCEN_bm;
|
|
// Make sure that the RTC is stopped before initializing it
|
|
RTC.CTRL = RTC_PRESCALER_OFF_gc;
|
|
// Optimize for speed
|
|
#pragma optsize-
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
|
|
// Wait until the RTC is not busy
|
|
while (RTC.STATUS & RTC_SYNCBUSY_bm);
|
|
|
|
// Set the RTC period register
|
|
RTC.PER = 0x0040;
|
|
// Set the RTC count register
|
|
RTC.CNT = 0x0000;
|
|
// Set the RTC compare register
|
|
RTC.COMP = 0x0000;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
// Restore optimization for size if needed
|
|
#pragma optsize_default
|
|
// Set the clock prescaler: RTC Clock/1
|
|
// and start the RTC
|
|
RTC.CTRL = RTC_PRESCALER_DIV1_gc;
|
|
// RTC Clock output disabled
|
|
PORTCFG.CLKEVOUT &= ~PORTCFG_RTCOUT_bm;
|
|
// RTC overflow interrupt: Medium Level
|
|
// RTC compare interrupt: Disabled
|
|
RTC.INTCTRL = RTC_OVFINTLVL_OFF_gc | RTC_COMPINTLVL_OFF_gc;
|
|
}
|
|
|
|
void Init_Sleep_Mode()
|
|
{
|
|
sleep_set_mode(SLEEP_SMODE_IDLE_gc);
|
|
}
|
|
|
|
void Handle_Sleep_Mode()
|
|
{
|
|
if ((ui16_RX_TX_State == 0) && (ui8_allow_sleep == 0))
|
|
{
|
|
if (b_Line1_Active == true)
|
|
{
|
|
if ((PORTD.IN & 0x01) == 0)
|
|
{
|
|
RX_Interrupt_Handler(0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (b_Line2_Active == true)
|
|
{
|
|
if ((PORTD.IN & 0x02) == 0)
|
|
{
|
|
RX_Interrupt_Handler(1);
|
|
return;
|
|
}
|
|
}
|
|
|
|
sleep_enable();
|
|
PR.PRGEN |= 0x59;
|
|
PR.PRPA |= 0x05;
|
|
PR.PRPB |= 0x05;
|
|
PR.PRPC |= 0x64;
|
|
PR.PRPD |= 0x64;
|
|
PR.PRPE |= 0x64;
|
|
PR.PRPF |= 0x64;
|
|
sleep_enter();
|
|
sleep_disable();
|
|
}
|
|
}
|
|
|
|
void turn_off_pulls(void)
|
|
{
|
|
PORTC.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTC.PIN2CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTC.PIN3CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTC.PIN4CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN1CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN3CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN4CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN5CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN6CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
PORTD.PIN7CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc;
|
|
}
|
|
|
|
void Switch_LEDs_On(uint8 ui8_LED_Pins)
|
|
{
|
|
ui8_LED_Pins &= ~ui8_LED_lock;
|
|
PORTB.OUT |= ui8_LED_Pins;
|
|
}
|
|
|
|
void Switch_LEDs_Off(uint8 ui8_LED_Pins)
|
|
{
|
|
ui8_LED_Pins &= ~ui8_LED_lock;
|
|
PORTB.OUT &= ~ui8_LED_Pins;
|
|
}
|
|
|
|
void Handle_Battery_Empty()
|
|
{
|
|
extern sint16 si16_adca_mVolts_Cel[7];
|
|
|
|
if (si16_adca_mVolts_Cel[2] >= 2500 && si16_adca_mVolts_Cel[2] <= 3600)
|
|
{
|
|
si16_Bat_Empty++;
|
|
|
|
if (si16_Bat_Empty > si16_adca_mVolts_Cel[2] - 3300)
|
|
{
|
|
si16_Bat_Empty = 0;
|
|
|
|
if (PORTB.OUT & 0x02)
|
|
{
|
|
// Error-LED ist an
|
|
Switch_LEDs_Off(0x02);
|
|
}
|
|
else
|
|
{
|
|
Switch_LEDs_On(0x02);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Func_2ms(void)
|
|
{
|
|
if (ui8_tick_2ms)
|
|
{
|
|
Handle_Battery_Empty();
|
|
|
|
if (ui8_allow_sleep & CLOCK_SLEEP)
|
|
{
|
|
if ((s_Time.ui8_Time_min + (s_Time.ui8_Time_hrs * 60)) > eep_clock && eep_clock > 0)
|
|
{
|
|
ui8_allow_sleep &= ~CLOCK_SLEEP;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (ui8_tick_2ms)
|
|
{
|
|
//IncreaseTimestamp(1,983,515);
|
|
ui8_tick_2ms--;
|
|
}
|
|
}
|
|
|
|
// Event System initialization
|
|
void event_system_init(void)
|
|
{
|
|
// Event System Channel 0 source: Port D, Pin0
|
|
EVSYS.CH0MUX = EVSYS_CHMUX_PORTD_PIN0_gc;
|
|
// Event System Channel 1 source: Port D, Pin1
|
|
EVSYS.CH1MUX = EVSYS_CHMUX_PORTD_PIN1_gc;
|
|
// Event System Channel 2 source: None
|
|
EVSYS.CH2MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 3 source: None
|
|
EVSYS.CH3MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 4 source: None
|
|
EVSYS.CH4MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 5 source: None
|
|
EVSYS.CH5MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 6 source: None
|
|
EVSYS.CH6MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 7 source: None
|
|
EVSYS.CH7MUX = EVSYS_CHMUX_OFF_gc;
|
|
// Event System Channel 0 Digital Filter Coefficient: 4 Samples
|
|
// Quadrature Decoder: Off
|
|
EVSYS.CH0CTRL = (EVSYS.CH0CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
EVSYS_DIGFILT_4SAMPLES_gc;
|
|
// Event System Channel 1 Digital Filter Coefficient: 4 Samples
|
|
EVSYS.CH1CTRL = EVSYS_DIGFILT_4SAMPLES_gc;
|
|
// Event System Channel 2 Digital Filter Coefficient: 1 Sample
|
|
// Quadrature Decoder: Off
|
|
EVSYS.CH2CTRL = (EVSYS.CH2CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel 3 Digital Filter Coefficient: 1 Sample
|
|
EVSYS.CH3CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel 4 Digital Filter Coefficient: 1 Sample
|
|
// Quadrature Decoder: Off
|
|
EVSYS.CH4CTRL = (EVSYS.CH4CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel 5 Digital Filter Coefficient: 1 Sample
|
|
EVSYS.CH5CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel 6 Digital Filter Coefficient: 1 Sample
|
|
EVSYS.CH6CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel 7 Digital Filter Coefficient: 1 Sample
|
|
EVSYS.CH7CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// Event System Channel output: Disabled
|
|
PORTCFG.CLKEVOUT &= ~PORTCFG_EVOUT_gm;
|
|
PORTCFG.EVOUTSEL &= ~PORTCFG_EVOUTSEL_gm;
|
|
}
|
|
|
|
//void event_system_init(void)
|
|
//{
|
|
// // Event System Channel 0 source: RTC Overflow
|
|
// EVSYS.CH0MUX = EVSYS_CHMUX_RTC_OVF_gc;
|
|
// // Event System Channel 1 source: None
|
|
// EVSYS.CH1MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 2 source: None
|
|
// EVSYS.CH2MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 3 source: None
|
|
// EVSYS.CH3MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 4 source: None
|
|
// EVSYS.CH4MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 5 source: None
|
|
// EVSYS.CH5MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 6 source: None
|
|
// EVSYS.CH6MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 7 source: None
|
|
// EVSYS.CH7MUX = EVSYS_CHMUX_OFF_gc;
|
|
// // Event System Channel 0 Digital Filter Coefficient: 1 Sample
|
|
// // Quadrature Decoder: Off
|
|
// EVSYS.CH0CTRL = (EVSYS.CH0CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
// EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 1 Digital Filter Coefficient: 1 Sample
|
|
// EVSYS.CH1CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 2 Digital Filter Coefficient: 1 Sample
|
|
// // Quadrature Decoder: Off
|
|
// EVSYS.CH2CTRL = (EVSYS.CH2CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
// EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 3 Digital Filter Coefficient: 1 Sample
|
|
// EVSYS.CH3CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 4 Digital Filter Coefficient: 1 Sample
|
|
// // Quadrature Decoder: Off
|
|
// EVSYS.CH4CTRL = (EVSYS.CH4CTRL & (~(EVSYS_QDIRM_gm | EVSYS_QDIEN_bm | EVSYS_QDEN_bm | EVSYS_DIGFILT_gm))) |
|
|
// EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 5 Digital Filter Coefficient: 1 Sample
|
|
// EVSYS.CH5CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 6 Digital Filter Coefficient: 1 Sample
|
|
// EVSYS.CH6CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel 7 Digital Filter Coefficient: 1 Sample
|
|
// EVSYS.CH7CTRL = EVSYS_DIGFILT_1SAMPLE_gc;
|
|
// // Event System Channel output: Disabled
|
|
// PORTCFG.CLKEVOUT &= ~PORTCFG_EVOUT_gm;
|
|
// PORTCFG.EVOUTSEL &= ~PORTCFG_EVOUTSEL_gm;
|
|
//}
|
|
|
|
// Disable a Timer/Counter type TC1
|
|
void tc1_disable(TC1_t* ptc)
|
|
{
|
|
// Timer/Counter off
|
|
ptc->CTRLA = TC_CLKSEL_OFF_gc;
|
|
// Issue a reset command
|
|
ptc->CTRLFSET = TC_CMD_RESET_gc;
|
|
}
|
|
|
|
|
|
// Timer/Counter TCC1 initialization
|
|
void tcc1_init(void)
|
|
{
|
|
unsigned char s;
|
|
// Note: The correct PORTC direction for the Compare Channels
|
|
// outputs is configured in the ports_init function.
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
// Disable and reset the timer/counter just to be sure
|
|
tc1_disable(&TCC1);
|
|
// Clock source: Event Channel 0
|
|
TCC1.CTRLA = TC_CLKSEL_EVCH0_gc;
|
|
// Mode: Normal Operation, Overflow Int./Event on TOP
|
|
// Compare/Capture on channel A: On
|
|
// Compare/Capture on channel B: Off
|
|
TCC1.CTRLB = (0 << TC1_CCBEN_bp) | (1 << TC1_CCAEN_bp) |
|
|
TC_WGMODE_NORMAL_gc;
|
|
// Capture event source: Event Channel 0
|
|
// Capture event action: Input Capture
|
|
TCC1.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH0_gc;
|
|
// Set Timer/Counter in 8bit mode
|
|
TCC1.CTRLE = TC_BYTEM_BYTEMODE_gc;
|
|
// Overflow interrupt: Disabled
|
|
// Error interrupt: Disabled
|
|
TCC1.INTCTRLA = TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_OFF_gc;
|
|
// Compare/Capture channel A interrupt: Medium Level
|
|
// Compare/Capture channel B interrupt: Disabled
|
|
TCC1.INTCTRLB = TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_MED_gc;
|
|
// High resolution extension: Off
|
|
HIRESC.CTRLA &= ~HIRES_HREN1_bm;
|
|
// Clear the interrupt flags
|
|
TCC1.INTFLAGS = TCC1.INTFLAGS;
|
|
// Set Counter register
|
|
TCC1.CNT = 0x0000;
|
|
// Set Period register
|
|
TCC1.PER = 0x0000;
|
|
// Set channel A Compare/Capture register
|
|
TCC1.CCA = 0x0001;
|
|
// Set channel B Compare/Capture register
|
|
TCC1.CCB = 0x0000;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
}
|
|
|
|
// Timer/Counter TCD0 initialization
|
|
void tcd0_init(void)
|
|
{
|
|
unsigned char s;
|
|
// Note: The correct PORTD direction for the Compare Channels
|
|
// outputs is configured in the ports_init function.
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
// Disable and reset the timer/counter just to be sure
|
|
tc0_disable(&TCD0);
|
|
// Clock source: ClkPer/1024
|
|
TCD0.CTRLA = TC_CLKSEL_DIV1024_gc;
|
|
// Mode: Normal Operation, Overflow Int./Event on TOP
|
|
// Compare/Capture on channel A: Off
|
|
// Compare/Capture on channel B: Off
|
|
// Compare/Capture on channel C: Off
|
|
// Compare/Capture on channel D: Off
|
|
TCD0.CTRLB = (0 << TC0_CCDEN_bp) | (0 << TC0_CCCEN_bp) | (0 << TC0_CCBEN_bp) | (0 << TC0_CCAEN_bp) |
|
|
TC_WGMODE_NORMAL_gc;
|
|
// Capture event source: Event Channel 0
|
|
// Capture event action: Input Capture
|
|
TCD0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH0_gc;
|
|
// Set Timer/Counter in Normal mode
|
|
TCD0.CTRLE = TC_BYTEM_NORMAL_gc;
|
|
// Overflow interrupt: Disabled
|
|
// Error interrupt: Disabled
|
|
TCD0.INTCTRLA = TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_OFF_gc;
|
|
// Compare/Capture channel A interrupt: Medium Level
|
|
// Compare/Capture channel B interrupt: Disabled
|
|
// Compare/Capture channel C interrupt: Disabled
|
|
// Compare/Capture channel D interrupt: Disabled
|
|
TCD0.INTCTRLB = TC_CCDINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_MED_gc;
|
|
// High resolution extension: Off
|
|
HIRESD.CTRLA &= ~HIRES_HREN0_bm;
|
|
// Clear the interrupt flags
|
|
TCD0.INTFLAGS = TCD0.INTFLAGS;
|
|
// Set Counter register
|
|
TCD0.CNT = 0x0000;
|
|
// Set Period register
|
|
TCD0.PER = 0x0000;
|
|
// Set channel A Compare/Capture register
|
|
TCD0.CCA = 0x0000;
|
|
// Set channel B Compare/Capture register
|
|
TCD0.CCB = 0x0000;
|
|
// Set channel C Compare/Capture register
|
|
TCD0.CCC = 0x0000;
|
|
// Set channel D Compare/Capture register
|
|
TCD0.CCD = 0x0000;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
}
|
|
|
|
// Timer/Counter TCD1 initialization
|
|
void tcd1_init(void)
|
|
{
|
|
unsigned char s;
|
|
// Note: The correct PORTD direction for the Compare Channels
|
|
// outputs is configured in the ports_init function.
|
|
// Save interrupts enabled/disabled state
|
|
s = SREG;
|
|
// Disable interrupts
|
|
#asm("cli")
|
|
// Disable and reset the timer/counter just to be sure
|
|
tc1_disable(&TCD1);
|
|
// Clock source: ClkPer/1024
|
|
TCD1.CTRLA = TC_CLKSEL_DIV1024_gc;
|
|
// Mode: Normal Operation, Overflow Int./Event on TOP
|
|
// Compare/Capture on channel A: Off
|
|
// Compare/Capture on channel B: Off
|
|
TCD1.CTRLB = (0 << TC1_CCBEN_bp) | (0 << TC1_CCAEN_bp) |
|
|
TC_WGMODE_NORMAL_gc;
|
|
// Capture event source: Event Channel 1
|
|
// Capture event action: Input Capture
|
|
TCD1.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH1_gc;
|
|
// Set Timer/Counter in Normal mode
|
|
TCD1.CTRLE = TC_BYTEM_NORMAL_gc;
|
|
// Overflow interrupt: Disabled
|
|
// Error interrupt: Disabled
|
|
TCD1.INTCTRLA = TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_OFF_gc;
|
|
// Compare/Capture channel A interrupt: Medium Level
|
|
// Compare/Capture channel B interrupt: Disabled
|
|
TCD1.INTCTRLB = TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_MED_gc;
|
|
// High resolution extension: Off
|
|
HIRESD.CTRLA &= ~HIRES_HREN1_bm;
|
|
// Clear the interrupt flags
|
|
TCD1.INTFLAGS = TCD1.INTFLAGS;
|
|
// Set Counter register
|
|
TCD1.CNT = 0x0000;
|
|
// Set Period register
|
|
TCD1.PER = 0x0000;
|
|
// Set channel A Compare/Capture register
|
|
TCD1.CCA = 0x0000;
|
|
// Set channel B Compare/Capture register
|
|
TCD1.CCB = 0x0000;
|
|
// Restore interrupts enabled/disabled state
|
|
SREG = s;
|
|
}
|
|
|
|
// Timer/Counter TCC1 Compare/Capture A interrupt service routine
|
|
interrupt [TCC1_CCA_vect] void tcc1_compare_capture_a_isr(void)
|
|
{
|
|
// Ensure that the Compare/Capture A interrupt flag is cleared
|
|
if (TCC1.INTFLAGS & TC1_CCAIF_bm)
|
|
{
|
|
TCC1.INTFLAGS |= TC1_CCAIF_bm;
|
|
}
|
|
|
|
IncreaseTimestamp(1, 983, 505);
|
|
}
|
|
|
|
// Timer/Counter TCD0 Compare/Capture A interrupt service routine
|
|
interrupt [TCD0_CCA_vect] void tcd0_compare_capture_a_isr(void)
|
|
{
|
|
// Ensure that the Compare/Capture A interrupt flag is cleared
|
|
if (TCD0.INTFLAGS & TC0_CCAIF_bm) TCD0.INTFLAGS |= TC0_CCAIF_bm;
|
|
|
|
// Write your code here
|
|
Switch_LEDs_On(0x04 << 1);
|
|
}
|
|
|
|
// Timer/Counter TCD1 Compare/Capture A interrupt service routine
|
|
interrupt [TCD1_CCA_vect] void tcd1_compare_capture_a_isr(void)
|
|
{
|
|
// Ensure that the Compare/Capture A interrupt flag is cleared
|
|
if (TCD1.INTFLAGS & TC1_CCAIF_bm) TCD1.INTFLAGS |= TC1_CCAIF_bm;
|
|
|
|
// Write your code here
|
|
Switch_LEDs_On(0x04 << 1);
|
|
}
|
|
|