mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

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