summaryrefslogtreecommitdiff
path: root/ucoo/hal/spi
diff options
context:
space:
mode:
authorNicolas Schodet2016-07-25 15:18:40 +0200
committerNicolas Schodet2019-10-09 23:05:44 +0200
commit4695b47da68a5b2f75270bea21e15b8f1b9fd6ff (patch)
tree6e5ef4d34ee69bcd6c6627f25a0ca3aa902d47e3 /ucoo/hal/spi
parentd7df91926bdb529e68eff9a215aef72072803b6e (diff)
Switch to CMSIS
Diffstat (limited to 'ucoo/hal/spi')
-rw-r--r--ucoo/hal/spi/spi_hard.stm32.cc86
-rw-r--r--ucoo/hal/spi/spi_hard.stm32.hh21
-rw-r--r--ucoo/hal/spi/test/test_spi.cc19
3 files changed, 69 insertions, 57 deletions
diff --git a/ucoo/hal/spi/spi_hard.stm32.cc b/ucoo/hal/spi/spi_hard.stm32.cc
index 264647d..898a565 100644
--- a/ucoo/hal/spi/spi_hard.stm32.cc
+++ b/ucoo/hal/spi/spi_hard.stm32.cc
@@ -22,10 +22,7 @@
//
// }}}
#include "ucoo/hal/spi/spi_hard.stm32.hh"
-
-#include <libopencm3/stm32/spi.h>
-#include <libopencm3/stm32/rcc.h>
-
+#include "ucoo/arch/rcc.stm32.hh"
#include "ucoo/common.hh"
namespace ucoo {
@@ -34,34 +31,33 @@ namespace ucoo {
struct spi_hardware_t
{
/// SPI base address.
- uint32_t base;
- /// APB number.
- int apb;
- /// Clock enable identifier.
- enum rcc_periph_clken clken;
+ SPI_TypeDef *base;
+ /// APB bus.
+ Bus bus;
+ /// RCC identifier.
+ Rcc rcc;
};
/// Information on SPI hardware array, this is zero indexed.
static const spi_hardware_t spi_hardware[] =
{
- { SPI1, 2, RCC_SPI1 },
- { SPI2, 1, RCC_SPI2 },
- { SPI3, 1, RCC_SPI3 },
+ { reg::SPI1, Bus::APB2, Rcc::SPI1 },
+ { reg::SPI2, Bus::APB1, Rcc::SPI2 },
+ { reg::SPI3, Bus::APB1, Rcc::SPI3 },
#ifdef SPI4_BASE
- { SPI4, 2, RCC_SPI4 },
+ { reg::SPI4, Bus::APB2, Rcc::SPI4 },
#endif
#ifdef SPI5_BASE
- { SPI5, 2, RCC_SPI5 },
+ { reg::SPI5, Bus::APB2, Rcc::SPI5 },
#endif
#ifdef SPI6_BASE
- { SPI6, 2, RCC_SPI6 },
+ { reg::SPI6, Bus::APB2, Rcc::SPI6 },
#endif
};
-SpiHardMaster::SpiHardMaster (int n)
- : n_ (n), enabled_ (false)
+SpiHardMaster::SpiHardMaster (SpiHardMaster::Instance inst)
+ : n_ (static_cast<int> (inst)), enabled_ (false)
{
- assert (n < lengthof (spi_hardware));
}
SpiHardMaster::~SpiHardMaster ()
@@ -73,24 +69,24 @@ void
SpiHardMaster::enable (int speed_hz, SpiMode mode)
{
enabled_ = true;
- uint32_t base = spi_hardware[n_].base;
+ auto base = spi_hardware[n_].base;
// Turn on.
- rcc_periph_clock_enable (spi_hardware[n_].clken);
+ rcc_peripheral_clock_enable (spi_hardware[n_].rcc);
// Compute speed, rounded down.
- int apb_freq = spi_hardware[n_].apb == 1 ? rcc_apb1_frequency
- : rcc_apb2_frequency;
- int freq = apb_freq / 2;
+ int apb_freq_hz = spi_hardware[n_].bus == Bus::APB1 ? rcc_apb1_freq_hz
+ : rcc_apb2_freq_hz;
+ int freq_hz = apb_freq_hz / 2;
int br = 0;
- while (freq > speed_hz)
+ while (freq_hz > speed_hz)
{
- freq = freq / 2;
+ freq_hz = freq_hz / 2;
br++;
- assert (br <= SPI_CR1_BR_FPCLK_DIV_256);
+ assert (br <= 7);
}
// Set parameters and enable.
- SPI_CR2 (base) = 0;
- SPI_CR1 (base) = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | (br << 3)
- | SPI_CR1_MSTR | mode;
+ base->CR2 = 0;
+ base->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE
+ | (br << SPI_CR1_BR_Pos) | SPI_CR1_MSTR | mode;
}
void
@@ -99,11 +95,11 @@ SpiHardMaster::disable ()
if (enabled_)
{
enabled_ = false;
- uint32_t base = spi_hardware[n_].base;
+ auto base = spi_hardware[n_].base;
// Stop SPI.
- SPI_CR1 (base) = 0;
+ base->CR1 = 0;
// Turn off.
- rcc_periph_clock_disable (spi_hardware[n_].clken);
+ rcc_peripheral_clock_disable (spi_hardware[n_].rcc);
}
}
@@ -111,13 +107,13 @@ void
SpiHardMaster::send_and_recv (const char *tx_buf, char *rx_buf, int count)
{
assert (enabled_);
- uint32_t base = spi_hardware[n_].base;
+ auto base = spi_hardware[n_].base;
while (count--)
{
- SPI_DR (base) = *tx_buf++;
- while (!(SPI_SR (base) & SPI_SR_RXNE))
+ base->DR = *tx_buf++;
+ while (!(base->SR & SPI_SR_RXNE))
;
- *rx_buf++ = SPI_DR (base);
+ *rx_buf++ = base->DR;
}
}
@@ -125,31 +121,31 @@ void
SpiHardMaster::send (const char *tx_buf, int count)
{
assert (enabled_);
- uint32_t base = spi_hardware[n_].base;
+ auto base = spi_hardware[n_].base;
while (count--)
{
- SPI_DR (base) = *tx_buf++;
- while (!(SPI_SR (base) & SPI_SR_TXE))
+ base->DR = *tx_buf++;
+ while (!(base->SR & SPI_SR_TXE))
;
}
// Wait for end of transfer.
- while (SPI_SR (base) & SPI_SR_BSY)
+ while (base->SR & SPI_SR_BSY)
;
// Clear RXNE.
- (void) SPI_DR (base);
+ (void) base->DR;
}
void
SpiHardMaster::recv (char *rx_buf, int count)
{
assert (enabled_);
- uint32_t base = spi_hardware[n_].base;
+ auto base = spi_hardware[n_].base;
while (count--)
{
- SPI_DR (base) = 0;
- while (!(SPI_SR (base) & SPI_SR_RXNE))
+ base->DR = 0;
+ while (!(base->SR & SPI_SR_RXNE))
;
- *rx_buf++ = SPI_DR (base);
+ *rx_buf++ = base->DR;
}
}
diff --git a/ucoo/hal/spi/spi_hard.stm32.hh b/ucoo/hal/spi/spi_hard.stm32.hh
index 7576be5..13d24d3 100644
--- a/ucoo/hal/spi/spi_hard.stm32.hh
+++ b/ucoo/hal/spi/spi_hard.stm32.hh
@@ -24,6 +24,7 @@
//
// }}}
#include "ucoo/intf/spi_master.hh"
+#include "ucoo/arch/reg.hh"
namespace ucoo {
@@ -31,8 +32,24 @@ namespace ucoo {
class SpiHardMaster : public SpiMaster
{
public:
- /// Constructor for the Nth SPI.
- SpiHardMaster (int n);
+ enum class Instance
+ {
+ SPI1,
+ SPI2,
+ SPI3,
+#ifdef SPI4_BASE
+ SPI4,
+#endif
+#ifdef SPI5_BASE
+ SPI5,
+#endif
+#ifdef SPI6_BASE
+ SPI6,
+#endif
+ };
+ public:
+ /// Constructor for an SPI instance.
+ SpiHardMaster (Instance inst);
/// Destructor, disable.
~SpiHardMaster ();
/// See SpiMaster::enable.
diff --git a/ucoo/hal/spi/test/test_spi.cc b/ucoo/hal/spi/test/test_spi.cc
index de155b7..73225ce 100644
--- a/ucoo/hal/spi/test/test_spi.cc
+++ b/ucoo/hal/spi/test/test_spi.cc
@@ -29,8 +29,6 @@
#include "ucoo/arch/arch.hh"
#include "ucoo/base/test/test.hh"
-#include <libopencm3/stm32/rcc.h>
-
#include <algorithm>
#include <cstdio>
@@ -41,15 +39,16 @@ main (int argc, const char **argv)
ucoo::Stream &ts = ucoo::test_stream ();
// Use connection to LIS302DL device on discovery board revision MB997B.
// Revision MB997C uses a different device.
- rcc_periph_clock_enable (RCC_GPIOA);
- rcc_periph_clock_enable (RCC_GPIOE);
- ucoo::Gpio ss (GPIOE, 3);
+ ucoo::GPIOA.enable ();
+ ucoo::GPIOE.enable ();
+ ucoo::Gpio ss = ucoo::GPIOE[3];
ss.set ();
ss.output ();
- ucoo::Gpio sck (GPIOA, 5), mosi (GPIOA, 7), miso (GPIOA, 6);
+ ucoo::Gpio sck = ucoo::GPIOA[5], mosi = ucoo::GPIOA[7],
+ miso = ucoo::GPIOA[6];
ucoo::SpiSoftMaster spis (sck, mosi, miso);
spis.enable (1000000, ucoo::SPI_MODE_3);
- ucoo::SpiHardMaster spih (0);
+ ucoo::SpiHardMaster spih (ucoo::SpiHardMaster::Instance::SPI1);
ucoo::SpiMaster *spi = &spis;
// Loop with simple IU.
char buf[64];
@@ -115,9 +114,9 @@ main (int argc, const char **argv)
case 'h':
spi->disable ();
spi = &spih;
- gpio_mode_setup (GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
- GPIO5 | GPIO6 | GPIO7);
- gpio_set_af (GPIOA, GPIO_AF5, GPIO5 | GPIO6 | GPIO7);
+ miso.af (5);
+ mosi.af (5);
+ sck.af (5);
spi->enable (1000000, ucoo::SPI_MODE_3);
break;
case 's':