From ec3ca5b4e615639dd3b4650eaa8d5739b78a1cbc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 19 Jun 2011 10:45:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3061 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- boards/ST_STM32L_DISCOVERY/board.h | 131 +++++----- os/hal/include/pal.h | 9 +- os/hal/platforms/STM32L1xx/core_cm3.h | 160 ++++++------- os/hal/platforms/STM32L1xx/hal_lld.c | 16 +- os/hal/platforms/STM32L1xx/hal_lld.h | 1 + os/hal/platforms/STM32L1xx/pal_lld.c | 186 +++++++++++++++ os/hal/platforms/STM32L1xx/pal_lld.h | 437 ++++++++++++++++++++++++++++++++++ os/hal/src/pal.c | 2 +- 8 files changed, 792 insertions(+), 150 deletions(-) create mode 100644 os/hal/platforms/STM32L1xx/pal_lld.c create mode 100644 os/hal/platforms/STM32L1xx/pal_lld.h diff --git a/boards/ST_STM32L_DISCOVERY/board.h b/boards/ST_STM32L_DISCOVERY/board.h index beb0d189e..46e592dbb 100644 --- a/boards/ST_STM32L_DISCOVERY/board.h +++ b/boards/ST_STM32L_DISCOVERY/board.h @@ -54,83 +54,104 @@ /* * I/O ports initial setup, this configuration is established soon after reset * in the initialization code. - * - * The digits have the following meaning: - * 0 - Analog input. - * 1 - Push Pull output 10MHz. - * 2 - Push Pull output 2MHz. - * 3 - Push Pull output 50MHz. - * 4 - Digital input. - * 5 - Open Drain output 10MHz. - * 6 - Open Drain output 2MHz. - * 7 - Open Drain output 50MHz. - * 8 - Digital input with PullUp or PullDown resistor depending on ODR. - * 9 - Alternate Push Pull output 10MHz. - * A - Alternate Push Pull output 2MHz. - * B - Alternate Push Pull output 50MHz. - * C - Reserved. - * D - Alternate Open Drain output 10MHz. - * E - Alternate Open Drain output 2MHz. - * F - Alternate Open Drain output 50MHz. * Please refer to the STM32 Reference Manual for details. */ +#define PIN_MODE_INPUT(n) (0 << ((n) * 2)) +#define PIN_MODE_OUTPUT(n) (1 << ((n) * 2)) +#define PIN_MODE_ALTERNATE(n) (2 << ((n) * 2)) +#define PIN_MODE_ANALOG(n) (3 << ((n) * 2)) +#define PIN_OTYPE_PUSHPULL(n) (0 << (n)) +#define PIN_OTYPE_OPENDRAIN(n) (1 << (n)) +#define PIN_OSPEED_400K(n) (0 << ((n) * 2)) +#define PIN_OSPEED_2M(n) (1 << ((n) * 2)) +#define PIN_OSPEED_10M(n) (2 << ((n) * 2)) +#define PIN_OSPEED_40M(n) (3 << ((n) * 2)) +#define PIN_PUDR_FLOATING(n) (0 << ((n) * 2)) +#define PIN_PUDR_PULLUP(n) (1 << ((n) * 2)) +#define PIN_PUDR_PULLDOWN(n) (2 << ((n) * 2)) /* * Port A setup. - * Everything input with pull-up except: - * PA0 - Normal input (BUTTON). - * PA2 - Alternate output (USART2 TX). - * PA3 - Normal input (USART2 RX). - * PA4 - Push pull output (SPI1 NSS), initially high state. - * PA5 - Alternate output (SPI1 SCK). - * PA6 - Normal input (SPI1 MISO). - * PA7 - Alternate output (SPI1 MOSI). - * PA9 - Alternate output (USART1 TX). - * PA10 - Normal input (USART1 RX). + * All input with pull-up except: + * PA0 - GPIOA_BUTTON (input floating). + * PA13 - JTMS/SWDAT (alternate 0). + * PA14 - JTCK/SWCLK (alternate 0). + * PA15 - JTDI (alternate 0). */ -#define VAL_GPIOACRL 0xB4B34B84 /* PA7...PA0 */ -#define VAL_GPIOACRH 0x888884B8 /* PA15...PA8 */ -#define VAL_GPIOAODR 0xFFFFFFFF +#define VAL_GPIOA_MODER (PIN_MODE_INPUT(GPIOA_BUTTON) | \ + PIN_MODE_ALTERNATE(13) | \ + PIN_MODE_ALTERNATE(14) | \ + PIN_MODE_ALTERNATE(15)) +#define VAL_GPIOA_OTYPER 0x00000000 +#define VAL_GPIOA_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOA_PUPDR (~(PIN_PUDR_FLOATING(GPIOA_BUTTON) | \ + PIN_PUDR_FLOATING(13) | \ + PIN_PUDR_FLOATING(14) | \ + PIN_PUDR_FLOATING(15))) +#define VAL_GPIOA_ODR 0xFFFFFFFF /* * Port B setup. - * Everything input with pull-up except: - * PB12 - Push pull output (SPI2 NSS), initially high state. - * PB13 - Alternate output (SPI2 SCK). - * PB14 - Normal input (SPI2 MISO). - * PB15 - Alternate output (SPI2 MOSI). + * All input with pull-up except: + * PB3 - JTDO (alternate 0). + * PB4 - JNTRST (alternate 0). + * PB6 - GPIOB_LED4 (output push-pull). + * PB7 - GPIOB_LED3 (output push-pull). */ -#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */ -#define VAL_GPIOBCRH 0xB4B38888 /* PB15...PB8 */ -#define VAL_GPIOBODR 0xFFFFFFFF +#define VAL_GPIOB_MODER (PIN_MODE_ALTERNATE(3) | \ + PIN_MODE_ALTERNATE(4) | \ + PIN_MODE_OUTPUT(GPIOB_LED4) | \ + PIN_MODE_OUTPUT(GPIOB_LED3)) +#define VAL_GPIOB_OTYPER 0x00000000 +#define VAL_GPIOB_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOB_PUPDR (~(PIN_PUDR_FLOATING(3) | \ + PIN_PUDR_FLOATING(4) | \ + PIN_PUDR_FLOATING(GPIOB_LED4) | \ + PIN_PUDR_FLOATING(GPIOB_LED3))) +#define VAL_GPIOB_ODR 0xFFFFFFFF /* * Port C setup. - * Everything input with pull-up except: - * PC8 - Push-pull output (LED4), initially low state. - * PC9 - Push-pull output (LED3), initially low state. + * All input with pull-up except: + * PC13 - OSC32_OUT (input floating). + * PC14 - OSC32_IN (input floating). */ -#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */ -#define VAL_GPIOCCRH 0x88888833 /* PC15...PC8 */ -#define VAL_GPIOCODR 0xFFFFFCFF +#define VAL_GPIOC_MODER 0x00000000 +#define VAL_GPIOC_OTYPER 0x00000000 +#define VAL_GPIOC_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOC_PUPDR (~(PIN_PUDR_FLOATING(15) | \ + PIN_PUDR_FLOATING(14))) +#define VAL_GPIOC_ODR 0xFFFFFFFF /* * Port D setup. - * Everything input with pull-up except: - * PD0 - Normal input (XTAL). - * PD1 - Normal input (XTAL). + * All input with pull-up. */ -#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */ -#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */ -#define VAL_GPIODODR 0xFFFFFFFF +#define VAL_GPIOD_MODER 0x00000000 +#define VAL_GPIOD_OTYPER 0x00000000 +#define VAL_GPIOD_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOD_PUPDR 0xFFFFFFFF +#define VAL_GPIOD_ODR 0xFFFFFFFF /* * Port E setup. - * Everything input with pull-up except: + * All input with pull-up. */ -#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */ -#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */ -#define VAL_GPIOEODR 0xFFFFFFFF +#define VAL_GPIOE_MODER 0x00000000 +#define VAL_GPIOE_OTYPER 0x00000000 +#define VAL_GPIOE_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOE_PUPDR 0xFFFFFFFF +#define VAL_GPIOE_ODR 0xFFFFFFFF + +/* + * Port H setup. + * All input with pull-up. + */ +#define VAL_GPIOH_MODER 0x00000000 +#define VAL_GPIOH_OTYPER 0x00000000 +#define VAL_GPIOH_OSPEEDR 0xFFFFFFFF +#define VAL_GPIOH_PUPDR 0xFFFFFFFF +#define VAL_GPIOH_ODR 0xFFFFFFFF #if !defined(_FROM_ASM_) #ifdef __cplusplus diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h index e9d0e31d8..fc0045bf4 100644 --- a/os/hal/include/pal.h +++ b/os/hal/include/pal.h @@ -35,13 +35,6 @@ /* Driver constants. */ /*===========================================================================*/ -/** - * @brief Bits in a mode word dedicated as mode selector. - * @details The other bits are not defined and may be used as device-specific - * option bits. - */ -#define PAL_MODE_MASK 0x1F - /** * @brief After reset state. * @details The state itself is not specified and is architecture dependent, @@ -516,7 +509,7 @@ extern "C" { #endif ioportmask_t palReadBus(IOBus *bus); void palWriteBus(IOBus *bus, ioportmask_t bits); - void palSetBusMode(IOBus *bus, uint_fast8_t mode); + void palSetBusMode(IOBus *bus, iomode_t mode); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32L1xx/core_cm3.h b/os/hal/platforms/STM32L1xx/core_cm3.h index 387221bc6..2e7746f5a 100644 --- a/os/hal/platforms/STM32L1xx/core_cm3.h +++ b/os/hal/platforms/STM32L1xx/core_cm3.h @@ -20,7 +20,7 @@ /* * Parts of this files have been modified in ChibiOS/RT in order to fix - * some code quality issues. + * some code quality issues and conflicting declarations. */ /**************************************************************************//** @@ -33,9 +33,9 @@ * Copyright (C) 2009 ARM Limited. All rights reserved. * * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. * * @par * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED @@ -59,7 +59,7 @@ * - Error 530: \n * return(__regBasePri); \n * Warning 530: Symbol '__regBasePri' (line 264) not initialized - * . + * . * - Error 550: \n * __regBasePri = (basePri & 0x1ff); \n * Warning 550: Symbol '__regBasePri' (line 271) not accessed @@ -104,7 +104,7 @@ #ifdef __cplusplus extern "C" { -#endif +#endif #define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */ #define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ @@ -157,19 +157,19 @@ typedef struct { __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; + uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; + uint32_t RSERVED1[24]; __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; + uint32_t RESERVED2[24]; __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; + uint32_t RESERVED3[24]; __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */ - uint32_t RESERVED4[56]; + uint32_t RESERVED4[56]; __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; + uint32_t RESERVED5[644]; __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ -} NVIC_Type; +} NVIC_Type; /*@}*/ /* end of group CMSIS_CM3_NVIC */ @@ -198,7 +198,7 @@ typedef struct __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */ __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */ __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */ -} SCB_Type; +} SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ @@ -335,7 +335,7 @@ typedef struct #define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - + #define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ @@ -434,26 +434,26 @@ typedef struct */ typedef struct { - __O union + __O union { __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */ __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */ __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */ } PORT [32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; + uint32_t RESERVED0[864]; __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */ - uint32_t RESERVED1[15]; + uint32_t RESERVED1[15]; __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; + uint32_t RESERVED2[15]; __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */ - uint32_t RESERVED3[29]; + uint32_t RESERVED3[29]; __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */ __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */ __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; + uint32_t RESERVED4[43]; __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */ __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */ - uint32_t RESERVED5[6]; + uint32_t RESERVED5[6]; __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */ __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */ __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */ @@ -466,7 +466,7 @@ typedef struct __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */ __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */ __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */ -} ITM_Type; +} ITM_Type; /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ @@ -570,7 +570,7 @@ typedef struct __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */ __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */ __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; +} MPU_Type; /* MPU Type Register */ #define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ @@ -827,7 +827,7 @@ extern uint32_t __get_PSP(void); * * @param topOfProcStack Process Stack Pointer * - * Assign the value ProcessStackPointer to the MSP + * Assign the value ProcessStackPointer to the MSP * (process stack pointer) Cortex processor register */ extern void __set_PSP(uint32_t topOfProcStack); @@ -847,7 +847,7 @@ extern uint32_t __get_MSP(void); * * @param topOfMainStack Main Stack Pointer * - * Assign the value mainStackPointer to the MSP + * Assign the value mainStackPointer to the MSP * (main stack pointer) Cortex processor register */ extern void __set_MSP(uint32_t topOfMainStack); @@ -938,7 +938,7 @@ extern void __set_FAULTMASK(uint32_t faultMask); /** * @brief Return the Control Register value - * + * * @return Control value * * Return the content of the control register @@ -1043,7 +1043,7 @@ static __INLINE void __set_FAULTMASK(uint32_t faultMask) /** * @brief Return the Control Register value - * + * * @return Control value * * Return the content of the control register @@ -1067,7 +1067,7 @@ static __INLINE void __set_CONTROL(uint32_t control) __regControl = control; } -#endif /* __ARMCC_VERSION */ +#endif /* __ARMCC_VERSION */ @@ -1080,7 +1080,7 @@ static __INLINE void __set_CONTROL(uint32_t control) static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); } static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); } -#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */ +#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */ static __INLINE void __WFI() { __ASM ("wfi"); } static __INLINE void __WFE() { __ASM ("wfe"); } static __INLINE void __SEV() { __ASM ("sev"); } @@ -1106,17 +1106,17 @@ static __INLINE void __CLREX() { __ASM ("clrex"); } * * Return the actual process stack pointer */ -extern uint32_t __get_PSP(void); +//extern uint32_t __get_PSP(void); /** * @brief Set the Process Stack Pointer * * @param topOfProcStack Process Stack Pointer * - * Assign the value ProcessStackPointer to the MSP + * Assign the value ProcessStackPointer to the MSP * (process stack pointer) Cortex processor register */ -extern void __set_PSP(uint32_t topOfProcStack); +//extern void __set_PSP(uint32_t topOfProcStack); /** * @brief Return the Main Stack Pointer @@ -1126,17 +1126,17 @@ extern void __set_PSP(uint32_t topOfProcStack); * Return the current value of the MSP (main stack pointer) * Cortex processor register */ -extern uint32_t __get_MSP(void); +//extern uint32_t __get_MSP(void); /** * @brief Set the Main Stack Pointer * * @param topOfMainStack Main Stack Pointer * - * Assign the value mainStackPointer to the MSP + * Assign the value mainStackPointer to the MSP * (main stack pointer) Cortex processor register */ -extern void __set_MSP(uint32_t topOfMainStack); +//extern void __set_MSP(uint32_t topOfMainStack); /** * @brief Reverse byte order in unsigned short value @@ -1146,7 +1146,7 @@ extern void __set_MSP(uint32_t topOfMainStack); * * Reverse byte order in unsigned short value */ -extern uint32_t __REV16(uint16_t value); +//extern uint32_t __REV16(uint16_t value); /** * @brief Reverse bit order of value @@ -1156,7 +1156,7 @@ extern uint32_t __REV16(uint16_t value); * * Reverse bit order of value */ -extern uint32_t __RBIT(uint32_t value); +//extern uint32_t __RBIT(uint32_t value); /** * @brief LDR Exclusive (8 bit) @@ -1197,7 +1197,7 @@ extern uint32_t __LDREXW(uint32_t *addr); * * Exclusive STR command for 8 bit values */ -extern uint32_t __STREXB(uint8_t value, uint8_t *addr); +//extern uint32_t __STREXB(uint8_t value, uint8_t *addr); /** * @brief STR Exclusive (16 bit) @@ -1208,7 +1208,7 @@ extern uint32_t __STREXB(uint8_t value, uint8_t *addr); * * Exclusive STR command for 16 bit values */ -extern uint32_t __STREXH(uint16_t value, uint16_t *addr); +//extern uint32_t __STREXH(uint16_t value, uint16_t *addr); /** * @brief STR Exclusive (32 bit) @@ -1256,7 +1256,7 @@ extern uint32_t __get_PSP(void); * * @param topOfProcStack Process Stack Pointer * - * Assign the value ProcessStackPointer to the MSP + * Assign the value ProcessStackPointer to the MSP * (process stack pointer) Cortex processor register */ extern void __set_PSP(uint32_t topOfProcStack); @@ -1276,7 +1276,7 @@ extern uint32_t __get_MSP(void); * * @param topOfMainStack Main Stack Pointer * - * Assign the value mainStackPointer to the MSP + * Assign the value mainStackPointer to the MSP * (main stack pointer) Cortex processor register */ extern void __set_MSP(uint32_t topOfMainStack); @@ -1337,7 +1337,7 @@ extern void __set_FAULTMASK(uint32_t faultMask); /** * @brief Return the Control Register value -* +* * @return Control value * * Return the content of the control register @@ -1485,7 +1485,7 @@ extern uint32_t __STREXW(uint32_t value, uint32_t *addr); * @param PriorityGroup is priority grouping field * * Set the priority grouping field using the required unlock sequence. - * The parameter priority_grouping is assigned to the field + * The parameter priority_grouping is assigned to the field * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. * In case of a conflict between priority grouping and available * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. @@ -1494,11 +1494,11 @@ static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - + reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ reg_value = (reg_value | - (0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (0x5FA << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ SCB->AIRCR = reg_value; } @@ -1506,7 +1506,7 @@ static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) /** * @brief Get the Priority Grouping from NVIC Interrupt Controller * - * @return priority grouping field + * @return priority grouping field * * Get the priority grouping from NVIC Interrupt Controller. * priority grouping is SCB->AIRCR [10:8] PRIGROUP field. @@ -1531,9 +1531,9 @@ static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) /** * @brief Disable the interrupt line for external interrupt specified - * + * * @param IRQn The positive number of the external interrupt to disable - * + * * Disable a device specific interupt in the NVIC interrupt controller. * The interrupt number cannot be a negative value. */ @@ -1544,11 +1544,11 @@ static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) /** * @brief Read the interrupt pending bit for a device specific interrupt source - * + * * @param IRQn The number of the device specifc interrupt * @return 1 = interrupt pending, 0 = interrupt not pending * - * Read the pending register in NVIC and return 1 if its status is pending, + * Read the pending register in NVIC and return 1 if its status is pending, * otherwise it returns 0 */ static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) @@ -1558,7 +1558,7 @@ static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) /** * @brief Set the pending bit for an external interrupt - * + * * @param IRQn The number of the interrupt for set pending * * Set the pending bit for the specified interrupt. @@ -1574,7 +1574,7 @@ static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) * * @param IRQn The number of the interrupt for clear pending * - * Clear the pending bit for the specified interrupt. + * Clear the pending bit for the specified interrupt. * The interrupt number cannot be a negative value. */ static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) @@ -1588,7 +1588,7 @@ static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) * @param IRQn The number of the interrupt for read active bit * @return 1 = interrupt active, 0 = interrupt not active * - * Read the active register in NVIC and returns 1 if its status is active, + * Read the active register in NVIC and returns 1 if its status is active, * otherwise it returns 0. */ static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) @@ -1602,8 +1602,8 @@ static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) * @param IRQn The number of the interrupt for set priority * @param priority The priority to set * - * Set the priority for the specified interrupt. The interrupt - * number can be positive to specify an external (device specific) + * Set the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) * interrupt, or negative to specify an internal (core) interrupt. * * Note: The priority cannot be set for every core interrupt. @@ -1622,8 +1622,8 @@ static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) * @param IRQn The number of the interrupt for get priority * @return The priority for the interrupt * - * Read the priority for the specified interrupt. The interrupt - * number can be positive to specify an external (device specific) + * Read the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) * interrupt, or negative to specify an internal (core) interrupt. * * The returned priority value is automatically aligned to the implemented @@ -1664,7 +1664,7 @@ static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t P PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - + return ( ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | ((SubPriority & ((1 << (SubPriorityBits )) - 1))) @@ -1680,7 +1680,7 @@ static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t P * @param pPreemptPriority The preemptive priority value (starting from 0) * @param pSubPriority The sub priority value (starting from 0) * - * Decode an interrupt priority value with the given priority group to + * Decode an interrupt priority value with the given priority group to * preemptive priority value and sub priority value. * In case of a conflict between priority grouping and available * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. @@ -1695,7 +1695,7 @@ static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGr PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); } @@ -1713,18 +1713,18 @@ static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGr * @return 1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the - * system tick timer / counter in free running mode to generate + * system tick timer / counter in free running mode to generate * periodical interrupts. */ static __INLINE uint32_t SysTick_Config(uint32_t ticks) -{ +{ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ } @@ -1743,10 +1743,10 @@ static __INLINE uint32_t SysTick_Config(uint32_t ticks) */ static __INLINE void NVIC_SystemReset(void) { - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ + __DSB(); /* Ensure completion of memory access */ while(1); /* wait until reset */ } @@ -1774,9 +1774,9 @@ extern volatile int ITM_RxBuffer; /*!< variable to receive ch * @param ch character to output * @return character to output * - * The function outputs a character via the ITM channel 0. - * The function returns when no debugger is connected that has booked the output. - * It is blocking when a debugger is connected, but the previous character send is not transmitted. + * The function outputs a character via the ITM channel 0. + * The function returns when no debugger is connected that has booked the output. + * It is blocking when a debugger is connected, but the previous character send is not transmitted. */ static __INLINE uint32_t ITM_SendChar (uint32_t ch) { @@ -1786,7 +1786,7 @@ static __INLINE uint32_t ITM_SendChar (uint32_t ch) { while (ITM->PORT[0].u32 == 0); ITM->PORT[0].u8 = (uint8_t) ch; - } + } return (ch); } @@ -1796,9 +1796,9 @@ static __INLINE uint32_t ITM_SendChar (uint32_t ch) * * @return received character, -1 = no character received * - * The function inputs a character via variable ITM_RxBuffer. - * The function returns when no debugger is connected that has booked the output. - * It is blocking when a debugger is connected, but the previous character send is not transmitted. + * The function inputs a character via variable ITM_RxBuffer. + * The function returns when no debugger is connected that has booked the output. + * It is blocking when a debugger is connected, but the previous character send is not transmitted. */ static __INLINE int ITM_ReceiveChar (void) { int ch = -1; /* no character available */ @@ -1807,8 +1807,8 @@ static __INLINE int ITM_ReceiveChar (void) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } - - return (ch); + + return (ch); } @@ -1817,8 +1817,8 @@ static __INLINE int ITM_ReceiveChar (void) { * * @return 1 = character available, 0 = no character available * - * The function checks variable ITM_RxBuffer whether a character is available or not. - * The function returns '1' if a character is available and '0' if no character is available. + * The function checks variable ITM_RxBuffer whether a character is available or not. + * The function returns '1' if a character is available and '0' if no character is available. */ static __INLINE int ITM_CheckChar (void) { diff --git a/os/hal/platforms/STM32L1xx/hal_lld.c b/os/hal/platforms/STM32L1xx/hal_lld.c index 8f6027865..c9d8a3914 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -59,10 +59,10 @@ void hal_lld_init(void) { /* Reset of all peripherals.*/ - RCC->APB1RSTR = 0xFFFFFFFF; - RCC->APB2RSTR = 0xFFFFFFFF; - RCC->APB1RSTR = 0; - RCC->APB2RSTR = 0; +// RCC->APB1RSTR = 0xFFFFFFFF; +// RCC->APB2RSTR = 0xFFFFFFFF; +// RCC->APB1RSTR = 0; +// RCC->APB2RSTR = 0; /* SysTick initialization using the system clock.*/ SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1; @@ -129,8 +129,12 @@ void stm32_clock_init(void) { #endif #if STM32_LSE_ENABLED - /* LSE activation.*/ - RCC->CSR |= RCC_CSR_LSEON; + /* LSE activation, have to unlock the register.*/ + if ((RCC->CSR & RCC_CSR_LSEON) == 0) { + PWR->CR |= PWR_CR_DBP; + RCC->CSR |= RCC_CSR_LSEON; + PWR->CR &= ~PWR_CR_DBP; + } while ((RCC->CSR & RCC_CSR_LSERDY) == 0) ; /* Waits until LSE is stable. */ #endif diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index e2e2fb925..5e451409d 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -63,6 +63,7 @@ #define STM32_VOS_1P5 (2 << 11) /**< Core voltage 1.5 Volts. */ #define STM32_VOS_1P8 (3 << 11) /**< Core voltage 1.8 Volts. */ +/* RCC_CR register bits definitions.*/ #define STM32_RTCPRE_MASK (3 << 29) /**< RTCPRE mask. */ #define STM32_RTCPRE_DIV2 (0 << 29) /**< HSE divided by 2. */ #define STM32_RTCPRE_DIV4 (1 << 29) /**< HSE divided by 4. */ diff --git a/os/hal/platforms/STM32L1xx/pal_lld.c b/os/hal/platforms/STM32L1xx/pal_lld.c new file mode 100644 index 000000000..c56996db7 --- /dev/null +++ b/os/hal/platforms/STM32L1xx/pal_lld.c @@ -0,0 +1,186 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/pal_lld.c + * @brief STM32 GPIO low level driver code. + * + * @addtogroup PAL + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +#if STM32_HAS_GPIOG +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \ + RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN) +#elif STM32_HAS_GPIOE +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN) +#else +#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \ + RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \ + RCC_APB2ENR_AFIOEN) +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 I/O ports configuration. + * @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled. + * + * @param[in] config the STM32 ports configuration + * + * @notapi + */ +void _pal_lld_init(const PALConfig *config) { + + /* + * Enables the GPIO related clocks. + */ + RCC->APB2ENR |= APB2_EN_MASK; + + /* + * Initial GPIO setup. + */ + GPIOA->ODR = config->PAData.odr; + GPIOA->CRH = config->PAData.crh; + GPIOA->CRL = config->PAData.crl; + GPIOB->ODR = config->PBData.odr; + GPIOB->CRH = config->PBData.crh; + GPIOB->CRL = config->PBData.crl; + GPIOC->ODR = config->PCData.odr; + GPIOC->CRH = config->PCData.crh; + GPIOC->CRL = config->PCData.crl; + GPIOD->ODR = config->PDData.odr; + GPIOD->CRH = config->PDData.crh; + GPIOD->CRL = config->PDData.crl; +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) + GPIOE->ODR = config->PEData.odr; + GPIOE->CRH = config->PEData.crh; + GPIOE->CRL = config->PEData.crl; +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) + GPIOF->ODR = config->PFData.odr; + GPIOF->CRH = config->PFData.crh; + GPIOF->CRL = config->PFData.crl; +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) + GPIOG->ODR = config->PGData.odr; + GPIOG->CRH = config->PGData.crh; + GPIOG->CRL = config->PGData.crl; +#endif +#endif +#endif +} + +/** + * @brief Pads mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note This function is not meant to be invoked directly by the + * application code. + * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode) { + static const uint8_t cfgtab[] = { + 4, /* PAL_MODE_RESET, implemented as input.*/ + 2, /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/ + 4, /* PAL_MODE_INPUT */ + 8, /* PAL_MODE_INPUT_PULLUP */ + 8, /* PAL_MODE_INPUT_PULLDOWN */ + 0, /* PAL_MODE_INPUT_ANALOG */ + 3, /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/ + 7, /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 8, /* Reserved.*/ + 0xB, /* PAL_MODE_STM32_ALTERNATE_PUSHPULL, 50MHz.*/ + 0xF, /* PAL_MODE_STM32_ALTERNATE_OPENDRAIN, 50MHz.*/ + }; + uint32_t mh, ml, crh, crl, cfg; + unsigned i; + + if (mode == PAL_MODE_INPUT_PULLUP) + port->BSRR = mask; + else if (mode == PAL_MODE_INPUT_PULLDOWN) + port->BRR = mask; + cfg = cfgtab[mode]; + mh = ml = crh = crl = 0; + for (i = 0; i < 8; i++) { + ml <<= 4; + mh <<= 4; + crl <<= 4; + crh <<= 4; + if ((mask & 0x0080) == 0) + ml |= 0xf; + else + crl |= cfg; + if ((mask & 0x8000) == 0) + mh |= 0xf; + else + crh |= cfg; + mask <<= 1; + } + port->CRH = (port->CRH & mh) | crh; + port->CRL = (port->CRL & ml) | crl; +} + +#endif /* HAL_USE_PAL */ + +/** @} */ diff --git a/os/hal/platforms/STM32L1xx/pal_lld.h b/os/hal/platforms/STM32L1xx/pal_lld.h new file mode 100644 index 000000000..d1f353af0 --- /dev/null +++ b/os/hal/platforms/STM32L1xx/pal_lld.h @@ -0,0 +1,437 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/pal_lld.h + * @brief STM32 GPIO low level driver header. + * + * @addtogroup PAL + * @{ + */ + +#ifndef _PAL_LLD_H_ +#define _PAL_LLD_H_ + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Unsupported modes and specific modes */ +/*===========================================================================*/ + +#undef PAL_MODE_RESET +#undef PAL_MODE_UNCONNECTED +#undef PAL_MODE_INPUT +#undef PAL_MODE_INPUT_PULLUP +#undef PAL_MODE_INPUT_PULLDOWN +#undef PAL_MODE_INPUT_ANALOG +#undef PAL_MODE_OUTPUT_PUSHPULL +#undef PAL_MODE_OUTPUT_OPENDRAIN + +#define PAL_STM32_MODE_MASK (3 >> 0) +#define PAL_STM32_MODE_INPUT (0 >> 0) +#define PAL_STM32_MODE_OUTPUT (1 >> 0) +#define PAL_STM32_MODE_ALTERNATE (2 >> 0) +#define PAL_STM32_MODE_ANALOG (3 >> 0) + +#define PAL_STM32_OTYPE_MASK (1 >> 2) +#define PAL_STM32_OTYPE_PUSHPULL (0 >> 2) +#define PAL_STM32_OTYPE_OPENDRAIN (1 >> 2) + +#define PAL_STM32_OSPEED_MASK (3 >> 3) +#define PAL_STM32_OSPEED_400K (0 >> 3) +#define PAL_STM32_OSPEED_2M (1 >> 3) +#define PAL_STM32_OSPEED_10M (2 >> 3) +#define PAL_STM32_OSPEED_40M (3 >> 3) + +#define PAL_STM32_PUDR_MASK (3 >> 5) +#define PAL_STM32_PUDR_FLOATING (0 >> 5) +#define PAL_STM32_PUDR_PULLUP (1 >> 5) +#define PAL_STM32_PUDR_PULLDOWN (2 >> 5) + +#define PAL_STM32_ALTERNATE_MASK (15 >> 7) +#define PAL_STM32_ALTERNATE(n) ((n) >> 7) + +/** + * @brief This mode is implemented as input. + */ +#define PAL_MODE_RESET PAL_STM32_MODE_INPUT + +/** + * @brief This mode is implemented as output. + */ +#define PAL_MODE_UNCONNECTED PAL_STM32_MODE_OUTPUT + +/** + * @brief Regular input high-Z pad. + */ +#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT + +/** + * @brief Input pad with weak pull up resistor. + */ +#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLUP) + +/** + * @brief Input pad with weak pull down resistor. + */ +#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \ + PAL_STM32_PUDR_PULLDOWN) + +/** + * @brief Analog input mode. + */ +#define PAL_MODE_INPUT_ANALOG PAL_STM32_MODE_ANALOG + +/** + * @brief Push-pull output pad. + */ +#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \ + PAL_STM32_OTYPE_PUSHPULL) + +/** + * @brief Open-drain output pad. + */ +#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \ + PAL_STM32_OTYPE_OPENDRAIN) + +/** + * @brief Alternate push-pull output. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE_PUSHPULL(n) (PAL_STM32_MODE_ALTERNATE | \ + PAL_STM32_OTYPE_PUSHPULL | \ + PAL_STM32_ALTERNATE(n)) + +/** + * @brief Alternate push-pull output. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE_OPENDRAIN(n) (PAL_STM32_MODE_ALTERNATE | \ + PAL_STM32_OTYPE_OPENDRAIN | \ + PAL_STM32_ALTERNATE(n)) + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @brief GPIO port setup info. + */ +typedef struct { + /** Initial value for MODER register.*/ + uint32_t moder; + /** Initial value for OTYPER register.*/ + uint32_t otyper; + /** Initial value for OSPEEDR register.*/ + uint32_t ospeedr; + /** Initial value for PUPDR register.*/ + uint32_t pupdr; + /** Initial value for ODR register.*/ + uint32_t odr; +} stm32_gpio_setup_t; + +/** + * @brief STM32 GPIO static initializer. + * @details An instance of this structure must be passed to @p palInit() at + * system startup time in order to initialize the digital I/O + * subsystem. This represents only the initial setup, specific pads + * or whole ports can be reprogrammed at later time. + */ +typedef struct { + /** @brief Port A setup data.*/ + stm32_gpio_setup_t PAData; + /** @brief Port B setup data.*/ + stm32_gpio_setup_t PBData; + /** @brief Port C setup data.*/ + stm32_gpio_setup_t PCData; + /** @brief Port D setup data.*/ + stm32_gpio_setup_t PDData; +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) + /** @brief Port E setup data.*/ + stm32_gpio_setup_t PEData; +#endif +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) + /** @brief Port F setup data.*/ + stm32_gpio_setup_t PFData; +#endif +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) + /** @brief Port G setup data.*/ + stm32_gpio_setup_t PGData; +#endif +#if STM32_HAS_GPIOH || defined(__DOXYGEN__) + /** @brief Port H setup data.*/ + stm32_gpio_setup_t PGData; +#endif +} PALConfig; + +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 16 + +/** + * @brief Whole port mask. + * @details This macro specifies all the valid bits into a port. + */ +#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF) + +/** + * @brief Digital I/O port sized unsigned type. + */ +typedef uint32_t ioportmask_t; + +/** + * @brief Digital I/O modes. + */ +typedef uint32_t iomode_t; + +/** + * @brief Port Identifier. + * @details This type can be a scalar or some kind of pointer, do not make + * any assumption about it, use the provided macros when populating + * variables of this type. + */ +typedef GPIO_TypeDef * ioportid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/* The low level driver wraps the definitions already present in the STM32 */ +/* firmware library. */ +/*===========================================================================*/ + +/** + * @brief GPIO port A identifier. + */ +#if STM32_HAS_GPIOA || defined(__DOXYGEN__) +#define IOPORT1 GPIOA +#endif + +/** + * @brief GPIO port B identifier. + */ +#if STM32_HAS_GPIOB || defined(__DOXYGEN__) +#define IOPORT2 GPIOB +#endif + +/** + * @brief GPIO port C identifier. + */ +#if STM32_HAS_GPIOC || defined(__DOXYGEN__) +#define IOPORT3 GPIOC +#endif + +/** + * @brief GPIO port D identifier. + */ +#if STM32_HAS_GPIOD || defined(__DOXYGEN__) +#define IOPORT4 GPIOD +#endif + +/** + * @brief GPIO port E identifier. + */ +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) +#define IOPORT5 GPIOE +#endif + +/** + * @brief GPIO port F identifier. + */ +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) +#define IOPORT6 GPIOF +#endif + +/** + * @brief GPIO port G identifier. + */ +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) +#define IOPORT7 GPIOG +#endif + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, please put them in a file named ioports_lld.c if so. */ +/*===========================================================================*/ + +/** + * @brief GPIO ports subsystem initialization. + * + * @notapi + */ +#define pal_lld_init(config) _pal_lld_init(config) + +/** + * @brief Reads an I/O port. + * @details This function is implemented by reading the GPIO IDR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port the port identifier + * @return The port bits. + * + * @notapi + */ +#define pal_lld_readport(port) ((port)->IDR) + +/** + * @brief Reads the output latch. + * @details This function is implemented by reading the GPIO ODR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port the port identifier + * @return The latched logical states. + * + * @notapi + */ +#define pal_lld_readlatch(port) ((port)->ODR) + +/** + * @brief Writes on a I/O port. + * @details This function is implemented by writing the GPIO ODR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be written on the specified port + * + * @notapi + */ +#define pal_lld_writeport(port, bits) ((port)->ODR = (bits)) + +/** + * @brief Sets a bits mask on a I/O port. + * @details This function is implemented by writing the GPIO BSRR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be ORed on the specified port + * + * @notapi + */ +#define pal_lld_setport(port, bits) ((port)->BSRR = (bits)) + +/** + * @brief Clears a bits mask on a I/O port. + * @details This function is implemented by writing the GPIO BRR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] bits the bits to be cleared on the specified port + * + * @notapi + */ +#define pal_lld_clearport(port, bits) ((port)->BRR = (bits)) + +/** + * @brief Writes a group of bits. + * @details This function is implemented by writing the GPIO BSRR register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] offset the group bit offset within the port + * @param[in] bits the bits to be written. Values exceeding the group + * width are masked. + * + * @notapi + */ +#define pal_lld_writegroup(port, mask, offset, bits) \ + ((port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \ + (((bits) & (mask)) << (offset))) + +/** + * @brief Pads group mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +#define pal_lld_setgroupmode(port, mask, mode) \ + _pal_lld_setgroupmode(port, mask, mode) + +/** + * @brief Writes a logical state on an output pad. + * @note This function is not meant to be invoked directly by the + * application code. + * @note Writing on pads programmed as pull-up or pull-down has the side + * effect to modify the resistor setting because the output latched + * data is used for the resistor selection. + * + * @param[in] port the port identifier + * @param[in] pad the pad number within the port + * @param[in] bit logical value, the value must be @p PAL_LOW or + * @p PAL_HIGH + * + * @notapi + */ +#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) + +extern const PALConfig pal_default_config; + +#ifdef __cplusplus +extern "C" { +#endif + void _pal_lld_init(const PALConfig *config); + void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + uint_fast8_t mode); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_PAL */ + +#endif /* _PAL_LLD_H_ */ + +/** @} */ diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c index 534935a55..10e57e284 100644 --- a/os/hal/src/pal.c +++ b/os/hal/src/pal.c @@ -110,7 +110,7 @@ void palWriteBus(IOBus *bus, ioportmask_t bits) { * * @api */ -void palSetBusMode(IOBus *bus, uint_fast8_t mode) { +void palSetBusMode(IOBus *bus, iomode_t mode) { chDbgCheck((bus != NULL) && (bus->offset < PAL_IOPORTS_WIDTH), "palSetBusMode"); -- cgit v1.2.3