Hack in support for other boards/microcontrollers, add GpioDriver

There's definitely plenty of cleanup work to be done (see:
"ifdefs").
This commit is contained in:
2020-04-11 11:03:17 -07:00
parent 385402e7aa
commit 99317eb99b
17 changed files with 1156 additions and 99 deletions

View File

@@ -0,0 +1,215 @@
#include "Bsp/Drivers/GpioDriver.h"
#include "Bsp/macros.h"
namespace BSP {
/*********************************************
*
* GpioPin
*
*********************************************/
GpioDriver::GpioDriver(GPIO_TypeDef *gpio)
: m_gpio(gpio)
{}
void GpioDriver::init() {
return;
}
void GpioDriver::enable() {
#if defined(STM32L0XX)
if (m_gpio == GPIOA) {
SET(RCC->IOPENR, RCC_IOPENR_IOPAEN);
} else if (m_gpio == GPIOB) {
SET(RCC->IOPENR, RCC_IOPENR_IOPBEN);
} else if (m_gpio == GPIOC) {
SET(RCC->IOPENR, RCC_IOPENR_IOPCEN);
} else if (m_gpio == GPIOH) {
SET(RCC->IOPENR, RCC_IOPENR_IOPHEN);
}
#elif defined(STM32L4XX)
if (m_gpio == GPIOA) {
SET(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
} else if (m_gpio == GPIOB) {
SET(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN);
} else if (m_gpio == GPIOC) {
SET(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN);
} else if (m_gpio == GPIOH) {
SET(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN);
}
#else
#error "Unknown device family"
#endif
}
void GpioDriver::disable() {
#if defined(STM32L0XX)
if (m_gpio == GPIOA) {
CLR(RCC->IOPENR, RCC_IOPENR_IOPAEN);
} else if (m_gpio == GPIOB) {
CLR(RCC->IOPENR, RCC_IOPENR_IOPBEN);
} else if (m_gpio == GPIOC) {
CLR(RCC->IOPENR, RCC_IOPENR_IOPCEN);
} else if (m_gpio == GPIOH) {
CLR(RCC->IOPENR, RCC_IOPENR_IOPHEN);
}
#elif defined(STM32L4XX)
if (m_gpio == GPIOA) {
CLR(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
} else if (m_gpio == GPIOB) {
CLR(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN);
} else if (m_gpio == GPIOC) {
CLR(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN);
} else if (m_gpio == GPIOH) {
CLR(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN);
}
#else
#error "Unknown device family"
#endif
}
void GpioDriver::set_pin_moder(uint32_t index, moder_t mode) {
uint32_t moder_value = 0;
switch (mode) {
case moder_t::INPUT:
moder_value = 0;
break;
case moder_t::OUTPUT:
moder_value = 1;
break;
case moder_t::ALTERNATE_FUNCTION:
moder_value = 2;
break;
}
SET_STRIDE_TO(m_gpio->MODER, 2, index, moder_value);
}
void GpioDriver::set_pin_pupdr(uint32_t index, input_pull_t pull_mode) {
uint32_t pupdr_value = 0;
switch (pull_mode) {
case input_pull_t::FLOATING:
pupdr_value = 0;
break;
case input_pull_t::PULL_UP:
pupdr_value = 1;
break;
case input_pull_t::PULL_DOWN:
pupdr_value = 2;
break;
}
SET_STRIDE_TO(m_gpio->PUPDR, 2, index, pupdr_value);
}
void GpioDriver::set_pin_otyper(uint32_t index, output_mode_t mode) {
uint32_t mask = 1 << index;
if (mode == output_mode_t::OPEN_DRAIN) {
SET(m_gpio->OTYPER, mask);
} else {
SET(m_gpio->OTYPER, mask);
}
}
void GpioDriver::set_pin_ospeedr(uint32_t index, output_speed_t speed) {
uint32_t speed_val = 0;
if (speed == output_speed_t::LOW) {
speed_val = 0;
} else if (speed == output_speed_t::MEDIUM) {
speed_val = 1;
} else if (speed == output_speed_t::HIGH) {
speed_val = 2;
} else if (speed == output_speed_t::VERY_HIGH) {
speed_val = 3;
}
SET_STRIDE_TO(m_gpio->OSPEEDR, 2, index, speed_val);
}
void GpioDriver::configure_pin_input(uint32_t index, input_pull_t pull_mode) {
if (index > 15) {
return;
}
set_pin_pupdr(index, pull_mode);
set_pin_moder(index, moder_t::INPUT);
}
void GpioDriver::configure_pin_output(uint32_t index, output_mode_t mode, output_speed_t speed) {
if (index > 15) {
return;
}
set_pin_moder(index, moder_t::INPUT); // Avoid glitches during configuration
set_pin_otyper(index, mode);
set_pin_ospeedr(index, speed);
set_pin_moder(index, moder_t::OUTPUT);
}
void GpioDriver::configure_pin_alternate_function(uint32_t index, uint32_t function) {
if (index > 15) {
return;
}
if (function > 7) {
return;
}
set_pin_moder(index, moder_t::INPUT); // Avoid glitches during configuration
if (index < 8) {
SET_STRIDE_TO(m_gpio->AFR[0], 4, index, function);
} else {
SET_STRIDE_TO(m_gpio->AFR[1], 4, index - 8, function);
}
set_pin_moder(index, moder_t::ALTERNATE_FUNCTION);
}
bool GpioDriver::read_pin(uint32_t index) {
return (m_gpio->IDR >> index) & 1;
}
void GpioDriver::write_pin(uint32_t index, bool value) {
SET_STRIDE_TO(m_gpio->ODR, 1, index, value);
}
/*********************************************
*
* GpioPin
*
*********************************************/
GpioPin::GpioPin(GpioDriver &driver, uint32_t index)
: m_gpio(driver)
, m_index(index)
{}
void GpioPin::configure_input(GpioDriver::input_pull_t pull_mode) {
m_gpio.configure_pin_input(m_index, pull_mode);
}
void GpioPin::configure_output(GpioDriver::output_mode_t mode, GpioDriver::output_speed_t speed) {
m_gpio.configure_pin_output(m_index, mode, speed);
}
void GpioPin::configure_alternate_function(uint32_t function) {
m_gpio.configure_pin_alternate_function(m_index, function);
}
bool GpioPin::read() {
return m_gpio.read_pin(m_index);
}
void GpioPin::write(bool val) {
return m_gpio.write_pin(m_index, val);
}
uint32_t GpioPin::get_index() {
return m_index;
}
GpioDriver& GpioPin::get_driver() {
return m_gpio;
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) 2019 Max Regan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "Bsp/ReturnCode.h"
#include "Bsp/TaskScheduler.h"
#include "Mcu.h"
namespace BSP {
class GpioDriver {
public:
GpioDriver(GPIO_TypeDef *gpio);
void init();
void enable();
void disable();
enum class output_mode_t {
PUSH_PULL,
OPEN_DRAIN,
};
enum class output_speed_t {
LOW,
MEDIUM,
HIGH,
VERY_HIGH,
};
enum class input_pull_t {
FLOATING,
PULL_UP,
PULL_DOWN,
};
friend class GpioPin;
private:
enum class moder_t {
INPUT,
OUTPUT,
ALTERNATE_FUNCTION,
};
void set_pin_moder(uint32_t index, moder_t mode);
void set_pin_pupdr(uint32_t index, input_pull_t pull_mode);
void set_pin_otyper(uint32_t index, output_mode_t mode);
void set_pin_ospeedr(uint32_t index, output_speed_t speed);
void configure_pin_input(uint32_t index, input_pull_t pull_mode);
void configure_pin_output(uint32_t index, output_mode_t mode, output_speed_t speed);
void configure_pin_alternate_function(uint32_t index, uint32_t function);
void write_pin(uint32_t index, bool value);
bool read_pin(uint32_t index);
GPIO_TypeDef * const m_gpio;
};
class GpioPin {
public:
GpioPin(GpioDriver &m_driver, uint32_t index);
void configure_input(GpioDriver::input_pull_t pull_mode);
void configure_output(GpioDriver::output_mode_t mode, GpioDriver::output_speed_t speed);
void configure_alternate_function(uint32_t function);
void write(bool value);
bool read();
GpioDriver &get_driver();
uint32_t get_index();
private:
GpioDriver &m_gpio;
uint32_t const m_index;
};
}

View File

@@ -23,7 +23,7 @@
#include "Bsp/Drivers/LowPower.h"
#include "Bsp/macros.h"
#include "stm32l0xx.h"
#include "Mcu.h"
uint32_t wakeups = 0;
@@ -56,7 +56,12 @@ ReturnCode LowPower::disable_debug()
CLR(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
CLR(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
#if defined(STM32L0XX)
CLR(RCC->APB2SMENR, RCC_APB2SMENR_DBGSMEN);
#elif defined(STM32L4XX)
#else
#error "Unsupported device type"
#endif
return ReturnCode::OK;
}
@@ -70,12 +75,24 @@ ReturnCode LowPower::sleep()
ReturnCode LowPower::stop()
{
#if defined(STM32L0XX)
SET(PWR->CR, PWR_CR_CWUF); // clear wakeup flag
while(PWR->CSR & PWR_CSR_WUF) {};
CLR(PWR->CR, PWR_CR_PDDS); // Enter stop mode when the CPU enters deepsleep
CLR(RCC->CFGR, RCC_CFGR_STOPWUCK); // MSI oscillator is wake-up from stop clock
SET(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); // low-power mode = stop mode
#elif defined(STM32L4XX)
SET(PWR->SCR, PWR_SCR_CWUF1); // clear wakeup flag
while(PWR->SR1 & PWR_SR1_WUF1) {};
SET_TO(PWR->CR1, PWR_CR1_LPMS, 1 << PWR_CR1_LPMS_Pos); // Enter stop mode 1 when the CPU enters deepsleep
CLR(RCC->CFGR, RCC_CFGR_STOPWUCK); // MSI oscillator is wake-up from stop clock
SET(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); // low-power mode = stop mode
#else
#error "Unsupported device type"
#endif
__WFI(); // enter low-power mode (Wake from interrupt)
wakeups++;

View File

@@ -34,9 +34,15 @@ LptimPwm::LptimPwm(LPTIM_TypeDef *lptim)
void LptimPwm::init_lptim()
{
/* Enable LPTIM in APB1 */
#if defined(STM32L0XX)
SET(RCC->APB1ENR,
RCC_APB1ENR_LPTIM1EN);
#elif defined(STM32L4XX)
SET(RCC->APB1ENR1,
RCC_APB1ENR1_LPTIM1EN);
#else
#error "Unsupported family"
#endif
// Enable low-speed internal
RCC->CSR |= RCC_CSR_LSION;
while (!(RCC->CSR & RCC_CSR_LSIRDY)) {};
@@ -90,21 +96,6 @@ ReturnCode LptimPwm::init()
{
init_lptim();
/* Enable GPIO port A */
SET(RCC->IOPENR, RCC_IOPENR_IOPAEN);
/* Assign LPTIM1_OUT to PA7 */
SET_TO(GPIOA->AFR[0],
GPIO_AFRL_AFRL7,
1u << GPIO_AFRL_AFRL7_Pos);
SET_TO(GPIOA->MODER,
GPIO_MODER_MODE7,
2u << GPIO_MODER_MODE7_Pos);
CLR(GPIOA->OTYPER, GPIO_OTYPER_OT_7);
CLR(GPIOA->PUPDR, GPIO_PUPDR_PUPD7);
return ReturnCode::OK;
}

View File

@@ -22,7 +22,7 @@
#pragma once
#include "Bsp/ReturnCode.h"
#include "stm32l0xx.h"
#include "Mcu.h"
namespace BSP {

View File

@@ -58,19 +58,27 @@ void RtcDriver::enable_periodic_alarm()
// Only calculate alarms when second rolls over
SET_TO(RTC->ALRMASSR, RTC_ALRMASSR_MASKSS, RTC_ALRMASSR_MASKSS);
#if defined(STM32L0XX)
SET(RTC->CR, RTC_CR_ALRAE | RTC_CR_ALRAIE);
SET(EXTI->IMR, EXTI_IMR_IM17);
SET(EXTI->EMR, EXTI_EMR_EM17);
SET(EXTI->RTSR, EXTI_RTSR_RT17);
#elif defined(STM32L4XX)
SET(RTC->CR, RTC_CR_ALRAE | RTC_CR_ALRAIE);
SET(EXTI->IMR1, EXTI_IMR1_IM18);
SET(EXTI->EMR1, EXTI_EMR1_EM18);
SET(EXTI->RTSR1, EXTI_RTSR1_RT18);
#else
#error "Unsupported family"
#endif
}
ReturnCode RtcDriver::init_hw()
{
//SET(RCC->CSR, RCC_CSR_RTCRST);
#if defined(STM32L0XX)
uint32_t temp = RCC->CSR;
SET(RCC->CSR, RCC_CSR_RTCRST);
SET(RCC->APB1ENR, RCC_APB1ENR_PWREN);
SET(PWR->CR, PWR_CR_DBP);
@@ -91,6 +99,32 @@ ReturnCode RtcDriver::init_hw()
RTC->ISR = RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF)) {}
#elif defined(STM32L4XX)
uint32_t temp = RCC->CSR;
SET(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
SET(PWR->CR1, PWR_CR1_DBP);
/*<! Set RTC input clock to the LSE (low-speed external 32.768kHz) clock */
if (!(RCC->BDCR & RCC_BDCR_LSERDY)) {
// TODO: Does this help?
SET(temp, RCC_BDCR_LSEON);
}
SET_TO(temp, RCC_BDCR_RTCSEL, RCC_BDCR_RTCSEL_0);
SET(temp, RCC_BDCR_RTCEN);
RCC->BDCR = temp;
while (!(RCC->BDCR & RCC_BDCR_LSERDY)) {}
enable_rtc_write();
RTC->ICSR = RTC_ICSR_INIT;
while (!(RTC->ICSR & RTC_ICSR_INITF)) {}
#else
#error "Unsupported device type"
#endif
/*<! Set the Clock Prescalers (32.768kHz / 1 / 32768 = 1Hz */
/*<! Set the Async prescaler to the Maximum (divide the clock by 128) */
// XXX reset to 0, this is to enable easier debugging
@@ -113,6 +147,7 @@ ReturnCode RtcDriver::init_hw()
SET_TO(time, RTC_TR_SU, 6 << RTC_TR_SU_Pos);
RTC->TR = time;
#if defined(STM32L0XX)
CLR(RTC->ISR, RTC_ISR_INIT);
SET(EXTI->IMR, EXTI_IMR_IM20);
@@ -124,6 +159,22 @@ ReturnCode RtcDriver::init_hw()
NVIC_EnableIRQ(RTC_IRQn);
NVIC_SetPriority(RTC_IRQn, 0);
#elif defined(STM32L4XX)
CLR(RTC->ICSR, RTC_ICSR_INIT);
SET(EXTI->IMR1, EXTI_IMR1_IM20);
SET(EXTI->EMR1, EXTI_EMR1_EM20);
SET(EXTI->RTSR1, EXTI_RTSR1_RT20);
// Enable Wakeup irq, we may/will use them later
SET(RTC->CR, RTC_CR_WUTIE);
NVIC_EnableIRQ(RTC_WKUP_IRQn);
NVIC_SetPriority(RTC_WKUP_IRQn, 0);
#else
#error "Unsupported device type"
#endif
enable_periodic_alarm();
disable_rtc_write();
@@ -164,8 +215,16 @@ ReturnCode RtcDriver::set_time(const BSP::WallClockTime &wall_time)
{
enable_rtc_write();
#if defined(STM32L0XX)
RTC->ISR = RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF)) {}
#elif defined(STM32L4XX)
RTC->ICSR = RTC_ICSR_INIT;
while (!(RTC->ICSR & RTC_ICSR_INITF)) {}
#else
#error "Unsupported device type"
#endif
/*<! Load initial date and time */
@@ -182,9 +241,17 @@ ReturnCode RtcDriver::set_time(const BSP::WallClockTime &wall_time)
SET_TO(time, RTC_TR_SU, wall_time.get_seconds_ones() << RTC_TR_SU_Pos);
RTC->TR = time;
#if defined(STM32L0XX)
CLR(RTC->ISR, RTC_ISR_INIT);
while ((RTC->ISR & RTC_ISR_INITF)) {}
while (!(RTC->ISR & RTC_ISR_RSF)) {}
#elif defined(STM32L4XX)
CLR(RTC->ICSR, RTC_ICSR_INIT);
while ((RTC->ICSR & RTC_ICSR_INITF)) {}
while (!(RTC->ICSR & RTC_ICSR_RSF)) {}
#else
#error "Unsupported device type"
#endif
disable_rtc_write();
@@ -204,7 +271,15 @@ ReturnCode RtcDriver::set_wakeup_in(BSP::time_t wakeup_delay)
/*<! If there is an ongoing wakeup, disable it */
if (RTC->CR & RTC_CR_WUTE) {
CLR(RTC->CR, RTC_CR_WUTE);
#if defined(STM32L0XX)
while (!(RTC->ISR & RTC_ISR_WUTWF)) {}
#elif defined(STM32L4XX)
while (!(RTC->ICSR & RTC_ICSR_WUTWF)) {}
#else
#error "Unsupported device type"
#endif
}
uint32_t wucksel = 0;
@@ -278,7 +353,9 @@ static uint32_t wakeup_alarms = 0;
extern "C" void RTC_IRQHandler()
{
// Clear the wakeup and alarm irq in the EXTI
#if defined(STM32L0XX)
SET(EXTI->PR, EXTI_PR_PIF20 | EXTI_PR_PIF17);
if (RTC->ISR & RTC_ISR_ALRAF) {
@@ -295,6 +372,28 @@ extern "C" void RTC_IRQHandler()
CLR(RTC->CR, RTC_CR_WUTE);
}
#elif defined(STM32L4XX)
SET(EXTI->PR1, EXTI_PR1_PIF20 | EXTI_PR1_PIF18);
if (RTC->SR & RTC_SR_ALRAF) {
RtcDriver::increment_seconds();
CLR(RTC->SR, RTC_SR_ALRAF);
}
if (RTC->SR & RTC_SR_WUTF) {
wakeup_alarms++;
// Clear the interrupt in the RTC
SET(RTC->SCR, RTC_SCR_CWUTF);
// Disable the Wakeup timer (its periodic, but we use it as a
// one-shot timer
CLR(RTC->CR, RTC_CR_WUTE);
}
#else
#error "Unsupported device type"
#endif
}
}

View File

@@ -27,7 +27,7 @@
#include "Bsp/ReturnCode.h"
#include "Bsp/Time.h"
#include "stm32l0xx.h"
#include "Mcu.h"
namespace BSP {

View File

@@ -27,51 +27,19 @@ namespace BSP {
using RC = BSP::ReturnCode;
using BSP::Schedule::TaskScheduler;
using BSP::Schedule::NextTime;
using BSP::GpioPin;
using BSP::Time;
SpiDriver::SpiDriver(TaskScheduler &scheduler)
SpiDriver::SpiDriver(TaskScheduler &scheduler, GpioPin &nss)
: m_scheduler(scheduler)
, m_spi(SPI1)
, m_nss(nss)
{}
void SpiDriver::init()
{
SET(RCC->IOPENR, RCC_IOPENR_IOPAEN);
SET(RCC->IOPENR, RCC_IOPENR_IOPBEN);
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
/* Assign SPI_MOSI to PB1, since PA7 is taken by LPTIM_OUT */
GPIOB->AFR[0] &= ~GPIO_AFRH_AFRH1;
GPIOB->AFR[0] |= 1u << GPIO_AFRH_AFRH1_Pos;
SET_TO(GPIOB->MODER, GPIO_MODER_MODE1, 2u << GPIO_MODER_MODE1_Pos);
GPIOB->OTYPER &= ~GPIO_OTYPER_OT_1;
GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD12;
// SPI1 NSS (PA4)
SET_TO(GPIOA->MODER, GPIO_MODER_MODE4, 1u << GPIO_MODER_MODE4_Pos);
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD4;
// SPI1 SCK (PA5)
GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL5;
SET_TO(GPIOA->MODER, GPIO_MODER_MODE5, 2u << GPIO_MODER_MODE5_Pos);
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD5;
// SPI1 MISO (PA6)
GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL6;
SET_TO(GPIOA->MODER, GPIO_MODER_MODE6, 2u << GPIO_MODER_MODE6_Pos);
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_6;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD6;
// Enable Master mode and half the baud rate, so it's set to ~1MHz
m_spi->CR1 |= SPI_CR1_MSTR | SPI_CR1_LSBFIRST | SPI_CR1_SSM;
//m_spi->CR1 |= 1u << SPI_CR1_BR_Pos;
@@ -91,17 +59,14 @@ RC SpiDriver::tx_blocking(const uint8_t *data, size_t len)
m_spi->CR1 |= SPI_CR1_SPE;
//FLIP(GPIOB->ODR, GPIO_ODR_OD3);
CLR(m_spi->CR1, SPI_CR1_SSI);
SET(GPIOA->ODR, GPIO_ODR_OD4);
m_nss.write(1);
for (size_t i = 0; i < len; i++) {
while (!(m_spi->SR & SPI_SR_TXE)) {}
m_spi->DR = data[i];
}
//FLIP(GPIOB->ODR, GPIO_ODR_OD3);
while (!(m_spi->SR & SPI_SR_TXE)) {}
// Ensure that NSS is held for long enough to meet the display's thSCS
@@ -109,6 +74,7 @@ RC SpiDriver::tx_blocking(const uint8_t *data, size_t len)
m_spi->CR1 &= ~SPI_CR1_SPE;
SET(m_spi->CR1, SPI_CR1_SSI);
m_nss.write(0);
CLR(GPIOA->ODR, GPIO_ODR_OD4);
return RC::OK;

View File

@@ -23,17 +23,19 @@
#include "Bsp/ReturnCode.h"
#include "Bsp/TaskScheduler.h"
#include "Bsp/Drivers/GpioDriver.h"
// TODO: Find a better include for this
#include "stm32l0xx.h"
#include "Mcu.h"
namespace BSP {
class SpiDriver : public BSP::Schedule::Task {
public:
// TODO: Add configurability / provide a real abstraction
SpiDriver(BSP::Schedule::TaskScheduler &scheduler);
// TODO: Allow other CS pins of either polaritu
// TODO: Allow configurable CPHA, CPOL
// TODO: Allow other SPI instances (not just SPI1)
SpiDriver(BSP::Schedule::TaskScheduler &scheduler, BSP::GpioPin &nss);
void init();
BSP::Schedule::NextTime execute() override;
@@ -42,6 +44,7 @@ public:
private:
BSP::Schedule::TaskScheduler &m_scheduler;
SPI_TypeDef *m_spi;
BSP::GpioPin &m_nss;
};
}