updated latest changes from nucleo

pull/785/head
Richard Osterloh 2014-12-11 14:55:45 +00:00
parent 14666bb183
commit 77c3fe2358
25 changed files with 1168 additions and 393 deletions

View File

@ -12,9 +12,9 @@
;* calls main()).
;* After Reset the Cortex-M0+ processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main.
;* <<< Use Configuration Wizard in Context Menu >>>
;* <<< Use Configuration Wizard in Context Menu >>>
;*******************************************************************************
;*
;*
;* 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,
@ -48,20 +48,25 @@
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
EXPORT __initial_sp
Stack_Mem SPACE Stack_Size
__initial_sp
__initial_sp EQU 0x20002000 ; Top of RAM
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000200
Heap_Size EQU 0x00000400
AREA HEAP, NOINIT, READWRITE, ALIGN=3
EXPORT __heap_base
EXPORT __heap_limit
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
__heap_limit EQU (__initial_sp - Stack_Size)
PRESERVE8
THUMB
@ -103,7 +108,7 @@ __Vectors DCD __initial_sp ; Top of Stack
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_3_IRQHandler ; DMA1 Channel 2 and Channel 3
DCD DMA1_Channel4_5_6_7_IRQHandler ; DMA1 Channel 4, Channel 5, Channel 6 and Channel 7
DCD ADC1_COMP_IRQHandler ; ADC1, COMP1 and COMP2
DCD ADC1_COMP_IRQHandler ; ADC1, COMP1 and COMP2
DCD LPTIM1_IRQHandler ; LPTIM1
DCD 0 ; Reserved
DCD TIM2_IRQHandler ; TIM2
@ -123,7 +128,7 @@ __Vectors DCD __initial_sp ; Top of Stack
DCD RNG_LPUART1_IRQHandler ; RNG and LPUART1
DCD LCD_IRQHandler ; LCD
DCD USB_IRQHandler ; USB
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
@ -134,7 +139,7 @@ __Vectors_Size EQU __Vectors_End - __Vectors
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
@ -213,7 +218,7 @@ TSC_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_3_IRQHandler
DMA1_Channel4_5_6_7_IRQHandler
ADC1_COMP_IRQHandler
ADC1_COMP_IRQHandler
LPTIM1_IRQHandler
TIM2_IRQHandler
TIM6_DAC_IRQHandler
@ -234,33 +239,4 @@ USB_IRQHandler
ENDP
ALIGN
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END
;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
END

View File

@ -2,14 +2,14 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64k
RAM (rwx) : ORIGIN = 0x200000C0, LENGTH = 8K - 0xC0
RAM (rwx) : ORIGIN = 0x200000C0, LENGTH = 8K - 0xC0
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
@ -62,7 +62,7 @@ SECTIONS
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH

View File

