123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721 |
- /**
- * @file mxc_sys.c
- * @brief System level setup help
- */
- /*******************************************************************************
- * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
- * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of Maxim Integrated
- * Products, Inc. shall not be used except as stated in the Maxim Integrated
- * Products, Inc. Branding Policy.
- *
- * The mere transfer of this software does not imply any licenses
- * of trade secrets, proprietary technology, copyrights, patents,
- * trademarks, maskwork rights, or any other form of intellectual
- * property whatsoever. Maxim Integrated Products, Inc. retains all
- * ownership rights.
- *
- * $Date: 2020-01-17 08:38:51 -0600 (Fri, 17 Jan 2020) $
- * $Revision: 50772 $
- *
- ******************************************************************************/
- #include <stddef.h>
- #include "mxc_config.h"
- #include "mxc_assert.h"
- #include "mxc_sys.h"
- #include "gpio.h"
- #include "mxc_pins.h"
- #include "gcr_regs.h"
- #include "tmr_regs.h"
- #include "pwrseq_regs.h"
- #include "spi17y_regs.h"
- #include "spimss_regs.h"
- #include "mxc_delay.h"
- #include "rtc.h"
- /**
- * @ingroup MXC_sys
- * @{
- */
- /***** Definitions *****/
- #define SYS_CLOCK_TIMEOUT MXC_DELAY_MSEC(1)
- #define SYS_RTC_CLK 32768UL
- /***** Functions ******/
- static int SYS_Clock_Timeout(uint32_t ready)
- {
- // Start timeout, wait for ready
- mxc_delay_start(SYS_CLOCK_TIMEOUT);
- do {
- if (MXC_GCR->clkcn & ready) {
- mxc_delay_stop();
- return E_NO_ERROR;
- }
- } while (mxc_delay_check() == E_BUSY);
- return E_TIME_OUT;
- }
- /* ************************************************************************ */
- int SYS_Clock_Select(sys_system_clock_t clock, mxc_tmr_regs_t* tmr)
- {
- uint32_t current_clock,ovr, div;
- // Save the current system clock
- current_clock = MXC_GCR->clkcn & MXC_F_GCR_CLKCN_CLKSEL;
- // Set FWS higher than what the minimum for the fastest clock is
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x5UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- switch(clock) {
- case SYS_CLOCK_NANORING:
- // Set NANORING clock as System Clock
- MXC_SETFIELD(MXC_GCR->clkcn, MXC_F_GCR_CLKCN_CLKSEL, MXC_S_GCR_CLKCN_CLKSEL_NANORING);
- break;
- case SYS_CLOCK_HFXIN:
- // Enable 32k Oscillator
- MXC_GCR->clkcn |=MXC_F_GCR_CLKCN_X32K_EN;
- // Check if 32k clock is ready
- if (SYS_Clock_Timeout(MXC_F_GCR_CLKCN_X32K_RDY) != E_NO_ERROR) {
- return E_TIME_OUT;
- }
- MXC_RTC->ctrl |= MXC_F_RTC_CTRL_WE; // Allow writing to registers
- // Set 32k clock as System Clock
- MXC_SETFIELD(MXC_GCR->clkcn, MXC_F_GCR_CLKCN_CLKSEL, MXC_S_GCR_CLKCN_CLKSEL_HFXIN);
- break;
- case SYS_CLOCK_HFXIN_DIGITAL:
- // Enable 32k Oscillator
- MXC_GCR->clkcn |=MXC_F_GCR_CLKCN_X32K_EN;
- // Check if 32k clock is ready
- if (SYS_Clock_Timeout(MXC_F_GCR_CLKCN_X32K_RDY) != E_NO_ERROR) {
- return E_TIME_OUT;
- }
- MXC_RTC->ctrl |= MXC_F_RTC_CTRL_WE; // Allow writing to registers
- MXC_RTC->oscctrl |= MXC_F_RTC_OSCCTRL_BYPASS; // To allow square wave driven on 32KIN
- // Set 32k clock as System Clock
- MXC_SETFIELD(MXC_GCR->clkcn, MXC_F_GCR_CLKCN_CLKSEL, MXC_S_GCR_CLKCN_CLKSEL_HFXIN);
- break;
- case SYS_CLOCK_HIRC:
- // Enable 96MHz Clock
- MXC_GCR->clkcn |=MXC_F_GCR_CLKCN_HIRC_EN;
- // Check if 96MHz clock is ready
- if (SYS_Clock_Timeout(MXC_F_GCR_CLKCN_HIRC_RDY) != E_NO_ERROR) {
- return E_TIME_OUT;
- }
- // Set 96MHz clock as System Clock
- MXC_SETFIELD(MXC_GCR->clkcn, MXC_F_GCR_CLKCN_CLKSEL, MXC_S_GCR_CLKCN_CLKSEL_HIRC);
- break;
- default:
- return E_BAD_PARAM;
- }
- // Wait for system clock to be ready
- if (SYS_Clock_Timeout(MXC_F_GCR_CLKCN_CKRDY) != E_NO_ERROR) {
- // Restore the old system clock if timeout
- MXC_SETFIELD(MXC_GCR->clkcn, MXC_F_GCR_CLKCN_CLKSEL, current_clock);
- return E_TIME_OUT;
- }
- // Disable other clocks
- switch(clock) {
- case SYS_CLOCK_NANORING:
- MXC_GCR->clkcn &= ~(MXC_F_GCR_CLKCN_HIRC_EN);
- break;
- case SYS_CLOCK_HFXIN:
- MXC_GCR->clkcn &= ~(MXC_F_GCR_CLKCN_HIRC_EN);
- break;
- case SYS_CLOCK_HFXIN_DIGITAL:
- MXC_GCR->clkcn &= ~(MXC_F_GCR_CLKCN_HIRC_EN);
- break;
- case SYS_CLOCK_HIRC:
- //Don't disable 32KHz clock
- break;
- }
- // Update the system core clock
- SystemCoreClockUpdate();
- // Get the clock divider
- div = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_PSC) >> MXC_F_GCR_CLKCN_PSC_POS;
- //get ovr setting
- ovr = (MXC_PWRSEQ->lp_ctrl & MXC_F_PWRSEQ_LP_CTRL_OVR);
- //Set flash wait settings
- if(ovr == MXC_S_PWRSEQ_LP_CTRL_OVR_0_9V){
- if(div == 0){
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- } else{
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- }
- } else if( ovr == MXC_S_PWRSEQ_LP_CTRL_OVR_1_0V){
- if(div == 0){
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- } else{
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- }
- } else {
- if(div == 0){
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x4UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- } else if(div == 1){
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x2UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- } else{
- MXC_GCR->memckcn = (MXC_GCR->memckcn & ~(MXC_F_GCR_MEMCKCN_FWS)) | (0x1UL << MXC_F_GCR_MEMCKCN_FWS_POS);
- }
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_ClockEnable_X32K(sys_cfg_rtc_t *sys_cfg)
- {
- // Enable 32k Oscillator
- MXC_GCR->clkcn |=MXC_F_GCR_CLKCN_X32K_EN;
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_ClockDisable_X32K()
- {
- // Disable 32k Oscillator
- MXC_GCR->clkcn &= (~MXC_F_GCR_CLKCN_X32K_EN);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_UART_Init(mxc_uart_regs_t *uart, const sys_cfg_uart_t* sys_cfg)
- {
- // Configure GPIO for UART
- if (uart == MXC_UART0) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_UART0);
- if(sys_cfg->map == MAP_A){
- GPIO_Config(&gpio_cfg_uart0a);
- }
- else{
- return E_BAD_PARAM;
- }
- if(sys_cfg->flow_flag == UART_FLOW_ENABLE){
- GPIO_Config(&gpio_cfg_uart0rtscts);
- }
- }
- if (uart == MXC_UART1) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_UART1);
- if(sys_cfg->map == MAP_A){
- GPIO_Config(&gpio_cfg_uart1a);
- }
- else if(sys_cfg->map == MAP_B){
- GPIO_Config(&gpio_cfg_uart1b);
- }
- else if(sys_cfg->map == MAP_C){
- GPIO_Config(&gpio_cfg_uart1c);
- }
- else{
- return E_BAD_PARAM;
- }
- if(sys_cfg->flow_flag == UART_FLOW_ENABLE){
- GPIO_Config(&gpio_cfg_uart1rtscts);
- }
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_UART_Shutdown(mxc_uart_regs_t *uart)
- {
- if (uart == MXC_UART0) {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_UART0);
- }
- else if (uart == MXC_UART1) {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_UART1);
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_I2C_Init(mxc_i2c_regs_t *i2c, const sys_cfg_i2c_t* sys_cfg)
- {
- // Configure GPIO for I2C
- if (i2c == MXC_I2C0) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_I2C0);
- GPIO_Config(&gpio_cfg_i2c0);
- } else if (i2c == MXC_I2C1) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_I2C1);
- GPIO_Config(&gpio_cfg_i2c1);
- } else {
- return E_NO_DEVICE;
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_I2C_Shutdown(mxc_i2c_regs_t *i2c)
- {
- if (i2c == MXC_I2C0) {
- gpio_cfg_t cfg = { gpio_cfg_i2c0.port, gpio_cfg_i2c0.mask, GPIO_FUNC_IN, GPIO_PAD_NONE };
- SYS_ClockDisable(SYS_PERIPH_CLOCK_I2C0);
- GPIO_Config(&cfg);
- } else if (i2c == MXC_I2C1) {
- gpio_cfg_t cfg = { gpio_cfg_i2c1.port, gpio_cfg_i2c1.mask, GPIO_FUNC_IN, GPIO_PAD_NONE };
- SYS_ClockDisable(SYS_PERIPH_CLOCK_I2C1);
- GPIO_Config(&cfg);
- } else {
- return E_NO_DEVICE;
- }
- // Clear registers
- i2c->ctrl = 0;
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_DMA_Init(void)
- {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_DMA);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_DMA_Shutdown(void)
- {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_DMA);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- unsigned SYS_I2C_GetFreq(mxc_i2c_regs_t *i2c)
- {
- return PeripheralClock;
- }
- /* ************************************************************************ */
- unsigned SYS_TMR_GetFreq(mxc_tmr_regs_t *tmr)
- {
- return PeripheralClock;
- }
- /* ************************************************************************ */
- void SYS_Reset0(sys_reset0_t reset)
- {
- MXC_GCR->rstr0 = reset;
- while(MXC_GCR->rstr0 != 0x0) {}
- }
- /* ************************************************************************ */
- void SYS_Reset1(sys_reset1_t reset)
- {
- MXC_GCR->rstr1 = reset;
- while(MXC_GCR->rstr0 != 0x0) {}
- }
- /* ************************************************************************ */
- void SYS_ClockDisable(sys_periph_clock_t clock)
- {
- /* The sys_periph_clock_t enum uses bit 27 (an unused bit in both perkcn registers)
- to determine which of the two perckcn registers to write to. */
- if (clock & (1<<27)) {
- clock &= ~(1<<27);
- MXC_GCR->perckcn1 |= clock;
- } else {
- MXC_GCR->perckcn0 |= clock;
- }
- }
- /* ************************************************************************ */
- void SYS_ClockEnable(sys_periph_clock_t clock)
- {
- /* The sys_periph_clock_t enum uses bit 27 (an unused bit in both perkcn registers)
- to determine which of the two perckcn registers to write to. */
- if (clock & (1<<27)) {
- clock &= ~(1<<27);
- MXC_GCR->perckcn1 &= ~(clock);
- } else {
- MXC_GCR->perckcn0 &= ~(clock);
- }
- }
- /* ************************************************************************ */
- #if defined (__ICCARM__)
- #pragma optimize=none /* Turn off optimizations for next function */
- #elif defined ( __CC_ARM )
- /* Keil MDK - Turn off optimizations after saving current state */
- #pragma push /* Save current optimization level */
- #pragma O0 /* Optimization level 0 */
- #elif ( __GNUC__ )
- /* GCC - Turn off optimizations after saving current state */
- #pragma GCC push_options /* Save current optimization level */
- #pragma GCC optimize ("O0") /* Set optimization level to none for this function */
- #endif
- void SYS_Flash_Operation(void)
- {
- volatile uint32_t *line_addr;
- volatile uint32_t __attribute__ ((unused)) line;
- // Clear the cache
- MXC_ICC->cache_ctrl ^= MXC_F_ICC_CACHE_CTRL_CACHE_EN;
- MXC_ICC->cache_ctrl ^= MXC_F_ICC_CACHE_CTRL_CACHE_EN;
- // Clear the line fill buffer
- line_addr = (uint32_t*)(MXC_FLASH_MEM_BASE);
- line = *line_addr;
- line_addr = (uint32_t*)(MXC_FLASH_MEM_BASE + MXC_FLASH_PAGE_SIZE);
- line = *line_addr;
- }
- /* Set optimizations to the previous level. For IAR, the optimize none applies
- only to the next function. Keil MDK and GNUC need state restored. */
- #if defined ( __CC_ARM )
- #pragma pop /* Restore Kiel MDK optimizations to saved level */
- #elif defined ( __GNUC__ )
- #pragma GCC pop_options /* Restore GCC optimization level */
- #endif
- /* ************************************************************************ */
- int SYS_TMR_Init(mxc_tmr_regs_t *tmr, const sys_cfg_tmr_t* sys_cfg)
- {
- if(sys_cfg) {
- if(sys_cfg->out_en) {
- if (tmr == MXC_TMR0) {
- GPIO_Config(&gpio_cfg_tmr0);
- }
- }
- }
- if (tmr == MXC_TMR0) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_T0);
- }
- else if (tmr == MXC_TMR1) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_T1);
- }
- else if (tmr == MXC_TMR2) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_T2);
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_FLC_Init(const sys_cfg_flc_t* sys_cfg)
- {
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_FLC_Shutdown(void)
- {
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_SPI17Y_Init(mxc_spi17y_regs_t *spi, const sys_cfg_spi17y_t* sys_cfg)
- {
- // Configure GPIO for spi17y
- if (spi == MXC_SPI17Y) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_SPI17Y);
- if(sys_cfg->map == MAP_A){
- GPIO_Config(&gpio_cfg_spi17y);
- MXC_GPIO0->ds |= 0x0003BF0;
- }else{
- return E_BAD_PARAM;
- }
- } else {
- return E_NO_DEVICE;
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_SPI17Y_Shutdown(mxc_spi17y_regs_t *spi)
- {
- if (spi == MXC_SPI17Y) {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_SPI17Y);
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_SPIMSS_Init(mxc_spimss_regs_t *spi, const sys_cfg_spimss_t* sys_cfg)
- {
- // Configure GPIO for spimss
- if (spi == MXC_SPIMSS) {
- SYS_ClockEnable(SYS_PERIPH_CLOCK_SPIMSS);
- if(sys_cfg->map == MAP_A){
- GPIO_Config(&gpio_cfg_spimss1a); // SPI1A chosen
- }else if(sys_cfg->map == MAP_B){
- GPIO_Config(&gpio_cfg_spimss1b); // SPI1B chosen
- }else{
- return E_BAD_PARAM;
- }
- } else {
- return E_NO_DEVICE;
- }
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_SPIMSS_Shutdown(mxc_spimss_regs_t *spi)
- {
- if(spi == MXC_SPIMSS) {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_SPIMSS);
- }
- return E_NO_ERROR;
- }
- int SYS_TMR_Shutdown(mxc_tmr_regs_t *tmr)
- {
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_I2S_Init(const sys_cfg_i2s_t* sys_cfg)
- {
- if(sys_cfg->map == MAP_A) {
- GPIO_Config(&gpio_cfg_i2s1a);
- }
- else if(sys_cfg->map == MAP_B) {
- GPIO_Config(&gpio_cfg_i2s1b);
- }
- else {
- return E_BAD_PARAM;
- }
- SYS_ClockEnable(SYS_PERIPH_CLOCK_SPIMSS);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_I2S_Shutdown(void)
- {
- SYS_ClockDisable(SYS_PERIPH_CLOCK_SPIMSS);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- int SYS_I2S_GetFreq(mxc_spimss_regs_t *spimss)
- {
- return PeripheralClock;
- }
- /* ************************************************************************ */
- int SYS_RTC_SqwavInit(const sys_cfg_rtc_t* sys_cfg)
- {
- GPIO_Config(&gpio_cfg_rtc);
- return E_NO_ERROR;
- }
- /* ************************************************************************ */
- uint32_t SYS_SysTick_GetFreq(void)
- {
- // Determine is using internal (SystemCoreClock) or external (32768) clock
- if ( (SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) || !(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)) {
- return SystemCoreClock;
- } else {
- return SYS_RTC_CLK;
- }
- }
- /* ************************************************************************ */
- int SYS_SysTick_Config(uint32_t ticks, int clk_src, mxc_tmr_regs_t* tmr)
- {
- if(ticks == 0)
- return E_BAD_PARAM;
- // If SystemClock, call default CMSIS config and return
- if (clk_src) {
- return SysTick_Config(ticks);
- } else { /* External clock source requested
- enable RTC clock in run mode*/
- RTC_Init(MXC_RTC, 0, 0, NULL);
- RTC_EnableRTCE(MXC_RTC);
- // Disable SysTick Timer
- SysTick->CTRL = 0;
- // Check reload value for valid
- if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) {
- // Reload value impossible
- return E_BAD_PARAM;
- }
- // set reload register
- SysTick->LOAD = ticks - 1;
- // set Priority for Systick Interrupt
- NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
- // Load the SysTick Counter Value
- SysTick->VAL = 0;
- // Enable SysTick IRQ and SysTick Timer leaving clock source as external
- SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
- // Function successful
- return E_NO_ERROR;
- }
- }
- /* ************************************************************************ */
- void SYS_SysTick_Disable(void)
- {
- SysTick->CTRL = 0;
- }
- /* ************************************************************************ */
- int SYS_SysTick_Delay(uint32_t ticks)
- {
- uint32_t cur_ticks, num_full, num_remain, previous_ticks, num_subtract, i;
- uint32_t reload, value, ctrl; // save/restore variables
- if(ticks == 0)
- return E_BAD_PARAM;
- // If SysTick is not enabled we can take it for our delay
- if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)) {
- // Save current state in case it's disabled but already configured, restore at return.
- reload = SysTick->LOAD;
- value = SysTick->VAL;
- ctrl = SysTick->CTRL;
- // get the number of ticks less than max RELOAD.
- num_remain = ticks % SysTick_LOAD_RELOAD_Msk;
- /* if ticks is < Max SysTick Reload num_full will be 0, otherwise it will
- give us the number of max SysTicks cycles required */
- num_full = (ticks - 1) / SysTick_LOAD_RELOAD_Msk;
- // Do the required full systick countdowns
- if (num_full) {
- // load the max count value into systick
- SysTick->LOAD = SysTick_LOAD_RELOAD_Msk;
- // load the starting value
- SysTick->VAL = 0;
- // enable SysTick counter with SystemClock source internal, immediately forces LOAD register into VAL register
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
- // CountFlag will get set when VAL reaches zero
- for (i = num_full; i > 0; i--) {
- do {
- cur_ticks = SysTick->CTRL;
- } while (!(cur_ticks & SysTick_CTRL_COUNTFLAG_Msk));
- }
- // Disable systick
- SysTick->CTRL = 0;
- }
- // Now handle the remainder of ticks
- if (num_remain) {
- SysTick->LOAD = num_remain;
- SysTick->VAL = 0;
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
- // wait for countflag to get set
- do {
- cur_ticks = SysTick->CTRL;
- } while (!(cur_ticks & SysTick_CTRL_COUNTFLAG_Msk));
- // Disable systick
- SysTick->CTRL = 0;
- }
- // restore original state of SysTick and return
- SysTick->LOAD = reload;
- SysTick->VAL = value;
- SysTick->CTRL = ctrl;
- return E_NO_ERROR;
- } else { /* SysTick is enabled
- When SysTick is enabled count flag can not be used
- and the reload can not be changed.
- Do not read the CTRL register -> clears count flag */
- // Get the reload value for wrap/reload case
- reload = SysTick->LOAD;
- // Read the starting systick value
- previous_ticks = SysTick->VAL;
- do {
- // get current SysTick value
- cur_ticks = SysTick->VAL;
- // Check for wrap/reload of timer countval
- if (cur_ticks > previous_ticks) {
- // subtract count to 0 (previous_ticks) and wrap (reload value - cur_ticks)
- num_subtract = (previous_ticks + (reload - cur_ticks));
- } else { /* standard case (no wrap)
- subtract off the number of ticks since last pass */
- num_subtract = (previous_ticks - cur_ticks);
- }
- // check to see if we are done.
- if (num_subtract >= ticks)
- return E_NO_ERROR;
- else
- ticks -= num_subtract;
- // cur_ticks becomes previous_ticks for next timer read.
- previous_ticks = cur_ticks;
- } while (ticks > 0);
- // Should not ever be reached
- return E_NO_ERROR;
- }
- }
- /* ************************************************************************ */
- void SYS_SysTick_DelayUs(uint32_t us)
- {
- SYS_SysTick_Delay((uint32_t)(((uint64_t)SYS_SysTick_GetFreq() * us) / 1000000));
- }
- /* ************************************************************************ */
- int SYS_WDT_Init(mxc_wdt_regs_t* wdt, const sys_cfg_wdt_t* sys_cfg)
- {
- return E_NO_ERROR;
- }
- /**@} end of ingroup MXC_sys*/
|