mbed library sources(for async_print)
Fork of mbed-src by
Revision 161:09d8213f0000, committed 2014-04-22
- Comitter:
- mbed_official
- Date:
- Tue Apr 22 10:00:06 2014 +0100
- Parent:
- 160:6870f452afa4
- Child:
- 162:937d965048d3
- Commit message:
- Synchronized with git revision cebd0ea8b60ac69c86f0fe9560acc47a392fd915
Full URL: https://github.com/mbedmicro/mbed/commit/cebd0ea8b60ac69c86f0fe9560acc47a392fd915/
Update device.h
Changed in this revision
--- a/targets/hal/TARGET_Freescale/TARGET_K20D5M/clk_freqs.h Mon Apr 14 11:30:06 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/clk_freqs.h Tue Apr 22 10:00:06 2014 +0100 @@ -25,7 +25,7 @@ * \return Bus frequency */ static inline uint32_t bus_frequency(void) { - return SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); + return SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT) + 1); } /*!
--- a/targets/hal/TARGET_Freescale/TARGET_K20D5M/device.h Mon Apr 14 11:30:06 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/device.h Tue Apr 22 10:00:06 2014 +0100 @@ -45,7 +45,7 @@ #define DEVICE_LOCALFILESYSTEM 0 #define DEVICE_ID_LENGTH 24 -#define DEVICE_SLEEP 0 +#define DEVICE_SLEEP 1 #define DEVICE_DEBUG_AWARENESS 0
--- a/targets/hal/TARGET_Freescale/TARGET_K20D5M/gpio_irq_api.c Mon Apr 14 11:30:06 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/gpio_irq_api.c Tue Apr 22 10:00:06 2014 +0100 @@ -165,3 +165,43 @@ // Interrupt configuration and clear interrupt port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK; } + +void gpio_irq_enable(gpio_irq_t *obj) { + switch (obj->port) { + case PortA: + NVIC_EnableIRQ(PORTA_IRQn); + break; + case PortB: + NVIC_EnableIRQ(PORTB_IRQn); + break; + case PortC: + NVIC_EnableIRQ(PORTC_IRQn); + break; + case PortD: + NVIC_EnableIRQ(PORTD_IRQn); + break; + case PortE: + NVIC_EnableIRQ(PORTE_IRQn); + break; + } +} + +void gpio_irq_disable(gpio_irq_t *obj) { + switch (obj->port) { + case PortA: + NVIC_DisableIRQ(PORTA_IRQn); + break; + case PortB: + NVIC_DisableIRQ(PORTB_IRQn); + break; + case PortC: + NVIC_DisableIRQ(PORTC_IRQn); + break; + case PortD: + NVIC_DisableIRQ(PORTD_IRQn); + break; + case PortE: + NVIC_DisableIRQ(PORTE_IRQn); + break; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/sleep.c Tue Apr 22 10:00:06 2014 +0100 @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" + +//Normal wait mode +void sleep(void) +{ + SMC->PMPROT = SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK; + + //Normal sleep mode for ARM core: + SCB->SCR = 0; + __WFI(); +} + +//Very low-power stop mode +void deepsleep(void) +{ + //Check if PLL/FLL is enabled: + uint32_t PLL_FLL_en = (MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0); + + SMC->PMPROT = SMC_PMPROT_AVLLS_MASK | SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK; + SMC->PMCTRL = SMC_PMCTRL_STOPM(2); + + //Deep sleep for ARM core: + SCB->SCR = 1<<SCB_SCR_SLEEPDEEP_Pos; + + __WFI(); + + //Switch back to PLL as clock source if needed + //The interrupt that woke up the device will run at reduced speed + if (PLL_FLL_en) { + if (MCG->C6 & (1<<MCG_C6_PLLS_SHIFT) != 0) /* If PLL */ + while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U); /* Wait until locked */ + MCG->C1 &= ~MCG_C1_CLKS_MASK; + } + +}
--- a/targets/hal/TARGET_Freescale/TARGET_K20D5M/us_ticker.c Mon Apr 14 11:30:06 2014 +0100 +++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/us_ticker.c Tue Apr 22 10:00:06 2014 +0100 @@ -18,109 +18,95 @@ #include "PeripheralNames.h" #include "clk_freqs.h" -static void pit_init(void); -static void lptmr_init(void); +#define PIT_TIMER PIT->CHANNEL[0] +#define PIT_TIMER_IRQ PIT0_IRQn +#define PIT_TICKER PIT->CHANNEL[1] +#define PIT_TICKER_IRQ PIT1_IRQn + +static void timer_init(void); +static void ticker_init(void); static int us_ticker_inited = 0; -static uint32_t pit_ldval = 0; +static uint32_t clk_mhz; void us_ticker_init(void) { if (us_ticker_inited) return; us_ticker_inited = 1; - - pit_init(); - lptmr_init(); -} + + SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT + PIT->MCR = 0; // Enable PIT + + clk_mhz = bus_frequency() / 1000000; -static uint32_t pit_us_ticker_counter = 0; - -void pit0_isr(void) { - pit_us_ticker_counter++; - PIT->CHANNEL[0].LDVAL = pit_ldval; // 1us - PIT->CHANNEL[0].TFLG = 1; + timer_init(); + ticker_init(); } /****************************************************************************** * Timer for us timing. + * + * The K20D5M does not have a prescaler on its PIT timer nor the option + * to chain timers, which is why a software timer is required to get 32-bit + * word length. ******************************************************************************/ -static void pit_init(void) { - SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT - PIT->MCR = 0; // Enable PIT - - pit_ldval = bus_frequency() / 1000000; +static volatile uint32_t msb_counter = 0; +static uint32_t timer_ldval = 0; - PIT->CHANNEL[0].LDVAL = pit_ldval; // 1us - PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK; - PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1 +static void timer_isr(void) { + msb_counter++; + PIT_TIMER.TFLG = 1; +} - NVIC_SetVector(PIT0_IRQn, (uint32_t)pit0_isr); - NVIC_EnableIRQ(PIT0_IRQn); +static void timer_init(void) { + //CLZ counts the leading zeros, returning number of bits not used by clk_mhz + timer_ldval = clk_mhz << __CLZ(clk_mhz); + + PIT_TIMER.LDVAL = timer_ldval; // 1us + PIT_TIMER.TCTRL |= PIT_TCTRL_TIE_MASK; + PIT_TIMER.TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 0 + + NVIC_SetVector(PIT_TIMER_IRQ, (uint32_t)timer_isr); + NVIC_EnableIRQ(PIT_TIMER_IRQ); } uint32_t us_ticker_read() { if (!us_ticker_inited) us_ticker_init(); + + uint32_t retval; + __disable_irq(); + retval = (timer_ldval - PIT_TIMER.CVAL) / clk_mhz; //Hardware bits + retval |= msb_counter << __CLZ(clk_mhz); //Software bits + + if (PIT_TIMER.TFLG == 1) { //If overflow bit is set, force it to be handled + timer_isr(); //Handle IRQ, read again to make sure software/hardware bits are synced + NVIC_ClearPendingIRQ(PIT_TIMER_IRQ); + return us_ticker_read(); + } - return pit_us_ticker_counter; + __enable_irq(); + return retval; } /****************************************************************************** * Timer Event * * It schedules interrupts at given (32bit)us interval of time. - * It is implemented used the 16bit Low Power Timer that remains powered in all - * power modes. + * It is implemented using PIT channel 1, since no prescaler is available, + * some bits are implemented in software. ******************************************************************************/ -static void lptmr_isr(void); - -static void lptmr_init(void) { - /* Clock the timer */ - SIM->SCGC5 |= SIM_SCGC5_LPTIMER_MASK; - - /* Reset */ - LPTMR0->CSR = 0; - - /* Set interrupt handler */ - NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr); - NVIC_EnableIRQ(LPTimer_IRQn); - - /* Clock at (1)MHz -> (1)tick/us */ - /* Check if the external oscillator can be divided to 1MHz */ - uint32_t extosc = extosc_frequency(); +static void ticker_isr(void); - if (extosc != 0) { //If external oscillator found - OSC0->CR |= OSC_CR_ERCLKEN_MASK; - if (extosc % 1000000u == 0) { //If it is a multiple if 1MHz - extosc /= 1000000; - if (extosc == 1) { //1MHz, set timerprescaler in bypass mode - LPTMR0->PSR = LPTMR_PSR_PCS(3) | LPTMR_PSR_PBYP_MASK; - return; - } else { //See if we can divide it to 1MHz - uint32_t divider = 0; - extosc >>= 1; - while (1) { - if (extosc == 1) { - LPTMR0->PSR = LPTMR_PSR_PCS(3) | LPTMR_PSR_PRESCALE(divider); - return; - } - if (extosc % 2 != 0) //If we can't divide by two anymore - break; - divider++; - extosc >>= 1; - } - } - } - } - //No suitable external oscillator clock -> Use fast internal oscillator (4MHz) - MCG->C1 |= MCG_C1_IRCLKEN_MASK; - MCG->C2 |= MCG_C2_IRCS_MASK; - LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(1); +static void ticker_init(void) { + /* Set interrupt handler */ + NVIC_SetVector(PIT_TICKER_IRQ, (uint32_t)ticker_isr); + NVIC_EnableIRQ(PIT_TICKER_IRQ); } void us_ticker_disable_interrupt(void) { - LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK; + PIT_TICKER.TCTRL &= ~PIT_TCTRL_TIE_MASK; } void us_ticker_clear_interrupt(void) { @@ -128,40 +114,24 @@ } static uint32_t us_ticker_int_counter = 0; -static uint16_t us_ticker_int_remainder = 0; -static void lptmr_set(unsigned short count) { - /* Reset */ - LPTMR0->CSR = 0; - - /* Set the compare register */ - LPTMR0->CMR = count; - - /* Enable interrupt */ - LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; - - /* Start the timer */ - LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; +inline static void ticker_set(uint32_t count) { + PIT_TICKER.TCTRL = 0; + PIT_TICKER.LDVAL = count; + PIT_TICKER.TCTRL = PIT_TCTRL_TIE_MASK | PIT_TCTRL_TEN_MASK; } -static void lptmr_isr(void) { - // write 1 to TCF to clear the LPT timer compare flag - LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; +static void ticker_isr(void) { + // Clear IRQ flag + PIT_TICKER.TFLG = 1; if (us_ticker_int_counter > 0) { - lptmr_set(0xFFFF); + ticker_set(0xFFFFFFFF); us_ticker_int_counter--; - } else { - if (us_ticker_int_remainder > 0) { - lptmr_set(us_ticker_int_remainder); - us_ticker_int_remainder = 0; - - } else { - // This function is going to disable the interrupts if there are - // no other events in the queue - us_ticker_irq_handler(); - } + // This function is going to disable the interrupts if there are + // no other events in the queue + us_ticker_irq_handler(); } } @@ -173,13 +143,17 @@ return; } - us_ticker_int_counter = (uint32_t)(delta >> 16); - us_ticker_int_remainder = (uint16_t)(0xFFFF & delta); - if (us_ticker_int_counter > 0) { - lptmr_set(0xFFFF); + //Calculate how much falls outside the 32-bit after multiplying with clk_mhz + //We shift twice 16-bit to keep everything within the 32-bit variable + us_ticker_int_counter = (uint32_t)(delta >> 16); + us_ticker_int_counter *= clk_mhz; + us_ticker_int_counter >>= 16; + + uint32_t us_ticker_int_remainder = (uint32_t)delta * clk_mhz; + if (us_ticker_int_remainder == 0) { + ticker_set(0xFFFFFFFF); us_ticker_int_counter--; } else { - lptmr_set(us_ticker_int_remainder); - us_ticker_int_remainder = 0; + ticker_set(us_ticker_int_remainder); } }
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F100RB/device.h Mon Apr 14 11:30:06 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F100RB/device.h Tue Apr 22 10:00:06 2014 +0100 @@ -53,6 +53,7 @@ #define DEVICE_SLEEP 1 +#define DEVICE_ERROR_PATTERN 1 //fast blink green and blue leds on error //======================================= #define DEVICE_SEMIHOST 0