Initail STM32 Baremetal build

This commit is contained in:
David Sidrane
2015-08-14 05:46:33 -10:00
parent b0fef2ed1f
commit 9750e3f58d
4 changed files with 105 additions and 21 deletions
@@ -16,6 +16,7 @@
# include <cstdio> # include <cstdio>
# include <ctime> # include <ctime>
# include <cstring> # include <cstring>
#elif UAVCAN_STM32_BAREMETAL
#else #else
# error "Unknown OS" # error "Unknown OS"
#endif #endif
@@ -24,6 +25,7 @@
namespace uavcan_stm32 namespace uavcan_stm32
{ {
class CanDriver; class CanDriver;
#if UAVCAN_STM32_CHIBIOS #if UAVCAN_STM32_CHIBIOS
@@ -91,35 +93,47 @@ public:
void signalFromInterrupt(); void signalFromInterrupt();
}; };
class Mutex #elif UAVCAN_STM32_BAREMETAL
class BusEvent
{ {
pthread_mutex_t mutex_; volatile bool ready;
public: public:
Mutex() BusEvent(CanDriver& can_driver)
: ready(false)
{ {
init(); (void)can_driver;
} }
int init() bool wait(uavcan::MonotonicDuration duration)
{ {
return pthread_mutex_init(&mutex_, NULL); bool lready = ready;
return __atomic_exchange_n (&lready, false, __ATOMIC_SEQ_CST);
} }
int deinit() void signal()
{ {
return pthread_mutex_destroy(&mutex_); __atomic_store_n (&ready, true, __ATOMIC_SEQ_CST);
} }
void signalFromInterrupt()
{
__atomic_store_n (&ready, true, __ATOMIC_SEQ_CST);
}
};
class Mutex
{
public:
void lock() void lock()
{ {
(void)pthread_mutex_lock(&mutex_);
}
};
void unlock() void unlock()
{ {
(void)pthread_mutex_unlock(&mutex_);
} };
}; };
class MutexLocker class MutexLocker
@@ -132,7 +146,6 @@ public:
{ {
mutex_.lock(); mutex_.lock();
} }
~MutexLocker() ~MutexLocker()
{ {
mutex_.unlock(); mutex_.unlock();
@@ -154,7 +167,6 @@ public:
{ {
mutex_.lock(); mutex_.lock();
} }
~MutexLocker() ~MutexLocker()
{ {
mutex_.unlock(); mutex_.unlock();
@@ -162,4 +174,5 @@ public:
}; };
#endif #endif
} }
@@ -13,6 +13,8 @@
# include <arch/board/board.h> # include <arch/board/board.h>
# include <chip/stm32_tim.h> # include <chip/stm32_tim.h>
# include <syslog.h> # include <syslog.h>
#elif UAVCAN_STM32_BAREMETAL
# include <chip.h>
#else #else
# error "Unknown OS" # error "Unknown OS"
#endif #endif
@@ -57,6 +59,15 @@
# endif # endif
#endif #endif
#if UAVCAN_STM32_BAREMETAL
/**
* Priority mask for timer and CAN interrupts.
*/
# ifndef UAVCAN_STM32_IRQ_PRIORITY_MASK
# define UAVCAN_STM32_IRQ_PRIORITY_MASK 0
# endif
#endif
/** /**
* Glue macros * Glue macros
*/ */
@@ -92,6 +103,22 @@ struct CriticalSectionLocker
} }
}; };
#elif UAVCAN_STM32_BAREMETAL
struct CriticalSectionLocker
{
CriticalSectionLocker()
{
__disable_irq();
}
~CriticalSectionLocker()
{
__enable_irq();
}
};
#endif #endif
namespace clock namespace clock
@@ -14,11 +14,13 @@
# include <nuttx/arch.h> # include <nuttx/arch.h>
# include <nuttx/irq.h> # include <nuttx/irq.h>
# include <arch/board/board.h> # include <arch/board/board.h>
#elif UAVCAN_STM32_BAREMETAL
#include <chip.h>
#else #else
# error "Unknown OS" # error "Unknown OS"
#endif #endif
#if !UAVCAN_STM32_NUTTX #if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# if !(defined(STM32F10X_CL) || defined(STM32F2XX) || defined(STM32F4XX)) # if !(defined(STM32F10X_CL) || defined(STM32F2XX) || defined(STM32F4XX))
// IRQ numbers // IRQ numbers
# define CAN1_RX0_IRQn USB_LP_CAN1_RX0_IRQn # define CAN1_RX0_IRQn USB_LP_CAN1_RX0_IRQn
@@ -188,7 +190,9 @@ int CanIface::computeTimings(const uavcan::uint32_t target_bitrate, Timings& out
/* /*
* Hardware configuration * Hardware configuration
*/ */
#if UAVCAN_STM32_CHIBIOS #if UAVCAN_STM32_BAREMETAL
const uavcan::uint32_t pclk = STM32_PCLK1_FREQUENCY;
#elif UAVCAN_STM32_CHIBIOS
const uavcan::uint32_t pclk = STM32_PCLK1; const uavcan::uint32_t pclk = STM32_PCLK1;
#elif UAVCAN_STM32_NUTTX #elif UAVCAN_STM32_NUTTX
const uavcan::uint32_t pclk = STM32_PCLK1_FREQUENCY; const uavcan::uint32_t pclk = STM32_PCLK1_FREQUENCY;
@@ -838,6 +842,22 @@ uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks,
return 1; // Return value doesn't matter as long as it is non-negative return 1; // Return value doesn't matter as long as it is non-negative
} }
#if UAVCAN_STM32_BAREMETAL
static void nvicEnableVector(int irq, uint8_t prio)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#endif
int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode) int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode)
{ {
int res = 0; int res = 0;
@@ -921,7 +941,7 @@ int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMod
IRQ_ATTACH(STM32_IRQ_CAN2SCE, can2_irq); IRQ_ATTACH(STM32_IRQ_CAN2SCE, can2_irq);
# endif # endif
# undef IRQ_ATTACH # undef IRQ_ATTACH
#else #elif UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
{ {
CriticalSectionLocker lock; CriticalSectionLocker lock;
nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK); nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
@@ -1044,7 +1064,7 @@ static int can2_irq(const int irq, void*)
# endif # endif
#else // UAVCAN_STM32_NUTTX #else // UAVCAN_STM32_NUTTX
UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1052,6 +1072,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1059,6 +1080,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1066,6 +1088,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1075,6 +1098,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler)
# if UAVCAN_STM32_NUM_IFACES > 1 # if UAVCAN_STM32_NUM_IFACES > 1
UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1082,6 +1106,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1089,6 +1114,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -1096,6 +1122,7 @@ UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE(); UAVCAN_STM32_IRQ_EPILOGUE();
} }
UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler);
UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler) UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler)
{ {
UAVCAN_STM32_IRQ_PROLOGUE(); UAVCAN_STM32_IRQ_PROLOGUE();
@@ -14,7 +14,7 @@
/* /*
* Timer instance * Timer instance
*/ */
# if UAVCAN_STM32_CHIBIOS # if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
# define TIMX UAVCAN_STM32_GLUE2(TIM, UAVCAN_STM32_TIMER_NUMBER) # define TIMX UAVCAN_STM32_GLUE2(TIM, UAVCAN_STM32_TIMER_NUMBER)
# define TIMX_IRQn UAVCAN_STM32_GLUE3(TIM, UAVCAN_STM32_TIMER_NUMBER, _IRQn) # define TIMX_IRQn UAVCAN_STM32_GLUE3(TIM, UAVCAN_STM32_TIMER_NUMBER, _IRQn)
# define TIMX_INPUT_CLOCK STM32_TIMCLK1 # define TIMX_INPUT_CLOCK STM32_TIMCLK1
@@ -70,6 +70,23 @@ uavcan::MonotonicTime prev_utc_adj_at;
uavcan::uint64_t time_mono = 0; uavcan::uint64_t time_mono = 0;
uavcan::uint64_t time_utc = 0; uavcan::uint64_t time_utc = 0;
} }
# if UAVCAN_STM32_NUTTX || UAVCAN_STM32_BAREMETAL
#if UAVCAN_STM32_BAREMETAL
static void nvicEnableVector(int irq, uint8_t prio)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#endif
void init() void init()
@@ -82,7 +99,7 @@ void init()
initialized = true; initialized = true;
# if UAVCAN_STM32_CHIBIOS # if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
// Power-on and reset // Power-on and reset
TIMX_RCC_ENR |= TIMX_RCC_ENR_MASK; TIMX_RCC_ENR |= TIMX_RCC_ENR_MASK;
TIMX_RCC_RSTR |= TIMX_RCC_RSTR_MASK; TIMX_RCC_RSTR |= TIMX_RCC_RSTR_MASK;
@@ -201,7 +218,7 @@ uavcan::MonotonicTime getMonotonic()
volatile uavcan::uint64_t time = time_mono; volatile uavcan::uint64_t time = time_mono;
# if UAVCAN_STM32_CHIBIOS # if UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
volatile uavcan::uint32_t cnt = TIMX->CNT; volatile uavcan::uint32_t cnt = TIMX->CNT;
if (TIMX->SR & TIM_SR_UIF) if (TIMX->SR & TIM_SR_UIF)