@ -0,0 +1,332 @@
;/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
;* File Name : startup_stm32l053xx.s
;* Author : MCD Application Team
;* Version : V1.1.0
;* Date : 18-June-2014
;* Description : STM32L053xx Ultra Low Power Devices vector
;* This module performs:
;* - Set the initial SP
;* - Set the initial PC == _iar_program_start,
;* - Set the vector table entries with the exceptions ISR
;* address.
;* - Configure the system clock
;* - Branches to main in the C library (which eventually
;* calls main()).
;* After Reset the Cortex-M0+ processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main.
;********************************************************************************
;*
;* 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.
;*
;*******************************************************************************/
;
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD RTC_IRQHandler ; RTC through EXTI Line
DCD FLASH_IRQHandler ; FLASH
DCD RCC_CRS_IRQHandler ; RCC_CRS
DCD EXTI0_1_IRQHandler ; EXTI Line 0 and 1
DCD EXTI2_3_IRQHandler ; EXTI Line 2 and 3
DCD EXTI4_15_IRQHandler ; EXTI Line 4 to 15
DCD TSC_IRQHandler ; TSC
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_3_IRQHandler ; DMA1 Channel 2 and Channel 3
DCD DMA1_Channel4_5_6_7_IRQHandler ; DMA1 Channel 4, Channel 5, Channel 6 and Channel 7
DCD ADC1_COMP_IRQHandler ; ADC1, COMP1 and COMP2
DCD LPTIM1_IRQHandler ; LPTIM1
DCD 0 ; Reserved
DCD TIM2_IRQHandler ; TIM2
DCD 0 ; Reserved
DCD TIM6_DAC_IRQHandler ; TIM6 and DAC
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD TIM21_IRQHandler ; TIM21
DCD 0 ; Reserved
DCD TIM22_IRQHandler ; TIM22
DCD I2C1_IRQHandler ; I2C1
DCD I2C2_IRQHandler ; I2C2
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD RNG_LPUART1_IRQHandler ; RNG and LPUART1
DCD LCD_IRQHandler ; LCD
DCD USB_IRQHandler ; USB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:NOROOT:REORDER(2)
Reset_Handler
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK NMI_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
NMI_Handler
B NMI_Handler
PUBWEAK HardFault_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
HardFault_Handler
B HardFault_Handler
PUBWEAK SVC_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
SVC_Handler
B SVC_Handler
PUBWEAK DebugMon_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
DebugMon_Handler
B DebugMon_Handler
PUBWEAK PendSV_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
PendSV_Handler
B PendSV_Handler
PUBWEAK SysTick_Handler
SECTION .text:CODE:NOROOT:REORDER(1)
SysTick_Handler
B SysTick_Handler
PUBWEAK WWDG_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
WWDG_IRQHandler
B WWDG_IRQHandler
PUBWEAK PVD_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
PVD_IRQHandler
B PVD_IRQHandler
PUBWEAK RTC_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
RTC_IRQHandler
B RTC_IRQHandler
PUBWEAK FLASH_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
FLASH_IRQHandler
B FLASH_IRQHandler
PUBWEAK RCC_CRS_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
RCC_CRS_IRQHandler
B RCC_CRS_IRQHandler
PUBWEAK EXTI0_1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
EXTI0_1_IRQHandler
B EXTI0_1_IRQHandler
PUBWEAK EXTI2_3_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
EXTI2_3_IRQHandler
B EXTI2_3_IRQHandler
PUBWEAK EXTI4_15_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
EXTI4_15_IRQHandler
B EXTI4_15_IRQHandler
PUBWEAK TSC_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
TSC_IRQHandler
B TSC_IRQHandler
PUBWEAK DMA1_Channel1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
DMA1_Channel1_IRQHandler
B DMA1_Channel1_IRQHandler
PUBWEAK DMA1_Channel2_3_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
DMA1_Channel2_3_IRQHandler
B DMA1_Channel2_3_IRQHandler
PUBWEAK DMA1_Channel4_5_6_7_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
DMA1_Channel4_5_6_7_IRQHandler
B DMA1_Channel4_5_6_7_IRQHandler
PUBWEAK ADC1_COMP_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
ADC1_COMP_IRQHandler
B ADC1_COMP_IRQHandler
PUBWEAK LPTIM1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
LPTIM1_IRQHandler
B LPTIM1_IRQHandler
PUBWEAK TIM2_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
TIM2_IRQHandler
B TIM2_IRQHandler
PUBWEAK TIM6_DAC_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
TIM6_DAC_IRQHandler
B TIM6_DAC_IRQHandler
PUBWEAK TIM21_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
TIM21_IRQHandler
B TIM21_IRQHandler
PUBWEAK TIM22_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
TIM22_IRQHandler
B TIM22_IRQHandler
PUBWEAK I2C1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
I2C1_IRQHandler
B I2C1_IRQHandler
PUBWEAK I2C2_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
I2C2_IRQHandler
B I2C2_IRQHandler
PUBWEAK SPI1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
SPI1_IRQHandler
B SPI1_IRQHandler
PUBWEAK SPI2_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
SPI2_IRQHandler
B SPI2_IRQHandler
PUBWEAK USART1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
USART1_IRQHandler
B USART1_IRQHandler
PUBWEAK USART2_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
USART2_IRQHandler
B USART2_IRQHandler
PUBWEAK RNG_LPUART1_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
RNG_LPUART1_IRQHandler
B RNG_LPUART1_IRQHandler
PUBWEAK LCD_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
LCD_IRQHandler
B LCD_IRQHandler
PUBWEAK USB_IRQHandler
SECTION .text:CODE:NOROOT:REORDER(1)
USB_IRQHandler
B USB_IRQHandler
END
;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****

View File

@ -0,0 +1,30 @@
/* [ROM = 64kb = 0x10000] */
define symbol __intvec_start__ = 0x08000000;
define symbol __region_ROM_start__ = 0x08000000;
define symbol __region_ROM_end__ = 0x0800FFFF;
/* [RAM = 8kb = 0x2000] Vector table dynamic copy: 48 vectors = 192 bytes (0xC0) to be reserved in RAM */
define symbol __NVIC_start__ = 0x20000000;
define symbol __NVIC_end__ = 0x200000BF; /* Aligned on 8 bytes */
define symbol __region_RAM_start__ = 0x200000C0;
define symbol __region_RAM_end__ = 0x20001FFF;
/* Memory regions */
define memory mem with size = 4G;
define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__];
define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__];
/* Stack and Heap */
define symbol __size_cstack__ = 0x500;
define symbol __size_heap__ = 0x1000;
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block STACKHEAP with fixed order { block HEAP, block CSTACK };
initialize by copy with packing = zeros { readwrite };
do not initialize { section .noinit };
place at address mem:__intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite, block STACKHEAP };

View File

