2016-10-07 23:44:50 +02:00
|
|
|
/*
|
|
|
|
|
* System.c
|
|
|
|
|
*
|
|
|
|
|
* Created on: 10.02.2013
|
|
|
|
|
* Author: skuser
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "System.h"
|
|
|
|
|
#include "LED.h"
|
|
|
|
|
#include <avr/interrupt.h>
|
|
|
|
|
|
|
|
|
|
#ifndef WDT_PER_500CLK_gc
|
|
|
|
|
#define WDT_PER_500CLK_gc WDT_PER_512CLK_gc
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
ISR(BADISR_vect) {
|
2017-11-07 15:53:23 +01:00
|
|
|
//LED_PORT.OUTSET = LED_RED;
|
2019-11-15 10:21:40 +01:00
|
|
|
while (1);
|
2016-10-07 23:44:50 +02:00
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
ISR(RTC_OVF_vect) {
|
2017-11-07 15:53:23 +01:00
|
|
|
SYSTEM_TICK_REGISTER += SYSTEM_TICK_PERIOD;
|
2016-10-07 23:44:50 +02:00
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemInit(void) {
|
2016-10-07 23:44:50 +02:00
|
|
|
if (RST.STATUS & RST_WDRF_bm) {
|
|
|
|
|
/* On Watchdog reset clear WDRF bit, disable watchdog
|
|
|
|
|
* and jump into bootloader */
|
|
|
|
|
RST.STATUS = RST_WDRF_bm;
|
|
|
|
|
|
|
|
|
|
CCP = CCP_IOREG_gc;
|
|
|
|
|
WDT.CTRL = WDT_CEN_bm;
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
asm volatile("jmp %0"::"i"(BOOT_SECTION_START + 0x1FC));
|
2016-10-07 23:44:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* XTAL x 2 as SysCLK */
|
|
|
|
|
OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
|
|
|
|
|
OSC.CTRL |= OSC_XOSCEN_bm;
|
2019-11-15 10:21:40 +01:00
|
|
|
while (!(OSC.STATUS & OSC_XOSCRDY_bm))
|
2016-10-07 23:44:50 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (2 << OSC_PLLFAC_gp);
|
|
|
|
|
OSC.CTRL |= OSC_PLLEN_bm;
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
while (!(OSC.STATUS & OSC_PLLRDY_bm))
|
2017-11-07 15:53:23 +01:00
|
|
|
;
|
2016-10-07 23:44:50 +02:00
|
|
|
|
2017-11-07 15:53:23 +01:00
|
|
|
/* Set PLL as main clock */
|
|
|
|
|
CCP = CCP_IOREG_gc;
|
|
|
|
|
CLK.CTRL = CLK_SCLKSEL_PLL_gc;
|
2016-10-07 23:44:50 +02:00
|
|
|
|
2017-11-07 15:53:23 +01:00
|
|
|
SYSTEM_TICK_REGISTER = 0;
|
2016-10-07 23:44:50 +02:00
|
|
|
|
|
|
|
|
/* Enable RTC with roughly 1kHz clock for system tick
|
|
|
|
|
* and to wake up while sleeping. */
|
|
|
|
|
CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm;
|
|
|
|
|
RTC.PER = SYSTEM_TICK_PERIOD - 1;
|
|
|
|
|
RTC.COMP = SYSTEM_TICK_PERIOD - 1;
|
|
|
|
|
RTC.CTRL = RTC_PRESCALER_DIV1_gc;
|
|
|
|
|
RTC.INTCTRL = RTC_OVFINTLVL_LO_gc;
|
|
|
|
|
|
|
|
|
|
/* Enable EEPROM data memory mapping */
|
|
|
|
|
//NVM.CTRLB |= NVM_EEMAPEN_bm;
|
|
|
|
|
|
|
|
|
|
/* Enable DMA */
|
2017-11-07 15:53:23 +01:00
|
|
|
DMA.CTRL = DMA_ENABLE_bm | DMA_DBUFMODE_DISABLED_gc | DMA_PRIMODE_RR0123_gc;
|
2016-10-07 23:44:50 +02:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemReset(void) {
|
2016-10-07 23:44:50 +02:00
|
|
|
CCP = CCP_IOREG_gc;
|
|
|
|
|
RST.CTRL = RST_SWRST_bm;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemEnterBootloader(void) {
|
2016-10-07 23:44:50 +02:00
|
|
|
/* Use Watchdog timer to reset into bootloader. */
|
|
|
|
|
CCP = CCP_IOREG_gc;
|
|
|
|
|
WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemStartUSBClock(void) {
|
2017-11-07 15:53:23 +01:00
|
|
|
//SystemSleepDisable();
|
2016-10-07 23:44:50 +02:00
|
|
|
#if 0
|
|
|
|
|
/* 48MHz USB Clock using 12MHz XTAL */
|
|
|
|
|
OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
|
|
|
|
|
OSC.CTRL |= OSC_XOSCEN_bm;
|
2019-11-15 10:21:40 +01:00
|
|
|
while (!(OSC.STATUS & OSC_XOSCRDY_bm))
|
2016-10-07 23:44:50 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp);
|
|
|
|
|
|
|
|
|
|
OSC.CTRL |= OSC_PLLEN_bm;
|
2019-11-15 10:21:40 +01:00
|
|
|
while (!(OSC.STATUS & OSC_PLLRDY_bm))
|
2016-10-07 23:44:50 +02:00
|
|
|
;
|
|
|
|
|
#else
|
|
|
|
|
/* Use internal HS RC for USB */
|
|
|
|
|
OSC.CTRL |= OSC_RC32MEN_bm;
|
2019-11-15 10:21:40 +01:00
|
|
|
while (!(OSC.STATUS & OSC_RC32MRDY_bm))
|
2016-10-07 23:44:50 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
/* Load RC32 CAL values for 48MHz use */
|
|
|
|
|
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
|
|
|
|
|
DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA));
|
|
|
|
|
DFLLRC32M.CALB = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC));
|
|
|
|
|
NVM.CMD = NVM_CMD_NO_OPERATION_gc;
|
|
|
|
|
|
|
|
|
|
/* For USBSOF operation, whe need to use COMP = 48MHz/1kHz = 0xBB80 */
|
|
|
|
|
DFLLRC32M.COMP1 = 0x80;
|
|
|
|
|
DFLLRC32M.COMP2 = 0xBB;
|
|
|
|
|
|
|
|
|
|
/* Select USBSOF as DFLL source */
|
|
|
|
|
OSC.DFLLCTRL &= ~OSC_RC32MCREF_gm;
|
|
|
|
|
OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc;
|
|
|
|
|
|
|
|
|
|
/* Enable DFLL */
|
|
|
|
|
DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemStopUSBClock(void) {
|
2017-11-07 15:53:23 +01:00
|
|
|
//SystemSleepEnable();
|
2016-10-07 23:44:50 +02:00
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
/* Disable USB Clock to minimize power consumption */
|
|
|
|
|
CLK.USBCTRL &= ~CLK_USBSEN_bm;
|
|
|
|
|
OSC.CTRL &= ~OSC_PLLEN_bm;
|
|
|
|
|
OSC.CTRL &= ~OSC_XOSCEN_bm;
|
|
|
|
|
#else
|
|
|
|
|
/* Disable USB Clock to minimize power consumption */
|
|
|
|
|
CLK.USBCTRL &= ~CLK_USBSEN_bm;
|
|
|
|
|
DFLLRC32M.CTRL &= ~DFLL_ENABLE_bm;
|
|
|
|
|
OSC.CTRL &= ~OSC_RC32MEN_bm;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 10:21:40 +01:00
|
|
|
void SystemInterruptInit(void) {
|
2016-10-07 23:44:50 +02:00
|
|
|
/* Enable all interrupt levels */
|
|
|
|
|
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
|
|
|
|
|
sei();
|
|
|
|
|
}
|