Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • avn/swd/miosix-kernel
  • emilio.corigliano/miosix-kernel
2 results
Select Git revision
Show changes
Showing
with 2080 additions and 157 deletions
...@@ -99,20 +99,20 @@ void __attribute__((noinline)) HardFault_impl() ...@@ -99,20 +99,20 @@ void __attribute__((noinline)) HardFault_impl()
#ifdef WITH_ERRLOG #ifdef WITH_ERRLOG
IRQerrorLog("\r\n***Unexpected HardFault @ "); IRQerrorLog("\r\n***Unexpected HardFault @ ");
printUnsignedInt(getProgramCounter()); printUnsignedInt(getProgramCounter());
#ifndef _ARCH_CORTEXM0 #if !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM0_STM32G0) && !defined(_ARCH_CORTEXM0_STM32L0)
unsigned int hfsr=SCB->HFSR; unsigned int hfsr=SCB->HFSR;
if(hfsr & 0x40000000) //SCB_HFSR_FORCED if(hfsr & 0x40000000) //SCB_HFSR_FORCED
IRQerrorLog("Fault escalation occurred\r\n"); IRQerrorLog("Fault escalation occurred\r\n");
if(hfsr & 0x00000002) //SCB_HFSR_VECTTBL if(hfsr & 0x00000002) //SCB_HFSR_VECTTBL
IRQerrorLog("A BusFault occurred during a vector table read\r\n"); IRQerrorLog("A BusFault occurred during a vector table read\r\n");
#endif //_ARCH_CORTEXM0 #endif // !_ARCH_CORTEXM0_STM32F0 && !_ARCH_CORTEXM0_STM32G0 && !_ARCH_CORTEXM0_STM32L0
#endif //WITH_ERRLOG #endif //WITH_ERRLOG
miosix_private::IRQsystemReboot(); miosix_private::IRQsystemReboot();
} }
// Cortex M0/M0+ architecture does not have the interrupts handled by code // Cortex M0/M0+ architecture does not have the interrupts handled by code
// below this point // below this point
#ifndef _ARCH_CORTEXM0 #if !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM0_STM32G0) && !defined(_ARCH_CORTEXM0_STM32L0)
void __attribute__((naked)) MemManage_Handler() void __attribute__((naked)) MemManage_Handler()
{ {
...@@ -262,7 +262,7 @@ void DebugMon_Handler() ...@@ -262,7 +262,7 @@ void DebugMon_Handler()
miosix_private::IRQsystemReboot(); miosix_private::IRQsystemReboot();
} }
#endif //_ARCH_CORTEXM0 #endif // !_ARCH_CORTEXM0_STM32F0 && !_ARCH_CORTEXM0_STM32G0 && !_ARCH_CORTEXM0_STM32L0
void PendSV_Handler() void PendSV_Handler()
{ {
......
/***************************************************************************
* Copyright (C) 2021 by Terraneo Federico *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "kernel/kernel.h"
#include "interfaces/os_timer.h"
#include "interfaces/arch_registers.h"
namespace miosix {
class STM32Timer2 : public TimerAdapter<STM32Timer2, 32>
{
public:
static inline unsigned int IRQgetTimerCounter() { return TIM2->CNT; }
static inline void IRQsetTimerCounter(unsigned int v) { TIM2->CNT=v; }
static inline unsigned int IRQgetTimerMatchReg() { return TIM2->CCR1; }
static inline void IRQsetTimerMatchReg(unsigned int v) { TIM2->CCR1=v; }
static inline bool IRQgetOverflowFlag() { return TIM2->SR & TIM_SR_UIF; }
static inline void IRQclearOverflowFlag() { TIM2->SR = ~TIM_SR_UIF; }
static inline bool IRQgetMatchFlag() { return TIM2->SR & TIM_SR_CC1IF; }
static inline void IRQclearMatchFlag() { TIM2->SR = ~TIM_SR_CC1IF; }
static inline void IRQforcePendingIrq() { NVIC_SetPendingIRQ(TIM2_IRQn); }
static inline void IRQstopTimer() { TIM2->CR1 &= ~TIM_CR1_CEN; }
static inline void IRQstartTimer() { TIM2->CR1 |= TIM_CR1_CEN; }
static unsigned int IRQTimerFrequency()
{
// The global variable SystemCoreClock from ARM's CMSIS allows to know
// the CPU frequency.
unsigned int result=SystemCoreClock;
// The timer frequency may however be a submultiple of the CPU frequency,
// due to the bus at whch the periheral is connected being slower. The
// RCC->CFGR register tells us how slower the APB1 bus is running.
// This formula takes into account that if the APB1 clock is divided by a
// factor of two or greater, the timer is clocked at twice the bus
// interface. After this, the freq variable contains the frequency in Hz
// at which the timer prescaler is clocked.
#if _ARCH_CORTEXM0_STM32F0
if(RCC->CFGR & RCC_CFGR_PPRE_2) result/=1<<((RCC->CFGR>>8) & 0x3);
#else
if(RCC->CFGR & RCC_CFGR_PPRE1_2) result/=1<<((RCC->CFGR>>8) & 0x3);
#endif
return result;
}
static void IRQinitTimer()
{
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC_SYNC();
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP; //Stop while debugging
// Setup TIM2 base configuration
// Mode: Up-counter
// Interrupts: counter overflow, Compare/Capture on channel 1
TIM2->CR1=TIM_CR1_URS;
TIM2->DIER=TIM_DIER_UIE | TIM_DIER_CC1IE;
NVIC_SetPriority(TIM2_IRQn,3); //High priority for TIM2 (Max=0, min=15)
NVIC_EnableIRQ(TIM2_IRQn);
// Configure channel 1 as:
// Output channel (CC1S=0)
// No preload(OC1PE=0), hence TIM2_CCR1 can be written at anytime
// No effect on the output signal on match (OC1M = 0)
TIM2->CCMR1 = 0;
TIM2->CCR1 = 0;
// TIM2 Operation Frequency Configuration: Max Freq. and longest period
TIM2->PSC = 0;
TIM2->ARR = 0xFFFFFFFF;
TIM2->EGR = TIM_EGR_UG; //To enforce the timer to apply PSC
}
};
static STM32Timer2 timer;
DEFAULT_OS_TIMER_INTERFACE_IMPLMENTATION(timer);
} //namespace miosix
void __attribute__((naked)) TIM2_IRQHandler()
{
saveContext();
asm volatile ("bl _Z11osTimerImplv");
restoreContext();
}
void __attribute__((used)) osTimerImpl()
{
miosix::timer.IRQhandler();
}
/***************************************************************************
* Copyright (C) 2021 by Terraneo Federico *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "kernel/kernel.h"
#include "interfaces/os_timer.h"
#include "interfaces/arch_registers.h"
#include "kernel/logging.h"
namespace miosix {
class STM32Timer4 : public TimerAdapter<STM32Timer4, 16>
{
public:
static inline unsigned int IRQgetTimerCounter() { return TIM4->CNT; }
static inline void IRQsetTimerCounter(unsigned int v) { TIM4->CNT=v; }
static inline unsigned int IRQgetTimerMatchReg() { return TIM4->CCR1; }
static inline void IRQsetTimerMatchReg(unsigned int v) { TIM4->CCR1=v; }
static inline bool IRQgetOverflowFlag() { return TIM4->SR & TIM_SR_UIF; }
static inline void IRQclearOverflowFlag() { TIM4->SR = ~TIM_SR_UIF; }
static inline bool IRQgetMatchFlag() { return TIM4->SR & TIM_SR_CC1IF; }
static inline void IRQclearMatchFlag() { TIM4->SR = ~TIM_SR_CC1IF; }
static inline void IRQforcePendingIrq() { NVIC_SetPendingIRQ(TIM4_IRQn); }
static inline void IRQstopTimer() { TIM4->CR1 &= ~TIM_CR1_CEN; }
static inline void IRQstartTimer() { TIM4->CR1 |= TIM_CR1_CEN; }
/*
* These microcontrollers unfortunately do not have a 32bit timer.
* 16bit timers overflow too frequently if clocked at the maximum speed,
* and this is bad both because it nullifies the gains of a tickless kernel
* and because if interrupts are disabled for an entire timer period the
* OS loses the knowledge of time. For this reason, we set the timer clock
* to a lower value using the prescaler.
*/
static const int timerFrequency=1000000; //1MHz
static unsigned int IRQTimerFrequency()
{
return timerFrequency;
}
static void IRQinitTimer()
{
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC_SYNC();
#ifndef _ARCH_CORTEXM3_STM32L1
DBGMCU->CR |= DBGMCU_CR_DBG_TIM4_STOP; //Stop while debugging
#else
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM4_STOP; //Stop while debugging
#endif
// Setup TIM4 base configuration
// Mode: Up-counter
// Interrupts: counter overflow, Compare/Capture on channel 1
TIM4->CR1=TIM_CR1_URS;
TIM4->DIER=TIM_DIER_UIE | TIM_DIER_CC1IE;
NVIC_SetPriority(TIM4_IRQn,3); //High priority for TIM4 (Max=0, min=15)
NVIC_EnableIRQ(TIM4_IRQn);
// Configure channel 1 as:
// Output channel (CC1S=0)
// No preload(OC1PE=0), hence TIM4_CCR1 can be written at anytime
// No effect on the output signal on match (OC1M = 0)
TIM4->CCMR1 = 0;
TIM4->CCR1 = 0;
// TIM4 Operation Frequency Configuration: Max Freq. and longest period
// The global variable SystemCoreClock from ARM's CMSIS allows to know
// the CPU frequency.
unsigned int timerInputFreq=SystemCoreClock;
// The timer frequency may however be a submultiple of the CPU frequency,
// due to the bus at whch the periheral is connected being slower. The
// RCC->CFGR register tells us how slower the APB1 bus is running.
// This formula takes into account that if the APB1 clock is divided by a
// factor of two or greater, the timer is clocked at twice the bus
// interface. After this, the freq variable contains the frequency in Hz
// at which the timer prescaler is clocked.
if(RCC->CFGR & RCC_CFGR_PPRE1_2) timerInputFreq/=1<<((RCC->CFGR>>8) & 0x3);
//Handle the case when the prescribed timer frequency is not achievable.
//For now, we just enter an infinite loop so if someone selects an
//impossible frequency it won't go unnoticed during testing
if(timerInputFreq % timerFrequency)
{
IRQbootlog("Frequency error\r\n");
for(;;) ;
}
TIM4->PSC = (timerInputFreq/timerFrequency)-1;
TIM4->ARR = 0xFFFF;
TIM4->EGR = TIM_EGR_UG; //To enforce the timer to apply PSC
}
};
static STM32Timer4 timer;
DEFAULT_OS_TIMER_INTERFACE_IMPLMENTATION(timer);
} //namespace miosix
void __attribute__((naked)) TIM4_IRQHandler()
{
saveContext();
asm volatile ("bl _Z11osTimerImplv");
restoreContext();
}
void __attribute__((used)) osTimerImpl()
{
miosix::timer.IRQhandler();
}
/***************************************************************************
* Copyright (C) 2021 by Terraneo Federico *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "kernel/kernel.h"
#include "interfaces/os_timer.h"
#include "interfaces/arch_registers.h"
namespace miosix {
class STM32Timer5 : public TimerAdapter<STM32Timer5, 32>
{
public:
static inline unsigned int IRQgetTimerCounter() { return TIM5->CNT; }
static inline void IRQsetTimerCounter(unsigned int v) { TIM5->CNT=v; }
static inline unsigned int IRQgetTimerMatchReg() { return TIM5->CCR1; }
static inline void IRQsetTimerMatchReg(unsigned int v) { TIM5->CCR1=v; }
static inline bool IRQgetOverflowFlag() { return TIM5->SR & TIM_SR_UIF; }
static inline void IRQclearOverflowFlag() { TIM5->SR = ~TIM_SR_UIF; }
static inline bool IRQgetMatchFlag() { return TIM5->SR & TIM_SR_CC1IF; }
static inline void IRQclearMatchFlag() { TIM5->SR = ~TIM_SR_CC1IF; }
static inline void IRQforcePendingIrq() { NVIC_SetPendingIRQ(TIM5_IRQn); }
static inline void IRQstopTimer() { TIM5->CR1 &= ~TIM_CR1_CEN; }
static inline void IRQstartTimer() { TIM5->CR1 |= TIM_CR1_CEN; }
static unsigned int IRQTimerFrequency()
{
// The global variable SystemCoreClock from ARM's CMSIS allows to know
// the CPU frequency.
unsigned int result=SystemCoreClock;
// The timer frequency may however be a submultiple of the CPU frequency,
// due to the bus at whch the periheral is connected being slower. The
// RCC->CFGR register tells us how slower the APB1 bus is running.
// This formula takes into account that if the APB1 clock is divided by a
// factor of two or greater, the timer is clocked at twice the bus
// interface. After this, the freq variable contains the frequency in Hz
// at which the timer prescaler is clocked.
#if defined(_ARCH_CORTEXM7_STM32H7)
if(RCC->D2CFGR & RCC_D2CFGR_D2PPRE1_2) result/=1<<((RCC->D2CFGR>>4) & 0x3);
#else
if(RCC->CFGR & RCC_CFGR_PPRE1_2) result/=1<<((RCC->CFGR>>10) & 0x3);
#endif
return result;
}
static void IRQinitTimer()
{
#if defined(_ARCH_CORTEXM7_STM32H7)
RCC->APB1LENR |= RCC_APB1LENR_TIM5EN;
RCC_SYNC();
DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM5; //Stop while debugging
#elif defined(_ARCH_CORTEXM4_STM32L4)
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM5EN;
RCC_SYNC();
DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM5_STOP; //Stop while debugging
#else
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
RCC_SYNC();
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP; //Stop while debugging
#endif
// Setup TIM5 base configuration
// Mode: Up-counter
// Interrupts: counter overflow, Compare/Capture on channel 1
TIM5->CR1=TIM_CR1_URS;
TIM5->DIER=TIM_DIER_UIE | TIM_DIER_CC1IE;
NVIC_SetPriority(TIM5_IRQn,3); //High priority for TIM5 (Max=0, min=15)
NVIC_EnableIRQ(TIM5_IRQn);
// Configure channel 1 as:
// Output channel (CC1S=0)
// No preload(OC1PE=0), hence TIM5_CCR1 can be written at anytime
// No effect on the output signal on match (OC1M = 0)
TIM5->CCMR1 = 0;
TIM5->CCR1 = 0;
// TIM5 Operation Frequency Configuration: Max Freq. and longest period
TIM5->PSC = 0;
TIM5->ARR = 0xFFFFFFFF;
TIM5->EGR = TIM_EGR_UG; //To enforce the timer to apply PSC
}
};
static STM32Timer5 timer;
DEFAULT_OS_TIMER_INTERFACE_IMPLMENTATION(timer);
} //namespace miosix
void __attribute__((naked)) TIM5_IRQHandler()
{
saveContext();
asm volatile ("bl _Z11osTimerImplv");
restoreContext();
}
void __attribute__((used)) osTimerImpl()
{
miosix::timer.IRQhandler();
}
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> * * along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/ ***************************************************************************/
#include "sd_stm32f2_f4.h" #include "sd_stm32f2_f4_f7.h"
#include "interfaces/bsp.h" #include "interfaces/bsp.h"
#include "interfaces/arch_registers.h" #include "interfaces/arch_registers.h"
#include "core/cache_cortexMx.h" #include "core/cache_cortexMx.h"
...@@ -52,9 +52,17 @@ ...@@ -52,9 +52,17 @@
*/ */
#if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7) #if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
#if SD_SDMMC==1
#define SDIO SDMMC1 #define SDIO SDMMC1
#define RCC_APB2ENR_SDIOEN RCC_APB2ENR_SDMMC1EN #define RCC_APB2ENR_SDIOEN RCC_APB2ENR_SDMMC1EN
#define SDIO_IRQn SDMMC1_IRQn #define SDIO_IRQn SDMMC1_IRQn
#elif SD_SDMMC==2
#define SDIO SDMMC2
#define RCC_APB2ENR_SDIOEN RCC_APB2ENR_SDMMC2EN
#define SDIO_IRQn SDMMC2_IRQn
#else
#error SD_SDMMC undefined or not in range
#endif
#define SDIO_STA_STBITERR 0 //This bit has been removed #define SDIO_STA_STBITERR 0 //This bit has been removed
#define SDIO_STA_RXOVERR SDMMC_STA_RXOVERR #define SDIO_STA_RXOVERR SDMMC_STA_RXOVERR
...@@ -76,6 +84,7 @@ ...@@ -76,6 +84,7 @@
#define SDIO_CLKCR_CLKEN SDMMC_CLKCR_CLKEN #define SDIO_CLKCR_CLKEN SDMMC_CLKCR_CLKEN
#define SDIO_CLKCR_PWRSAV SDMMC_CLKCR_PWRSAV #define SDIO_CLKCR_PWRSAV SDMMC_CLKCR_PWRSAV
#define SDIO_CLKCR_PWRSAV SDMMC_CLKCR_PWRSAV #define SDIO_CLKCR_PWRSAV SDMMC_CLKCR_PWRSAV
#define SDIO_CLKCR_WIDBUS_0 SDMMC_CLKCR_WIDBUS_0
#define SDIO_MASK_STBITERRIE 0 //This bit has been removed #define SDIO_MASK_STBITERRIE 0 //This bit has been removed
#define SDIO_MASK_RXOVERRIE SDMMC_MASK_RXOVERRIE #define SDIO_MASK_RXOVERRIE SDMMC_MASK_RXOVERRIE
...@@ -91,16 +100,32 @@ ...@@ -91,16 +100,32 @@
#define SDIO_POWER_PWRCTRL_1 SDMMC_POWER_PWRCTRL_1 #define SDIO_POWER_PWRCTRL_1 SDMMC_POWER_PWRCTRL_1
#define SDIO_POWER_PWRCTRL_0 SDMMC_POWER_PWRCTRL_0 #define SDIO_POWER_PWRCTRL_0 SDMMC_POWER_PWRCTRL_0
constexpr int ICR_FLAGS_CLR=0x5ff;
#else //defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
constexpr int ICR_FLAGS_CLR=0x7ff;
#endif //defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7) #endif //defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
#define DMA_Stream DMA2_Stream0
#else
#define DMA_Stream DMA2_Stream3
#endif
/** /**
* \internal * \internal
* DMA2 Stream3 interrupt handler * DMA2 Stream interrupt handler
*/ */
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
void __attribute__((naked)) DMA2_Stream0_IRQHandler()
#else
void __attribute__((naked)) DMA2_Stream3_IRQHandler() void __attribute__((naked)) DMA2_Stream3_IRQHandler()
#endif
{ {
saveContext(); saveContext();
asm volatile("bl _ZN6miosix18DMA2stream3irqImplEv"); asm volatile("bl _ZN6miosix12SDDMAirqImplEv");
restoreContext(); restoreContext();
} }
...@@ -108,14 +133,16 @@ void __attribute__((naked)) DMA2_Stream3_IRQHandler() ...@@ -108,14 +133,16 @@ void __attribute__((naked)) DMA2_Stream3_IRQHandler()
* \internal * \internal
* SDIO interrupt handler * SDIO interrupt handler
*/ */
#if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7) #if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==1
void __attribute__((naked)) SDMMC1_IRQHandler() void __attribute__((naked)) SDMMC1_IRQHandler()
#elif (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
void __attribute__((naked)) SDMMC2_IRQHandler()
#else //stm32f2 and stm32f4 #else //stm32f2 and stm32f4
void __attribute__((naked)) SDIO_IRQHandler() void __attribute__((naked)) SDIO_IRQHandler()
#endif #endif
{ {
saveContext(); saveContext();
asm volatile("bl _ZN6miosix11SDIOirqImplEv"); asm volatile("bl _ZN6miosix9SDirqImplEv");
restoreContext(); restoreContext();
} }
...@@ -130,16 +157,26 @@ static unsigned int sdioFlags; ///< \internal SDIO status flags ...@@ -130,16 +157,26 @@ static unsigned int sdioFlags; ///< \internal SDIO status flags
* \internal * \internal
* DMA2 Stream3 interrupt handler actual implementation * DMA2 Stream3 interrupt handler actual implementation
*/ */
void __attribute__((used)) DMA2stream3irqImpl() void __attribute__((used)) SDDMAirqImpl()
{ {
dmaFlags=DMA2->LISR; dmaFlags=DMA2->LISR;
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
if(dmaFlags & (DMA_LISR_TEIF0 | DMA_LISR_DMEIF0 | DMA_LISR_FEIF0))
transferError=true;
DMA2->LIFCR = DMA_LIFCR_CTCIF0
| DMA_LIFCR_CTEIF0
| DMA_LIFCR_CDMEIF0
| DMA_LIFCR_CFEIF0;
#else
if(dmaFlags & (DMA_LISR_TEIF3 | DMA_LISR_DMEIF3 | DMA_LISR_FEIF3)) if(dmaFlags & (DMA_LISR_TEIF3 | DMA_LISR_DMEIF3 | DMA_LISR_FEIF3))
transferError=true; transferError=true;
DMA2->LIFCR=DMA_LIFCR_CTCIF3 | DMA2->LIFCR = DMA_LIFCR_CTCIF3
DMA_LIFCR_CTEIF3 | | DMA_LIFCR_CTEIF3
DMA_LIFCR_CDMEIF3 | | DMA_LIFCR_CDMEIF3
DMA_LIFCR_CFEIF3; | DMA_LIFCR_CFEIF3;
#endif
if(!waiting) return; if(!waiting) return;
waiting->IRQwakeup(); waiting->IRQwakeup();
...@@ -152,14 +189,14 @@ void __attribute__((used)) DMA2stream3irqImpl() ...@@ -152,14 +189,14 @@ void __attribute__((used)) DMA2stream3irqImpl()
* \internal * \internal
* DMA2 Stream3 interrupt handler actual implementation * DMA2 Stream3 interrupt handler actual implementation
*/ */
void __attribute__((used)) SDIOirqImpl() void __attribute__((used)) SDirqImpl()
{ {
sdioFlags=SDIO->STA; sdioFlags=SDIO->STA;
if(sdioFlags & (SDIO_STA_STBITERR | SDIO_STA_RXOVERR | if(sdioFlags & (SDIO_STA_STBITERR | SDIO_STA_RXOVERR |
SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL)) SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL))
transferError=true; transferError=true;
SDIO->ICR=0x7ff;//Clear flags SDIO->ICR=ICR_FLAGS_CLR; //Clear flags
if(!waiting) return; if(!waiting) return;
waiting->IRQwakeup(); waiting->IRQwakeup();
...@@ -193,12 +230,22 @@ enum CardType ...@@ -193,12 +230,22 @@ enum CardType
static CardType cardType=Invalid; static CardType cardType=Invalid;
//SD card GPIOs //SD card GPIOs
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
typedef Gpio<GPIOG_BASE,9> sdD0;
typedef Gpio<GPIOG_BASE,10> sdD1;
typedef Gpio<GPIOB_BASE,3> sdD2;
typedef Gpio<GPIOB_BASE,4> sdD3;
typedef Gpio<GPIOD_BASE,6> sdCLK;
typedef Gpio<GPIOD_BASE,7> sdCMD;
#else
typedef Gpio<GPIOC_BASE,8> sdD0; typedef Gpio<GPIOC_BASE,8> sdD0;
typedef Gpio<GPIOC_BASE,9> sdD1; typedef Gpio<GPIOC_BASE,9> sdD1;
typedef Gpio<GPIOC_BASE,10> sdD2; typedef Gpio<GPIOC_BASE,10> sdD2;
typedef Gpio<GPIOC_BASE,11> sdD3; typedef Gpio<GPIOC_BASE,11> sdD3;
typedef Gpio<GPIOC_BASE,12> sdCLK; typedef Gpio<GPIOC_BASE,12> sdCLK;
typedef Gpio<GPIOD_BASE,2> sdCMD; typedef Gpio<GPIOD_BASE,2> sdCMD;
#endif
// //
// Class BufferConverter // Class BufferConverter
...@@ -631,12 +678,12 @@ CmdResult Command::send(CommandType cmd, unsigned int arg) ...@@ -631,12 +678,12 @@ CmdResult Command::send(CommandType cmd, unsigned int arg)
{ {
if(SDIO->STA & SDIO_STA_CMDSENT) if(SDIO->STA & SDIO_STA_CMDSENT)
{ {
SDIO->ICR=0x7ff;//Clear flags SDIO->ICR=ICR_FLAGS_CLR;//Clear flags
return CmdResult(cc,CmdResult::Ok); return CmdResult(cc,CmdResult::Ok);
} }
delayUs(1); delayUs(1);
} }
SDIO->ICR=0x7ff;//Clear flags SDIO->ICR=ICR_FLAGS_CLR;//Clear flags
return CmdResult(cc,CmdResult::Timeout); return CmdResult(cc,CmdResult::Timeout);
} }
...@@ -646,7 +693,7 @@ CmdResult Command::send(CommandType cmd, unsigned int arg) ...@@ -646,7 +693,7 @@ CmdResult Command::send(CommandType cmd, unsigned int arg)
unsigned int status=SDIO->STA; unsigned int status=SDIO->STA;
if(status & SDIO_STA_CMDREND) if(status & SDIO_STA_CMDREND)
{ {
SDIO->ICR=0x7ff;//Clear flags SDIO->ICR=ICR_FLAGS_CLR;//Clear flags
if(SDIO->RESPCMD==cc) return CmdResult(cc,CmdResult::Ok); if(SDIO->RESPCMD==cc) return CmdResult(cc,CmdResult::Ok);
else return CmdResult(cc,CmdResult::RespNotMatch); else return CmdResult(cc,CmdResult::RespNotMatch);
} }
...@@ -754,7 +801,7 @@ private: ...@@ -754,7 +801,7 @@ private:
#endif //SD_ONE_BIT_DATABUS #endif //SD_ONE_BIT_DATABUS
///\internal Maximum number of calls to IRQreduceClockSpeed() allowed ///\internal Maximum number of calls to IRQreduceClockSpeed() allowed
static const unsigned char MAX_ALLOWED_REDUCTIONS=1; static const unsigned char MAX_ALLOWED_REDUCTIONS=5;
///\internal value returned by getRetryCount() while *not* calibrating clock. ///\internal value returned by getRetryCount() while *not* calibrating clock.
static const unsigned char MAX_RETRY=10; static const unsigned char MAX_RETRY=10;
...@@ -768,6 +815,10 @@ private: ...@@ -768,6 +815,10 @@ private:
void ClockController::calibrateClockSpeed(SDIODriver *sdio) void ClockController::calibrateClockSpeed(SDIODriver *sdio)
{ {
#ifdef SD_DIVIDER
// The frequency will be divided by a factor of SD_DIVIDER + 2
setClockSpeed(SD_DIVIDER);
#else
//During calibration we call readBlock() which will call reduceClockSpeed() //During calibration we call readBlock() which will call reduceClockSpeed()
//so not to invalidate calibration clock reduction must not be available //so not to invalidate calibration clock reduction must not be available
clockReductionAvailable=0; clockReductionAvailable=0;
...@@ -796,6 +847,7 @@ void ClockController::calibrateClockSpeed(SDIODriver *sdio) ...@@ -796,6 +847,7 @@ void ClockController::calibrateClockSpeed(SDIODriver *sdio)
setClockSpeed(minFreq); setClockSpeed(minFreq);
DBG("Optimal CLKCR=%d\n",minFreq); DBG("Optimal CLKCR=%d\n",minFreq);
} }
#endif
//Make clock reduction available //Make clock reduction available
clockReductionAvailable=MAX_ALLOWED_REDUCTIONS; clockReductionAvailable=MAX_ALLOWED_REDUCTIONS;
...@@ -884,11 +936,18 @@ static void displayBlockTransferError() ...@@ -884,11 +936,18 @@ static void displayBlockTransferError()
static unsigned int dmaTransferCommonSetup(const unsigned char *buffer) static unsigned int dmaTransferCommonSetup(const unsigned char *buffer)
{ {
//Clear both SDIO and DMA interrupt flags //Clear both SDIO and DMA interrupt flags
SDIO->ICR=0x7ff; SDIO->ICR=ICR_FLAGS_CLR;
DMA2->LIFCR=DMA_LIFCR_CTCIF3 | #if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
DMA_LIFCR_CTEIF3 | DMA2->LIFCR = DMA_LIFCR_CTCIF0
DMA_LIFCR_CDMEIF3 | | DMA_LIFCR_CTEIF0
DMA_LIFCR_CFEIF3; | DMA_LIFCR_CDMEIF0
| DMA_LIFCR_CFEIF0;
#else
DMA2->LIFCR = DMA_LIFCR_CTCIF3
| DMA_LIFCR_CTEIF3
| DMA_LIFCR_CDMEIF3
| DMA_LIFCR_CFEIF3;
#endif
transferError=false; transferError=false;
dmaFlags=sdioFlags=0; dmaFlags=sdioFlags=0;
...@@ -937,24 +996,28 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk, ...@@ -937,24 +996,28 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk,
SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun
SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail
SDIO_MASK_DTIMEOUTIE; //Interrupt on data timeout SDIO_MASK_DTIMEOUTIE; //Interrupt on data timeout
DMA2_Stream3->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO); DMA_Stream->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
DMA2_Stream3->M0AR=reinterpret_cast<unsigned int>(buffer); DMA_Stream->M0AR=reinterpret_cast<unsigned int>(buffer);
//Note: DMA2_Stream3->NDTR is don't care in peripheral flow control mode //Note: DMA_Stream->NDTR is don't care in peripheral flow control mode
DMA2_Stream3->FCR=DMA_SxFCR_FEIE | //Interrupt on fifo error DMA_Stream->FCR = DMA_SxFCR_FEIE //Interrupt on fifo error
DMA_SxFCR_DMDIS | //Fifo enabled | DMA_SxFCR_DMDIS //Fifo enabled
DMA_SxFCR_FTH_0; //Take action if fifo half full | DMA_SxFCR_FTH_0; //Take action if fifo half full
DMA2_Stream3->CR=DMA_SxCR_CHSEL_2 | //Channel 4 (SDIO) #if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
DMA_SxCR_PBURST_0 | //4-beat bursts read from SDIO DMA_Stream->CR = (11 << DMA_SxCR_CHSEL_Pos) //Channel 4 (SDIO)
DMA_SxCR_PL_0 | //Medium priority DMA stream #else
memoryTransferSize | //RAM data size depends on alignment DMA_Stream->CR = DMA_SxCR_CHSEL_2 //Channel 4 (SDIO)
DMA_SxCR_PSIZE_1 | //Read 32bit at a time from SDIO #endif
DMA_SxCR_MINC | //Increment RAM pointer | DMA_SxCR_PBURST_0 //4-beat bursts read from SDIO
0 | //Peripheral to memory direction | DMA_SxCR_PL_0 //Medium priority DMA stream
DMA_SxCR_PFCTRL | //Peripheral is flow controller | memoryTransferSize //RAM data size depends on alignment
DMA_SxCR_TCIE | //Interrupt on transfer complete | DMA_SxCR_PSIZE_1 //Read 32bit at a time from SDIO
DMA_SxCR_TEIE | //Interrupt on transfer error | DMA_SxCR_MINC //Increment RAM pointer
DMA_SxCR_DMEIE | //Interrupt on direct mode error | 0 //Peripheral to memory direction
DMA_SxCR_EN; //Start the DMA | DMA_SxCR_PFCTRL //Peripheral is flow controller
| DMA_SxCR_TCIE //Interrupt on transfer complete
| DMA_SxCR_TEIE //Interrupt on transfer error
| DMA_SxCR_DMEIE //Interrupt on direct mode error
| DMA_SxCR_EN; //Start the DMA
SDIO->DLEN=nblk*512; SDIO->DLEN=nblk*512;
if(waiting==0) if(waiting==0)
...@@ -977,8 +1040,8 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk, ...@@ -977,8 +1040,8 @@ static bool multipleBlockRead(unsigned char *buffer, unsigned int nblk,
} }
} }
} else transferError=true; } else transferError=true;
DMA2_Stream3->CR=0; DMA_Stream->CR=0;
while(DMA2_Stream3->CR & DMA_SxCR_EN) ; //DMA may take time to stop while(DMA_Stream->CR & DMA_SxCR_EN) ; //DMA may take time to stop
SDIO->DCTRL=0; //Disable data path state machine SDIO->DCTRL=0; //Disable data path state machine
SDIO->MASK=0; SDIO->MASK=0;
...@@ -1040,26 +1103,30 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk, ...@@ -1040,26 +1103,30 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk,
SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun SDIO_MASK_TXUNDERRIE | //Interrupt on tx underrun
SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail SDIO_MASK_DCRCFAILIE | //Interrupt on data CRC fail
SDIO_MASK_DTIMEOUTIE; //Interrupt on data timeout SDIO_MASK_DTIMEOUTIE; //Interrupt on data timeout
DMA2_Stream3->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO); DMA_Stream->PAR=reinterpret_cast<unsigned int>(&SDIO->FIFO);
DMA2_Stream3->M0AR=reinterpret_cast<unsigned int>(buffer); DMA_Stream->M0AR=reinterpret_cast<unsigned int>(buffer);
//Note: DMA2_Stream3->NDTR is don't care in peripheral flow control mode //Note: DMA_Stream->NDTR is don't care in peripheral flow control mode
//Quirk: not enabling DMA_SxFCR_FEIE because the SDIO seems to generate //Quirk: not enabling DMA_SxFCR_FEIE because the SDIO seems to generate
//a spurious fifo error. The code was tested and the transfer completes //a spurious fifo error. The code was tested and the transfer completes
//successfully even in the presence of this fifo error //successfully even in the presence of this fifo error
DMA2_Stream3->FCR=DMA_SxFCR_DMDIS | //Fifo enabled DMA_Stream->FCR = DMA_SxFCR_DMDIS //Fifo enabled
DMA_SxFCR_FTH_1 | //Take action if fifo full | DMA_SxFCR_FTH_1 //Take action if fifo full
DMA_SxFCR_FTH_0; | DMA_SxFCR_FTH_0;
DMA2_Stream3->CR=DMA_SxCR_CHSEL_2 | //Channel 4 (SDIO) #if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
DMA_SxCR_PBURST_0 | //4-beat bursts write to SDIO DMA_Stream->CR = (11 << DMA_SxCR_CHSEL_Pos) // Channel 4 (SDIO)
DMA_SxCR_PL_0 | //Medium priority DMA stream #else
memoryTransferSize | //RAM data size depends on alignment DMA_Stream->CR = DMA_SxCR_CHSEL_2 // Channel 4 (SDIO)
DMA_SxCR_PSIZE_1 | //Write 32bit at a time to SDIO #endif
DMA_SxCR_MINC | //Increment RAM pointer | DMA_SxCR_PBURST_0 //4-beat bursts write to SDIO
DMA_SxCR_DIR_0 | //Memory to peripheral direction | DMA_SxCR_PL_0 //Medium priority DMA stream
DMA_SxCR_PFCTRL | //Peripheral is flow controller | memoryTransferSize //RAM data size depends on alignment
DMA_SxCR_TEIE | //Interrupt on transfer error | DMA_SxCR_PSIZE_1 //Write 32bit at a time to SDIO
DMA_SxCR_DMEIE | //Interrupt on direct mode error | DMA_SxCR_MINC //Increment RAM pointer
DMA_SxCR_EN; //Start the DMA | DMA_SxCR_DIR_0 //Memory to peripheral direction
| DMA_SxCR_PFCTRL //Peripheral is flow controller
| DMA_SxCR_TEIE //Interrupt on transfer error
| DMA_SxCR_DMEIE //Interrupt on direct mode error
| DMA_SxCR_EN; //Start the DMA
SDIO->DLEN=nblk*512; SDIO->DLEN=nblk*512;
if(waiting==0) if(waiting==0)
...@@ -1082,8 +1149,8 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk, ...@@ -1082,8 +1149,8 @@ static bool multipleBlockWrite(const unsigned char *buffer, unsigned int nblk,
} }
} }
} else transferError=true; } else transferError=true;
DMA2_Stream3->CR=0; DMA_Stream->CR=0;
while(DMA2_Stream3->CR & DMA_SxCR_EN) ; //DMA may take time to stop while(DMA_Stream->CR & DMA_SxCR_EN) ; //DMA may take time to stop
SDIO->DCTRL=0; //Disable data path state machine SDIO->DCTRL=0; //Disable data path state machine
SDIO->MASK=0; SDIO->MASK=0;
...@@ -1161,6 +1228,22 @@ static void initSDIOPeripheral() ...@@ -1161,6 +1228,22 @@ static void initSDIOPeripheral()
RCC_SYNC(); RCC_SYNC();
RCC->APB2ENR |= RCC_APB2ENR_SDIOEN; RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
RCC_SYNC(); RCC_SYNC();
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
sdD0::mode(Mode::ALTERNATE);
sdD0::alternateFunction(11);
#ifndef SD_ONE_BIT_DATABUS
sdD1::mode(Mode::ALTERNATE);
sdD1::alternateFunction(11);
sdD2::mode(Mode::ALTERNATE);
sdD2::alternateFunction(10);
sdD3::mode(Mode::ALTERNATE);
sdD3::alternateFunction(10);
#endif // SD_ONE_BIT_DATABUS
sdCLK::mode(Mode::ALTERNATE);
sdCLK::alternateFunction(11);
sdCMD::mode(Mode::ALTERNATE);
sdCMD::alternateFunction(11);
#else
sdD0::mode(Mode::ALTERNATE); sdD0::mode(Mode::ALTERNATE);
sdD0::alternateFunction(12); sdD0::alternateFunction(12);
#ifndef SD_ONE_BIT_DATABUS #ifndef SD_ONE_BIT_DATABUS
...@@ -1175,9 +1258,16 @@ static void initSDIOPeripheral() ...@@ -1175,9 +1258,16 @@ static void initSDIOPeripheral()
sdCLK::alternateFunction(12); sdCLK::alternateFunction(12);
sdCMD::mode(Mode::ALTERNATE); sdCMD::mode(Mode::ALTERNATE);
sdCMD::alternateFunction(12); sdCMD::alternateFunction(12);
#endif
} }
#if (defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)) && SD_SDMMC==2
NVIC_SetPriority(DMA2_Stream0_IRQn,15);//Low priority for DMA
NVIC_EnableIRQ(DMA2_Stream0_IRQn);
#else
NVIC_SetPriority(DMA2_Stream3_IRQn,15);//Low priority for DMA NVIC_SetPriority(DMA2_Stream3_IRQn,15);//Low priority for DMA
NVIC_EnableIRQ(DMA2_Stream3_IRQn); NVIC_EnableIRQ(DMA2_Stream3_IRQn);
#endif
NVIC_SetPriority(SDIO_IRQn,15);//Low priority for SDIO NVIC_SetPriority(SDIO_IRQn,15);//Low priority for SDIO
NVIC_EnableIRQ(SDIO_IRQn); NVIC_EnableIRQ(SDIO_IRQn);
...@@ -1186,7 +1276,11 @@ static void initSDIOPeripheral() ...@@ -1186,7 +1276,11 @@ static void initSDIOPeripheral()
SDIO->CLKCR=0; SDIO->CLKCR=0;
SDIO->CMD=0; SDIO->CMD=0;
SDIO->DCTRL=0; SDIO->DCTRL=0;
#if defined(_ARCH_CORTEXM7_STM32F7) || defined(_ARCH_CORTEXM7_STM32H7)
SDIO->ICR=0x4005ff;
#else
SDIO->ICR=0xc007ff; SDIO->ICR=0xc007ff;
#endif
SDIO->POWER=SDIO_POWER_PWRCTRL_1 | SDIO_POWER_PWRCTRL_0; //Power on state SDIO->POWER=SDIO_POWER_PWRCTRL_1 | SDIO_POWER_PWRCTRL_0; //Power on state
//This delay is particularly important: when setting the POWER register a //This delay is particularly important: when setting the POWER register a
//glitch on the CMD pin happens. This glitch has a fast fall time and a slow //glitch on the CMD pin happens. This glitch has a fast fall time and a slow
......
This diff is collapsed.
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#ifdef _ARCH_ARM7_LPC2000 #ifdef _ARCH_ARM7_LPC2000
#include "serial_lpc2000.h" #include "serial_lpc2000.h"
#elif defined(_ARCH_CORTEXM0_STM32) || defined(_ARCH_CORTEXM3_STM32) \ #elif defined(_ARCH_CORTEXM0_STM32F0) || defined(_ARCH_CORTEXM3_STM32F1) \
|| defined(_ARCH_CORTEXM4_STM32F4) || defined(_ARCH_CORTEXM3_STM32F2) \ || defined(_ARCH_CORTEXM4_STM32F4) || defined(_ARCH_CORTEXM3_STM32F2) \
|| defined(_ARCH_CORTEXM3_STM32L1) || defined(_ARCH_CORTEXM7_STM32F7) \ || defined(_ARCH_CORTEXM3_STM32L1) || defined(_ARCH_CORTEXM7_STM32F7) \
|| defined(_ARCH_CORTEXM7_STM32H7) || defined(_ARCH_CORTEXM4_STM32F3) \ || defined(_ARCH_CORTEXM7_STM32H7) || defined(_ARCH_CORTEXM4_STM32F3) \
......
...@@ -83,7 +83,7 @@ ATSAMSerial::ATSAMSerial(int id, int baudrate) ...@@ -83,7 +83,7 @@ ATSAMSerial::ATSAMSerial(int id, int baudrate)
port=USART2; port=USART2;
//TODO: USART2 hardcoded //TODO: USART2 hardcoded
PM->PM_UNLOCK=0xaa<<24 | PM_PBAMASK_OFFSET; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(PM_PBAMASK_OFFSET);
PM->PM_PBAMASK |= PM_PBAMASK_USART2; PM->PM_PBAMASK |= PM_PBAMASK_USART2;
NVIC_SetPriority(USART2_IRQn,15);//Lowest priority for serial NVIC_SetPriority(USART2_IRQn,15);//Lowest priority for serial
NVIC_EnableIRQ(USART2_IRQn); NVIC_EnableIRQ(USART2_IRQn);
...@@ -233,7 +233,7 @@ ATSAMSerial::~ATSAMSerial() ...@@ -233,7 +233,7 @@ ATSAMSerial::~ATSAMSerial()
//TODO: USART2 hardcoded //TODO: USART2 hardcoded
NVIC_DisableIRQ(USART2_IRQn); NVIC_DisableIRQ(USART2_IRQn);
NVIC_ClearPendingIRQ(USART2_IRQn); NVIC_ClearPendingIRQ(USART2_IRQn);
PM->PM_UNLOCK=0xaa<<24 | PM_PBAMASK_OFFSET; PM->PM_UNLOCK = PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(PM_PBAMASK_OFFSET);
PM->PM_PBAMASK &= ~PM_PBAMASK_USART2; PM->PM_PBAMASK &= ~PM_PBAMASK_USART2;
} }
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "filesystem/console/console_device.h" #include "filesystem/console/console_device.h"
#include "kernel/sync.h" #include "kernel/sync.h"
#include "kernel/queue.h" #include "kernel/queue.h"
#include "board_settings.h"
namespace miosix { namespace miosix {
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "filesystem/console/console_device.h" #include "filesystem/console/console_device.h"
#include "kernel/sync.h" #include "kernel/sync.h"
#include "kernel/queue.h" #include "kernel/queue.h"
#include "board_settings.h"
namespace miosix { namespace miosix {
......
...@@ -171,8 +171,9 @@ private: ...@@ -171,8 +171,9 @@ private:
FastMutex txMutex;///< Mutex used to guard the tx queue FastMutex txMutex;///< Mutex used to guard the tx queue
FastMutex rxMutex;///< Mutex used to guard the rx queue FastMutex rxMutex;///< Mutex used to guard the rx queue
Queue<char,swTxQueue> txQueue;///< Tx software queue DynUnsyncQueue<char> txQueue;///< Rx software queue
DynUnsyncQueue<char> rxQueue;///< Rx software queue DynUnsyncQueue<char> rxQueue;///< Rx software queue
Thread *txWaiting; ///< Thread waiting on rx queue
Thread *rxWaiting; ///< Thread waiting on rx queue Thread *rxWaiting; ///< Thread waiting on rx queue
bool idle; ///< Receiver idle bool idle; ///< Receiver idle
......
This diff is collapsed.
This diff is collapsed.
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> * * along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/ ***************************************************************************/
#include "board_settings.h"
#include "stm32_sgm.h" #include "stm32_sgm.h"
#include <string.h> #include <string.h>
#include "miosix.h" #include "miosix.h"
......