@ -0,0 +1,145 @@
/**
******************************************************************************
* @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 set_compare(uint16_t count);
extern volatile uint32_t SlaveCounter;
extern volatile uint32_t oc_int_part;
extern volatile uint16_t oc_rem_part;
void timer_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
TimMasterHandle.Instance = TIM_MST;
// Clear Update interrupt flag
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE);
SlaveCounter++;
}
// Channel 1 for mbed timeout
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
if (oc_rem_part > 0) {
set_compare(oc_rem_part); // Finish the remaining time left
oc_rem_part = 0;
} else {
if (oc_int_part > 0) {
set_compare(0xFFFF);
oc_rem_part = cval; // To finish the counter loop the next time
oc_int_part--;
} else {
us_ticker_irq_handler();
}
}
}
// Channel 2 for HAL tick
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_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;
}
}
}
// 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;
// Update the SystemCoreClock variable
SystemCoreClockUpdate();
// 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;
HAL_TIM_Base_Init(&TimMasterHandle);
// Configure output compare channel 1 for mbed timeout (enabled later when used)
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
// Configure output compare 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);
// Configure interrupts
// Update interrupt used for 32-bit counter
// Output compare channel 1 interrupt for mbed timeout
// Output compare channel 2 interrupt for HAL tick
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ);
// Enable interrupts
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); // For 32-bit counter
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); // For HAL tick
// Enable timer
HAL_TIM_Base_Start(&TimMasterHandle);
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 "stm32l0xx.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21
#define TIM_MST_IRQ TIM21_IRQn
#define TIM_MST_RCC __TIM21_CLK_ENABLE()
#define TIM_MST_RESET_ON __TIM21_FORCE_RESET()
#define TIM_MST_RESET_OFF __TIM21_RELEASE_RESET()
#define HAL_TICK_DELAY (1000) // 1 ms
#ifdef __cplusplus
}
#endif
#endif // __HAL_TICK_H
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -36,8 +36,7 @@
* APB2CLK (MHz) | 32 | 32
*-----------------------------------------------------------------------------
* USB capable (48 MHz precise clock) | YES | YES
*-----------------------------------------------------------------------------
*
*-----------------------------------------------------------------------------
******************************************************************************
* @attention
*
@ -81,6 +80,7 @@
*/
#include "stm32l0xx.h"
#include "hal_tick.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
@ -207,11 +207,16 @@ void SystemInit (void)
#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;
}
/**
@ -448,12 +453,6 @@ uint8_t SetSysClock_PLL_HSI(void)
return 1; // OK
}
/* Used for the different timeouts in the HAL */
void SysTick_Handler(void)
{
HAL_IncTick();
}
/**
* @}
*/

View File

@ -0,0 +1,170 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* 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 "PeripheralPins.h"
// =====
// Note: Commented lines are alternative possibilities which are not used per default.
// If you change them, you will have also to modify the corresponding xxx_api.c file
// for pwmout, analogin, analogout, ...
// =====
//*** ADC ***
const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0
{PA_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN1
{PA_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN2
{PA_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN3
{PA_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN4
{PA_5, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN5
{PA_6, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN6
{PA_7, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN7
{PB_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN8
{PB_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN9
{PC_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN10
{PC_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN11
{PC_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN12
{PC_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN13
{PC_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN14
{PC_5, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN15
{NC, NC, 0}
};
//*** DAC ***
const PinMap PinMap_DAC[] = {
{PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT
{NC, NC, 0}
};
//*** I2C ***
const PinMap PinMap_I2C_SDA[] = {
{PB_7, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF1_I2C1)},
{PB_9, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
{PB_11, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF6_I2C2)},
{PB_14, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C2)},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PB_6, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF1_I2C1)},
{PB_8, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
{PB_10, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF6_I2C2)},
{PB_13, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C2)},
{NC, NC, 0}
};
//*** PWM ***
// TIM21 cannot be used because already used by the us_ticker
const PinMap PinMap_PWM[] = {
{PA_0, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH1
{PA_1, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH2
// {PA_2, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM21)}, // TIM21_CH1
// {PA_2, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH3 - used by STDIO TX
// {PA_3, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM21)}, // TIM21_CH2
// {PA_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH4 - used by STDIO RX
{PA_5, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM2)}, // TIM2_CH1 - used also to drive the LED
{PA_6, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM22)}, // TIM22_CH1
{PA_7, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM22)}, // TIM22_CH2
{PA_15, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM2)}, // TIM2_CH1
{PB_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH2
{PB_4, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM22)}, // TIM22_CH1
{PB_5, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM22)}, // TIM22_CH2
{PB_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH3
{PB_11, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH4
// {PB_13, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM21)}, // TIM21_CH1
// {PB_14, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM21)}, // TIM21_CH2
{PC_6, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM22)}, // TIM22_CH1
{PC_7, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM22)}, // TIM22_CH2
{NC, NC, 0}
};
//*** SERIAL ***
const PinMap PinMap_UART_TX[] = {
{PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PA_9, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART1)},
{PA_14, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)}, // Warning: this pin is used by SWCLK
{PB_6, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{PB_10, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_LPUART1)},
{PC_4, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_LPUART1)},
{PC_10, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_LPUART1)},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{PA_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PA_10, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART1)},
{PA_15, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PB_7, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{PB_11, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_LPUART1)},
{PC_5, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_LPUART1)},
{PC_11, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_LPUART1)},
{NC, NC, 0}
};
//*** SPI ***
const PinMap PinMap_SPI_MOSI[] = {
{PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_12, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_SPI2)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_11, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{PC_2, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_SPI2)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_3, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_9, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_12, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{NC, NC, 0}
};

