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 2184 additions and 198 deletions
......@@ -99,20 +99,20 @@ void __attribute__((noinline)) HardFault_impl()
#ifdef WITH_ERRLOG
IRQerrorLog("\r\n***Unexpected HardFault @ ");
printUnsignedInt(getProgramCounter());
#ifndef _ARCH_CORTEXM0
#if !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM0_STM32G0) && !defined(_ARCH_CORTEXM0_STM32L0)
unsigned int hfsr=SCB->HFSR;
if(hfsr & 0x40000000) //SCB_HFSR_FORCED
IRQerrorLog("Fault escalation occurred\r\n");
if(hfsr & 0x00000002) //SCB_HFSR_VECTTBL
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
miosix_private::IRQsystemReboot();
}
// Cortex M0/M0+ architecture does not have the interrupts handled by code
// below this point
#ifndef _ARCH_CORTEXM0
#if !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM0_STM32G0) && !defined(_ARCH_CORTEXM0_STM32L0)
void __attribute__((naked)) MemManage_Handler()
{
......@@ -262,7 +262,7 @@ void DebugMon_Handler()
miosix_private::IRQsystemReboot();
}
#endif //_ARCH_CORTEXM0
#endif // !_ARCH_CORTEXM0_STM32F0 && !_ARCH_CORTEXM0_STM32G0 && !_ARCH_CORTEXM0_STM32L0
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();
}
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2014 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/> *
***************************************************************************/
#ifndef SD_STM32L4_H
#define SD_STM32L4_H
#include "kernel/sync.h"
#include "filesystem/devfs/devfs.h"
#include "filesystem/ioctl.h"
namespace miosix {
/**
* Driver for the SDIO peripheral in STM32F2 and F4 microcontrollers
*/
class SDIODriver : public Device
{
public:
/**
* \return an instance to this class, singleton
*/
static intrusive_ref_ptr<SDIODriver> instance();
virtual ssize_t readBlock(void *buffer, size_t size, off_t where);
virtual ssize_t writeBlock(const void *buffer, size_t size, off_t where);
virtual int ioctl(int cmd, void *arg);
private:
/**
* Constructor
*/
SDIODriver();
FastMutex mutex;
};
} //namespace miosix
#endif //SD_STM32L4_H
\ No newline at end of file
......@@ -3,7 +3,7 @@
#ifdef _ARCH_ARM7_LPC2000
#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_CORTEXM3_STM32L1) || defined(_ARCH_CORTEXM7_STM32F7) \
|| defined(_ARCH_CORTEXM7_STM32H7) || defined(_ARCH_CORTEXM4_STM32F3) \
......
......@@ -83,7 +83,7 @@ ATSAMSerial::ATSAMSerial(int id, int baudrate)
port=USART2;
//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;
NVIC_SetPriority(USART2_IRQn,15);//Lowest priority for serial
NVIC_EnableIRQ(USART2_IRQn);
......@@ -233,7 +233,7 @@ ATSAMSerial::~ATSAMSerial()
//TODO: USART2 hardcoded
NVIC_DisableIRQ(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;
}
......
......@@ -30,7 +30,6 @@
#include "filesystem/console/console_device.h"
#include "kernel/sync.h"
#include "kernel/queue.h"
#include "board_settings.h"
namespace miosix {
......
......@@ -31,7 +31,6 @@
#include "filesystem/console/console_device.h"
#include "kernel/sync.h"
#include "kernel/queue.h"
#include "board_settings.h"
namespace miosix {
......
......@@ -87,7 +87,8 @@ void __attribute__ ((interrupt("IRQ"),naked)) usart1irq()
// 20ms of full data rate. In the 8N1 format one char is made of 10 bits.
// So (baudrate/10)*0.02=baudrate/500
LPC2000Serial::LPC2000Serial(int id, int baudrate) : Device(Device::TTY),
rxQueue(hwRxQueueLen+baudrate/500), rxWaiting(0), idle(true)
txQueue(swTxQueue), rxQueue(hwRxQueueLen+baudrate/500),
txWaiting(nullptr), rxWaiting(nullptr), idle(true)
{
InterruptDisableLock dLock;
if(id<0 || id>1 || ports[id]!=0) errorHandler(UNEXPECTED);
......@@ -177,13 +178,13 @@ ssize_t LPC2000Serial::writeBlock(const void *buffer, size_t size, off_t where)
if(len==0) break;
}
} else {
if(txQueue.IRQput(*buf)==true)
if(txQueue.tryPut(*buf))
{
buf++;
len--;
} else {
FastInterruptEnableLock eLock(dLock);
txQueue.waitUntilNotFull();
txWaiting=Thread::IRQgetCurrentThread();
while(txWaiting) Thread::IRQenableIrqAndWait(dLock);
}
}
}
......@@ -256,8 +257,14 @@ void LPC2000Serial::IRQhandleInterrupt()
case 0x2: //THRE
for(int i=0;i<hwTxQueueLen;i++)
{
//If software queue empty, stop
if(txQueue.IRQget(c,hppw)==false) break;
if(txWaiting)
{
txWaiting->IRQwakeup();
if(txWaiting->IRQgetPriority()>
Thread::IRQgetCurrentThread()->IRQgetPriority()) hppw=true;
txWaiting=nullptr;
}
if(txQueue.tryGet(c)==false) break; //If software queue empty, stop
serial->THR=c;
}
break;
......@@ -267,7 +274,7 @@ void LPC2000Serial::IRQhandleInterrupt()
rxWaiting->IRQwakeup();
if(rxWaiting->IRQgetPriority()>
Thread::IRQgetCurrentThread()->IRQgetPriority()) hppw=true;
rxWaiting=0;
rxWaiting=nullptr;
}
if(hppw) Scheduler::IRQfindNextThread();
}
......
......@@ -171,8 +171,9 @@ private:
FastMutex txMutex;///< Mutex used to guard the tx 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
Thread *txWaiting; ///< Thread waiting on rx queue
Thread *rxWaiting; ///< Thread waiting on rx queue
bool idle; ///< Receiver idle
......
......@@ -34,7 +34,7 @@
#include "interfaces/gpio.h"
#include "board_settings.h"
#if defined(_ARCH_CORTEXM3_STM32) && defined(__ENABLE_XRAM)
#if defined(_ARCH_CORTEXM3_STM32F1) && defined(__ENABLE_XRAM)
//Quirk: concurrent access to the FSMC from both core and DMA is broken in
//the stm32f1, so disable DMA mode if XRAM is enabled.
#undef SERIAL_1_DMA
......@@ -46,7 +46,7 @@
#define SERIAL_DMA
#endif
#if defined(SERIAL_DMA) && defined(_ARCH_CORTEXM0_STM32)
#if defined(SERIAL_DMA) && defined(_ARCH_CORTEXM0_STM32F0)
#undef SERIAL_1_DMA
#undef SERIAL_2_DMA
#undef SERIAL_3_DMA
......@@ -248,7 +248,7 @@ private:
void waitSerialTxFifoEmpty()
{
#if !defined(_ARCH_CORTEXM7_STM32F7) && !defined(_ARCH_CORTEXM7_STM32H7) \
&& !defined(_ARCH_CORTEXM0_STM32) && !defined(_ARCH_CORTEXM4_STM32F3) \
&& !defined(_ARCH_CORTEXM0_STM32F0) && !defined(_ARCH_CORTEXM4_STM32F3) \
&& !defined(_ARCH_CORTEXM4_STM32L4)
while((port->SR & USART_SR_TC)==0) ;
#else //_ARCH_CORTEXM7_STM32F7/H7
......@@ -265,14 +265,14 @@ private:
USART_TypeDef *port; ///< Pointer to USART peripheral
#ifdef SERIAL_DMA
#if defined(_ARCH_CORTEXM3_STM32) || defined(_ARCH_CORTEXM4_STM32F3) \
#if defined(_ARCH_CORTEXM3_STM32F1) || defined(_ARCH_CORTEXM4_STM32F3) \
|| defined(_ARCH_CORTEXM4_STM32L4)
DMA_Channel_TypeDef *dmaTx; ///< Pointer to DMA TX peripheral
DMA_Channel_TypeDef *dmaRx; ///< Pointer to DMA RX peripheral
#else //_ARCH_CORTEXM3_STM32 and _ARCH_CORTEXM4_STM32F3
#else //_ARCH_CORTEXM3_STM32F1 and _ARCH_CORTEXM4_STM32F3
DMA_Stream_TypeDef *dmaTx; ///< Pointer to DMA TX peripheral
DMA_Stream_TypeDef *dmaRx; ///< Pointer to DMA RX peripheral
#endif //_ARCH_CORTEXM3_STM32 and _ARCH_CORTEXM4_STM32F3
#endif //_ARCH_CORTEXM3_STM32F1 and _ARCH_CORTEXM4_STM32F3
Thread *txWaiting; ///< Thread waiting for tx, or 0
static const unsigned int txBufferSize=16; ///< Size of tx buffer, for tx speedup
/// Tx buffer, for tx speedup. This buffer must not end up in the CCM of the
......
......@@ -96,33 +96,33 @@ void SynchronizedServo::enable(int channel)
case 0:
TIM4->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE;
TIM4->CCER |= TIM_CCER_CC1E;
#ifndef _ARCH_CORTEXM3_STM32 //Only stm32f2 and stm32f4 have it
#ifndef _ARCH_CORTEXM3_STM32F1 //Only stm32f2 and stm32f4 have it
servo1out::alternateFunction(2);
#endif //_ARCH_CORTEXM3_STM32
#endif //_ARCH_CORTEXM3_STM32F1
servo1out::mode(Mode::ALTERNATE);
break;
case 1:
TIM4->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
TIM4->CCER |= TIM_CCER_CC2E;
#ifndef _ARCH_CORTEXM3_STM32 //Only stm32f2 and stm32f4 have it
#ifndef _ARCH_CORTEXM3_STM32F1 //Only stm32f2 and stm32f4 have it
servo2out::alternateFunction(2);
#endif //_ARCH_CORTEXM3_STM32
#endif //_ARCH_CORTEXM3_STM32F1
servo2out::mode(Mode::ALTERNATE);
break;
case 2:
TIM4->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
TIM4->CCER |= TIM_CCER_CC3E;
#ifndef _ARCH_CORTEXM3_STM32 //Only stm32f2 and stm32f4 have it
#ifndef _ARCH_CORTEXM3_STM32F1 //Only stm32f2 and stm32f4 have it
servo3out::alternateFunction(2);
#endif //_ARCH_CORTEXM3_STM32
#endif //_ARCH_CORTEXM3_STM32F1
servo3out::mode(Mode::ALTERNATE);
break;
case 3:
TIM4->CCMR2 |= TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE;
TIM4->CCER |= TIM_CCER_CC4E;
#ifndef _ARCH_CORTEXM3_STM32 //Only stm32f2 and stm32f4 have it
#ifndef _ARCH_CORTEXM3_STM32F1 //Only stm32f2 and stm32f4 have it
servo4out::alternateFunction(2);
#endif //_ARCH_CORTEXM3_STM32
#endif //_ARCH_CORTEXM3_STM32F1
servo4out::mode(Mode::ALTERNATE);
break;
}
......@@ -321,7 +321,7 @@ unsigned int SynchronizedServo::getPrescalerInputFrequency()
unsigned int freq=SystemCoreClock;
//The position of the PPRE1 bit in RCC->CFGR is different in some stm32
#ifdef _ARCH_CORTEXM3_STM32
#ifdef _ARCH_CORTEXM3_STM32F1
const unsigned int ppre1=8;
#else //stm32f2 and f4
const unsigned int ppre1=10;
......
/***************************************************************************
* Copyright (C) 2024 by Niccolò Betto *
* *
* 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 "stm32_bsram.h"
#include <miosix.h>
#include <cstring>
namespace miosix
{
static ResetReason lastReset = ResetReason::UNKNOWN;
static ResetReason readResetRegister()
{
uint32_t resetReg = RCC->CSR;
// Clear the reset flag
RCC->CSR |= RCC_CSR_RMVF;
if (resetReg & RCC_CSR_LPWRRSTF)
{
return ResetReason::LOW_POWER;
}
else if (resetReg & RCC_CSR_WWDGRSTF)
{
return ResetReason::WINDOW_WATCHDOG;
}
#ifdef _ARCH_CORTEXM7_STM32F7
else if (resetReg & RCC_CSR_IWDGRSTF)
#else
else if (resetReg & RCC_CSR_WDGRSTF)
#endif
{
return ResetReason::INDEPENDENT_WATCHDOG;
}
else if (resetReg & RCC_CSR_SFTRSTF)
{
return ResetReason::SOFTWARE;
}
else if (resetReg & RCC_CSR_PORRSTF)
{
return ResetReason::POWER_ON;
}
#ifdef _ARCH_CORTEXM7_STM32F7
else if (resetReg & RCC_CSR_PINRSTF)
#else
else if (resetReg & RCC_CSR_PADRSTF)
#endif
{
return ResetReason::PIN;
}
else
{
return ResetReason::UNKNOWN;
}
}
ResetReason lastResetReason() { return lastReset; }
namespace BSRAM
{
void init()
{
// Enable PWR clock
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
// Enable write on BSRAM since we need it to write on the PWR peripheral
enableWrite();
// Enable backup SRAM Clock
RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN;
// Enable the backup regulator and wait for it to be ready
#ifdef _ARCH_CORTEXM7_STM32F7
PWR->CSR1 |= PWR_CSR1_BRE;
while (!(PWR->CSR1 & (PWR_CSR1_BRR)))
;
#else
PWR->CSR |= PWR_CSR_BRE;
while (!(PWR->CSR & (PWR_CSR_BRR)))
;
#endif
// Retrieve last reset reason
lastReset = readResetRegister();
// Disable write on BSRAM since we don't need to write on the peripheral for
// now. It will be necessary to re-enable the write on the backup SRAM
// around a PRESERVED variable to effectively change its value.
disableWrite();
}
void disableWrite()
{
// Ensure all memory instructions complete before disabling write
__DMB();
// Enable backup domain write protection
#ifdef _ARCH_CORTEXM7_STM32F7
PWR->CR1 &= ~PWR_CR1_DBP;
#else
PWR->CR &= ~PWR_CR_DBP;
#endif
// Ensure write is disabled when exiting this function
__DMB();
}
void enableWrite()
{
// Disable backup domain write protection
#ifdef _ARCH_CORTEXM7_STM32F7
PWR->CR1 |= PWR_CR1_DBP;
#else
PWR->CR |= PWR_CR_DBP;
#endif
// Ensure writes to the control registers complete before returning
__DMB();
}
} // namespace BSRAM
} // namespace miosix
This diff is collapsed.
......@@ -25,7 +25,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "board_settings.h"
#include "stm32_sgm.h"
#include <string.h>
#include "miosix.h"
......