mbed w/ spi bug fig
Fork of mbed-src by
Revision 240:9a7c54113eaf, committed 2014-06-26
- Comitter:
- mbed_official
- Date:
- Thu Jun 26 09:45:08 2014 +0100
- Parent:
- 239:8cadf13dff33
- Child:
- 241:ffe41b0c8126
- Commit message:
- Synchronized with git revision 288cce7281f1f4bd5ab515fff36cdf6090bc4480
Full URL: https://github.com/mbedmicro/mbed/commit/288cce7281f1f4bd5ab515fff36cdf6090bc4480/
[DISCO-F051R8] Updated with F030R8 recent changes
Changed in this revision
--- a/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/stm32f0xx.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/stm32f0xx.h Thu Jun 26 09:45:08 2014 +0100 @@ -76,7 +76,7 @@ */ #if !defined (STM32F030) && !defined (STM32F031) && !defined (STM32F051) && !defined (STM32F072) && !defined (STM32F042) -#define STM32F030 + /* #define STM32F030 */ /* #define STM32F031 */ #define STM32F051 /* #define STM32F072 */
--- a/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c Thu Jun 26 09:45:08 2014 +0100 @@ -3,11 +3,11 @@ * @file system_stm32f0xx.c * @author MCD Application Team * @version V1.0.1 - * @date 29-May-2012 + * @date 12-January-2014 * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. * This file contains the system clock configuration for STM32F0xx devices, * and is generated by the clock configuration tool - * STM32f0xx_Clock_Configuration_V1.0.1.xls + * STM32F0xx_Clock_Configuration_V1.0.1.xls * * 1. This file provides two functions and one global variable to be called from * user application: @@ -40,52 +40,44 @@ * value to your own configuration. * * 5. This file configures the system clock as follows: - *============================================================================= - *============================================================================= - * System Clock source | PLL(HSI) *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 48000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 48000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB Prescaler | 1 + * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI + * | (external 8 MHz clock) | (internal 8 MHz) + * | 2- PLL_HSE_XTAL | + * | (external 8 MHz xtal) | *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | NA - *---------------------------------------------------------------------------- - * PLLMUL | 12 - *----------------------------------------------------------------------------- - * PREDIV | 2 + * SYSCLK(MHz) | 48 | 48 *----------------------------------------------------------------------------- - * I2S input clock(Hz) | 48000000 - * | - * To achieve the following I2S config: | - * - Master clock output (MCKO): OFF | - * - Frame wide : 16bit | - * - Audio sampling freq (KHz) : 44.1 | - * - Error % : 0.2674 | + * AHBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- - * Flash Latency(WS) | 1 - *----------------------------------------------------------------------------- - * Prefetch Buffer | ON + * APBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> * - * http://www.st.com/software_license_agreement_liberty_v2 + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * 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. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ @@ -127,6 +119,10 @@ * @{ */ +/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */ +#define USE_PLL_HSE_EXTC (1) /* Use external clock */ +#define USE_PLL_HSE_XTAL (1) /* Use external xtal */ + /** * @} */ @@ -145,7 +141,11 @@ * @{ */ -static void SetSysClock(void); +#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif + +uint8_t SetSysClock_PLL_HSI(void); /** * @} @@ -191,7 +191,8 @@ /* Disable all interrupts */ RCC->CIR = 0x00000000; - /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings */ SetSysClock(); } @@ -275,35 +276,136 @@ } /** - * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash - * settings. - * @note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * @param None * @retval None */ -static void SetSysClock(void) +void SetSysClock(void) { -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ + /* 1- Try to start with HSE and external clock */ +#if USE_PLL_HSE_EXTC != 0 + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { + /* 2- If fail try to start with HSE and external xtal */ + #if USE_PLL_HSE_XTAL != 0 + if (SetSysClock_PLL_HSE(0) == 0) + #endif + { + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) + { + while(1) + { + // [TODO] Put something here to tell the user that a problem occured... + } + } + } + } + + // Output clock on MCO pin (PA8) for debugging purpose + /* + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_0); + // Output clock on MCO pin + // Warning: only RCC_MCOPrescaler_1 is available on STM32F030x8 devices + RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCOPrescaler_1); + */ +} + +#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) /******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + __IO uint32_t StartUpCounter = 0; + __IO uint32_t HSEStatus = 0; - /* At this stage the HSI is already enabled and used as System clock source */ + /* Bypass HSE: can be done only if HSE is OFF */ + RCC->CR &= ((uint32_t)~RCC_CR_HSEON); /* To be sure HSE is OFF */ + if (bypass != 0) + { + RCC->CR |= ((uint32_t)RCC_CR_HSEBYP); + } + else + { + RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP); + } - /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + /* Check if HSE has started correctly */ + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; /* Enable Prefetch Buffer and set Flash Latency */ FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; - /* HCLK = SYSCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + /* PLL configuration + PLLCLK = 48 MHz (xtal 8 MHz * 6) */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } - /* PCLK = HCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } - /* PLL configuration */ + return 1; // OK + } + else + { + return 0; // FAIL + } +} +#endif + +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + /* Enable Prefetch Buffer and set Flash Latency */ + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + + /* PLL configuration + PLLCLK = 48 MHz ((HSI 8 MHz / 2) * 12) */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; @@ -321,6 +423,8 @@ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) { } + + return 1; // OK } /**
--- a/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.h Thu Jun 26 09:45:08 2014 +0100 @@ -94,6 +94,8 @@ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); +extern void SetSysClock(void); + /** * @} */
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/PeripheralNames.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/PeripheralNames.h Thu Jun 26 09:45:08 2014 +0100 @@ -67,7 +67,9 @@ typedef enum { TIM_3 = (int)TIM3_BASE, TIM_14 = (int)TIM14_BASE, - TIM_16 = (int)TIM16_BASE + TIM_15 = (int)TIM15_BASE, + TIM_16 = (int)TIM16_BASE, + TIM_17 = (int)TIM17_BASE } PWMName; #ifdef __cplusplus
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/analogin_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/analogin_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -27,20 +27,31 @@ */ #include "mbed_assert.h" #include "analogin_api.h" -#include "wait_api.h" #if DEVICE_ANALOGIN #include "cmsis.h" #include "pinmap.h" +#include "error.h" +#include "wait_api.h" static const PinMap PinMap_ADC[] = { {PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN0 {PA_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN1 + {PA_2, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN2 + {PA_3, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN3 {PA_4, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN4 + {PA_5, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN5 + {PA_6, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN6 + {PA_7, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN7 {PB_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN8 + {PB_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN9 + {PC_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN10 {PC_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN11 - {PC_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN10 + {PC_2, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN12 + {PC_3, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN13 + {PC_4, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN14 + {PC_5, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN15 {NC, NC, 0} }; @@ -102,33 +113,63 @@ case PA_1: ADC_ChannelConfig(adc, ADC_Channel_1, ADC_SampleTime_7_5Cycles); break; + case PA_2: + ADC_ChannelConfig(adc, ADC_Channel_2, ADC_SampleTime_7_5Cycles); + break; + case PA_3: + ADC_ChannelConfig(adc, ADC_Channel_3, ADC_SampleTime_7_5Cycles); + break; case PA_4: ADC_ChannelConfig(adc, ADC_Channel_4, ADC_SampleTime_7_5Cycles); break; + case PA_5: + ADC_ChannelConfig(adc, ADC_Channel_5, ADC_SampleTime_7_5Cycles); + break; + case PA_6: + ADC_ChannelConfig(adc, ADC_Channel_6, ADC_SampleTime_7_5Cycles); + break; + case PA_7: + ADC_ChannelConfig(adc, ADC_Channel_7, ADC_SampleTime_7_5Cycles); + break; case PB_0: ADC_ChannelConfig(adc, ADC_Channel_8, ADC_SampleTime_7_5Cycles); break; - case PC_1: - ADC_ChannelConfig(adc, ADC_Channel_11, ADC_SampleTime_7_5Cycles); + case PB_1: + ADC_ChannelConfig(adc, ADC_Channel_9, ADC_SampleTime_7_5Cycles); break; case PC_0: ADC_ChannelConfig(adc, ADC_Channel_10, ADC_SampleTime_7_5Cycles); break; + case PC_1: + ADC_ChannelConfig(adc, ADC_Channel_11, ADC_SampleTime_7_5Cycles); + break; + case PC_2: + ADC_ChannelConfig(adc, ADC_Channel_12, ADC_SampleTime_7_5Cycles); + break; + case PC_3: + ADC_ChannelConfig(adc, ADC_Channel_13, ADC_SampleTime_7_5Cycles); + break; + case PC_4: + ADC_ChannelConfig(adc, ADC_Channel_14, ADC_SampleTime_7_5Cycles); + break; + case PC_5: + ADC_ChannelConfig(adc, ADC_Channel_15, ADC_SampleTime_7_5Cycles); + break; default: return 0; } - while(!ADC_GetFlagStatus(adc, ADC_FLAG_ADRDY)); // Wait ADC ready + while (!ADC_GetFlagStatus(adc, ADC_FLAG_ADRDY)); // Wait ADC ready ADC_StartOfConversion(adc); // Start conversion - while(ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion + while (ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion - return(ADC_GetConversionValue(adc)); // Get conversion value + return (ADC_GetConversionValue(adc)); // Get conversion value } uint16_t analogin_read_u16(analogin_t *obj) { - return(adc_read(obj)); + return (adc_read(obj)); } float analogin_read(analogin_t *obj) {
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/device.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/device.h Thu Jun 26 09:45:08 2014 +0100 @@ -42,10 +42,10 @@ #define DEVICE_SERIAL 1 #define DEVICE_I2C 1 -#define DEVICE_I2CSLAVE 0 +#define DEVICE_I2CSLAVE 1 #define DEVICE_SPI 1 -#define DEVICE_SPISLAVE 0 +#define DEVICE_SPISLAVE 1 #define DEVICE_RTC 1
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -67,8 +67,7 @@ MBED_ASSERT(obj->pin != (PinName)NC); if (direction == PIN_OUTPUT) { pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)); - } - else { // PIN_INPUT + } else { // PIN_INPUT pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); } }
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_irq_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_irq_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -53,8 +53,7 @@ uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]); // Clear interrupt flag - if (EXTI_GetITStatus(pin) != RESET) - { + if (EXTI_GetITStatus(pin) != RESET) { EXTI_ClearITPendingBit(pin); } @@ -63,16 +62,21 @@ // Check which edge has generated the irq if ((gpio->IDR & pin) == 0) { irq_handler(channel_ids[irq_index], IRQ_FALL); - } - else { + } else { irq_handler(channel_ids[irq_index], IRQ_RISE); } } // The irq_index is passed to the function -static void gpio_irq0(void) {handle_interrupt_in(0);} -static void gpio_irq1(void) {handle_interrupt_in(1);} -static void gpio_irq2(void) {handle_interrupt_in(2);} +static void gpio_irq0(void) { + handle_interrupt_in(0); +} +static void gpio_irq1(void) { + handle_interrupt_in(1); +} +static void gpio_irq2(void) { + handle_interrupt_in(2); +} extern uint32_t Set_GPIO_Clock(uint32_t port_idx); @@ -87,24 +91,20 @@ uint32_t pin_index = STM_PIN(pin); // Select irq number and interrupt routine - switch (pin) { - case PC_13: // User button - irq_n = EXTI4_15_IRQn; + if ((pin_index == 0) || (pin_index == 1)) { + irq_n = EXTI0_1_IRQn; vector = (uint32_t)&gpio_irq0; irq_index = 0; - break; - case PA_0: - irq_n = EXTI0_1_IRQn; + } else if ((pin_index == 2) || (pin_index == 3)) { + irq_n = EXTI2_3_IRQn; vector = (uint32_t)&gpio_irq1; irq_index = 1; - break; - case PB_3: - irq_n = EXTI2_3_IRQn; + } else if ((pin_index > 3) && (pin_index < 16)) { + irq_n = EXTI4_15_IRQn; vector = (uint32_t)&gpio_irq2; irq_index = 2; - break; - default: - error("This pin is not supported"); + } else { + error("InterruptIn error: pin not supported.\n"); return -1; } @@ -171,8 +171,7 @@ if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; obj->event = EDGE_BOTH; - } - else { // NONE or RISE + } else { // NONE or RISE EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; obj->event = EDGE_RISE; } @@ -182,8 +181,7 @@ if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; obj->event = EDGE_BOTH; - } - else { // NONE or FALL + } else { // NONE or FALL EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; obj->event = EDGE_FALL; } @@ -191,8 +189,7 @@ if (enable) { EXTI_InitStructure.EXTI_LineCmd = ENABLE; - } - else { + } else { EXTI_InitStructure.EXTI_LineCmd = DISABLE; }
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_object.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/gpio_object.h Thu Jun 26 09:45:08 2014 +0100 @@ -52,8 +52,7 @@ MBED_ASSERT(obj->pin != (PinName)NC); if (value) { *obj->reg_set = obj->mask; - } - else { + } else { *obj->reg_clr = obj->mask; } }
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/i2c_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/i2c_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -42,12 +42,16 @@ #define LONG_TIMEOUT ((int)0x8000) static const PinMap PinMap_I2C_SDA[] = { + {PB_7, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, {PB_9, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, + {PB_11, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, {NC, NC, 0} }; static const PinMap PinMap_I2C_SCL[] = { + {PB_6, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, {PB_8, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, + {PB_10, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_1)}, {NC, NC, 0} }; @@ -62,10 +66,11 @@ // Enable I2C clock if (obj->i2c == I2C_1) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); + RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK); } - //if (obj->i2c == I2C_2) { - // RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); - //} + if (obj->i2c == I2C_2) { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); + } // Configure I2C pins pinmap_pinout(scl, PinMap_I2C_SCL); @@ -81,28 +86,54 @@ } void i2c_frequency(i2c_t *obj, int hz) { - MBED_ASSERT((hz == 100000) || (hz == 200000) || (hz == 400000)); //"Only 100kHz, 200kHz and 400kHz I2C frequencies are supported." + MBED_ASSERT((hz == 100000) || (hz == 200000) || (hz == 400000) || (hz == 1000000)); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_InitTypeDef I2C_InitStructure; uint32_t tim = 0; - // Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235) - // with Rise time = 100ns and Fall time = 10ns + // Disable the Fast Mode Plus capability + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, DISABLE); + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, DISABLE); + + /* + Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235) + * Standard mode (up to 100 kHz) + * Fast Mode (up to 400 kHz) + * Fast Mode Plus (up to 1 MHz) + Below values obtained with: + - I2C clock source = 48 MHz (System Clock) + - Analog filter delay = ON + - Digital filter coefficient = 0 + - Rise time = 100 ns + - Fall time = 10ns + */ switch (hz) { case 100000: - tim = 0x00201D2B; // Standard mode + tim = 0x10805E89; // Standard mode break; case 200000: - tim = 0x0010021E; // Fast mode + tim = 0x00905E82; // Fast Mode break; case 400000: - tim = 0x0010020A; // Fast mode + tim = 0x00901850; // Fast Mode + break; + case 1000000: + tim = 0x00700818; // Fast Mode Plus + // Enable the Fast Mode Plus capability + if (obj->i2c == I2C_1) { + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE); + } + if (obj->i2c == I2C_2) { + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, ENABLE); + } break; default: break; } // I2C configuration + I2C_DeInit(i2c); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x00; @@ -144,12 +175,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); int count; + int timeout; int value; if (length == 0) return 0; // Configure slave address, nbytes, reload, end mode and start or stop generation - I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Read); // Read all bytes for (count = 0; count < length; count++) { @@ -157,48 +189,39 @@ data[count] = (char)value; } + timeout = FLAG_TIMEOUT; + while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) { + timeout--; + if (timeout == 0) return 0; + } + + if (stop) i2c_stop(obj); + return length; } int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); - //int timeout; + int timeout; int count; if (length == 0) return 0; - // TODO: the stop is always sent even with I2C_SoftEnd_Mode. To be corrected. - - // Configure slave address, nbytes, reload, end mode and start or stop generation - //if (stop) { - I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); - //} - //else { - // I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); - //} + // Configure slave address, nbytes, reload, end mode and start generation + I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); // Write all bytes for (count = 0; count < length; count++) { - if (i2c_byte_write(obj, data[count]) != 1) { - i2c_stop(obj); - return 0; - } + i2c_byte_write(obj, data[count]); } - /* - if (stop) { - // Wait until STOPF flag is set - timeout = LONG_TIMEOUT; - while (I2C_GetFlagStatus(i2c, I2C_ISR_STOPF) == RESET) { + timeout = FLAG_TIMEOUT; + while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) { timeout--; - if (timeout == 0) { - return 0; - } + if (timeout == 0) return 0; } - // Clear STOPF flag - I2C_ClearFlag(i2c, I2C_ICR_STOPCF); - } - */ + + if (stop) i2c_stop(obj); return count; } @@ -245,10 +268,10 @@ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); } - //if (obj->i2c == I2C_2) { - // RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); - // RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); - //} + if (obj->i2c == I2C_2) { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); + } } #if DEVICE_I2CSLAVE @@ -257,6 +280,9 @@ I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); uint16_t tmpreg; + // reset own address enable + i2c->OAR1 &= ~ I2C_OAR1_OA1EN; + // Get the old register value tmpreg = i2c->OAR1; // Reset address bits @@ -264,7 +290,7 @@ // Set new address tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits // Store the new register value - i2c->OAR1 = tmpreg; + i2c->OAR1 = tmpreg | I2C_OAR1_OA1EN; } void i2c_slave_mode(i2c_t *obj, int enable_slave) { @@ -278,8 +304,20 @@ #define WriteAddressed 3 // the master is writing to this slave (slave = receiver) int i2c_slave_receive(i2c_t *obj) { - // TO BE DONE - return(0); + I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); + int event = NoData; + + if (I2C_GetFlagStatus(i2c, I2C_ISR_BUSY) == SET) { + if (I2C_GetFlagStatus(i2c, I2C_ISR_ADDR) == SET) { + // Check direction + if (I2C_GetFlagStatus(i2c, I2C_ISR_DIR) == SET) { + event = ReadAddressed; + } else event = WriteAddressed; + // Clear adress match flag to generate an acknowledge + i2c->ICR |= I2C_ICR_ADDRCF; + } + } + return event; } int i2c_slave_read(i2c_t *obj, char *data, int length) {
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/objects.h Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/objects.h Thu Jun 26 09:45:08 2014 +0100 @@ -70,6 +70,8 @@ uint32_t databits; uint32_t stopbits; uint32_t parity; + PinName pin_tx; + PinName pin_rx; }; struct spi_s { @@ -80,6 +82,10 @@ uint32_t mode; uint32_t nss; uint32_t br_presc; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; }; struct i2c_s {
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/pinmap.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/pinmap.c Thu Jun 26 09:45:08 2014 +0100 @@ -28,8 +28,8 @@ ******************************************************************************* */ #include "mbed_assert.h" -#include "device.h" #include "pinmap.h" +#include "PortNames.h" #include "error.h" // Enable GPIO clock and return GPIO base address @@ -121,8 +121,7 @@ // Configure pull-up/pull-down resistors uint32_t pupd = (uint32_t)mode; - if (pupd > 2) - pupd = 0; // Open-drain = No pull-up/No pull-down + if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/port_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/port_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -28,12 +28,13 @@ ******************************************************************************* */ #include "port_api.h" + +#if DEVICE_PORTIN || DEVICE_PORTOUT + #include "pinmap.h" #include "gpio_api.h" #include "error.h" -#if DEVICE_PORTIN || DEVICE_PORTOUT - extern uint32_t Set_GPIO_Clock(uint32_t port_idx); // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) @@ -66,8 +67,7 @@ if (obj->mask & (1 << i)) { // If the pin is used if (dir == PIN_OUTPUT) { pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)); - } - else { // PIN_INPUT + } else { // PIN_INPUT pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); } } @@ -90,8 +90,7 @@ int port_read(port_t *obj) { if (obj->direction == PIN_OUTPUT) { return (*obj->reg_out & obj->mask); - } - else { // PIN_INPUT + } else { // PIN_INPUT return (*obj->reg_in & obj->mask); } }
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/pwmout_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/pwmout_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -27,35 +27,55 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* */ +#include "mbed_assert.h" #include "pwmout_api.h" +#if DEVICE_PWMOUT + #include "cmsis.h" #include "pinmap.h" -#include "error.h" +// TIM1 cannot be used because already used by the us_ticker static const PinMap PinMap_PWM[] = { - {PA_7, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_4)}, // TIM14_CH1 + {PA_4, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_4)}, // TIM14_CH1 + {PA_6, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH1 +// {PA_6, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_5)}, // TIM16_CH1 + {PA_7, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH2 +// {PA_7, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_4)}, // TIM14_CH1 +// {PA_7, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_5)}, // TIM17_CH1 + {PB_0, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH3 + {PB_1, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM14_CH1 +// {PB_1, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH4 + {PB_4, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH1 + {PB_5, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH2 + {PB_6, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM16_CH1N + {PB_7, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM17_CH1N + {PB_8, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM16_CH1 + {PB_9, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM17_CH1 + {PB_14, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM15_CH1 + {PB_15, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM15_CH2 +// {PB_15, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_3)}, // TIM15_CH1N + {PC_6, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH1 {PC_7, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH2 - {PB_6, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM16_CH1N --> FAIL + {PC_8, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH3 + {PC_9, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH4 {NC, NC, 0} }; void pwmout_init(pwmout_t* obj, PinName pin) { // Get the peripheral name from the pin and assign it to the object obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); - - if (obj->pwm == (PWMName)NC) { - error("PWM pinout mapping failed"); - } + MBED_ASSERT(obj->pwm != (PWMName)NC); // Enable TIM clock if (obj->pwm == TIM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); if (obj->pwm == TIM_14) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); + if (obj->pwm == TIM_15) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE); if (obj->pwm == TIM_16) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE); + if (obj->pwm == TIM_17) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, ENABLE); // Configure GPIO pinmap_pinout(pin, PinMap_PWM); - //pin_mode(pin, PullUp); obj->pin = pin; obj->period = 0; @@ -65,8 +85,8 @@ } void pwmout_free(pwmout_t* obj) { - TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); - TIM_DeInit(tim); + // Configure GPIOs + pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); } void pwmout_write(pwmout_t* obj, float value) { @@ -81,32 +101,63 @@ obj->pulse = (uint32_t)((float)obj->period * value); + // Configure channels TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_Pulse = obj->pulse; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_Low; + TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; - // Configure channel 1 - if (obj->pin == PA_7) { - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + switch (obj->pin) { + // Channels 1 + case PA_4: + case PA_6: + case PB_1: + case PB_4: + case PB_8: + case PB_9: + case PB_14: + case PC_6: + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); + TIM_OC1Init(tim, &TIM_OCInitStructure); + break; + // Channels 1N + case PB_6: + case PB_7: + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC1Init(tim, &TIM_OCInitStructure); - } - - // Configure channel 1N - if (obj->pin == PB_6) { - TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; - TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; - TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); - TIM_OC1Init(tim, &TIM_OCInitStructure); - } - - // Configure channel 2 - if (obj->pin == PC_7) { + break; + // Channels 2 + case PA_7: + case PB_5: + case PC_7: TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC2Init(tim, &TIM_OCInitStructure); + break; + // Channels 3 + case PB_0: + case PC_8: + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable); + TIM_OC3Init(tim, &TIM_OCInitStructure); + break; + // Channels 4 +// case PB_1: + case PC_9: + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable); + TIM_OC4Init(tim, &TIM_OCInitStructure); + break; + default: + return; } + + TIM_CtrlPWMOutputs(tim, ENABLE); + } float pwmout_read(pwmout_t* obj) { @@ -160,3 +211,5 @@ float value = (float)us / (float)obj->period; pwmout_write(obj, value); } + +#endif
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/rtc_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/rtc_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -29,41 +29,77 @@ */ #include "rtc_api.h" +#if DEVICE_RTC + +#include "wait_api.h" + +#define LSE_STARTUP_TIMEOUT ((uint16_t)500) // delay in ms + static int rtc_inited = 0; void rtc_init(void) { + uint32_t StartUpCounter = 0; + uint32_t LSEStatus = 0; + uint32_t rtc_freq = 0; + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock - PWR_BackupAccessCmd(ENABLE); // Enable access to RTC + PWR_BackupAccessCmd(ENABLE); // Enable access to Backup domain + + // Reset back up registers + RCC_BackupResetCmd(ENABLE); + RCC_BackupResetCmd(DISABLE); - // Note: the LSI is used as RTC source clock - // The RTC Clock may vary due to LSI frequency dispersion. + // Enable LSE clock + RCC_LSEConfig(RCC_LSE_ON); + + // Wait till LSE is ready + do { + LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY); + wait_ms(1); + StartUpCounter++; + } while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT)); + if (StartUpCounter > LSE_STARTUP_TIMEOUT) { + // The LSE has not started, use LSI instead. + // The RTC Clock may vary due to LSI frequency dispersion. + RCC_LSEConfig(RCC_LSE_OFF); RCC_LSICmd(ENABLE); // Enable LSI - while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready - - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source + rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture + } else { + // The LSE has correctly started + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source + rtc_freq = LSE_VALUE; + } RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock RTC_WaitForSynchro(); // Wait for RTC registers synchronization - uint32_t lsi_freq = 40000; // *** TODO** To be measured precisely using a timer input capture - RTC_InitTypeDef RTC_InitStructure; RTC_InitStructure.RTC_AsynchPrediv = 127; - RTC_InitStructure.RTC_SynchPrediv = (lsi_freq / 128) - 1; + RTC_InitStructure.RTC_SynchPrediv = (rtc_freq / 128) - 1; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); - PWR_BackupAccessCmd(DISABLE); // Disable access to RTC + PWR_BackupAccessCmd(DISABLE); // Disable access to Backup domain rtc_inited = 1; } void rtc_free(void) { - RCC_DeInit(); // Resets the RCC clock configuration to the default reset state + // Reset RTC + PWR_BackupAccessCmd(ENABLE); // Enable access to Backup Domain + RTC_DeInit(); + RCC_BackupResetCmd(ENABLE); + RCC_BackupResetCmd(DISABLE); + // Disable RTC, LSE and LSI clocks + RCC_RTCCLKCmd(DISABLE); + RCC_LSEConfig(RCC_LSE_OFF); + RCC_LSICmd(DISABLE); + rtc_inited = 0; } @@ -135,3 +171,5 @@ RTC_SetTime(RTC_Format_BIN, &timeStruct); PWR_BackupAccessCmd(DISABLE); // Disable access to RTC } + +#endif
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/serial_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/serial_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -29,19 +29,25 @@ */ #include "mbed_assert.h" #include "serial_api.h" + +#if DEVICE_SERIAL + #include "cmsis.h" #include "pinmap.h" #include <string.h> static const PinMap PinMap_UART_TX[] = { + {PA_2, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, {PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, - {PA_2, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, + {PB_6, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_0)}, {NC, NC, 0} }; static const PinMap PinMap_UART_RX[] = { + {PA_3, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, {PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, - {PA_3, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, + {PA_15, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, + {PB_7, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_0)}, {NC, NC, 0} }; @@ -83,9 +89,11 @@ // Enable USART clock if (obj->uart == UART_1) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + obj->index = 0; } if (obj->uart == UART_2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); + obj->index = 1; } // Configure the UART pins @@ -100,11 +108,10 @@ obj->stopbits = USART_StopBits_1; obj->parity = USART_Parity_No; - init_usart(obj); + obj->pin_tx = tx; + obj->pin_rx = rx; - // The index is used by irq - if (obj->uart == UART_1) obj->index = 0; - if (obj->uart == UART_2) obj->index = 1; + init_usart(obj); // For stdio management if (obj->uart == STDIO_UART) { @@ -115,6 +122,22 @@ } void serial_free(serial_t *obj) { + // Reset UART and disable clock + if (obj->uart == UART_1) { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE); + } + if (obj->uart == UART_2) { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE); + } + + // Configure GPIOs + pin_function(obj->pin_tx, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); + pin_function(obj->pin_rx, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); + serial_irq_ids[obj->index] = 0; } @@ -126,8 +149,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { if (data_bits == 8) { obj->databits = USART_WordLength_8b; - } - else { + } else { obj->databits = USART_WordLength_9b; } @@ -147,8 +169,7 @@ if (stop_bits == 2) { obj->stopbits = USART_StopBits_2; - } - else { + } else { obj->stopbits = USART_StopBits_1; } @@ -173,8 +194,12 @@ } } -static void uart1_irq(void) {uart_irq((USART_TypeDef*)UART_1, 0);} -static void uart2_irq(void) {uart_irq((USART_TypeDef*)UART_2, 1);} +static void uart1_irq(void) { + uart_irq((USART_TypeDef*)UART_1, 0); +} +static void uart2_irq(void) { + uart_irq((USART_TypeDef*)UART_2, 1); +} void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { irq_handler = handler; @@ -200,8 +225,7 @@ if (irq == RxIrq) { USART_ITConfig(usart, USART_IT_RXNE, ENABLE); - } - else { // TxIrq + } else { // TxIrq USART_ITConfig(usart, USART_IT_TC, ENABLE); } @@ -216,8 +240,7 @@ USART_ITConfig(usart, USART_IT_RXNE, DISABLE); // Check if TxIrq is disabled too if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; - } - else { // TxIrq + } else { // TxIrq USART_ITConfig(usart, USART_IT_TXE, DISABLE); // Check if RxIrq is disabled too if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; @@ -275,3 +298,5 @@ void serial_break_clear(serial_t *obj) { } + +#endif
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/sleep.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/sleep.c Thu Jun 26 09:45:08 2014 +0100 @@ -28,10 +28,12 @@ ******************************************************************************* */ #include "sleep_api.h" + +#if DEVICE_SLEEP + #include "cmsis.h" -void sleep(void) -{ +void sleep(void) { // Disable us_ticker update interrupt TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE); @@ -44,11 +46,15 @@ // MCU STOP mode // Wake-up with external interrupt -void deepsleep(void) -{ +void deepsleep(void) { // Enable PWR clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Request to enter STOP mode with regulator in low power mode PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); + + // After wake-up from STOP reconfigure the PLL + SetSysClock(); } + +#endif
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/spi_api.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/spi_api.c Thu Jun 26 09:45:08 2014 +0100 @@ -38,22 +38,30 @@ static const PinMap PinMap_SPI_MOSI[] = { {PA_7, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_15, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, {NC, NC, 0} }; static const PinMap PinMap_SPI_MISO[] = { {PA_6, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_14, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, {NC, NC, 0} }; static const PinMap PinMap_SPI_SCLK[] = { {PA_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_3, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, + {PB_13, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, {NC, NC, 0} }; // Only used in Slave mode static const PinMap PinMap_SPI_SSEL[] = { - {PB_6, SPI_1, STM_PIN_DATA(GPIO_Mode_IN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)}, // Generic IO, not real H/W NSS pin + {PA_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)}, + {PA_15, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)}, + {PB_12, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0)}, {NC, NC, 0} }; @@ -111,32 +119,51 @@ obj->cpha = SPI_CPHA_1Edge; obj->br_presc = SPI_BaudRatePrescaler_8; // 1 MHz + obj->pin_miso = miso; + obj->pin_mosi = mosi; + obj->pin_sclk = sclk; + obj->pin_ssel = ssel; + if (ssel == NC) { // Master obj->mode = SPI_Mode_Master; obj->nss = SPI_NSS_Soft; - } - else { // Slave + } else { // Slave pinmap_pinout(ssel, PinMap_SPI_SSEL); obj->mode = SPI_Mode_Slave; - obj->nss = SPI_NSS_Soft; + obj->nss = SPI_NSS_Hard; } init_spi(obj); } void spi_free(spi_t *obj) { - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - SPI_I2S_DeInit(spi); + // Reset SPI and disable clock + if (obj->spi == SPI_1) { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, DISABLE); + } + + if (obj->spi == SPI_2) { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, DISABLE); + } + + // Configure GPIOs + pin_function(obj->pin_miso, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); + pin_function(obj->pin_mosi, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); + pin_function(obj->pin_sclk, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); + pin_function(obj->pin_ssel, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); } void spi_format(spi_t *obj, int bits, int mode, int slave) { // Save new values - if (bits == 8) { + if (bits == 16) { + obj->bits = SPI_DataSize_16b; + } else { obj->bits = SPI_DataSize_8b; } - else { - obj->bits = SPI_DataSize_16b; - } switch (mode) { case 0: @@ -160,8 +187,7 @@ if (slave == 0) { obj->mode = SPI_Mode_Master; obj->nss = SPI_NSS_Soft; - } - else { + } else { obj->mode = SPI_Mode_Slave; obj->nss = SPI_NSS_Hard; } @@ -170,26 +196,24 @@ } void spi_frequency(spi_t *obj, int hz) { - // Get SPI clock frequency - uint32_t PCLK = SystemCoreClock; - - // Choose the baud rate divisor (between 2 and 256) - uint32_t divisor = PCLK / hz; - - // Find the nearest power-of-2 - divisor = (divisor > 0 ? divisor-1 : 0); - divisor |= divisor >> 1; - divisor |= divisor >> 2; - divisor |= divisor >> 4; - divisor |= divisor >> 8; - divisor |= divisor >> 16; - divisor++; - - uint32_t baud_rate = __builtin_ffs(divisor) - 2; - - // Save new value - obj->br_presc = ((baud_rate > 7) ? (7 << 3) : (baud_rate << 3)); - + // Note: The frequencies are obtained with SPI clock = 48 MHz (APB1 & APB2 clocks) + if (hz < 300000) { + obj->br_presc = SPI_BaudRatePrescaler_256; // 188 kHz + } else if ((hz >= 300000) && (hz < 700000)) { + obj->br_presc = SPI_BaudRatePrescaler_128; // 375 kHz + } else if ((hz >= 700000) && (hz < 1000000)) { + obj->br_presc = SPI_BaudRatePrescaler_64; // 750 kHz + } else if ((hz >= 1000000) && (hz < 3000000)) { + obj->br_presc = SPI_BaudRatePrescaler_32; // 1.5 MHz + } else if ((hz >= 3000000) && (hz < 6000000)) { + obj->br_presc = SPI_BaudRatePrescaler_16; // 3 MHz + } else if ((hz >= 6000000) && (hz < 12000000)) { + obj->br_presc = SPI_BaudRatePrescaler_8; // 6 MHz + } else if ((hz >= 12000000) && (hz < 24000000)) { + obj->br_presc = SPI_BaudRatePrescaler_4; // 12 MHz + } else { // >= 24000000 + obj->br_presc = SPI_BaudRatePrescaler_2; // 24 MHz + } init_spi(obj); } @@ -212,19 +236,21 @@ static inline void ssp_write(spi_t *obj, int value) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); while (!ssp_writeable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode + if (obj->bits == SPI_DataSize_8b) { SPI_SendData8(spi, (uint8_t)value); - else + } else { // 16-bit SPI_I2S_SendData16(spi, (uint16_t)value); + } } static inline int ssp_read(spi_t *obj) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); while (!ssp_readable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode + if (obj->bits == SPI_DataSize_8b) { return (int)SPI_ReceiveData8(spi); - else // 16 bit mode + } else { // 16-bit return (int)SPI_I2S_ReceiveData16(spi); + } } static inline int ssp_busy(spi_t *obj) { @@ -240,24 +266,26 @@ } int spi_slave_receive(spi_t *obj) { - return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); + return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); }; int spi_slave_read(spi_t *obj) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode + if (obj->bits == SPI_DataSize_8b) { return (int)SPI_ReceiveData8(spi); - else + } else { // 16-bit return (int)SPI_I2S_ReceiveData16(spi); + } } void spi_slave_write(spi_t *obj, int value) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); while (!ssp_writeable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode + if (obj->bits == SPI_DataSize_8b) { SPI_SendData8(spi, (uint8_t)value); - else + } else { // 16-bit SPI_I2S_SendData16(spi, (uint16_t)value); + } } int spi_busy(spi_t *obj) {
--- a/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/us_ticker.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/hal/TARGET_STM/TARGET_DISCO_F051R8/us_ticker.c Thu Jun 26 09:45:08 2014 +0100 @@ -67,14 +67,12 @@ if (oc_rem_part > 0) { set_compare(oc_rem_part); // Finish the remaining time left oc_rem_part = 0; - } - else { + } else { if (oc_int_part > 0) { set_compare(0xFFFF); oc_rem_part = cval; // To finish the counter loop the next time oc_int_part--; - } - else { + } else { us_ticker_irq_handler(); } } @@ -139,8 +137,7 @@ if (delta <= 0) { // This event was in the past us_ticker_irq_handler(); - } - else { + } else { oc_int_part = (uint32_t)(delta >> 16); oc_rem_part = (uint16_t)(delta & 0xFFFF); if (oc_rem_part <= (0xFFFF - cval)) {