View File

@ -0,0 +1,66 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* 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 MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
//*** ADC ***
extern const PinMap PinMap_ADC[];
//*** DAC ***
extern const PinMap PinMap_DAC[];
//*** I2C ***
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
//*** PWM ***
extern const PinMap PinMap_PWM[];
//*** SERIAL ***
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
//*** SPI ***
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_SSEL[];
#endif

View File

@ -33,32 +33,14 @@
#include "wait_api.h"
#include "cmsis.h"
#include "pinmap.h"
static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0
{PA_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN1
{PA_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN2
{PA_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN3
{PA_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN4
{PA_5, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN5
{PA_6, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN6
{PA_7, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN7
{PB_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN8
{PB_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN9
{PC_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN10
{PC_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN11
{PC_2, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN12
{PC_3, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN13
{PC_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN14
{PC_5, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN15
{NC, NC, 0}
};
#include "PeripheralPins.h"
ADC_HandleTypeDef AdcHandle;
int adc_inited = 0;
void analogin_init(analogin_t *obj, PinName pin) {
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);
@ -96,15 +78,16 @@ void analogin_init(analogin_t *obj, PinName pin) {
AdcHandle.Init.LowPowerFrequencyMode = DISABLE; // To be enabled only if ADC clock < 2.8 MHz
AdcHandle.Init.LowPowerAutoOff = DISABLE;
HAL_ADC_Init(&AdcHandle);
// Calibration
HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
__HAL_ADC_ENABLE(&AdcHandle);
}
}
static inline uint16_t adc_read(analogin_t *obj) {
static inline uint16_t adc_read(analogin_t *obj)
{
ADC_ChannelConfTypeDef sConfig;
AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
@ -176,14 +159,16 @@ static inline uint16_t adc_read(analogin_t *obj) {
}
}
uint16_t analogin_read_u16(analogin_t *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) {
float analogin_read(analogin_t *obj)
{
uint16_t value = adc_read(obj);
return (float)value * (1.0f / (float)0xFFF); // 12 bits range
}

View File

@ -33,17 +33,14 @@
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DAC_RANGE (0xFFF) // 12 bits
static const PinMap PinMap_DAC[] = {
{PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT
{NC, NC, 0}
};
static DAC_HandleTypeDef DacHandle;
void analogout_init(dac_t *obj, PinName pin) {
void analogout_init(dac_t *obj, PinName pin)
{
DAC_ChannelConfTypeDef sConfig;
DacHandle.Instance = DAC;
@ -70,7 +67,8 @@ void analogout_init(dac_t *obj, PinName pin) {
analogout_write_u16(obj, 0);
}
void analogout_free(dac_t *obj) {
void analogout_free(dac_t *obj)
{
// Reset DAC and disable clock
__DAC_FORCE_RESET();
__DAC_RELEASE_RESET();
@ -80,16 +78,19 @@ void analogout_free(dac_t *obj) {
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
static inline void dac_write(dac_t *obj, uint16_t 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) {
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) {
@ -99,7 +100,8 @@ 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 {
@ -107,12 +109,14 @@ void analogout_write_u16(dac_t *obj, uint16_t 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

@ -34,14 +34,16 @@
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(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)
return;
@ -59,11 +61,13 @@ void gpio_init(gpio_t *obj, PinName pin) {
obj->reg_clr = &gpio->BRR;
}
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(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));

View File

@ -38,54 +38,107 @@
#define EDGE_FALL (2)
#define EDGE_BOTH (3)
// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15)
#define CHANNEL_NUM (3)
static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0};
static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0};
static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0};
// Max pins for one line (max with EXTI4_15)
#define MAX_PIN_LINE (12)
typedef struct gpio_channel {
uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts
uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance
uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group
} gpio_channel_t;
static gpio_channel_t channels[CHANNEL_NUM] = {
{.pin_mask = 0},
{.pin_mask = 0},
{.pin_mask = 0}
};
// Used to return the index for channels array.
static uint32_t pin_base_nr[16] = {
// EXTI0_1
0, // pin 0
1, // pin 1
// EXTI2_3
0, // pin 2
1, // pin 3
// EXTI4_15
0, // pin 4
1, // pin 5
2, // pin 6
3, // pin 7
4, // pin 8
5, // pin 9
6, // pin 10
7, // pin 11
8, // pin 12
9, // pin 13
10, // pin 14
11 // pin 15
};
static gpio_irq_handler irq_handler;
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]);
static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line)
{
gpio_channel_t *gpio_channel = &channels[irq_index];
uint32_t gpio_idx;
// Clear interrupt flag
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
}
for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) {
uint32_t current_mask = (1 << gpio_idx);
if (channel_ids[irq_index] == 0) return;
if (gpio_channel->pin_mask & current_mask) {
// Retrieve the gpio and pin that generate the irq
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]);
uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx]));
// Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) {
irq_handler(channel_ids[irq_index], IRQ_FALL);
} else {
irq_handler(channel_ids[irq_index], IRQ_RISE);
// Clear interrupt flag
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
if (gpio_channel->channel_ids[gpio_idx] == 0) continue;
// Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) {
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL);
} else {
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE);
}
}
}
}
}
// The irq_index is passed to the function
// EXTI lines 0 to 1
static void gpio_irq0(void) {
handle_interrupt_in(0);
static void gpio_irq0(void)
{
handle_interrupt_in(0, 2);
}
// EXTI lines 2 to 3
static void gpio_irq1(void) {
handle_interrupt_in(1);
static void gpio_irq1(void)
{
handle_interrupt_in(1, 2);
}
// EXTI lines 4 to 15
static void gpio_irq2(void) {
handle_interrupt_in(2);
static void gpio_irq2(void)
{
handle_interrupt_in(2, 12);
}
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;
gpio_channel_t *gpio_channel;
uint32_t gpio_idx;
if (pin == NC) return -1;
@ -125,19 +178,30 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
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;
gpio_channel = &channels[irq_index];
gpio_idx = pin_base_nr[pin_index];
gpio_channel->pin_mask |= (1 << gpio_idx);
gpio_channel->channel_ids[gpio_idx] = id;
gpio_channel->channel_gpio[gpio_idx] = gpio_add;
gpio_channel->channel_pin[gpio_idx] = pin_index;
irq_handler = handler;
return 0;
}
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;
void gpio_irq_free(gpio_irq_t *obj)
{
gpio_channel_t *gpio_channel = &channels[obj->irq_index];
uint32_t pin_index = STM_PIN(obj->pin);
uint32_t gpio_idx = pin_base_nr[pin_index];
gpio_channel->pin_mask &= ~(1 << gpio_idx);
gpio_channel->channel_ids[gpio_idx] = 0;
gpio_channel->channel_gpio[gpio_idx] = 0;
gpio_channel->channel_pin[gpio_idx] = 0;
// Disable EXTI line
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
obj->event = EDGE_NONE;
@ -191,11 +255,13 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
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_in;
__IO uint32_t *reg_set;
__IO uint16_t *reg_clr;
__IO uint32_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,7 +34,7 @@
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
@ -42,28 +42,13 @@
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
static const PinMap PinMap_I2C_SDA[] = {
{PB_7, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF1_I2C1)},
{PB_9, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
{PB_11, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF6_I2C2)},
{PB_14, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C2)},
{NC, NC, 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PB_6, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF1_I2C1)},
{PB_8, I2C_1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
{PB_10, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF6_I2C2)},
{PB_13, I2C_2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C2)},
{NC, NC, 0}
};
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
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);
@ -72,7 +57,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1)&& !i2c1_inited) {
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
@ -83,7 +68,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, OpenDrain);
}
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2)&& !i2c2_inited) {
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C pins
@ -100,14 +85,15 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz) {
void i2c_frequency(i2c_t *obj, int hz)
{
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));
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Common settings: I2C clock = 32 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
@ -135,7 +121,8 @@ void i2c_frequency(i2c_t *obj, int hz) {
HAL_I2C_Init(&I2cHandle);
}
inline int i2c_start(i2c_t *obj) {
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@ -158,7 +145,8 @@ inline int i2c_start(i2c_t *obj) {
return 0;
}
inline int i2c_stop(i2c_t *obj) {
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
@ -167,7 +155,8 @@ inline int i2c_stop(i2c_t *obj) {
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
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;
@ -213,7 +202,8 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
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;
@ -256,7 +246,8 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
return count;
}
int i2c_byte_read(i2c_t *obj, int last) {
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@ -271,7 +262,8 @@ int i2c_byte_read(i2c_t *obj, int last) {
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data) {
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
@ -288,12 +280,13 @@ int i2c_byte_write(i2c_t *obj, int data) {
return 1;
}
void i2c_reset(i2c_t *obj) {
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));
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
@ -307,7 +300,8 @@ void i2c_reset(i2c_t *obj) {
#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;
@ -325,7 +319,8 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
@ -351,7 +346,8 @@ 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) {
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
@ -368,7 +364,8 @@ int i2c_slave_receive(i2c_t *obj) {
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
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);
@ -376,7 +373,8 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);

View File

@ -28,7 +28,8 @@
#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();
}

View File

@ -50,8 +50,8 @@ struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
__IO uint16_t *reg_in;
__IO uint16_t *reg_out;
__IO uint32_t *reg_in;
__IO uint32_t *reg_out;
};
struct analogin_s {

View File

@ -50,7 +50,8 @@ static const uint32_t gpio_mode[13] = {
};
// Enable GPIO clock and return GPIO base address
uint32_t Set_GPIO_Clock(uint32_t port_idx) {
uint32_t Set_GPIO_Clock(uint32_t port_idx)
{
uint32_t gpio_add = 0;
switch (port_idx) {
case PortA:
@ -83,7 +84,8 @@ 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);
@ -119,7 +121,8 @@ void pin_function(PinName pin, int data) {
/**
* 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);
@ -131,7 +134,9 @@ void pin_mode(PinName pin, PinMode mode) {
// Configure pull-up/pull-down resistors
uint32_t pupd = (uint32_t)mode;
if (pupd > 2)
{
pupd = 0; // Open-drain = No pull-up/No pull-down
}
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPD0 << (pin_index * 2)));
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));

View File

@ -38,11 +38,13 @@ 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) {
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
@ -59,7 +61,8 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
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
@ -73,7 +76,8 @@ void port_dir(port_t *obj, PinDirection dir) {
}
}
void port_mode(port_t *obj, PinMode mode) {
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
@ -82,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

@ -34,34 +34,12 @@
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
// TIM21 cannot be used because already used by the us_ticker
static const PinMap PinMap_PWM[] = {
{PA_0, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH1
{PA_1, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH2
// {PA_2, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM21)}, // TIM21_CH1
// {PA_2, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH3 - used by STDIO TX
// {PA_3, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM21)}, // TIM21_CH2
// {PA_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH4 - used by STDIO RX
{PA_5, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM2)}, // TIM2_CH1 - used also to drive the LED
{PA_6, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM22)}, // TIM22_CH1
{PA_7, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM22)}, // TIM22_CH2
{PA_15, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_TIM2)}, // TIM2_CH1
{PB_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH2
{PB_4, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM22)}, // TIM22_CH1
{PB_5, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_TIM22)}, // TIM22_CH2
{PB_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH3
{PB_11, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2)}, // TIM2_CH4
// {PB_13, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM21)}, // TIM21_CH1
// {PB_14, PWM_21, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM21)}, // TIM21_CH2
{PC_6, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM22)}, // TIM22_CH1
{PC_7, PWM_22, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM22)}, // TIM22_CH2
{NC, NC, 0}
};
#include "PeripheralPins.h"
static TIM_HandleTypeDef TimHandle;
void pwmout_init(pwmout_t* obj, PinName pin) {
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);
@ -84,12 +62,14 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
pwmout_period_us(obj, 20000); // 20 ms per default
}
void pwmout_free(pwmout_t* obj) {
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) {
void pwmout_write(pwmout_t* obj, float value)
{
TIM_OC_InitTypeDef sConfig;
int channel = 0;
@ -112,22 +92,18 @@ void pwmout_write(pwmout_t* obj, float value) {
switch (obj->pin) {
// Channels 1
case PA_0:
// case PA_2:
case PA_5:
case PA_6:
case PA_15:
case PB_4:
// case PB_13:
case PC_6:
channel = TIM_CHANNEL_1;
break;
// Channels 2
case PA_1:
// case PA_3:
case PA_7:
case PB_3:
case PB_5:
// case PB_14:
case PC_7:
channel = TIM_CHANNEL_2;
break;
@ -149,7 +125,8 @@ void pwmout_write(pwmout_t* obj, float value) {
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);
@ -157,15 +134,18 @@ float pwmout_read(pwmout_t* obj) {
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) {
void pwmout_period_us(pwmout_t* obj, int us)
{
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
float dc = pwmout_read(obj);
@ -173,7 +153,7 @@ void pwmout_period_us(pwmout_t* obj, int us) {
__HAL_TIM_DISABLE(&TimHandle);
TimHandle.Init.Period = us - 1;
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&TimHandle);
@ -187,15 +167,18 @@ void pwmout_period_us(pwmout_t* obj, int 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

@ -37,7 +37,8 @@ static int rtc_inited = 0;
static RTC_HandleTypeDef RtcHandle;
void rtc_init(void) {
void rtc_init(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
uint32_t rtc_freq = 0;
@ -58,8 +59,8 @@ void rtc_init(void) {
// 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 */
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_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
@ -77,7 +78,7 @@ void rtc_init(void) {
// Connect LSI to RTC
__HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
// [TODO] This value is LSI typical value. To be measured precisely using a timer input capture
// This value is LSI typical value. To be measured precisely using a timer input capture for example.
rtc_freq = 32000;
}
@ -96,7 +97,8 @@ void rtc_init(void) {
}
}
void rtc_free(void) {
void rtc_free(void)
{
// Enable Power clock
__PWR_CLK_ENABLE();
@ -121,7 +123,8 @@ void rtc_free(void) {
rtc_inited = 0;
}
int rtc_isenabled(void) {
int rtc_isenabled(void)
{
return rtc_inited;
}
@ -142,7 +145,8 @@ 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;
@ -169,7 +173,8 @@ time_t rtc_read(void) {
return t;
}
void rtc_write(time_t t) {
void rtc_write(time_t t)
{
RTC_DateTypeDef dateStruct;
RTC_TimeTypeDef timeStruct;

View File

@ -35,28 +35,7 @@
#include "cmsis.h"
#include "pinmap.h"
#include <string.h>
static const PinMap PinMap_UART_TX[] = {
{PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PA_9, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART1)},
{PA_14, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)}, // Warning: this pin is used by SWCLK
{PB_6, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{PB_10, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_LPUART1)},
{PC_4, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_LPUART1)},
{PC_10, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_LPUART1)},
{NC, NC, 0}
};
static const PinMap PinMap_UART_RX[] = {
{PA_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PA_10, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART1)},
{PA_15, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART2)},
{PB_7, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{PB_11, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_LPUART1)},
{PC_5, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_LPUART1)},
{PC_11, LPUART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_LPUART1)},
{NC, NC, 0}
};
#include "PeripheralPins.h"
#define UART_NUM (3)
@ -69,7 +48,8 @@ UART_HandleTypeDef UartHandle;
int stdio_uart_inited = 0;
serial_t stdio_uart;
static void init_uart(serial_t *obj) {
static void init_uart(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// [TODO] Workaround to be removed after HAL driver is corrected
@ -94,11 +74,12 @@ static void init_uart(serial_t *obj) {
// Disable the reception overrun detection
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
HAL_UART_Init(&UartHandle);
}
void serial_init(serial_t *obj, PinName tx, PinName rx) {
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);
@ -150,7 +131,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
}
}
void serial_free(serial_t *obj) {
void serial_free(serial_t *obj)
{
// Reset UART and disable clock
if (obj->uart == UART_1) {
__USART1_FORCE_RESET();
@ -177,12 +159,14 @@ void serial_free(serial_t *obj) {
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_uart(obj);
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
if (data_bits == 9) {
obj->databits = UART_WORDLENGTH_9B;
} else {
@ -216,7 +200,8 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
* INTERRUPTS HANDLING
******************************************************************************/
static void uart_irq(UARTName name, int id) {
static void uart_irq(UARTName name, int id)
{
UartHandle.Instance = (USART_TypeDef *)name;
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
@ -230,24 +215,29 @@ static void uart_irq(UARTName name, int id) {
}
}
static void uart1_irq(void) {
static void uart1_irq(void)
{
uart_irq(UART_1, 0);
}
static void uart2_irq(void) {
static void uart2_irq(void)
{
uart_irq(UART_2, 1);
}
static void lpuart1_irq(void) {
static void lpuart1_irq(void)
{
uart_irq(LPUART_1, 2);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
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;
@ -302,19 +292,22 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj) {
int serial_getc(serial_t *obj)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_readable(obj));
return (int)(uart->RDR & (uint32_t)0xFF);
}
void serial_putc(serial_t *obj, int c) {
void serial_putc(serial_t *obj, int c)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_writable(obj));
uart->TDR = (uint32_t)(c & (uint32_t)0xFF);
}
int serial_readable(serial_t *obj) {
int serial_readable(serial_t *obj)
{
int status;
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is received
@ -322,7 +315,8 @@ int serial_readable(serial_t *obj) {
return status;
}
int serial_writable(serial_t *obj) {
int serial_writable(serial_t *obj)
{
int status;
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is transmitted
@ -330,22 +324,26 @@ int serial_writable(serial_t *obj) {
return status;
}
void serial_clear(serial_t *obj) {
void serial_clear(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
__HAL_UART_CLEAR_IT(&UartHandle, UART_CLEAR_TCF);
__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) {
void serial_break_set(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
__HAL_UART_SEND_REQ(&UartHandle, UART_SENDBREAK_REQUEST);
}
void serial_break_clear(serial_t *obj) {
void serial_break_clear(serial_t *obj)
{
}
#endif

View File

@ -35,31 +35,27 @@
static TIM_HandleTypeDef TimMasterHandle;
void sleep(void) {
// Disable us_ticker update interrupt
void sleep(void)
{
TimMasterHandle.Instance = TIM21;
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
// Disable HAL tick interrupt
__HAL_TIM_DISABLE_IT(&TimMasterHandle, (TIM_IT_CC2 | TIM_IT_UPDATE));
// Request to enter SLEEP mode
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// Re-enable us_ticker update interrupt
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
// Enable HAL tick interrupt
__HAL_TIM_ENABLE_IT(&TimMasterHandle, (TIM_IT_CC2 | TIM_IT_UPDATE));
}
void deepsleep(void) {
// Disable us_ticker update interrupt
TimMasterHandle.Instance = TIM21;
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
void deepsleep(void)
{
// Request to enter STOP mode with regulator in low power mode
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// After wake-up from STOP reconfigure the PLL
SetSysClock();
// Re-enable us_ticker update interrupt
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
}
#endif

View File

@ -35,44 +35,12 @@
#include <math.h>
#include "cmsis.h"
#include "pinmap.h"
static const PinMap PinMap_SPI_MOSI[] = {
{PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_12, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_SPI2)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_11, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{PC_2, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_SPI2)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_SCLK[] = {
{PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_3, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{NC, NC, 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI1)},
{PB_9, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_12, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_SPI2)},
{NC, NC, 0}
};
#include "PeripheralPins.h"
static SPI_HandleTypeDef SpiHandle;
static void init_spi(spi_t *obj) {
static void init_spi(spi_t *obj)
{
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
__HAL_SPI_DISABLE(&SpiHandle);
@ -94,7 +62,8 @@ static void init_spi(spi_t *obj) {
__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);
@ -143,7 +112,8 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
init_spi(obj);
}
void spi_free(spi_t *obj) {
void spi_free(spi_t *obj)
{
// Reset SPI and disable clock
if (obj->spi == SPI_1) {
__SPI1_FORCE_RESET();
@ -164,7 +134,8 @@ void spi_free(spi_t *obj) {
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_16BIT;
@ -202,7 +173,8 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
init_spi(obj);
}
void spi_frequency(spi_t *obj, int hz) {
void spi_frequency(spi_t *obj, int hz)
{
// Note: The frequencies are obtained with SPI1 clock = 32 MHz (APB2 clock)
if (hz < 250000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz
@ -224,7 +196,8 @@ void spi_frequency(spi_t *obj, int hz) {
init_spi(obj);
}
static inline int ssp_readable(spi_t *obj) {
static inline int ssp_readable(spi_t *obj)
{
int status;
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is received
@ -232,7 +205,8 @@ static inline int ssp_readable(spi_t *obj) {
return status;
}
static inline int ssp_writeable(spi_t *obj) {
static inline int ssp_writeable(spi_t *obj)
{
int status;
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is transmitted
@ -240,47 +214,55 @@ static inline int ssp_writeable(spi_t *obj) {
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));
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));
return (int)spi->DR;
}
static inline int ssp_busy(spi_t *obj) {
static inline int ssp_busy(spi_t *obj)
{
int status;
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) ? 1 : 0);
};
int spi_slave_read(spi_t *obj) {
int spi_slave_read(spi_t *obj)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj));
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));
spi->DR = (uint16_t)value;
}
int spi_busy(spi_t *obj) {
int spi_busy(spi_t *obj)
{
return ssp_busy(obj);
}

View File

@ -29,80 +29,35 @@
#include "us_ticker_api.h"
#include "PeripheralNames.h"
// Timer selection:
#define TIM_MST TIM21
#define TIM_MST_IRQ TIM21_IRQn
#define TIM_MST_RCC __TIM21_CLK_ENABLE()
// Timer selection
#define TIM_MST TIM21
static TIM_HandleTypeDef TimMasterHandle;
static int us_ticker_inited = 0;
static int us_ticker_inited = 0;
static volatile uint32_t SlaveCounter = 0;
static volatile uint32_t oc_int_part = 0;
static volatile uint16_t oc_rem_part = 0;
volatile uint32_t SlaveCounter = 0;
volatile uint32_t oc_int_part = 0;
volatile uint16_t oc_rem_part = 0;
void set_compare(uint16_t count) {
void set_compare(uint16_t count)
{
TimMasterHandle.Instance = TIM_MST;
// Set new output compare value
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, count);
// Enable IT
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
}
static void tim_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
// Clear Update interrupt flag
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE);
SlaveCounter++;
}
// Clear CC1 interrupt flag
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
if (oc_rem_part > 0) {
set_compare(oc_rem_part); // Finish the remaining time left
oc_rem_part = 0;
} else {
if (oc_int_part > 0) {
set_compare(0xFFFF);
oc_rem_part = cval; // To finish the counter loop the next time
oc_int_part--;
} else {
us_ticker_irq_handler();
}
}
}
}
void us_ticker_init(void) {
void us_ticker_init(void)
{
if (us_ticker_inited) return;
us_ticker_inited = 1;
// Enable timer clock
TIM_MST_RCC;
// Configure time base
TimMasterHandle.Instance = TIM_MST;
TimMasterHandle.Init.Period = 0xFFFF;
TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 <20>s tick
TimMasterHandle.Init.ClockDivision = 0;
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&TimMasterHandle);
// Configure interrupts
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
// Update interrupt used for 32-bit counter
// Output compare interrupt used for timeout feature
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ);
// Enable timer
HAL_TIM_Base_Start(&TimMasterHandle);
HAL_InitTick(0); // The passed value is not used
}
uint32_t us_ticker_read() {
uint32_t us_ticker_read()
{
uint32_t counter, counter2;
if (!us_ticker_inited) us_ticker_init();
// A situation might appear when Master overflows right after Slave is read and before the
@ -123,7 +78,8 @@ uint32_t us_ticker_read() {
return counter2;
}
void us_ticker_set_interrupt(timestamp_t timestamp) {
void us_ticker_set_interrupt(timestamp_t timestamp)
{
int delta = (int)((uint32_t)timestamp - us_ticker_read());
uint16_t cval = TIM_MST->CNT;
@ -142,10 +98,16 @@ void us_ticker_set_interrupt(timestamp_t timestamp) {
}
}
void us_ticker_disable_interrupt(void) {
void us_ticker_disable_interrupt(void)
{
TimMasterHandle.Instance = TIM_MST;
__HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
}
void us_ticker_clear_interrupt(void) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
void us_ticker_clear_interrupt(void)
{
TimMasterHandle.Instance = TIM_MST;
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
}
}