aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-19 10:45:38 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-19 10:45:38 +0000
commitec3ca5b4e615639dd3b4650eaa8d5739b78a1cbc (patch)
tree2f0d0c629a962faa0213a1e88e5427993153ee0d /os/hal
parente612b8c794623e0fc82b11cf47da4e1b410984f9 (diff)
downloadChibiOS-ec3ca5b4e615639dd3b4650eaa8d5739b78a1cbc.tar.gz
ChibiOS-ec3ca5b4e615639dd3b4650eaa8d5739b78a1cbc.tar.bz2
ChibiOS-ec3ca5b4e615639dd3b4650eaa8d5739b78a1cbc.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3061 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/pal.h9
-rw-r--r--os/hal/platforms/STM32L1xx/core_cm3.h160
-rw-r--r--os/hal/platforms/STM32L1xx/hal_lld.c16
-rw-r--r--os/hal/platforms/STM32L1xx/hal_lld.h1
-rw-r--r--os/hal/platforms/STM32L1xx/pal_lld.c186
-rw-r--r--os/hal/platforms/STM32L1xx/pal_lld.h437
-rw-r--r--os/hal/src/pal.c2
7 files changed, 716 insertions, 95 deletions
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
@@ -36,13 +36,6 @@
/*===========================================================================*/
/**
- * @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,
* it is guaranteed to be equal to the after-reset state. It is
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @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");