//----------------------------------------------------------------------------- static void uart_init(uint32_t baud) { uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU; HAL_GPIO_UART_TX_out(); HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_C_Val); HAL_GPIO_UART_RX_in(); HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_C_Val); PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM0_GCLK_ID_CORE) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); SERCOM0->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_CTRLA_RXPO(3/*PAD3*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/); SERCOM0->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/); SERCOM0->USART.BAUD.reg = (uint16_t)br+1; SERCOM0->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; }
/*************************************************************************//** *****************************************************************************/ void HAL_TimerInit(void) { halTimerIrqCount = 0; PM->APBCMASK.reg |= PM_APBCMASK_TC4; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(0x15/*TC4,TC5*/) | GCLK_CLKCTRL_GEN(0); SYSTIMER.CTRLA.reg = TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT16_Val) | TC_CTRLA_WAVEGEN(TC_CTRLA_WAVEGEN_MFRQ_Val) | TC_CTRLA_PRESCALER(3 /*DIV8*/) | TC_CTRLA_PRESCSYNC(TC_CTRLA_PRESCSYNC_PRESC_Val); halTimerSync(); SYSTIMER.COUNT.reg = 0; halTimerSync(); SYSTIMER.CC[0].reg = TIMER_TOP; halTimerSync(); SYSTIMER.CTRLA.reg = TC_CTRLA_ENABLE; halTimerSync(); SYSTIMER.INTENSET.reg = TC_INTENSET_MC(0); NVIC_EnableIRQ(TC4_IRQn); }
void RtcInit() { // SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ENABLE | SYSCTRL_XOSC32K_EN32K; // //wait for crystal to warm up // while((SYSCTRL->PCLKSR.reg & (SYSCTRL_PCLKSR_XOSC32KRDY)) == 0); GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(8); GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_SRC(GCLK_SOURCE_OSC8M) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Configure RTC GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(2); RTC->MODE1.CTRL.reg = RTC_MODE1_CTRL_MODE_COUNT16; while (RTC->MODE1.STATUS.bit.SYNCBUSY); // Prescaler needs to be enabled separately from the mode for some reason RTC->MODE1.CTRL.reg |= RTC_MODE1_CTRL_PRESCALER_DIV1; while (RTC->MODE1.STATUS.bit.SYNCBUSY); RTC->MODE1.PER.reg = 998; while (RTC->MODE1.STATUS.bit.SYNCBUSY); RTC->MODE1.READREQ.reg |= RTC_READREQ_RCONT | RTC_READREQ_ADDR(0x10); RTC->MODE1.INTENSET.reg = RTC_MODE1_INTENSET_OVF; RTC->MODE1.CTRL.bit.ENABLE = 1; while (RTC->MODE1.STATUS.bit.SYNCBUSY); NVIC_EnableIRQ(RTC_IRQn); }
/** Configures and starts the DFLL in closed loop mode with the given reference * generator. * * \param[in] source_generator Reference generator to use for the DFLL */ static void init_dfll( const enum system_clock_source source_generator) { struct system_gclk_gen_config cpu_clock_conf; system_gclk_gen_get_config_defaults(&cpu_clock_conf); cpu_clock_conf.output_enable = ENABLE_CPU_CLOCK_OUT; /* Switch to OSC8M/OSC16M while the DFLL is being reconfigured */ #if SAML21 cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC16M; #else cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC8M; #endif system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf); /* Turn off DFLL before adjusting its configuration */ system_clock_source_disable(SYSTEM_CLOCK_SOURCE_DFLL); /* Configure DFLL reference clock, use raw register write to * force-configure the channel even if the currently selected generator * clock has failed */ #if SAML21 GCLK->PCHCTRL[SYSCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_GEN(source_generator); #else GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SYSCTRL_GCLK_ID_DFLL48) | GCLK_CLKCTRL_GEN(source_generator); #endif system_gclk_chan_enable(SYSCTRL_GCLK_ID_DFLL48); /* Configure DFLL */ struct system_clock_source_dfll_config config_dfll; system_clock_source_dfll_get_config_defaults(&config_dfll); config_dfll.on_demand = false; config_dfll.loop_mode = SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED; config_dfll.multiply_factor = (48000000UL / system_gclk_chan_get_hz(SYSCTRL_GCLK_ID_DFLL48)); system_clock_source_dfll_set_config(&config_dfll); /* Restart DFLL */ system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL); while (system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL) == false) { /* Wait for DFLL to be stable before switch back */ } /* Switch back to the DFLL as the CPU clock source */ cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_DFLL; system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf); };
/*************************************************************************//** *****************************************************************************/ void HAL_UartInit(uint32_t baudrate) { uint64_t brr = (uint64_t)65536 * (F_CPU - 16 * baudrate) / F_CPU; HAL_GPIO_UART_TXD_out(); HAL_GPIO_UART_TXD_pmuxen(); HAL_GPIO_UART_RXD_in(); HAL_GPIO_UART_RXD_pmuxen(); PORTA_PMUX12 = PORTA_PMUX12_PMUXE(2/*C*/) | PORTA_PMUX12_PMUXO(2/*C*/); PM_APBCMASK |= PM_APBCMASK_SERCOM3; GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(0x10/*SERCOM3_CORE*/) | GCLK_CLKCTRL_GEN(0); SC3_USART_CTRLA = SC3_USART_CTRLA_MODE(1/*USART*/) | SC3_USART_CTRLA_DORD | SC3_USART_CTRLA_RXPO(3/*PAD3*/) | SC3_USART_CTRLA_TXPO/*PAD2*/; halUartSync(); SC3_USART_CTRLB = SC3_USART_CTRLB_TXEN | SC3_USART_CTRLB_RXEN | SC3_USART_CTRLB_CHSIZE(0/*8 bits*/); halUartSync(); SC3_USART_BAUD = (uint16_t)brr; halUartSync(); SC3_USART_CTRLA |= SC3_USART_CTRLA_ENABLE; halUartSync(); SC3_USART_INTENSET = SC3_USART_INTENSET_RXC; NVIC_ISER = NVIC_ISER_SERCOM3; txFifo.data = txData; txFifo.size = HAL_UART_TX_FIFO_SIZE; txFifo.bytes = 0; txFifo.head = 0; txFifo.tail = 0; rxFifo.data = rxData; rxFifo.size = HAL_UART_RX_FIFO_SIZE; rxFifo.bytes = 0; rxFifo.head = 0; rxFifo.tail = 0; udrEmpty = true; newData = false; }
void SystemInit(void) { // Setup flash to work with 48Mhz clock NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS_HALF; // Enable external 32Khz crystal uint32_t val = (SYSCTRL_XOSC32K_STARTUP(6) | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K); SYSCTRL->XOSC32K.reg = val; SYSCTRL->XOSC32K.reg = val | SYSCTRL_XOSC32K_ENABLE; while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY)) ; // Reset GCLK GCLK->CTRL.reg = GCLK_CTRL_SWRST; while (GCLK->CTRL.reg & GCLK_CTRL_SWRST) ; // Route 32Khz clock to DFLL48M GCLK->GENDIV.reg = GCLK_GENDIV_ID(CLK_32K); GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(CLK_32K) | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_GENEN); GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_ID(MCLK_DFLL48M) | GCLK_CLKCTRL_GEN(CLK_32K) | GCLK_CLKCTRL_CLKEN); // Configure DFLL48M clock SYSCTRL->DFLLCTRL.reg = 0; uint32_t mul = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, CLK_32K_FREQ); SYSCTRL->DFLLMUL.reg = (SYSCTRL_DFLLMUL_CSTEP(31) | SYSCTRL_DFLLMUL_FSTEP(511) | SYSCTRL_DFLLMUL_MUL(mul)); SYSCTRL->DFLLCTRL.reg = (SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK | SYSCTRL_DFLLCTRL_QLDIS | SYSCTRL_DFLLCTRL_ENABLE); uint32_t ready = (SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKC | SYSCTRL_PCLKSR_DFLLLCKF); while ((SYSCTRL->PCLKSR.reg & ready) != ready) ; // Switch main clock to DFLL48M clock GCLK->GENDIV.reg = GCLK_GENDIV_ID(CLK_MAIN); GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(CLK_MAIN) | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN); }
//----------------------------------------------------------------------------- static void timer_init(void) { PM->APBCMASK.reg |= PM_APBCMASK_TC1; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(TC1_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); TC1->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV256 | TC_CTRLA_PRESCSYNC_RESYNC; TC1->COUNT16.COUNT.reg = 0; timer_set_period(PERIOD_SLOW); TC1->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; TC1->COUNT16.INTENSET.reg = TC_INTENSET_MC(1); NVIC_EnableIRQ(TC1_IRQn); }
/*************************************************************************//** *****************************************************************************/ void halPhyInit(void) { // Configure IO pins HAL_GPIO_PHY_SLP_TR_out(); HAL_GPIO_PHY_SLP_TR_clr(); HAL_GPIO_PHY_RST_out(); HAL_GPIO_PHY_IRQ_in(); HAL_GPIO_PHY_IRQ_pmuxen(); HAL_GPIO_PHY_CS_out(); HAL_GPIO_PHY_MISO_in(); HAL_GPIO_PHY_MISO_pmuxen(); HAL_GPIO_PHY_MOSI_out(); HAL_GPIO_PHY_MOSI_pmuxen(); HAL_GPIO_PHY_SCK_out(); HAL_GPIO_PHY_SCK_pmuxen(); // Configure SPI PORT->Group[HAL_GPIO_PORTA].PMUX[9].bit.PMUXE = 2/*C*/; // MOSI PORT->Group[HAL_GPIO_PORTA].PMUX[9].bit.PMUXO = 2/*C*/; // SCK PORT->Group[HAL_GPIO_PORTA].PMUX[8].bit.PMUXE = 2/*C*/; // MISO PM->APBCMASK.reg |= PM_APBCMASK_SERCOM1; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM1_GCLK_ID_CORE) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); SERCOM1->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_RXEN; halPhySpiSync(); #if F_CPU <= 16000000 SERCOM1->SPI.BAUD.reg = 0; #elif F_CPU <= 32000000 SERCOM1->SPI.BAUD.reg = 1; #elif F_CPU <= 48000000 SERCOM1->SPI.BAUD.reg = 2; #else #error Unsupported frequency #endif SERCOM1->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_ENABLE | SERCOM_SPI_CTRLA_MODE_SPI_MASTER | SERCOM_SPI_CTRLA_DIPO(0) | SERCOM_SPI_CTRLA_DOPO; halPhySpiSync(); }
void SaLBuzzerInit() { pinOut(BUZZER); pinCfg(BUZZER); // PM->APBCMASK.reg |= PM_APBCMASK_TC5; // GCLK->GENDIV.reg = GCLK_GENDIV_ID(5) | GCLK_GENDIV_DIV(1); GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5) | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_GENEN; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(TC5_GCLK_ID); TC5->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16| TC_CTRLA_RUNSTDBY | // TC_CTRLA_PRESCSYNC_GCLK | TC_CTRLA_PRESCALER_DIV4; // TC5->COUNT16.EVCTRL.bit.EVACT = 0x1; TC5->COUNT16.CC[0].bit.CC = 700; //TC5->COUNT16.PER.reg = 0x02; TC5->COUNT16.INTENSET.reg = TC_INTENSET_MC0; TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; TC5->COUNT16.EVCTRL.bit.EVACT = 0x1; NVIC_EnableIRQ(TC5_IRQn); NVIC_SetPriority(TC5_IRQn,0xFFF); TC5->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; }
// **************************************************************************** void HAL_spi_init(void) { // Use GLKGEN0 (48 MHz) as clock source for SPI GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SPI_SERCOM_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); // Reset the peripheral SPI_SERCOM->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_SWRST; while (SPI_SERCOM->SPI.CTRLA.reg & SERCOM_SPI_CTRLA_SWRST); // 12 MHz SPI clock @ 48 MHz SPI_SERCOM->SPI.BAUD.reg = 1; // Enable the SPI master, mode 0 SPI_SERCOM->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | SERCOM_SPI_CTRLA_DOPO(0) | SERCOM_SPI_CTRLA_ENABLE ; }
//----------------------------------------------------------------------------- void udc_init(void) { HAL_GPIO_USB_DM_pmuxen(PORT_PMUX_PMUXE_G_Val); HAL_GPIO_USB_DP_pmuxen(PORT_PMUX_PMUXE_G_Val); PM->APBBMASK.reg |= PM_APBBMASK_USB; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(USB_GCLK_ID) | GCLK_CLKCTRL_GEN(0); USB->DEVICE.CTRLA.bit.SWRST = 1; while (USB->DEVICE.SYNCBUSY.bit.SWRST); USB->DEVICE.PADCAL.bit.TRANSN = NVM_READ_CAL(USB_TRANSN); USB->DEVICE.PADCAL.bit.TRANSP = NVM_READ_CAL(USB_TRANSP); USB->DEVICE.PADCAL.bit.TRIM = NVM_READ_CAL(USB_TRIM); memset((uint8_t *)udc_mem, 0, sizeof(udc_mem)); USB->DEVICE.DESCADD.reg = (uint32_t)udc_mem; USB->DEVICE.CTRLA.bit.MODE = USB_CTRLA_MODE_DEVICE_Val; USB->DEVICE.CTRLA.bit.RUNSTDBY = 1; USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; USB->DEVICE.CTRLB.bit.DETACH = 0; USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_EORST; USB->DEVICE.DeviceEndpoint[0].EPINTENSET.bit.RXSTP = 1; USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE; for (int i = 0; i < USB_EPT_NUM; i++) { udc_reset_endpoint(i, USB_IN_ENDPOINT); udc_reset_endpoint(i, USB_OUT_ENDPOINT); } NVIC_EnableIRQ(USB_IRQn); }
/*************************************************************************//** *****************************************************************************/ void HAL_TimerInit(void) { halTimerIrqCount = 0; PM_APBCMASK |= PM_APBCMASK_TC4; GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(0x15/*TC4,TC5*/) | GCLK_CLKCTRL_GEN(0); TC4_16_CTRLA = TC4_16_CTRLA_MODE(0/*16 bit*/) | TC4_16_CTRLA_WAVEGEN(1/*MFRQ*/) | TC4_16_CTRLA_PRESCALER(3/*DIV8*/) | TC4_16_CTRLA_PRESCSYNC(0x1/*PRESC*/); halTimerSync(); TC4_16_COUNT = 0; halTimerSync(); TC4_16_CC0 = TIMER_TOP; halTimerSync(); TC4_16_CTRLA |= TC4_16_CTRLA_ENABLE; halTimerSync(); TC4_16_INTENSET = TC4_16_INTENSET_MC0; NVIC_ISER = NVIC_ISER_TC4; }
// **************************************************************************** void HAL_uart_init(uint32_t baudrate) { #define UART_CLK 48000000 uint64_t brr = (uint64_t)65536 * (UART_CLK - 16 * baudrate) / UART_CLK; // Use GLKGEN0 (48 MHz) as clock source for the UART GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(UART_SERCOM_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); // Run UART from GCLK; Setup Rx and Tx pads UART_SERCOM->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_CTRLA_RXPO(HAL_GPIO_RX.rxpo) | SERCOM_USART_CTRLA_TXPO(tx_pad); // Enable transmit and receive; 8 bit characters UART_SERCOM->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0); // 8 bits while (UART_SERCOM->USART.SYNCBUSY.reg); UART_SERCOM->USART.BAUD.reg = (uint16_t)brr; while (UART_SERCOM->USART.SYNCBUSY.reg); UART_SERCOM->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; while (UART_SERCOM->USART.SYNCBUSY.reg); // Enable the receive interrupt UART_SERCOM->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC; NVIC_EnableIRQ(UART_SERCOM_IRQN); }
/** * @brief Configure clock sources and the cpu frequency */ static void clk_init(void) { /* enable clocks for the power, sysctrl and gclk modules */ PM->APBAMASK.reg = (PM_APBAMASK_PM | PM_APBAMASK_SYSCTRL | PM_APBAMASK_GCLK); /* adjust NVM wait states, see table 42.30 (p. 1070) in the datasheet */ #if (CLOCK_CORECLOCK > 24000000) PM->APBAMASK.reg |= PM_AHBMASK_NVMCTRL; NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(1); PM->APBAMASK.reg &= ~PM_AHBMASK_NVMCTRL; #endif /* configure internal 8MHz oscillator to run without prescaler */ SYSCTRL->OSC8M.bit.PRESC = 0; SYSCTRL->OSC8M.bit.ONDEMAND = 1; SYSCTRL->OSC8M.bit.RUNSTDBY = 0; SYSCTRL->OSC8M.bit.ENABLE = 1; while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {} #if CLOCK_USE_PLL /* reset the GCLK module so it is in a known state */ GCLK->CTRL.reg = GCLK_CTRL_SWRST; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} /* setup generic clock 1 to feed DPLL with 1MHz */ GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) | GCLK_GENDIV_ID(1)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_ID(1)); GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN(1) | GCLK_CLKCTRL_ID(1) | GCLK_CLKCTRL_CLKEN); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} /* enable PLL */ SYSCTRL->DPLLRATIO.reg = (SYSCTRL_DPLLRATIO_LDR(CLOCK_PLL_MUL)); SYSCTRL->DPLLCTRLB.reg = (SYSCTRL_DPLLCTRLB_REFCLK_GCLK); SYSCTRL->DPLLCTRLA.reg = (SYSCTRL_DPLLCTRLA_ENABLE); while(!(SYSCTRL->DPLLSTATUS.reg & (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK))) {} /* select the PLL as source for clock generator 0 (CPU core clock) */ GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_PLL_DIV) | GCLK_GENDIV_ID(0)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_FDPLL | GCLK_GENCTRL_ID(0)); #else /* do not use PLL, use internal 8MHz oscillator directly */ GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_DIV) | GCLK_GENDIV_ID(0)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_ID(0)); #endif /* make sure we synchronize clock generator 0 before we go on */ while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} /* Setup Clock generator 2 with divider 1 (32.768kHz) */ GCLK->GENDIV.reg = (GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(0)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_SRC_OSCULP32K); while (GCLK->STATUS.bit.SYNCBUSY) {} /* redirect all peripherals to a disabled clock generator (7) by default */ for (int i = 0x3; i <= 0x22; i++) { GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 ); while (GCLK->STATUS.bit.SYNCBUSY) {} } }
void rtc_init(void) { /* step #1: initialize SERCOM */ // enable clock to SERCOM3 - 8MHz core clock, 32KHz slow clock GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_CORE) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_SLOW) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(2); PM->APBCMASK.reg |= PM_APBCMASK_SERCOM3; // configure PA22/PA23 as SC3[0] and SC3[1] respectively PORT->Group[0].PMUX[23/2].bit.PMUXO = PORT_PMUX_PMUXO_C_Val; PORT->Group[0].PMUX[22/2].bit.PMUXE = PORT_PMUX_PMUXE_C_Val; PORT->Group[0].PINCFG[23].bit.PMUXEN = 1; PORT->Group[0].PINCFG[22].bit.PMUXEN = 1; // initialize SERCOM3 into TWI mode // high/low time periods are (5+N) GCLK cycles // values of 5 give 400KHz TWI speed // values of 15 give 200KHz TWI speed // values of 75 gives 50KHz TWI speed SERCOM3->I2CM.BAUD.reg = \ (15<<SERCOM_I2CM_BAUD_BAUD_Pos)| \ (15<<SERCOM_I2CM_BAUD_BAUDLOW_Pos); while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); // enable TWI mode SERCOM3->I2CM.CTRLA.reg = \ (3<<SERCOM_I2CM_CTRLA_SDAHOLD_Pos) |\ (0<<SERCOM_I2CM_CTRLA_INACTOUT_Pos) |\ (0<<SERCOM_I2CM_CTRLA_PINOUT_Pos) |\ SERCOM_I2CM_CTRLA_MODE_I2C_MASTER |\ (0<<SERCOM_I2CM_CTRLA_ENABLE_Pos); while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); // don't enable smart mode SERCOM3->I2CM.CTRLB.reg = 0; while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); // force TWI unit into idle mode SERCOM3->I2CM.STATUS.bit.BUSSTATE = 1; while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); // enable! SERCOM3->I2CM.CTRLA.bit.ENABLE = 1; while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); // force TWI unit into idle mode SERCOM3->I2CM.STATUS.bit.BUSSTATE = 1; while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY); /* step #2: initialize RTC chip itself */ // read entire RTC chip rtc_read(0x00,(uint8_t *) &rtc_data,sizeof(rtc_data)); // check config uint8_t csr_int_cache = rtc_data.csr.csr_int; // WRTC=1 (enable RTC) // FOBATB=1 (disable /INT output) // FO=10 (1Hz frequency output) rtc_data.csr.csr_int = (1<<6)|(1<<4)|(10<<0); // clear timestamps, VDD brownout = 2.8V, battery brownouts = see datasheet. rtc_data.csr.csr_pwr_vdd = (1<<7)|(2<<0); rtc_data.csr.csr_pwr_vbat = (0<<6)|(3<<3)|(3<<0); // rest of CSR registers is trimming - leave alone! // disable alarms rtc_data.alarm.alarm_sca0 = 0; rtc_data.alarm.alarm_mna0 = 0; rtc_data.alarm.alarm_hra0 = 0; rtc_data.alarm.alarm_dta0 = 0; rtc_data.alarm.alarm_moa0 = 0; rtc_data.alarm.alarm_dwa0 = 0; // disable DST rtc_data.dstcr.dstcr_DstMoFd = 0; // write everything back to RTC rtc_write(0x07,&rtc_data.csr.csr_sr,42); // if RTCF was set, write new time (00:00, jan 1, 2016) if (csr_int_cache & 0x01) { rtc_data.rtc.rtc_sc = 0x00; rtc_data.rtc.rtc_mn = 0x00; rtc_data.rtc.rtc_hr = 0x00; rtc_data.rtc.rtc_dt = 0x01; rtc_data.rtc.rtc_mo = 0x01; rtc_data.rtc.rtc_yr = 0x16; rtc_data.rtc.rtc_dw = 0; rtc_write(0x00,(uint8_t *) &rtc_data, 7); } }
void cal_init(void) { // CONFIGURE EIC // configure PA21 (INT from RTC, EXTINT5) input as EIC interrupt PORT->Group[0].PMUX[21/2].bit.PMUXO = PORT_PMUX_PMUXO_A_Val; PORT->Group[0].PINCFG[21].bit.PMUXEN = 1; // enable EIC clock PM->APBAMASK.reg |= PM_APBAMASK_EIC; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(EIC_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); // configure EXTINT5 to pass through EXTINT5 without any filtering/retiming EIC->CONFIG[0].bit.FILTEN5 = 0; EIC->CONFIG[0].bit.SENSE5 = EIC_CONFIG_SENSE5_HIGH_Val; // enable event for this interrupt EIC->EVCTRL.bit.EXTINTEO5 = 1; // enable EIC! EIC->CTRL.reg = EIC_CTRL_ENABLE; // CONFIGURE EVENT SYSTEM // enable event system clock PM->APBCMASK.reg |= PM_APBCMASK_EVSYS; // enable event channel 0 CLK // use GCLK generator 0 for now, we'll change this to GCLK1 later GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_EVSYS_CHANNEL_0; // event generator 0x11 is EXTINT5 and is a copy of what's on the IO pin. // resynchronize to the local GCLK and detect a falling edge. EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_FALLING_EDGE | EVSYS_CHANNEL_PATH_RESYNCHRONIZED | EVSYS_CHANNEL_EVGEN(0x11) | EVSYS_CHANNEL_CHANNEL(0); // event user 0x02 is TC2 // note that EVSYS_USER_CHANNEL(1) actually configures channel 0! EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) | EVSYS_USER_USER(0x02); // CONFIGURE TC2 // Use GCLK0 to clock timer while we configure it, we'll change it to GCLK1 later GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TC2_TC3; // enable APB clock (also enable TC3 clock, though it's probably not needed) PM->APBCMASK.reg |= PM_APBCMASK_TC2 | PM_APBCMASK_TC3; // 32 bit mode, top=CC0 TC2->COUNT32.CTRLA.reg = TC_CTRLA_RUNSTDBY | TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_MODE_COUNT32 | (0<<TC_CTRLA_ENABLE_Pos); while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // overflow every 16M samples, this makes subtracting time easy. TC2->COUNT32.CC[0].reg = CAPTURE_VALUE_MASK; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // zero counter TC2->COUNT32.COUNT.reg = 0; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // clear ONESHOT and DIR bits, so we count upwards and repeat TC2->COUNT32.CTRLBCLR.reg = TC_CTRLBCLR_ONESHOT | TC_CTRLBCLR_DIR; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // enable capture channel 1 TC2->COUNT32.CTRLC.reg = TC_CTRLC_CPTEN1; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // enable event input TC2->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI | TC_EVCTRL_EVACT_OFF; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // clear any pending interrupt flags TC2->COUNT32.INTFLAG.reg = TC_INTFLAG_MC1 | TC_INTFLAG_OVF | TC_INTFLAG_SYNCRDY; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // and fire away! TC2->COUNT32.CTRLA.bit.ENABLE = 1; while(TC2->COUNT32.STATUS.bit.SYNCBUSY); // now switch GCLKs for event and timer to GCLK1 //GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TC2_TC3; //GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_EVSYS_CHANNEL_0; }
// **************************************************************************** void HAL_hardware_init(bool is_servo_reader, bool servo_output_enabled, bool uart_output_enabled) { uint32_t *coarse_p; uint32_t coarse; // FIXME: output diagnostics on UART only if uart_output_enabled is false (void) uart_output_enabled; // ------------------------------------------------ // Perform GPIO initialization as early as possible HAL_gpio_set(HAL_GPIO_BLANK); HAL_gpio_out(HAL_GPIO_BLANK); HAL_gpio_clear(HAL_GPIO_SWITCHED_LIGHT_OUTPUT); HAL_gpio_out(HAL_GPIO_SWITCHED_LIGHT_OUTPUT); HAL_gpio_out(HAL_GPIO_XLAT); HAL_gpio_out(HAL_GPIO_SIN); HAL_gpio_pmuxen(HAL_GPIO_SIN); HAL_gpio_out(HAL_GPIO_SCK); HAL_gpio_pmuxen(HAL_GPIO_SCK); HAL_gpio_in(HAL_GPIO_CH3); HAL_gpio_pmuxen(HAL_GPIO_CH3); HAL_gpio_in(HAL_GPIO_PUSH_BUTTON); HAL_gpio_pmuxen(HAL_GPIO_USB_DM); HAL_gpio_pmuxen(HAL_GPIO_USB_DP); // Turn the status LED on to signify we are initializing HAL_gpio_out(HAL_GPIO_LED); HAL_gpio_out(HAL_GPIO_LED2); HAL_gpio_set(HAL_GPIO_LED); HAL_gpio_set(HAL_GPIO_LED2); // ------------------------------------------------ // Configure GPIOs shared between servo inputs, servo output and UART // Output UART Tx on OUT in all cases when the servo output is disabled if (servo_output_enabled) { HAL_gpio_out(HAL_GPIO_OUT); HAL_gpio_pmuxen(HAL_GPIO_OUT); } else { HAL_gpio_out(HAL_GPIO_TX_ON_OUT); HAL_gpio_pmuxen(HAL_GPIO_TX_ON_OUT); tx_pad = HAL_GPIO_TX_ON_OUT.txpo; } if (is_servo_reader) { HAL_gpio_in(HAL_GPIO_ST); HAL_gpio_pmuxen(HAL_GPIO_ST); HAL_gpio_in(HAL_GPIO_TH); HAL_gpio_pmuxen(HAL_GPIO_TH); } else { HAL_gpio_in(HAL_GPIO_RX); HAL_gpio_pmuxen(HAL_GPIO_RX); // In case we have a UART and a servi output, TH is unused. We can // use TH as Tx signal, just like in the LPC812 Mk4 light controller if (servo_output_enabled) { HAL_gpio_out(HAL_GPIO_TX_ON_TH); HAL_gpio_pmuxen(HAL_GPIO_TX_ON_TH); tx_pad = HAL_GPIO_TX_ON_TH.txpo; } else { HAL_gpio_in(HAL_GPIO_TH); HAL_gpio_pmuxen(HAL_GPIO_TH); } } // ------------------------------------------------ // Since we intend to run at 48 MHz system clock, we neeed to conigure // one wait state for the flash according to the datasheet. NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS(1); // ------------------------------------------------ // Set up the PLL to provide a 48 MHz system clock SYSCTRL->INTFLAG.reg = SYSCTRL_INTFLAG_BOD33RDY | SYSCTRL_INTFLAG_BOD33DET | SYSCTRL_INTFLAG_DFLLRDY; SYSCTRL->DFLLCTRL.reg = 0; while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY)); SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL(48000); // Load PLL calibration values from NVRAM coarse_p = (uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR; coarse = (*coarse_p & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos; SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512); SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE | SYSCTRL_DFLLCTRL_USBCRM | SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_STABLE | SYSCTRL_DFLLCTRL_CCDIS; while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY)); // ------------------------------------------------ // Reset the generic clock control block GCLK->CTRL.reg = GCLK_CTRL_SWRST; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Setup GENCLK0 to run at 48 MHz. This clock is used for high speed // peripherals such as SPI, USB and UART GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(1); GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0) | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Setup GENCLK1 to run at 2 MHz. We use GENCLK1 for timers that need // microsecond resolution (e.g. servo output and servo reader). // We derive the clock from the 48 MHz PLL, so we use a clock divider of // 24 GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) | GCLK_GENDIV_DIV(24); GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(1) | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // ------------------------------------------------ // Turn on power to the peripherals we use PM->APBCMASK.reg = UART_SERCOM_APBCMASK | SPI_SERCOM_APBCMASK | PM_APBAMASK_EIC | PM_APBCMASK_EVSYS | PM_APBCMASK_TCC0 | PM_APBCMASK_TC4 | PM_APBBMASK_USB; // ------------------------------------------------ // Initialize the Event System // Use GLKGEN0 (48 MHz) as clock source for the EVSYS0..2 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EVSYS_0 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EVSYS_1 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EVSYS_2 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); // Always turn on the Generic Clock within EVSYS EVSYS->CTRL.reg = EVSYS_CTRL_GCLKREQ; // ------------------------------------------------ // Configure the SYSTICK to create an interrupt every 1 millisecond SysTick_Config(48000); NVIC_SetPriority(SysTick_IRQn, 0); // ------------------------ // The UART Tx can be used for diagnostics output if it is not in use. // The pin is in use when HAL gets passed "uart_output_enabled==true" // (UART used for pre-processor, winch or slave output), or when we // have a servo reader and the servo output is enabled. // // Or in other words: the UART can output diagnostics on the OUT pin // when it is not in use, or the UART can output diagnostics on the TH/Tx // pin when we the UART reader is in use and no UART output function is // configured. diagnostics_on_uart = !uart_output_enabled; if (is_servo_reader) { if (servo_output_enabled) { diagnostics_on_uart = false; } } __enable_irq(); }
void _sysctrl_init_referenced_generators(void) { void *hw = (void *)SYSCTRL; #if CONF_DFLL_CONFIG == 1 # if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != CONF_DFLL_OPEN_LOOP_MODE hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(0) | GCLK_CLKCTRL_GEN(CONF_DFLL_GCLK) | ( 1 << GCLK_CLKCTRL_CLKEN_Pos )); # endif hri_sysctrl_write_DFLLCTRL_reg(hw, SYSCTRL_DFLLCTRL_ENABLE); while(!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw)) {; } hri_sysctrl_write_DFLLMUL_reg(hw, SYSCTRL_DFLLMUL_CSTEP( CONF_DFLL_CSTEP) | SYSCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP) | SYSCTRL_DFLLMUL_MUL(CONF_DFLL_MUL)); hri_sysctrl_write_DFLLVAL_reg(hw, CONF_DFLLVAL); hri_sysctrl_dfllctrl_reg_t tmp = ( CONF_DFLL_WAITLOCK << SYSCTRL_DFLLCTRL_WAITLOCK_Pos ) | ( CONF_DFLL_BPLCKC << SYSCTRL_DFLLCTRL_BPLCKC_Pos ) | ( CONF_DFLL_QLDIS << SYSCTRL_DFLLCTRL_QLDIS_Pos ) | ( CONF_DFLL_CCDIS << SYSCTRL_DFLLCTRL_CCDIS_Pos ) | ( CONF_DFLL_RUNSTDBY << SYSCTRL_DFLLCTRL_RUNSTDBY_Pos ) | ( CONF_DFLL_USBCRM << SYSCTRL_DFLLCTRL_USBCRM_Pos ) | ( CONF_DFLL_LLAW << SYSCTRL_DFLLCTRL_LLAW_Pos ) | ( CONF_DFLL_STABLE << SYSCTRL_DFLLCTRL_STABLE_Pos ) | ( CONF_DFLL_MODE << SYSCTRL_DFLLCTRL_MODE_Pos ) | ( CONF_DFLL_ENABLE << SYSCTRL_DFLLCTRL_ENABLE_Pos ); hri_sysctrl_write_DFLLCTRL_reg(hw, tmp); #endif #if CONF_DPLL_CONFIG == 1 # if CONF_DPLL_REFCLK == SYSCTRL_DPLLCTRLB_REFCLK_GCLK_Val hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(1) | GCLK_CLKCTRL_GEN(CONF_DPLL_GCLK) | ( 1 << GCLK_CLKCTRL_CLKEN_Pos )); # endif hri_sysctrl_write_DPLLCTRLA_reg(hw, ( CONF_DPLL_RUNSTDBY << SYSCTRL_DPLLCTRLA_RUNSTDBY_Pos ) | ( CONF_DPLL_ENABLE << SYSCTRL_DPLLCTRLA_ENABLE_Pos )); hri_sysctrl_write_DPLLRATIO_reg(hw, SYSCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | SYSCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR)); hri_sysctrl_write_DPLLCTRLB_reg(hw, SYSCTRL_DPLLCTRLB_DIV( CONF_DPLL_DIV) | ( CONF_DPLL_LBYPASS << SYSCTRL_DPLLCTRLB_LBYPASS_Pos ) | SYSCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME) | SYSCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK) | ( CONF_DPLL_WUF << SYSCTRL_DPLLCTRLB_WUF_Pos ) | ( CONF_DPLL_LPEN << SYSCTRL_DPLLCTRLB_LPEN_Pos ) | SYSCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER)); #endif #if CONF_DFLL_CONFIG == 1 # if CONF_DFLL_ENABLE == 1 if (hri_sysctrl_get_DFLLCTRL_MODE_bit(hw)) { # if CONF_DFLL_USBCRM == 0 hri_sysctrl_pclksr_reg_t status_mask = SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKF | SYSCTRL_PCLKSR_DFLLLCKC; # else hri_sysctrl_pclksr_reg_t status_mask = SYSCTRL_PCLKSR_DFLLRDY; # endif while(hri_sysctrl_get_PCLKSR_reg(hw, status_mask) != status_mask) {; } } else { while(!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw)) {; } } # endif # if CONF_DFLL_ONDEMAND == 1 hri_sysctrl_set_DFLLCTRL_ONDEMAND_bit(hw); # endif #endif #if CONF_DPLL_CONFIG == 1 # if CONF_DPLL_ENABLE == 1 while (!( hri_sysctrl_get_DPLLSTATUS_ENABLE_bit(hw) || hri_sysctrl_get_DPLLSTATUS_LOCK_bit(hw) || hri_sysctrl_get_DPLLSTATUS_CLKRDY_bit(hw))) {; } # endif # if CONF_DPLL_ONDEMAND == 1 hri_sysctrl_set_DPLLCTRLA_ONDEMAND_bit(hw); # endif #endif #if CONF_DFLL_CONFIG == 1 while(hri_gclk_get_STATUS_SYNCBUSY_bit(GCLK)) {; } #endif #if CONF_OSC32K_CONFIG == 0 || CONF_OSC32K_ENABLE == 0 /* Disable after all possible configurations needs sync written. */ hri_sysctrl_clear_OSC32K_ENABLE_bit(hw); #endif (void)hw; }