mbed library sources(for async_print)

Dependents:   AsyncPrint

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

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

targets/hal/TARGET_Freescale/TARGET_K20D5M/clk_freqs.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_K20D5M/device.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_K20D5M/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_K20D5M/sleep.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_K20D5M/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_DISCO_F100RB/device.h Show annotated file Show diff for this revision Revisions of this file
--- 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