[TARGET_DISCO_F303] reorder structure - part2

Update of mbed hal.
pull/678/head
ohagendorf 2014-11-05 01:11:22 +01:00
parent 0c3a635004
commit d61817a4c8
27 changed files with 8193 additions and 1339 deletions

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
* @file hal_tick.c
* @author MCD Application Team
* @brief Initialization of HAL tick
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* 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.
*
* 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.
*
******************************************************************************
*/
#include "hal_tick.h"
TIM_HandleTypeDef TimMasterHandle;
uint32_t PreviousVal = 0;
void us_ticker_irq_handler(void);
void timer_irq_handler(void) {
// Channel 1 for mbed timeout
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC1) == SET) {
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
us_ticker_irq_handler();
}
// Channel 2 for HAL tick
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC2) == SET) {
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC2);
uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle);
if ((val - PreviousVal) >= HAL_TICK_DELAY) {
// Increment HAL variable
HAL_IncTick();
// Prepare next interrupt
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY);
PreviousVal = val;
#if 0 // For DEBUG only
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
#endif
}
}
}
// Reconfigure the HAL tick using a standard timer instead of systick.
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
// Enable timer clock
TIM_MST_RCC;
// Reset timer
TIM_MST_RESET_ON;
TIM_MST_RESET_OFF;
// Configure time base
TimMasterHandle.Instance = TIM_MST;
TimMasterHandle.Init.Period = 0xFFFFFFFF;
TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
TimMasterHandle.Init.ClockDivision = 0;
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimMasterHandle.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&TimMasterHandle);
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ);
// Channel 1 for mbed timeout
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
// Channel 2 for HAL tick
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2);
PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle);
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY);
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2);
#if 0 // For DEBUG only
__GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
#endif
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,60 @@
/**
******************************************************************************
* @file hal_tick.h
* @author MCD Application Team
* @brief Initialization of HAL tick
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
*
* 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.
*
* 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.
*
******************************************************************************
*/
#ifndef __HAL_TICK_H
#define __HAL_TICK_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f3xx.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2
#define TIM_MST_IRQ TIM2_IRQn
#define TIM_MST_RCC __TIM2_CLK_ENABLE()
#define TIM_MST_RESET_ON __TIM2_FORCE_RESET()
#define TIM_MST_RESET_OFF __TIM2_RELEASE_RESET()
#define HAL_TICK_DELAY (1000) // 1 ms
#ifdef __cplusplus
}
#endif
#endif // __HAL_TICK_H
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -100,7 +100,7 @@
In this case, these drivers will not be included and the application code will
be based on direct access to peripherals registers
*/
/*#define USE_HAL_DRIVER */
#define USE_HAL_DRIVER
#endif /* USE_HAL_DRIVER */
/**

View File

@ -1,45 +1,30 @@
/**
******************************************************************************
* @file system_stm32f30x.c
* @file system_stm32f3xx.c
* @author MCD Application Team
* @version V1.0.0
* @date 05-March-2014
* @version V2.1.0
* @date 12-Sept-2014
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
* This file contains the system clock configuration for STM32F30x devices,
* and is generated by the clock configuration tool
* stm32f30x_Clock_Configuration_V1.0.0.xls
*
* 1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
* and Divider factors, AHB/APBx prescalers and Flash settings),
* depending on the configuration made in the clock xls tool.
* This function is called at startup just after reset and
*
* 1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f30x.s" file.
* the "startup_stm32f3xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* by the user application to setup the SysTick
* timer or configure other parameters.
*
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f30x.s" file, to
* Then SystemInit() function is called, in "startup_stm32f3xx.s" file, to
* configure the system clock before to branch to main program.
*
* 3. If the system clock source selected by user fails to startup, the SystemInit()
* function will do nothing and HSI still used as system clock source. User can
* add some code to deal with this issue inside the SetSysClock() function.
*
* 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define
* in "stm32f30x.h" file. When HSE is used as system clock source, directly or
* through PLL, and you are using different crystal you have to adapt the HSE
* value to your own configuration.
*
* 5. This file configures the system clock as follows:
* 3. This file configures the system clock as follows:
*-----------------------------------------------------------------------------
* System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
* | (external 8 MHz clock) | (internal 8 MHz)
@ -54,8 +39,8 @@
*-----------------------------------------------------------------------------
* APB2CLK (MHz) | 72 | 64
*-----------------------------------------------------------------------------
* USB capable (48 MHz precise clock) | YES | NO
*-----------------------------------------------------------------------------
* USB capable (48 MHz precise clock) | NO | NO
*-----------------------------------------------------------------------------
******************************************************************************
* @attention
*
@ -90,21 +75,24 @@
* @{
*/
/** @addtogroup stm32f30x_system
/** @addtogroup stm32f3xx_system
* @{
*/
/** @addtogroup STM32F30x_System_Private_Includes
*/
/** @addtogroup STM32F3xx_System_Private_Includes
* @{
*/
#include "stm32f3xx.h"
#include "hal_tick.h"
#include "stm32f3xx_hal.h"
/**
* @}
*/
/** @addtogroup STM32F30x_System_Private_TypesDefinitions
/** @addtogroup STM32F3xx_System_Private_TypesDefinitions
* @{
*/
@ -112,20 +100,29 @@
* @}
*/
/** @addtogroup STM32F30x_System_Private_Defines
/** @addtogroup STM32F3xx_System_Private_Defines
* @{
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/**
* @}
*/
*/
/** @addtogroup STM32F30x_System_Private_Macros
/** @addtogroup STM32F3xx_System_Private_Macros
* @{
*/
@ -137,19 +134,25 @@
* @}
*/
/** @addtogroup STM32F30x_System_Private_Variables
/** @addtogroup STM32F3xx_System_Private_Variables
* @{
*/
uint32_t SystemCoreClock = 64000000; /* Default with HSI. Will be updated if HSE is used */
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock there is no need to
call the 2 first functions listed above, since SystemCoreClock variable is
updated automatically.
*/
uint32_t SystemCoreClock = 72000000;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/**
* @}
*/
/** @addtogroup STM32F30x_System_Private_FunctionPrototypes
/** @addtogroup STM32F3xx_System_Private_FunctionPrototypes
* @{
*/
@ -163,14 +166,13 @@ uint8_t SetSysClock_PLL_HSI(void);
* @}
*/
/** @addtogroup STM32F30x_System_Private_Functions
/** @addtogroup STM32F3xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemFrequency variable.
* Initialize the FPU setting, vector table location and the PLL configuration is reset.
* @param None
* @retval None
*/
@ -202,20 +204,27 @@ void SystemInit(void)
/* Reset USARTSW[1:0], I2CSW and TIMs bits */
RCC->CFGR3 &= (uint32_t)0xFF00FCCC;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
/* Configure the Cube driver */
SystemCoreClock = 8000000; // At this stage the HSI is used as system clock
HAL_Init();
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings */
SetSysClock();
/* Reset the timer to avoid issues after the RAM initialization */
TIM_MST_RESET_ON;
TIM_MST_RESET_OFF;
}
/**
@ -223,69 +232,83 @@ void SystemInit(void)
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f30x.h file (default value
*
* (*) HSI_VALUE is a constant defined in stm32f3xx_hal.h file (default value
* 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f30x.h file (default value
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f3xx_hal.h file (default value
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00: /* HSI used as system clock */
case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock */
case RCC_CFGR_SWS_HSE: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock */
case RCC_CFGR_SWS_PLL: /* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
pllmull = ( pllmull >> 18) + 2;
if (pllsource == 0x00)
#if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx)
predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
{
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;
}
else
{
/* HSI oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull;
}
#else
if (pllsource == RCC_CFGR_PLLSRC_HSI_DIV2)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
else
{
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
}
SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;
}
#endif /* STM32F302xE || STM32F303xE || STM32F398xx */
break;
default: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
@ -295,7 +318,7 @@ void SystemCoreClockUpdate (void)
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
SystemCoreClock >>= tmp;
}
/**
@ -329,21 +352,8 @@ void SetSysClock(void)
}
}
/* Output SYSCLK on MCO pin(PA8) for debugging purpose */
/*
// Enable GPIOA clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Configure MCO pin (PA8)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Select the clock to output
RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCOPrescaler_1);
*/
/* Output clock on MCO1 pin(PA8) for debugging purpose */
//HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_SYSCLK, RCC_MCO_DIV1); // 72 MHz or 64 MHz
}
#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
@ -352,71 +362,46 @@ void SetSysClock(void)
/******************************************************************************/
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
{
__IO uint32_t StartUpCounter = 0;
__IO uint32_t HSEStatus = 0;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* 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)
/* Enable HSE oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
if (bypass == 0)
{
RCC->CR |= ((uint32_t)RCC_CR_HSEBYP);
RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
}
else
{
RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP);
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */
}
/* 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 and set flash latency
0WS for 0 < SYSCLK <= 24 MHz
1WS for 24 < SYSCLK <= 48 MHz
2WS for 48 < SYSCLK <= 72 MHz */
FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1; /* 2 WS */
/* Warning: values are obtained with external xtal or clock = 8 MHz */
/* SYSCLK = 72 MHz (8 MHz * 9) */
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_PLLMULL9
| RCC_CFGR_HPRE_DIV1 /* HCLK = 72 MHz */
| RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 72 MHz */
| RCC_CFGR_PPRE1_DIV2); /* PCLK1 = 36 MHz */
/* USBCLK = 48 MHz (72 MHz / 1.5) --> USB OK */
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* 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)
{
}
return 1; // OK
}
else
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 72 MHz (8 MHz * 9)
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
return 0; // FAIL
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 72 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 72 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 36 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 72 MHz
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
return 0; // FAIL
}
/* Output clock on MCO1 pin(PA8) for debugging purpose */
//if (bypass == 0)
// HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_HSE, RCC_MCO_DIV2); // 4 MHz with xtal
//else
// HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_HSE, RCC_MCO_DIV1); // 8 MHz with ext clock
return 1; // OK
}
#endif
@ -425,38 +410,35 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
/******************************************************************************/
uint8_t SetSysClock_PLL_HSI(void)
{
/* At this stage the HSI is already enabled and used as System clock source */
/* Enable prefetch buffer and set flash latency
0WS for 0 < SYSCLK <= 24 MHz
1WS for 24 < SYSCLK <= 48 MHz
2WS for 48 < SYSCLK <= 72 MHz */
FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1; /* 2 WS */
/* SYSCLK = 64 MHz (8 MHz / 2 * 16) */
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_PLLMULL16
| RCC_CFGR_HPRE_DIV1 /* HCLK = 64 MHz */
| RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 64 MHz */
| RCC_CFGR_PPRE1_DIV2); /* PCLK1 = 32 MHz */
/* USBCLK = 42.667 MHz (64 MHz / 1.5) --> USB NOT POSSIBLE */
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
/* Enable HSI oscillator and activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; // 64 MHz (8 MHz/2 * 16)
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
return 0; // FAIL
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 64 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 64 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 32 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 64 MHz
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
return 0; // FAIL
}
/* 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)
{
}
/* Output clock on MCO1 pin(PA8) for debugging purpose */
//HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_HSI, RCC_MCO_DIV1); // 8 MHz
return 1; // OK
}
@ -474,3 +456,4 @@ uint8_t SetSysClock_PLL_HSI(void)
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,10 +1,10 @@
/**
******************************************************************************
* @file system_stm32f30x.h
* @file system_stm32f3xx.h
* @author MCD Application Team
* @version V1.1.0
* @date 27-February-2014
* @brief CMSIS Cortex-M4 Device System Source File for STM32F30x devices.
* @version V2.1.0
* @date 12-Sept-2014
* @brief CMSIS Cortex-M4 Device System Source File for STM32F3xx devices.
******************************************************************************
* @attention
*
@ -33,33 +33,70 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f30x_system
/** @addtogroup stm32f3xx_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32F30X_H
#define __SYSTEM_STM32F30X_H
#ifndef __SYSTEM_STM32F3XX_H
#define __SYSTEM_STM32F3XX_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/** @addtogroup STM32F3xx_System_Includes
* @{
*/
/** @addtogroup STM32F30x_System_Exported_Functions
/**
* @}
*/
/** @addtogroup STM32F3xx_System_Exported_types
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
3) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) by calling HAL API function HAL_RCC_ClockConfig()
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* @}
*/
/** @addtogroup STM32F3xx_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F3xx_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F3xx_System_Exported_Functions
* @{
*/
@ -75,7 +112,7 @@ extern void SetSysClock(void);
}
#endif
#endif /*__SYSTEM_STM32F30X_H */
#endif /*__SYSTEM_STM32F3XX_H */
/**
* @}

View File

@ -45,7 +45,7 @@ typedef enum {
} DACName;
typedef enum {
UART_1 = (int)USART1_BASE,
UART_1 = (int)USART1_BASE,
UART_2 = (int)USART2_BASE,
UART_3 = (int)USART3_BASE
} UARTName;
@ -61,12 +61,12 @@ typedef enum {
typedef enum {
I2C_1 = (int)I2C1_BASE,
I2C_2 = (int)I2C2_BASE,
I2C_3 = (int)I2C3_BASE
I2C_2 = (int)I2C2_BASE
} I2CName;
typedef enum {
PWM_1 = (int)TIM1_BASE,
PWM_2 = (int)TIM2_BASE,
PWM_15 = (int)TIM15_BASE,
PWM_16 = (int)TIM16_BASE,
PWM_17 = (int)TIM17_BASE

View File

@ -36,21 +36,30 @@
extern "C" {
#endif
// MODE (see GPIOMode_TypeDef structure)
// OTYPE (see GPIOOType_TypeDef structure)
// PUPD (see GPIOPuPd_TypeDef structure)
// AFNUM (see AF_mapping constant table, 0xFF is not used)
#define STM_PIN_DATA(MODE, OTYPE, PUPD, AFNUM) (((AFNUM)<<8)|((PUPD)<<4)|((OTYPE)<<2)|((MODE)<<0))
#define STM_PIN_MODE(X) (((X)>>0) & 0x3)
#define STM_PIN_OTYPE(X) (((X)>>2) & 0x1)
#define STM_PIN_PUPD(X) (((X)>>4) & 0x3)
#define STM_PIN_AFNUM(X) (((X)>>8) & 0xF)
// See stm32f3xx_hal_gpio.h and stm32f3xx_hal_gpio_ex.h for values of MODE, PUPD and AFNUM
#define STM_PIN_DATA(MODE, PUPD, AFNUM) ((int)(((AFNUM) << 7) | ((PUPD) << 4) | ((MODE) << 0)))
#define STM_PIN_MODE(X) (((X) >> 0) & 0x0F)
#define STM_PIN_PUPD(X) (((X) >> 4) & 0x07)
#define STM_PIN_AFNUM(X) (((X) >> 7) & 0x0F)
#define STM_MODE_INPUT (0)
#define STM_MODE_OUTPUT_PP (1)
#define STM_MODE_OUTPUT_OD (2)
#define STM_MODE_AF_PP (3)
#define STM_MODE_AF_OD (4)
#define STM_MODE_ANALOG (5)
#define STM_MODE_IT_RISING (6)
#define STM_MODE_IT_FALLING (7)
#define STM_MODE_IT_RISING_FALLING (8)
#define STM_MODE_EVT_RISING (9)
#define STM_MODE_EVT_FALLING (10)
#define STM_MODE_EVT_RISING_FALLING (11)
#define STM_MODE_IT_EVT_RESET (12)
// High nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H)
// Low nibble = pin number
#define STM_PORT(X) (((uint32_t)(X) >> 4) & 0xF)
#define STM_PIN(X) ((uint32_t)(X) & 0xF)
typedef enum {
PIN_INPUT,
PIN_OUTPUT
@ -159,56 +168,56 @@ typedef enum {
PF_14 = 0x5E,
PF_15 = 0x5F,
// Arduino connector namings
A0 = PA_0,
A1 = PA_1,
A2 = PA_4,
A3 = PB_0,
A4 = PC_1,
A5 = PC_0,
D0 = PA_3,
D1 = PA_2,
D2 = PA_10,
D3 = PB_3,
D4 = PB_5,
D5 = PB_4,
D6 = PB_10,
D7 = PA_8,
D8 = PA_9,
D9 = PC_7,
D10 = PB_6,
D11 = PA_7,
D12 = PA_6,
D13 = PA_5,
D14 = PB_9,
D15 = PB_8,
// Arduino connector namings
A0 = PA_0,
A1 = PA_1,
A2 = PA_4,
A3 = PB_0,
A4 = PC_1,
A5 = PC_0,
D0 = PA_3,
D1 = PA_2,
D2 = PA_10,
D3 = PB_3,
D4 = PB_5,
D5 = PB_4,
D6 = PB_10,
D7 = PA_8,
D8 = PA_9,
D9 = PC_7,
D10 = PB_6,
D11 = PB_15,
D12 = PB_14,
D13 = PB_13,
D14 = PB_9,
D15 = PB_8,
// Generic signals namings
LED1 = PE_9,
LED2 = PE_8,
LED3 = PE_9,
LED4 = PE_8,
LED5 = PE_10,
LED6 = PE_15,
LED7 = PE_11,
LED8 = PE_14,
LED9 = PE_12,
LED10 = PE_13,
USER_BUTTON = PA_0,
SERIAL_TX = PA_2, /* USART2 */
SERIAL_RX = PA_3,
USBTX = PA_2, /* USART2 */
USBRX = PA_3,
I2C_SCL = PB_8, /* I2C1 */
I2C_SDA = PB_9,
SPI_MOSI = PB_5, /* SPI1 */
SPI_MISO = PB_4,
SPI_SCK = PB_3,
SPI_CS = PA_15,
PWM_OUT = PB_1,
// Not connected
NC = (int)0xFFFFFFFF
// Generic signals namings
LED1 = PE_9,
LED2 = PE_8,
LED3 = PE_9,
LED4 = PE_8,
LED5 = PE_10,
LED6 = PE_15,
LED7 = PE_11,
LED8 = PE_14,
LED9 = PE_12,
LED10 = PE_13,
USER_BUTTON = PA_0,
SERIAL_TX = PA_2,
SERIAL_RX = PA_3,
USBTX = PA_2,
USBRX = PA_3,
I2C_SCL = PB_8,
I2C_SDA = PB_9,
SPI_MOSI = PB_15,
SPI_MISO = PB_14,
SPI_SCK = PB_13,
SPI_CS = PB_6,
PWM_OUT = PB_4,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {

View File

@ -27,40 +27,40 @@
*/
#include "mbed_assert.h"
#include "analogin_api.h"
#include "wait_api.h"
#if DEVICE_ANALOGIN
#include "wait_api.h"
#include "cmsis.h"
#include "pinmap.h"
static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN1
{PA_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN2
{PA_2, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN3
{PA_3, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN4
{PA_4, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN5
{PC_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN6
{PC_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN7
{PC_2, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN8
{PC_3, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN9
{PA_6, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN10
{PB_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN11
{PB_1, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN12
{PB_13, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN13
{PB_11, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN14
{PA_7, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN15
{PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN1 - ARDUINO A0
{PA_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN2 - ARDUINO A1
{PA_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN3
{PA_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN4
{PA_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN5 - ARDUINO A2
{PA_6, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN10
{PA_7, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN15
{PB_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN11 - ARDUINO A3
{PB_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN12
{PB_11, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN14
{PB_13, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN13
{PC_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN6 - ARDUINO A5
{PC_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN7 - ARDUINO A4
{PC_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN8
{PC_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN9
{NC, NC, 0}
};
ADC_HandleTypeDef AdcHandle;
int adc_inited = 0;
void analogin_init(analogin_t *obj, PinName pin) {
ADC_TypeDef *adc;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
void analogin_init(analogin_t *obj, PinName pin)
{
// Get the peripheral name from the pin and assign it to the object
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
@ -75,117 +75,114 @@ void analogin_init(analogin_t *obj, PinName pin) {
if (adc_inited == 0) {
adc_inited = 1;
// Get ADC registers structure address
adc = (ADC_TypeDef *)(obj->adc);
// Enable ADC clock
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
__ADC34_CLK_ENABLE();
// Calibration
ADC_VoltageRegulatorCmd(adc, ENABLE);
wait_us(10);
ADC_SelectCalibrationMode(adc, ADC_CalibrationMode_Single);
ADC_StartCalibration(adc);
while (ADC_GetCalibrationStatus(adc) != RESET) {}
// Configure ADC
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
ADC_CommonInit(adc, &ADC_CommonInitStructure);
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
ADC_InitStructure.ADC_NbrOfRegChannel = 1;
ADC_Init(adc, &ADC_InitStructure);
// Enable ADC
ADC_Cmd(adc, ENABLE);
while (!ADC_GetFlagStatus(adc, ADC_FLAG_RDY)) {}
AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
AdcHandle.Init.Resolution = ADC_RESOLUTION12b;
AdcHandle.Init.ScanConvMode = DISABLE;
AdcHandle.Init.ContinuousConvMode = DISABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DMAContinuousRequests = DISABLE;
AdcHandle.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&AdcHandle);
}
}
static inline uint16_t adc_read(analogin_t *obj) {
// Get ADC registers structure address
ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc);
uint8_t channel = 0;
// Configure ADC channel
switch (obj->pin) {
case PA_0:
channel = ADC_Channel_1;
break;
case PA_1:
channel = ADC_Channel_2;
break;
case PA_2:
channel = ADC_Channel_3;
break;
case PA_3:
channel = ADC_Channel_4;
break;
case PA_4:
channel = ADC_Channel_5;
break;
case PC_0:
channel = ADC_Channel_6;
break;
case PC_1:
channel = ADC_Channel_7;
break;
case PC_2:
channel = ADC_Channel_8;
break;
case PC_3:
channel = ADC_Channel_9;
break;
case PA_6:
channel = ADC_Channel_10;
break;
case PB_0:
channel = ADC_Channel_11;
break;
case PB_1:
channel = ADC_Channel_12;
break;
case PB_13:
channel = ADC_Channel_13;
break;
case PB_11:
channel = ADC_Channel_14;
break;
case PA_7:
channel = ADC_Channel_15;
break;
default:
return 0;
}
static inline uint16_t adc_read(analogin_t *obj)
{
ADC_ChannelConfTypeDef sConfig;
ADC_RegularChannelConfig(adc, channel, 1, ADC_SampleTime_7Cycles5);
ADC_StartConversion(adc); // Start conversion
while (ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion
return (ADC_GetConversionValue(adc)); // Get conversion value
AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
// Configure ADC channel
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
switch (obj->pin) {
case PA_0:
sConfig.Channel = ADC_CHANNEL_1;
break;
case PA_1:
sConfig.Channel = ADC_CHANNEL_2;
break;
case PA_2:
sConfig.Channel = ADC_CHANNEL_3;
break;
case PA_3:
sConfig.Channel = ADC_CHANNEL_4;
break;
case PA_4:
sConfig.Channel = ADC_CHANNEL_5;
break;
case PA_6:
sConfig.Channel = ADC_CHANNEL_10;
break;
case PA_7:
sConfig.Channel = ADC_CHANNEL_15;
break;
case PB_0:
sConfig.Channel = ADC_CHANNEL_11;
break;
case PB_1:
sConfig.Channel = ADC_CHANNEL_12;
break;
case PB_11:
sConfig.Channel = ADC_CHANNEL_14;
break;
case PB_13:
sConfig.Channel = ADC_CHANNEL_13;
break;
case PC_0:
sConfig.Channel = ADC_CHANNEL_6;
break;
case PC_1:
sConfig.Channel = ADC_CHANNEL_7;
break;
case PC_2:
sConfig.Channel = ADC_CHANNEL_8;
break;
case PC_3:
sConfig.Channel = ADC_CHANNEL_9;
break;
default:
return 0;
}
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
HAL_ADC_Start(&AdcHandle); // Start conversion
// Wait end of conversion and get value
if (HAL_ADC_PollForConversion(&AdcHandle, 10) == HAL_OK) {
return (HAL_ADC_GetValue(&AdcHandle));
} else {
return 0;
}
}
uint16_t analogin_read_u16(analogin_t *obj) {
return (adc_read(obj));
uint16_t analogin_read_u16(analogin_t *obj)
{
uint16_t value = adc_read(obj);
// 12-bit to 16-bit conversion
value = ((value << 4) & (uint16_t)0xFFF0) | ((value >> 8) & (uint16_t)0x000F);
return value;
}
float analogin_read(analogin_t *obj) {
uint16_t value = adc_read(obj);
return (float)value * (1.0f / (float)0xFFF); // 12 bits range
float analogin_read(analogin_t *obj)
{
uint16_t value = adc_read(obj);
return (float)value * (1.0f / (float)0xFFF); // 12 bits range
}
#endif

View File

@ -32,80 +32,69 @@
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#define DAC_RANGE (0xFFF) // 12 bits
static const PinMap PinMap_DAC[] = {
{PA_4, DAC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // DAC_OUT1
{PA_5, DAC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // DAC_OUT2
{PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT1
{NC, NC, 0}
};
void analogout_init(dac_t *obj, PinName pin) {
DAC_TypeDef *dac;
DAC_InitTypeDef DAC_InitStructure;
static DAC_HandleTypeDef DacHandle;
// Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
void analogout_init(dac_t *obj, PinName pin)
{
DAC_ChannelConfTypeDef sConfig;
// Get the peripheral name from the pin and assign it to the object
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT(obj->dac != (DACName)NC);
dac = (DAC_TypeDef *)(obj->dac);
// Configure GPIO
pinmap_pinout(pin, PinMap_DAC);
// Save the channel for the write and read functions
obj->channel = pin;
// Save the pin for future use
obj->pin = pin;
// Enable DAC clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
__DAC1_CLK_ENABLE();
// Configure and enable DAC channel
DAC_StructInit(&DAC_InitStructure);
// Configure DAC
DacHandle.Instance = (DAC_TypeDef *)(obj->dac);
if (obj->channel == PA_4) {
DAC_Init(dac,DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(dac,DAC_Channel_1, ENABLE);
}
if (obj->channel == PA_5) {
DAC_Init(dac,DAC_Channel_2, &DAC_InitStructure);
DAC_Cmd(dac,DAC_Channel_2, ENABLE);
}
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1);
analogout_write_u16(obj, 0);
}
void analogout_free(dac_t *obj) {
DAC_TypeDef *dac = (DAC_TypeDef *)(obj->dac);
// Disable DAC
DAC_DeInit(dac);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, DISABLE);
void analogout_free(dac_t *obj)
{
// Reset DAC and disable clock
__DAC1_FORCE_RESET();
__DAC1_RELEASE_RESET();
__DAC1_CLK_DISABLE();
// Configure GPIO
pin_function(obj->channel, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
static inline void dac_write(dac_t *obj, uint16_t value) {
DAC_TypeDef *dac = (DAC_TypeDef *)(obj->dac);
if (obj->channel == PA_4) {
DAC_SetChannel1Data(dac,DAC_Align_12b_R, value);
}
if (obj->channel == PA_5) {
DAC_SetChannel2Data(dac,DAC_Align_12b_R, value);
}
static inline void dac_write(dac_t *obj, uint16_t value)
{
HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
}
static inline int dac_read(dac_t *obj) {
DAC_TypeDef *dac = (DAC_TypeDef *)(obj->dac);
if (obj->channel == PA_4) {
return (int)DAC_GetDataOutputValue(dac,DAC_Channel_1);
}
if (obj->channel == PA_5) {
return (int)DAC_GetDataOutputValue(dac,DAC_Channel_2);
}
return 0;
static inline int dac_read(dac_t *obj)
{
return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
}
void analogout_write(dac_t *obj, float value) {
void analogout_write(dac_t *obj, float value)
{
if (value < 0.0f) {
dac_write(obj, 0); // Min value
} else if (value > 1.0f) {
@ -115,20 +104,23 @@ void analogout_write(dac_t *obj, float value) {
}
}
void analogout_write_u16(dac_t *obj, uint16_t value) {
void analogout_write_u16(dac_t *obj, uint16_t value)
{
if (value > (uint16_t)DAC_RANGE) {
dac_write(obj, (uint16_t)DAC_RANGE); // Max value
} else {
dac_write(obj, value);
dac_write(obj, value);
}
}
float analogout_read(dac_t *obj) {
float analogout_read(dac_t *obj)
{
uint32_t value = dac_read(obj);
return (float)((float)value * (1.0f / (float)DAC_RANGE));
}
uint16_t analogout_read_u16(dac_t *obj) {
uint16_t analogout_read_u16(dac_t *obj)
{
return (uint16_t)dac_read(obj);
}

View File

@ -45,7 +45,7 @@
#define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0 // Not yet supported
#define DEVICE_SPISLAVE 1
#define DEVICE_RTC 1
@ -56,7 +56,6 @@
//=======================================
#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_ID_LENGTH 24

View File

@ -34,17 +34,21 @@
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
uint32_t gpio_set(PinName pin) {
uint32_t gpio_set(PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
pin_function(pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
pin_function(pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask
}
void gpio_init(gpio_t *obj, PinName pin) {
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC)
if (pin == (PinName)NC) {
return;
}
uint32_t port_index = STM_PORT(pin);
@ -55,19 +59,21 @@ void gpio_init(gpio_t *obj, PinName pin) {
// Fill GPIO object structure for future use
obj->mask = gpio_set(pin);
obj->reg_in = &gpio->IDR;
obj->reg_set = &gpio->BSRR;
obj->reg_clr = &gpio->BRR;
obj->reg_set = &gpio->BSRRL;
obj->reg_clr = &gpio->BSRRH;
}
void gpio_mode(gpio_t *obj, PinMode mode) {
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction) {
void gpio_dir(gpio_t *obj, PinDirection direction)
{
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));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
} else { // PIN_INPUT
pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
}

View File

@ -29,7 +29,6 @@
*/
#include <stddef.h>
#include "cmsis.h"
#include "gpio_irq_api.h"
#include "pinmap.h"
#include "mbed_error.h"
@ -47,18 +46,19 @@ static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0};
static gpio_irq_handler irq_handler;
static void handle_interrupt_in(uint32_t irq_index) {
static void handle_interrupt_in(uint32_t irq_index)
{
// Retrieve the gpio and pin that generate the irq
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]);
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
// Clear interrupt flag
if (EXTI_GetITStatus(channel_pin[irq_index]) != RESET) {
EXTI_ClearITPendingBit(channel_pin[irq_index]);
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
}
if (channel_ids[irq_index] == 0) return;
// Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) {
irq_handler(channel_ids[irq_index], IRQ_FALL);
@ -67,37 +67,47 @@ static void handle_interrupt_in(uint32_t irq_index) {
}
}
static void gpio_irq0(void) {
handle_interrupt_in(0); // EXTI line 0
// The irq_index is passed to the function
// EXTI line 0
static void gpio_irq0(void)
{
handle_interrupt_in(0);
}
static void gpio_irq1(void) {
handle_interrupt_in(1); // EXTI line 1
// EXTI line 1
static void gpio_irq1(void)
{
handle_interrupt_in(1);
}
static void gpio_irq2(void) {
handle_interrupt_in(2); // EXTI line 2
// EXTI line 2
static void gpio_irq2(void)
{
handle_interrupt_in(2);
}
static void gpio_irq3(void) {
handle_interrupt_in(3); // EXTI line 3
// EXTI line 3
static void gpio_irq3(void)
{
handle_interrupt_in(3);
}
static void gpio_irq4(void) {
handle_interrupt_in(4); // EXTI line 4
// EXTI line 4
static void gpio_irq4(void)
{
handle_interrupt_in(4);
}
static void gpio_irq5(void) {
handle_interrupt_in(5); // EXTI lines 5 to 9
// EXTI lines 5 to 9
static void gpio_irq5(void)
{
handle_interrupt_in(5);
}
static void gpio_irq6(void) {
handle_interrupt_in(6); // EXTI lines 10 to 15
// EXTI lines 10 to 15
static void gpio_irq6(void)
{
handle_interrupt_in(6);
}
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
uint32_t irq_index;
@ -120,7 +130,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_index = 1;
break;
case 2:
irq_n = EXTI2_TS_IRQn;
irq_n = EXTI2_TSC_IRQn;
vector = (uint32_t)&gpio_irq2;
irq_index = 2;
break;
@ -154,35 +164,17 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_index = 6;
break;
default:
error("This pin is not supported with InterruptIn.");
error("InterruptIn error: pin not supported.\n");
return -1;
}
// Enable GPIO clock
uint32_t gpio_add = Set_GPIO_Clock(port_index);
// Enable SYSCFG clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
// Connect EXTI line to pin
SYSCFG_EXTILineConfig(port_index, pin_index);
// Configure GPIO
pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0));
// Configure EXTI line
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = pin_index;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// Enable and set EXTI interrupt to the lowest priority
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq_n;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable EXTI interrupt
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
@ -190,66 +182,81 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
obj->irq_n = irq_n;
obj->irq_index = irq_index;
obj->event = EDGE_NONE;
obj->pin = pin;
channel_ids[irq_index] = id;
channel_gpio[irq_index] = gpio_add;
channel_pin[irq_index] = pin_index;
irq_handler = handler;
irq_handler = handler;
return 0;
}
void gpio_irq_free(gpio_irq_t *obj) {
void gpio_irq_free(gpio_irq_t *obj)
{
channel_ids[obj->irq_index] = 0;
channel_gpio[obj->irq_index] = 0;
channel_pin[obj->irq_index] = 0;
// Disable EXTI line
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
EXTI_Init(&EXTI_InitStructure);
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
obj->event = EDGE_NONE;
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
EXTI_InitTypeDef EXTI_InitStructure;
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
uint32_t mode = STM_MODE_IT_EVT_RESET;
uint32_t pull = GPIO_NOPULL;
EXTI_InitStructure.EXTI_Line = channel_pin[obj->irq_index];
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
if (event == IRQ_RISE) {
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
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
obj->event = EDGE_RISE;
}
}
if (event == IRQ_FALL) {
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
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
obj->event = EDGE_FALL;
}
}
if (enable) {
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
} else {
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
} else { // NONE or RISE
mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE;
}
}
if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
} else { // NONE or FALL
mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL;
}
}
} else { // Disable
if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL;
} else { // NONE or RISE
mode = STM_MODE_IT_EVT_RESET;
obj->event = EDGE_NONE;
}
}
if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE;
} else { // NONE or FALL
mode = STM_MODE_IT_EVT_RESET;
obj->event = EDGE_NONE;
}
}
}
EXTI_Init(&EXTI_InitStructure);
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
}
void gpio_irq_enable(gpio_irq_t *obj) {
void gpio_irq_enable(gpio_irq_t *obj)
{
NVIC_EnableIRQ(obj->irq_n);
}
void gpio_irq_disable(gpio_irq_t *obj) {
void gpio_irq_disable(gpio_irq_t *obj)
{
NVIC_DisableIRQ(obj->irq_n);
obj->event = EDGE_NONE;
}

View File

@ -43,12 +43,13 @@ extern "C" {
typedef struct {
PinName pin;
uint32_t mask;
__IO uint16_t *reg_in;
__IO uint32_t *reg_set;
__IO uint32_t *reg_in;
__IO uint16_t *reg_set;
__IO uint16_t *reg_clr;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value) {
static inline void gpio_write(gpio_t *obj, int value)
{
MBED_ASSERT(obj->pin != (PinName)NC);
if (value) {
*obj->reg_set = obj->mask;
@ -57,7 +58,8 @@ static inline void gpio_write(gpio_t *obj, int value) {
}
}
static inline int gpio_read(gpio_t *obj) {
static inline int gpio_read(gpio_t *obj)
{
MBED_ASSERT(obj->pin != (PinName)NC);
return ((*obj->reg_in & obj->mask) ? 1 : 0);
}

View File

@ -34,36 +34,42 @@
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define FLAG_TIMEOUT ((int)0x4000)
#define LONG_TIMEOUT ((int)0x8000)
static const PinMap PinMap_I2C_SDA[] = {
{PA_10, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PA_14, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PB_5, I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_8)},
{PB_7, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PB_9, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PC_9, I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_3)},
{PF_0, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PA_10, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
//{PA_14, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PB_5, I2C_3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF8_I2C3)},
//{PB_7, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PB_9, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PC_9, I2C_3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF3_I2C3)},
//{PF_0, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
{NC, NC, 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PA_8, I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_3)},
{PA_9, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PA_15, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PB_6, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PB_8, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
{PF_1, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
//{PA_8, I2C_3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF3_I2C3)},
{PA_9, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
//{PA_15, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PB_6, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PB_8, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
//{PF_1, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
{NC, NC, 0}
};
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
//int i2c3_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
@ -71,41 +77,51 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C clock
if (obj->i2c == I2C_1) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
// Enable I2C clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
// Configure I2C1 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
if (obj->i2c == I2C_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C2 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
if (obj->i2c == I2C_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
}
// Configure I2C pins
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(scl, OpenDrain);
pinmap_pinout(sda, PinMap_I2C_SDA);
pin_mode(sda, OpenDrain);
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure;
void i2c_frequency(i2c_t *obj, int hz)
{
uint32_t tim = 0;
// 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);
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
/*
Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235)
* Standard mode (up to 100 kHz)
@ -115,218 +131,239 @@ void i2c_frequency(i2c_t *obj, int hz) {
- I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE)
- Analog filter delay = ON
- Digital filter coefficient = 0
- Rise time = 100 ns
- Fall time = 10ns
*/
if (SystemCoreClock == 64000000) {
switch (hz) {
case 100000:
tim = 0x60302730; // Standard mode
break;
case 200000:
tim = 0x00C07AB3; // Fast Mode
break;
case 400000:
tim = 0x00C0216C; // Fast Mode
break;
case 1000000:
tim = 0x00900B22; // 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:
error("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported.");
break;
}
switch (hz) {
case 100000:
tim = 0x10B17DB4; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00E22163; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00A00D1E; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
} else if (SystemCoreClock == 72000000) {
switch (hz) {
case 100000:
tim = 0x10C08DCF; // Standard mode
break;
case 200000:
tim = 0xA010031A; // Fast Mode
tim = 0x10D28DCB; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00E0257A; // Fast Mode
tim = 0x00F32571; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00A00D26; // 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);
}
tim = 0x00C00D24; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
error("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported.");
break;
}
} else {
error("System clock setting is not supported.");
}
// I2C configuration
I2C_DeInit(i2c);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = tim;
I2C_Init(i2c, &I2C_InitStructure);
I2C_Cmd(i2c, ENABLE);
}
inline int i2c_start(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Test BUSY Flag
timeout = LONG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_ISR_BUSY) != RESET) {
timeout--;
if (timeout == 0) {
return 0;
// Enable the Fast Mode Plus capability
if (hz == 1000000) {
if (obj->i2c == I2C_1) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C1);
}
if (obj->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2);
}
}
I2C_GenerateSTART(i2c, ENABLE);
return 0;
// I2C configuration
I2cHandle.Init.Timing = tim;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
HAL_I2C_Init(&I2cHandle);
}
inline int i2c_stop(i2c_t *obj) {
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_GenerateSTOP(i2c, ENABLE);
return 0;
}
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_SoftEnd_Mode, I2C_Generate_Start_Read);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
timeout = FLAG_TIMEOUT;
while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) {
// Wait transfer complete
timeout = LONG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) return 0;
if (timeout == 0) {
return -1;
}
}
if (stop) i2c_stop(obj);
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
if (length == 0) return 0;
// 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
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) {
timeout--;
if (timeout == 0) return 0;
}
if (stop) i2c_stop(obj);
return count;
}
int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint8_t data;
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_ISR_RXNE) == RESET) {
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return 0;
return -1;
}
}
data = I2C_ReceiveData(i2c);
return (int)data;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_write(i2c_t *obj, int data) {
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_ISR_TXIS) == RESET) {
timeout--;
if (timeout == 0) {
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
I2C_SendData(i2c, (uint8_t)data);
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj) {
if (obj->i2c == I2C_1) {
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_3) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, DISABLE);
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// reset own address enable
i2c->OAR1 &= ~ I2C_OAR1_OA1EN;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
@ -334,11 +371,30 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg | I2C_OAR1_OA1EN;
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
// Nothing to do
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
@ -347,43 +403,44 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int event = NoData;
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = 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;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return event;
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
int count = 0;
// Read all bytes
for (count = 0; count < length; count++) {
data[count] = i2c_byte_read(obj, 0);
}
return count;
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int count = 0;
// Write all bytes
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
return count;
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}

View File

@ -28,7 +28,10 @@
#include "cmsis.h"
// This function is called after RAM initialization and before main.
void mbed_sdk_init() {
void mbed_sdk_init()
{
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
// Need to restart HAL driver after the RAM is initialized
HAL_Init();
}

View File

@ -43,14 +43,15 @@ struct gpio_irq_s {
IRQn_Type irq_n;
uint32_t irq_index;
uint32_t event;
PinName pin;
};
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
__IO uint16_t *reg_in;
__IO uint16_t *reg_out;
PinDirection direction;
__IO uint32_t *reg_in;
__IO uint32_t *reg_out;
};
struct analogin_s {
@ -60,7 +61,7 @@ struct analogin_s {
struct dac_s {
DACName dac;
PinName channel;
PinName pin;
};
struct serial_s {
@ -69,7 +70,7 @@ struct serial_s {
uint32_t baudrate;
uint32_t databits;
uint32_t stopbits;
uint32_t parity;
uint32_t parity;
PinName pin_tx;
PinName pin_rx;
};
@ -90,6 +91,7 @@ struct spi_s {
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct pwmout_s {

View File

@ -32,37 +32,54 @@
#include "PortNames.h"
#include "mbed_error.h"
// GPIO mode look-up table
static const uint32_t gpio_mode[13] = {
0x00000000, // 0 = GPIO_MODE_INPUT
0x00000001, // 1 = GPIO_MODE_OUTPUT_PP
0x00000011, // 2 = GPIO_MODE_OUTPUT_OD
0x00000002, // 3 = GPIO_MODE_AF_PP
0x00000012, // 4 = GPIO_MODE_AF_OD
0x00000003, // 5 = GPIO_MODE_ANALOG
0x10110000, // 6 = GPIO_MODE_IT_RISING
0x10210000, // 7 = GPIO_MODE_IT_FALLING
0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING
0x10120000, // 9 = GPIO_MODE_EVT_RISING
0x10220000, // 10 = GPIO_MODE_EVT_FALLING
0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING
0x10000000 // 12 = Reset IT and EVT (not in STM32Cube HAL)
};
// Enable GPIO clock and return GPIO base address
uint32_t Set_GPIO_Clock(uint32_t port_idx) {
uint32_t gpio_add;
uint32_t Set_GPIO_Clock(uint32_t port_idx)
{
uint32_t gpio_add = 0;
switch (port_idx) {
case PortA:
gpio_add = GPIOA_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
__GPIOA_CLK_ENABLE();
break;
case PortB:
gpio_add = GPIOB_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
__GPIOB_CLK_ENABLE();
break;
case PortC:
gpio_add = GPIOC_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
__GPIOC_CLK_ENABLE();
break;
case PortD:
gpio_add = GPIOD_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
__GPIOD_CLK_ENABLE();
break;
case PortE:
gpio_add = GPIOE_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
__GPIOE_CLK_ENABLE();
break;
case PortF:
gpio_add = GPIOF_BASE;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);
__GPIOF_CLK_ENABLE();
break;
default:
gpio_add = 0;
error("Port number is not correct.");
error("Pinmap error: wrong port number.");
break;
}
return gpio_add;
@ -71,12 +88,11 @@ uint32_t Set_GPIO_Clock(uint32_t port_idx) {
/**
* Configure pin (mode, speed, output type and pull-up/pull-down)
*/
void pin_function(PinName pin, int data) {
void pin_function(PinName pin, int data)
{
MBED_ASSERT(pin != (PinName)NC);
// Get the pin informations
uint32_t mode = STM_PIN_MODE(data);
uint32_t otype = STM_PIN_OTYPE(data);
uint32_t pupd = STM_PIN_PUPD(data);
uint32_t afnum = STM_PIN_AFNUM(data);
@ -87,37 +103,28 @@ void pin_function(PinName pin, int data) {
uint32_t gpio_add = Set_GPIO_Clock(port_index);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
// Configure Alternate Function
// Warning: Must be done before the GPIO is initialized
if (afnum != 0xFF) {
GPIO_PinAFConfig(gpio, (uint16_t)pin_index, afnum);
}
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_OType = (GPIOOType_TypeDef)otype;
GPIO_InitStructure.GPIO_PuPd = (GPIOPuPd_TypeDef)pupd;
GPIO_Init(gpio, &GPIO_InitStructure);
GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index);
GPIO_InitStructure.Mode = gpio_mode[mode];
GPIO_InitStructure.Pull = pupd;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = afnum;
HAL_GPIO_Init(gpio, &GPIO_InitStructure);
// [TODO] Disconnect JTAG-DP + SW-DP signals.
// Warning: Need to reconnect under reset
//if ((pin == PA_13) || (pin == PA_14)) {
//
//}
//if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) {
//
//}
}
/**
* Configure pin pull-up/pull-down
*/
void pin_mode(PinName pin, PinMode mode) {
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t port_index = STM_PORT(pin);
uint32_t pin_index = STM_PIN(pin);
@ -127,9 +134,10 @@ void pin_mode(PinName pin, PinMode mode) {
// Configure pull-up/pull-down resistors
uint32_t pupd = (uint32_t)mode;
if (pupd > 2)
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));
}

View File

@ -28,22 +28,23 @@
*******************************************************************************
*/
#include "port_api.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
#include "pinmap.h"
#include "gpio_api.h"
#include "mbed_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, ...)
// low nibble = pin number
PinName port_pin(PortName port, int pin_n) {
return (PinName)(pin_n + (port << 4));
PinName port_pin(PortName port, int pin_n)
{
return (PinName)(pin_n + (port << 4));
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
uint32_t port_index = (uint32_t)port;
// Enable GPIO clock
@ -53,29 +54,31 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
// Fill PORT object structure for future use
obj->port = port;
obj->mask = mask;
obj->direction = dir;
obj->direction = dir;
obj->reg_in = &gpio->IDR;
obj->reg_out = &gpio->ODR;
obj->reg_out = &gpio->ODR;
port_dir(obj, dir);
}
void port_dir(port_t *obj, PinDirection dir) {
void port_dir(port_t *obj, PinDirection dir)
{
uint32_t i;
obj->direction = dir;
for (i = 0; i < 16; i++) { // Process all pins
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));
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
} else { // PIN_INPUT
pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
}
}
}
}
void port_mode(port_t *obj, PinMode mode) {
uint32_t i;
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
for (i = 0; i < 16; i++) { // Process all pins
if (obj->mask & (1 << i)) { // If the pin is used
pin_mode(port_pin(obj->port, i), mode);
@ -83,11 +86,13 @@ void port_mode(port_t *obj, PinMode mode) {
}
}
void port_write(port_t *obj, int value) {
void port_write(port_t *obj, int value)
{
*obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask);
}
int port_read(port_t *obj) {
int port_read(port_t *obj)
{
if (obj->direction == PIN_OUTPUT) {
return (*obj->reg_out & obj->mask);
} else { // PIN_INPUT

View File

@ -37,240 +37,246 @@
// TIM2 cannot be used because already used by the us_ticker
static const PinMap PinMap_PWM[] = {
// {PA_0, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH1
// {PA_1, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH2
{PA_1, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_9)}, // TIM15_CH1N
{PA_2, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_9)}, // TIM15_CH1
{PA_3, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_9)}, // TIM15_CH2
// {PA_5, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH1
{PA_6, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1
{PA_7, PWM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM17_CH1
// {PA_7, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH1N
{PA_8, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH1
{PA_9, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH2
// {PA_9, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_10)}, // TIM2_CH3
{PA_10, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH3
// {PA_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_10)}, // TIM2_CH4
{PA_11, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_11)}, // TIM1_CH4
// {PA_11, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH1N
{PA_12, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1
// {PA_12, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH2N
{PA_13, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1N
// {PA_15, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH1
{PB_0, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH2N
{PB_1, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH3N
// {PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH2
{PB_4, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1
{PB_5, PWM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_10)}, // TIM17_CH1
{PB_6, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1N
{PB_7, PWM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM17_CH1N
{PB_8, PWM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM16_CH1
{PB_9, PWM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM17_CH1
// {PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH3
// {PB_11, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM2_CH4
{PB_13, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH1N
{PB_14, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM15_CH1
// {PB_14, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH2N
{PB_15, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)}, // TIM15_CH2
// {PB_15, PWM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_2)}, // TIM15_CH1N
// {PB_15, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_4)}, // TIM1_CH3N
{PC_0, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_2)}, // TIM1_CH1
{PC_1, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_2)}, // TIM1_CH2
{PC_2, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_2)}, // TIM1_CH3
{PC_3, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_2)}, // TIM1_CH4
{PC_13, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_4)}, // TIM1_CH1N
{PF_0, PWM_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_6)}, // TIM1_CH3N
// {PA_0, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
// {PA_1, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2
{PA_1, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM15)}, // TIM15_CH1N
{PA_2, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM15)}, // TIM15_CH1
{PA_3, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM15)}, // TIM15_CH2
// {PA_5, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
{PA_6, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1
{PA_7, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM17)}, // TIM17_CH1
// {PA_7, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH1N
{PA_8, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH1
{PA_9, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH2
// {PA_9, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_TIM2)}, // TIM2_CH3
{PA_10, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH3
// {PA_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_TIM2)}, // TIM2_CH4
{PA_11, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_TIM1)}, // TIM1_CH4
// {PA_11, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH1N
{PA_12, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1
// {PA_12, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH2N
{PA_13, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1N
// {PA_15, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
{PB_0, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH2N
{PB_1, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH3N
// {PB_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2
{PB_4, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1
{PB_5, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_TIM17)},// TIM17_CH1
{PB_6, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1N
{PB_7, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM17)}, // TIM17_CH1N
{PB_8, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM16)}, // TIM16_CH1
{PB_9, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM17)}, // TIM17_CH1
// {PB_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3
// {PB_11, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH4
{PB_13, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH1N
{PB_14, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15)}, // TIM15_CH1
// {PB_14, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH2N
{PB_15, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15)}, // TIM15_CH2
// {PB_15, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM15)}, // TIM15_CH1N
// {PB_15, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM1)}, // TIM1_CH3N
{PC_0, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1)}, // TIM1_CH1
{PC_1, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1)}, // TIM1_CH2
{PC_2, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1)}, // TIM1_CH3
{PC_3, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1)}, // TIM1_CH4
{PC_13, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM1)}, // TIM1_CH1N
{PF_0, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1)}, // TIM1_CH3N
{NC, NC, 0}
};
void pwmout_init(pwmout_t* obj, PinName pin) {
static TIM_HandleTypeDef TimHandle;
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);
MBED_ASSERT(obj->pwm != (PWMName)NC);
if (obj->pwm == (PWMName)NC) {
error("PWM error: pinout mapping failed.");
}
// Enable TIM clock
if (obj->pwm == PWM_1) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
if (obj->pwm == PWM_15) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
if (obj->pwm == PWM_16) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
if (obj->pwm == PWM_17) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, ENABLE);
if (obj->pwm == PWM_1) __TIM1_CLK_ENABLE();
if (obj->pwm == PWM_2) __TIM2_CLK_ENABLE();
if (obj->pwm == PWM_15) __TIM15_CLK_ENABLE();
if (obj->pwm == PWM_16) __TIM16_CLK_ENABLE();
if (obj->pwm == PWM_17) __TIM17_CLK_ENABLE();
// Configure GPIO
pinmap_pinout(pin, PinMap_PWM);
obj->pin = pin;
obj->period = 0;
obj->pulse = 0;
pwmout_period_us(obj, 20000); // 20 ms per default
}
void pwmout_free(pwmout_t* obj) {
TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
TIM_DeInit(tim);
void pwmout_free(pwmout_t* obj)
{
// Configure GPIO
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
void pwmout_write(pwmout_t* obj, float value) {
TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
TIM_OCInitTypeDef TIM_OCInitStructure;
void pwmout_write(pwmout_t* obj, float value)
{
TIM_OC_InitTypeDef sConfig;
int channel = 0;
int complementary_channel = 0;
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
if (value < (float)0.0) {
value = (float)0.0;
value = 0.0;
} else if (value > (float)1.0) {
value = (float)1.0;
value = 1.0;
}
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_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE;
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
switch (obj->pin) {
// Channels 1
// case PA_0:
case PA_2:
// case PA_5:
case PA_6:
case PA_7:
case PA_8:
case PA_12:
// case PA_15:
case PB_4:
case PB_5:
case PB_8:
case PB_9:
case PB_14:
case PC_0:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC1Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_1;
break;
// Channels 1N
case PA_1:
// case PA_7:
// case PA_11:
case PA_13:
case PB_6:
case PB_7:
case PB_13:
// case PB_15:
case PC_13:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC1Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_1;
complementary_channel = 1;
break;
// Channels 2
// case PA_1:
case PA_3:
case PA_9:
// case PB_3:
case PB_15:
case PC_1:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC2Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_2;
break;
// Channels 2N
// case PA_12:
case PB_0:
// case PB_14:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC2Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_2;
complementary_channel = 1;
break;
// Channels 3
// case PA_9:
case PA_10:
// case PB_10:
case PC_2:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC3Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_3;
break;
// Channels 3N
case PB_1:
case PF_0:
// case PB_15:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC3Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_3;
complementary_channel = 1;
break;
// Channels 4
// case PA_10:
case PA_11:
// case PB_11:
case PC_3:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC4Init(tim, &TIM_OCInitStructure);
channel = TIM_CHANNEL_4;
break;
default:
return;
}
HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel);
if (complementary_channel) {
HAL_TIMEx_PWMN_Start(&TimHandle, channel);
} else {
HAL_TIM_PWM_Start(&TimHandle, channel);
}
}
float pwmout_read(pwmout_t* obj) {
float pwmout_read(pwmout_t* obj)
{
float value = 0;
if (obj->period > 0) {
value = (float)(obj->pulse) / (float)(obj->period);
}
return ((value > (float)1.0) ? ((float)1.0) : (value));
return ((value > (float)1.0) ? (float)(1.0) : (value));
}
void pwmout_period(pwmout_t* obj, float seconds) {
void pwmout_period(pwmout_t* obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t* obj, int ms) {
void pwmout_period_ms(pwmout_t* obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
void pwmout_period_us(pwmout_t* obj, int us) {
TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
void pwmout_period_us(pwmout_t* obj, int us)
{
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
float dc = pwmout_read(obj);
TIM_Cmd(tim, DISABLE);
obj->period = us;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = obj->period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
__HAL_TIM_DISABLE(&TimHandle);
// Update the SystemCoreClock variable
SystemCoreClockUpdate();
TimHandle.Init.Period = us - 1;
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&TimHandle);
// Set duty cycle again
pwmout_write(obj, dc);
TIM_ARRPreloadConfig(tim, ENABLE);
// Warning: Main Output must be enabled on TIM1, TIM8, TIM5, TIM6 and TIM17
if ((obj->pwm == PWM_1) || (obj->pwm == PWM_15) || (obj->pwm == PWM_16) || (obj->pwm == PWM_17)) {
TIM_CtrlPWMOutputs(tim, ENABLE);
}
TIM_Cmd(tim, ENABLE);
// Save for future use
obj->period = us;
__HAL_TIM_ENABLE(&TimHandle);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
{
float value = (float)us / (float)obj->period;
pwmout_write(obj, value);
}

View File

@ -31,79 +31,98 @@
#if DEVICE_RTC
#include "wait_api.h"
#define LSE_STARTUP_TIMEOUT ((uint16_t)500) // delay in ms
#include "mbed_error.h"
static int rtc_inited = 0;
void rtc_init(void) {
uint32_t StartUpCounter = 0;
uint32_t LSEStatus = 0;
static RTC_HandleTypeDef RtcHandle;
void rtc_init(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
uint32_t rtc_freq = 0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock
PWR_BackupAccessCmd(ENABLE); // Enable access to Backup domain
// Reset back up registers
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
// 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 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
RTC_InitTypeDef RTC_InitStructure;
RTC_InitStructure.RTC_AsynchPrediv = 127;
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 Backup domain
if (rtc_inited) return;
rtc_inited = 1;
RtcHandle.Instance = RTC;
// Enable Power clock
__PWR_CLK_ENABLE();
// Enable access to Backup domain
HAL_PWR_EnableBkUpAccess();
// Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
// Enable LSE Oscillator
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */
RCC_OscInitStruct.LSEState = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) {
// Connect LSE to RTC
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
rtc_freq = LSE_VALUE;
} else {
// Enable LSI clock
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("RTC error: LSI clock initialization failed.");
}
// Connect LSI to RTC
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
// Note: The LSI clock can be measured precisely using a timer input capture.
rtc_freq = LSI_VALUE;
}
// Enable RTC
__HAL_RCC_RTC_ENABLE();
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = 127;
RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
error("RTC error: RTC initialization failed.");
}
}
void rtc_free(void) {
// 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);
void rtc_free(void)
{
// Enable Power clock
__PWR_CLK_ENABLE();
// Enable access to Backup domain
HAL_PWR_EnableBkUpAccess();
// Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
// Disable access to Backup domain
HAL_PWR_DisableBkUpAccess();
// Disable LSI and LSE clocks
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
rtc_inited = 0;
}
int rtc_isenabled(void) {
int rtc_isenabled(void)
{
return rtc_inited;
}
@ -124,52 +143,59 @@ int rtc_isenabled(void) {
tm_yday days since January 1 0-365
tm_isdst Daylight Saving Time flag
*/
time_t rtc_read(void) {
time_t rtc_read(void)
{
RTC_DateTypeDef dateStruct;
RTC_TimeTypeDef timeStruct;
struct tm timeinfo;
RtcHandle.Instance = RTC;
// Read actual date and time
RTC_GetTime(RTC_Format_BIN, &timeStruct);
RTC_GetDate(RTC_Format_BIN, &dateStruct);
// Warning: the time must be read first!
HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
// Setup a tm structure based on the RTC
timeinfo.tm_wday = dateStruct.RTC_WeekDay;
timeinfo.tm_mon = dateStruct.RTC_Month - 1;
timeinfo.tm_mday = dateStruct.RTC_Date;
timeinfo.tm_year = dateStruct.RTC_Year + 100;
timeinfo.tm_hour = timeStruct.RTC_Hours;
timeinfo.tm_min = timeStruct.RTC_Minutes;
timeinfo.tm_sec = timeStruct.RTC_Seconds;
timeinfo.tm_wday = dateStruct.WeekDay;
timeinfo.tm_mon = dateStruct.Month - 1;
timeinfo.tm_mday = dateStruct.Date;
timeinfo.tm_year = dateStruct.Year + 100;
timeinfo.tm_hour = timeStruct.Hours;
timeinfo.tm_min = timeStruct.Minutes;
timeinfo.tm_sec = timeStruct.Seconds;
// Convert to timestamp
time_t t = mktime(&timeinfo);
return t;
return t;
}
void rtc_write(time_t t) {
void rtc_write(time_t t)
{
RTC_DateTypeDef dateStruct;
RTC_TimeTypeDef timeStruct;
RtcHandle.Instance = RTC;
// Convert the time into a tm
struct tm *timeinfo = localtime(&t);
// Fill RTC structures
dateStruct.RTC_WeekDay = timeinfo->tm_wday;
dateStruct.RTC_Month = timeinfo->tm_mon + 1;
dateStruct.RTC_Date = timeinfo->tm_mday;
dateStruct.RTC_Year = timeinfo->tm_year - 100;
timeStruct.RTC_Hours = timeinfo->tm_hour;
timeStruct.RTC_Minutes = timeinfo->tm_min;
timeStruct.RTC_Seconds = timeinfo->tm_sec;
timeStruct.RTC_H12 = RTC_HourFormat_24;
dateStruct.WeekDay = timeinfo->tm_wday;
dateStruct.Month = timeinfo->tm_mon + 1;
dateStruct.Date = timeinfo->tm_mday;
dateStruct.Year = timeinfo->tm_year - 100;
timeStruct.Hours = timeinfo->tm_hour;
timeStruct.Minutes = timeinfo->tm_min;
timeStruct.Seconds = timeinfo->tm_sec;
timeStruct.TimeFormat = RTC_HOURFORMAT12_PM;
timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
timeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
// Change the RTC current date/time
PWR_BackupAccessCmd(ENABLE); // Enable access to RTC
RTC_SetDate(RTC_Format_BIN, &dateStruct);
RTC_SetTime(RTC_Format_BIN, &timeStruct);
PWR_BackupAccessCmd(DISABLE); // Disable access to RTC
HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
}
#endif

View File

@ -37,80 +37,94 @@
#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_7)},
{PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PA_14, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_3, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_6, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_9, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PC_4, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PC_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_9, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_14, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PB_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PB_6, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_9, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PB_10, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PC_4, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PC_10, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{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_7)},
{PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PA_15, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_4, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_7, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_8, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PB_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PC_5, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PC_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_7)},
{PA_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_10, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_15, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PB_4, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PB_7, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_8, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PB_11, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PC_5, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PC_11, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{NC, NC, 0}
};
#define UART_NUM (2)
#define UART_NUM (3)
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0};
static uart_irq_handler irq_handler;
UART_HandleTypeDef UartHandle;
int stdio_uart_inited = 0;
serial_t stdio_uart;
static void init_usart(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_InitTypeDef USART_InitStructure;
USART_Cmd(usart, DISABLE);
static void init_uart(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
USART_InitStructure.USART_BaudRate = obj->baudrate;
USART_InitStructure.USART_WordLength = obj->databits;
USART_InitStructure.USART_StopBits = obj->stopbits;
USART_InitStructure.USART_Parity = obj->parity;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(usart, &USART_InitStructure);
UartHandle.Init.BaudRate = obj->baudrate;
UartHandle.Init.WordLength = obj->databits;
UartHandle.Init.StopBits = obj->stopbits;
UartHandle.Init.Parity = obj->parity;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
if (obj->pin_rx == NC) {
UartHandle.Init.Mode = UART_MODE_TX;
} else if (obj->pin_tx == NC) {
UartHandle.Init.Mode = UART_MODE_RX;
} else {
UartHandle.Init.Mode = UART_MODE_TX_RX;
}
// Disable the reception overrun detection
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
USART_Cmd(usart, ENABLE);
HAL_UART_Init(&UartHandle);
}
void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Determine the UART to use
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
// Determine the UART to use (UART_1, UART_2, ...)
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
// Get the peripheral name from the pin and assign it to the object
// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
MBED_ASSERT(obj->uart != (UARTName)NC);
// Enable USART clock
// Enable USART clock + switch to SystemClock
if (obj->uart == UART_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
__USART1_CLK_ENABLE();
__HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK);
obj->index = 0;
}
if (obj->uart == UART_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
__USART2_CLK_ENABLE();
__HAL_RCC_USART2_CONFIG(RCC_USART2CLKSOURCE_SYSCLK);
obj->index = 1;
}
if (obj->uart == UART_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
__USART3_CLK_ENABLE();
__HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK);
obj->index = 2;
}
// Configure the UART pins
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
@ -123,163 +137,174 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Configure UART
obj->baudrate = 9600;
obj->databits = USART_WordLength_8b;
obj->stopbits = USART_StopBits_1;
obj->parity = USART_Parity_No;
obj->databits = UART_WORDLENGTH_8B;
obj->stopbits = UART_STOPBITS_1;
obj->parity = UART_PARITY_NONE;
obj->pin_tx = tx;
obj->pin_rx = rx;
init_usart(obj);
init_uart(obj);
// For stdio management
if (obj->uart == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj) {
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);
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__USART1_CLK_DISABLE();
}
if (obj->uart == UART_2) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__USART2_CLK_DISABLE();
}
if (obj->uart == UART_3) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, DISABLE);
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__USART3_CLK_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));
pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
serial_irq_ids[obj->index] = 0;
}
void serial_baud(serial_t *obj, int baudrate) {
void serial_baud(serial_t *obj, int baudrate)
{
obj->baudrate = baudrate;
init_usart(obj);
init_uart(obj);
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
if (data_bits == 8) {
obj->databits = USART_WordLength_8b;
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
if (data_bits == 9) {
obj->databits = UART_WORDLENGTH_9B;
} else {
obj->databits = USART_WordLength_9b;
obj->databits = UART_WORDLENGTH_8B;
}
switch (parity) {
case ParityOdd:
case ParityForced0:
obj->parity = USART_Parity_Odd;
break;
case ParityEven:
case ParityForced1:
obj->parity = USART_Parity_Even;
break;
default: // ParityNone
obj->parity = USART_Parity_No;
break;
}
if (stop_bits == 2) {
obj->stopbits = USART_StopBits_2;
} else {
obj->stopbits = USART_StopBits_1;
case ParityOdd:
case ParityForced0:
obj->parity = UART_PARITY_ODD;
break;
case ParityEven:
case ParityForced1:
obj->parity = UART_PARITY_EVEN;
break;
default: // ParityNone
obj->parity = UART_PARITY_NONE;
break;
}
init_usart(obj);
if (stop_bits == 2) {
obj->stopbits = UART_STOPBITS_2;
} else {
obj->stopbits = UART_STOPBITS_1;
}
init_uart(obj);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
// not api
static void uart_irq(USART_TypeDef* usart, int id) {
static void uart_irq(UARTName name, int id)
{
UartHandle.Instance = (USART_TypeDef *)name;
if (serial_irq_ids[id] != 0) {
if (USART_GetITStatus(usart, USART_IT_TC) != RESET) {
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
USART_ClearITPendingBit(usart, USART_IT_TC);
__HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
}
if (USART_GetITStatus(usart, USART_IT_RXNE) != RESET) {
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
USART_ClearITPendingBit(usart, USART_IT_RXNE);
volatile uint32_t tmpval = UartHandle.Instance->RDR; // Clear RXNE bit
}
}
}
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 uart3_irq(void) {
uart_irq((USART_TypeDef*)UART_3, 2);
static void uart1_irq(void)
{
uart_irq(UART_1, 0);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
static void uart2_irq(void)
{
uart_irq(UART_2, 1);
}
static void uart3_irq(void)
{
uart_irq(UART_3, 2);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
if (obj->uart == UART_1) {
irq_n = USART1_IRQn;
vector = (uint32_t)&uart1_irq;
irq_n = USART1_IRQn;
vector = (uint32_t)&uart1_irq;
}
if (obj->uart == UART_2) {
irq_n = USART2_IRQn;
vector = (uint32_t)&uart2_irq;
irq_n = USART2_IRQn;
vector = (uint32_t)&uart2_irq;
}
if (obj->uart == UART_3) {
irq_n = USART3_IRQn;
vector = (uint32_t)&uart3_irq;
irq_n = USART3_IRQn;
vector = (uint32_t)&uart3_irq;
}
if (enable) {
if (irq == RxIrq) {
USART_ITConfig(usart, USART_IT_RXNE, ENABLE);
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
} else { // TxIrq
USART_ITConfig(usart, USART_IT_TC, ENABLE);
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
}
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
} else { // disable
int all_disabled = 0;
if (irq == RxIrq) {
USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
// Check if TxIrq is disabled too
if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1;
} else { // TxIrq
USART_ITConfig(usart, USART_IT_TXE, DISABLE);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
// Check if RxIrq is disabled too
if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
}
if (all_disabled) NVIC_DisableIRQ(irq_n);
}
}
@ -287,53 +312,66 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
int serial_getc(serial_t *obj)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_readable(obj));
return (int)(USART_ReceiveData(usart));
if (obj->databits == UART_WORDLENGTH_8B) {
return (int)(uart->RDR & (uint8_t)0xFF);
} else {
return (int)(uart->RDR & (uint16_t)0x1FF);
}
}
void serial_putc(serial_t *obj, int c) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
void serial_putc(serial_t *obj, int c)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_writable(obj));
USART_SendData(usart, (uint16_t)c);
if (obj->databits == UART_WORDLENGTH_8B) {
uart->TDR = (uint8_t)(c & (uint8_t)0xFF);
} else {
uart->TDR = (uint16_t)(c & (uint16_t)0x1FF);
}
}
int serial_readable(serial_t *obj) {
int serial_readable(serial_t *obj)
{
int status;
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is received
status = ((USART_GetFlagStatus(usart, USART_FLAG_RXNE) != RESET) ? 1 : 0);
status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
return status;
}
int serial_writable(serial_t *obj) {
int serial_writable(serial_t *obj)
{
int status;
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is transmitted
status = ((USART_GetFlagStatus(usart, USART_FLAG_TXE) != RESET) ? 1 : 0);
status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0);
return status;
}
void serial_clear(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_ClearFlag(usart, USART_FLAG_TXE);
USART_ClearFlag(usart, USART_FLAG_RXNE);
void serial_clear(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
__HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
__HAL_UART_SEND_REQ(&UartHandle, UART_RXDATA_FLUSH_REQUEST);
}
void serial_pinout_tx(PinName tx) {
void serial_pinout_tx(PinName tx)
{
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_RequestCmd(usart, USART_Request_SBKRQ, ENABLE);
void serial_break_set(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
HAL_LIN_SendBreak(&UartHandle);
}
void serial_break_clear(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_RequestCmd(usart, USART_Request_SBKRQ, DISABLE);
USART_ClearFlag(usart, USART_FLAG_SBK);
void serial_break_clear(serial_t *obj)
{
}
#endif

View File

@ -33,23 +33,27 @@
#include "cmsis.h"
// MCU SLEEP mode
void sleep(void) {
// Enable PWR clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
static TIM_HandleTypeDef TimMasterHandle;
void sleep(void)
{
TimMasterHandle.Instance = TIM2;
// Disable HAL tick interrupt
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC2);
// Request to enter SLEEP mode
PWR_EnterSleepMode(PWR_SLEEPEntry_WFI);
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// Enable HAL tick interrupt
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2);
}
// MCU STOP mode
void deepsleep(void) {
// Enable PWR clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
void deepsleep(void)
{
// Request to enter STOP mode with regulator in low power mode
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// Enter Stop Mode
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// After wake-up from STOP reconfigure the PLL
SetSysClock();
}

View File

@ -37,245 +37,291 @@
#include "pinmap.h"
static const PinMap PinMap_SPI_MOSI[] = {
{PA_11, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PB_5, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PB_15, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PC_12, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PA_11, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_5, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_12, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{PA_10, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PB_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PB_14, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PC_11, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PA_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_11, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_SCLK[] = {
{PB_3, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PB_13, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PC_10, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PF_1, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PB_3, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_10, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PF_1, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{PA_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PA_15, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_6)},
{PB_12, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PF_0, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_DOWN, GPIO_AF_5)},
{PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PA_15, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_12, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PF_0, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{NC, NC, 0}
};
static void init_spi(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
SPI_InitTypeDef SPI_InitStructure;
static SPI_HandleTypeDef SpiHandle;
SPI_Cmd(spi, DISABLE);
static void init_spi(spi_t *obj)
{
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
SPI_InitStructure.SPI_Mode = obj->mode;
SPI_InitStructure.SPI_NSS = obj->nss;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = obj->bits;
SPI_InitStructure.SPI_CPOL = obj->cpol;
SPI_InitStructure.SPI_CPHA = obj->cpha;
SPI_InitStructure.SPI_BaudRatePrescaler = obj->br_presc;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(spi, &SPI_InitStructure);
__HAL_SPI_DISABLE(&SpiHandle);
SPI_RxFIFOThresholdConfig(spi, SPI_RxFIFOThreshold_QF);
SPI_Cmd(spi, ENABLE);
SpiHandle.Init.Mode = obj->mode;
SpiHandle.Init.BaudRatePrescaler = obj->br_presc;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.CLKPhase = obj->cpha;
SpiHandle.Init.CLKPolarity = obj->cpol;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.DataSize = obj->bits;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.NSS = obj->nss;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
HAL_SPI_Init(&SpiHandle);
__HAL_SPI_ENABLE(&SpiHandle);
}
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
// Determine the SPI to use
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT(obj->spi != (SPIName)NC);
// Enable SPI clock
if (obj->spi == SPI_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
__SPI2_CLK_ENABLE();
}
if (obj->spi == SPI_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
__SPI3_CLK_ENABLE();
}
// Configure the SPI pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
// Save new values
obj->bits = SPI_DataSize_8b;
obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge;
obj->br_presc = SPI_BaudRatePrescaler_256;
obj->bits = SPI_DATASIZE_8BIT;
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE;
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz (HSI) or 1.13 MHz (HSE)
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;
if (ssel == NC) { // SW NSS Master mode
obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT;
} else { // Slave
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->mode = SPI_Mode_Slave;
obj->nss = SPI_NSS_Hard;
obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT;
}
init_spi(obj);
}
void spi_free(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
SPI_I2S_DeInit(spi);
void spi_free(spi_t *obj)
{
// Reset SPI and disable clock
if (obj->spi == SPI_2) {
__SPI2_FORCE_RESET();
__SPI2_RELEASE_RESET();
__SPI2_CLK_DISABLE();
}
if (obj->spi == SPI_3) {
__SPI3_FORCE_RESET();
__SPI3_RELEASE_RESET();
__SPI3_CLK_DISABLE();
}
// Configure GPIOs
pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
// Save new values
if (bits == 16) {
obj->bits = SPI_DataSize_16b;
obj->bits = SPI_DATASIZE_16BIT;
} else {
obj->bits = SPI_DataSize_8b;
obj->bits = SPI_DATASIZE_8BIT;
}
switch (mode) {
case 0:
obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge;
break;
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE;
break;
case 1:
obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_2Edge;
break;
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_2EDGE;
break;
case 2:
obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_1Edge;
break;
obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_1EDGE;
break;
default:
obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_2Edge;
break;
obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_2EDGE;
break;
}
if (slave == 0) {
obj->mode = SPI_Mode_Master;
obj->nss = SPI_NSS_Soft;
obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT;
} else {
obj->mode = SPI_Mode_Slave;
obj->nss = SPI_NSS_Hard;
obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT;
}
init_spi(obj);
}
void spi_frequency(spi_t *obj, int hz) {
// Values depend of PCLK1: 32 MHz if HSI is used, 36 MHz if HSE is used
void spi_frequency(spi_t *obj, int hz)
{
// Values depend of APB1CLK : 32 MHz if HSI is used, 36 MHz if HSE is used
if (hz < 250000) {
obj->br_presc = SPI_BaudRatePrescaler_256; // 125 kHz - 141 kHz
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz
} else if ((hz >= 250000) && (hz < 500000)) {
obj->br_presc = SPI_BaudRatePrescaler_128; // 250 kHz - 280 kHz
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz
} else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BaudRatePrescaler_64; // 500 kHz - 560 kHz
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz
} else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BaudRatePrescaler_32; // 1 MHz - 1.13 MHz
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz
} else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BaudRatePrescaler_16; // 2 MHz - 2.25 MHz
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz
} else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BaudRatePrescaler_8; // 4 MHz - 4.5 MHz
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz
} else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BaudRatePrescaler_4; // 8 MHz - 9 MHz
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz
} else { // >= 16000000
obj->br_presc = SPI_BaudRatePrescaler_2; // 16 MHz - 18 MHz
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
}
init_spi(obj);
}
static inline int ssp_readable(spi_t *obj) {
static inline int ssp_readable(spi_t *obj)
{
int status;
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is received
status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) != RESET) ? 1 : 0);
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
return status;
}
static inline int ssp_writeable(spi_t *obj) {
static inline int ssp_writeable(spi_t *obj)
{
int status;
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is transmitted
status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_TXE) != RESET) ? 1 : 0);
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
return status;
}
static inline void ssp_write(spi_t *obj, int value) {
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) {
SPI_SendData8(spi, (uint8_t)value);
} else {
SPI_I2S_SendData16(spi, (uint16_t)value);
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
*p_spi_dr = (uint8_t)value;
} else { // SPI_DATASIZE_16BIT
spi->DR = (uint16_t)value;
}
}
static inline int ssp_read(spi_t *obj) {
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) {
return (int)SPI_ReceiveData8(spi);
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
return (int)(*p_spi_dr);
} else {
return (int)SPI_I2S_ReceiveData16(spi);
return (int)spi->DR;
}
}
static inline int ssp_busy(spi_t *obj) {
static inline int ssp_busy(spi_t *obj)
{
int status;
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_BSY) != RESET) ? 1 : 0);
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
return status;
}
int spi_master_write(spi_t *obj, int value) {
int spi_master_write(spi_t *obj, int value)
{
ssp_write(obj, value);
return ssp_read(obj);
}
int spi_slave_receive(spi_t *obj) {
int spi_slave_receive(spi_t *obj)
{
return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0);
};
int spi_slave_read(spi_t *obj) {
int spi_slave_read(spi_t *obj)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
if (obj->bits == SPI_DataSize_8b) {
return (int)SPI_ReceiveData8(spi);
while (!ssp_readable(obj));
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
return (int)(*p_spi_dr);
} else {
return (int)SPI_I2S_ReceiveData16(spi);
return (int)spi->DR;
}
}
void spi_slave_write(spi_t *obj, int value) {
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) {
SPI_SendData8(spi, (uint8_t)value);
} else {
SPI_I2S_SendData16(spi, (uint16_t)value);
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
*p_spi_dr = (uint8_t)value;
} else { // SPI_DATASIZE_16BIT
spi->DR = (uint16_t)value;
}
}
int spi_busy(spi_t *obj) {
int spi_busy(spi_t *obj)
{
return ssp_busy(obj);
}

View File

@ -30,52 +30,41 @@
#include "PeripheralNames.h"
// 32-bit timer selection
#define TIM_MST TIM2
#define TIM_MST_IRQ TIM2_IRQn
#define TIM_MST_RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE)
#define TIM_MST TIM2
static TIM_HandleTypeDef TimMasterHandle;
static int us_ticker_inited = 0;
void us_ticker_init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
void us_ticker_init(void)
{
if (us_ticker_inited) return;
us_ticker_inited = 1;
// Enable timer clock
TIM_MST_RCC;
// Configure time base
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 <20>s tick
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ);
// Enable timer
TIM_Cmd(TIM_MST, ENABLE);
TimMasterHandle.Instance = TIM_MST;
HAL_InitTick(0); // The passed value is not used
}
uint32_t us_ticker_read() {
uint32_t us_ticker_read()
{
if (!us_ticker_inited) us_ticker_init();
return TIM_MST->CNT;
}
void us_ticker_set_interrupt(timestamp_t timestamp) {
void us_ticker_set_interrupt(timestamp_t timestamp)
{
// Set new output compare value
TIM_SetCompare1(TIM_MST, (uint32_t)timestamp);
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, (uint32_t)timestamp);
// Enable IT
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
}
void us_ticker_disable_interrupt(void) {
TIM_ITConfig(TIM_MST, TIM_IT_CC1, DISABLE);
void us_ticker_disable_interrupt(void)
{
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
}
void us_ticker_clear_interrupt(void) {
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
void us_ticker_clear_interrupt(void)
{
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
}

View File

@ -32,7 +32,8 @@ class CoIDE(Exporter):
'NUCLEO_F401RE',
'NUCLEO_F411RE',
'DISCO_F429ZI',
'DISCO_F334C8'
'DISCO_F334C8',
'DISCO_F303VC'
]
# seems like CoIDE currently supports only one type

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Project version="2G - 1.7.5" name="{{name}}">
<Target name="{{name}}" isCurrent="1">
<Device manufacturerId="9" manufacturerName="ST" chipId="499" chipName="STM32F411RE" boardId="" boardName=""/>
<BuildOption>
<Compile>
<Option name="OptimizationLevel" value="4"/>
<Option name="UseFPU" value="0"/>
<Option name="UserEditCompiler" value="-fno-common; -fmessage-length=0; -Wall; -fno-strict-aliasing; -fno-rtti; -fno-exceptions; -ffunction-sections; -fdata-sections; -std=gnu++98"/>
<Option name="FPU" value="1"/>
<Option name="SupportCPlusplus" value="1"/>
<Includepaths>
{% for path in include_paths %} <Includepath path="{{path}}"/> {% endfor %}
</Includepaths>
<DefinedSymbols>
{% for s in symbols %} <Define name="{{s}}"/> {% endfor %}
</DefinedSymbols>
</Compile>
<Link useDefault="0">
<Option name="DiscardUnusedSection" value="1"/>
<Option name="UserEditLinkder" value=""/>
<Option name="UseMemoryLayout" value="0"/>
<Option name="LTO" value="0"/>
<Option name="IsNewStartupCode" value="1"/>
<Option name="Library" value="Not use C Library"/>
<Option name="nostartfiles" value="0"/>
<Option name="UserEditLinker" value="--specs=nano.specs; -u _printf_float; -u _scanf_float; {% for file in object_files %}
${project.path}/{{file}}; {% endfor %} {% for p in library_paths %}-L${project.path}/{{p}}; {% endfor %}"/>
<LinkedLibraries>
{% for lib in libraries %}
<Libset dir="" libs="{{lib}}"/>
{% endfor %}
<Libset dir="" libs="stdc++"/>
<Libset dir="" libs="supc++"/>
<Libset dir="" libs="m"/>
<Libset dir="" libs="gcc"/>
<Libset dir="" libs="c"/>
<Libset dir="" libs="nosys"/>
</LinkedLibraries>
<MemoryAreas debugInFlashNotRAM="1">
<Memory name="IROM1" type="ReadOnly" size="0x00080000" startValue="0x08000000"/>
<Memory name="IRAM1" type="ReadWrite" size="0x00020000" startValue="0x20000000"/>
<Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
<Memory name="IRAM2" type="ReadWrite" size="" startValue=""/>
</MemoryAreas>
<LocateLinkFile path="{{scatter_file}}" type="0"/>
</Link>
<Output>
<Option name="OutputFileType" value="0"/>
<Option name="Path" value="./"/>
<Option name="Name" value="{{name}}"/>
<Option name="HEX" value="1"/>
<Option name="BIN" value="1"/>
</Output>
<User>
<UserRun name="Run#1" type="Before" checked="0" value=""/>
<UserRun name="Run#1" type="After" checked="0" value=""/>
</User>
</BuildOption>
<DebugOption>
<Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
<Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
<Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="1M"/>
<Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
<Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
<Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
<Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="stm32f3xx_128.elf"/>
</DebugOption>
<ExcludeFile/>
</Target>
<Components path="./"/>
<Files>
{% for file in source_files %}
<File name="sources/{{file.path}}" path="{{file.path}}" type="{{file.type}}"/>
{% endfor %}
{% for file in header_files %}
<File name="headers/{{file.path}}" path="{{file.path}}" type="{{file.type}}"/>
{% endfor %}
</Files>
</Project>