summaryrefslogtreecommitdiffhomepage
path: root/digital/ucoolib
diff options
context:
space:
mode:
authorNicolas Schodet2013-02-24 23:43:23 +0100
committerNicolas Schodet2013-03-01 22:58:04 +0100
commit3a4bd5948939030b960c3363c04a33032d517fc7 (patch)
tree00fed9e08ae4640f0738f690e6ba735c62891802 /digital/ucoolib
parent54848f43e39e38ca31cfa4e95b93baa60e1cb20b (diff)
digital/ucoolib/ucoolib: change setup to enable/disable
Diffstat (limited to 'digital/ucoolib')
-rw-r--r--digital/ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc4
-rw-r--r--digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc110
-rw-r--r--digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh12
-rw-r--r--digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc6
-rw-r--r--digital/ucoolib/ucoolib/hal/spi/spi_soft.cc50
-rw-r--r--digital/ucoolib/ucoolib/hal/spi/spi_soft.hh14
-rw-r--r--digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc5
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc15
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc76
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh12
10 files changed, 162 insertions, 142 deletions
diff --git a/digital/ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc b/digital/ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc
index 67d1e835..b230bdcc 100644
--- a/digital/ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc
+++ b/digital/ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc
@@ -52,11 +52,11 @@ class TestAvrIspIntf : public ucoo::AvrIspIntf
ucoo::delay_us (100);
reset_.reset ();
int freq = 1000000 / sck_duration_us;
- spi_.setup (freq, ucoo::SPI_MODE_0);
+ spi_.enable (freq, ucoo::SPI_MODE_0);
}
void disable ()
{
- spi_.setup (0);
+ spi_.disable ();
reset_.input ();
}
void sck_pulse ()
diff --git a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
index f11006ba..2001391e 100644
--- a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
+++ b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
@@ -78,82 +78,82 @@ void i2c3_er_isr () { ucoo::I2cHard::er_isr (2); }
namespace ucoo {
-I2cHard::I2cHard (int n, bool enable, int speed)
- : n_ (n), enable_ (false), slave_addr_ (0), slave_data_handler_ (0),
+I2cHard::I2cHard (int n)
+ : n_ (n), enabled_ (false), slave_addr_ (0), slave_data_handler_ (0),
master_ (false), master_status_ (STATUS_ERROR), master_buf_ (0)
{
assert (n < i2c_nb);
assert (!i2c_instances[n]);
i2c_instances[n] = this;
- setup (enable, speed);
}
I2cHard::~I2cHard ()
{
- setup (false);
+ disable ();
i2c_instances[n_] = 0;
}
void
-I2cHard::setup (bool enable, int speed)
+I2cHard::enable (int speed)
{
- if (enable != enable_)
+ enabled_ = true;
+ uint32_t base = i2c_hardware[n_].base;
+ // Turn on.
+ rcc_peripheral_enable_clock (&RCC_APB1ENR, i2c_hardware[n_].rcc_en);
+ // Reset.
+ I2C_CR1 (base) = I2C_CR1_SWRST;
+ // TODO: make sure the bus is free!!! How!
+ I2C_CR1 (base) = 0;
+ // Compute clock parameters.
+ int pclk = rcc_ppre1_frequency;
+ int pclk_mhz = pclk / 1000000;
+ uint16_t ccr, tris;
+ if (speed <= 100000)
+ {
+ ccr = pclk / speed / 2;
+ tris = pclk_mhz + 1;
+ }
+ else
+ {
+ assert (speed <= 400000);
+ ccr = I2C_CCR_FS | I2C_CCR_DUTY | (pclk / speed / 25);
+ tris = pclk_mhz * 3 / 10 + 1;
+ }
+ // Set all parameters.
+ I2C_CCR (base) = ccr;
+ I2C_TRISE (base) = tris;
+ I2C_OAR1 (base) = slave_addr_ | (1 << 14);
+ I2C_OAR2 (base) = 0;
+ I2C_CR2 (base) = I2C_CR2_ITEVTEN | I2C_CR2_ITERREN | pclk_mhz;
+ // Enable.
+ nvic_enable_irq (i2c_hardware[n_].ev_irq);
+ nvic_enable_irq (i2c_hardware[n_].ev_irq + 1);
+ I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_PE;
+
+}
+
+void
+I2cHard::disable ()
+{
+ if (enabled_)
{
+ enabled_ = false;
uint32_t base = i2c_hardware[n_].base;
- if (enable)
- {
- // Turn on.
- rcc_peripheral_enable_clock (&RCC_APB1ENR,
- i2c_hardware[n_].rcc_en);
- // Reset.
- I2C_CR1 (base) = I2C_CR1_SWRST;
- // TODO: make sure the bus is free!!! How!
- I2C_CR1 (base) = 0;
- // Compute clock parameters.
- int pclk = rcc_ppre1_frequency;
- int pclk_mhz = pclk / 1000000;
- uint16_t ccr, tris;
- if (speed <= 100000)
- {
- ccr = pclk / speed / 2;
- tris = pclk_mhz + 1;
- }
- else
- {
- assert (speed <= 400000);
- ccr = I2C_CCR_FS | I2C_CCR_DUTY | (pclk / speed / 25);
- tris = pclk_mhz * 3 / 10 + 1;
- }
- // Set all parameters.
- I2C_CCR (base) = ccr;
- I2C_TRISE (base) = tris;
- I2C_OAR1 (base) = slave_addr_ | (1 << 14);
- I2C_OAR2 (base) = 0;
- I2C_CR2 (base) = I2C_CR2_ITEVTEN | I2C_CR2_ITERREN | pclk_mhz;
- // Enable.
- nvic_enable_irq (i2c_hardware[n_].ev_irq);
- nvic_enable_irq (i2c_hardware[n_].ev_irq + 1);
- I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_PE;
- }
- else
- {
- // TODO: wait for end of transfer?
- // Disable.
- nvic_disable_irq (i2c_hardware[n_].ev_irq);
- nvic_disable_irq (i2c_hardware[n_].ev_irq + 1);
- I2C_CR1 (base) = 0;
- // Turn off.
- rcc_peripheral_disable_clock (&RCC_APB1ENR,
- i2c_hardware[n_].rcc_en);
- }
- enable_ = enable;
+ // TODO: wait for end of transfer?
+ // Disable.
+ nvic_disable_irq (i2c_hardware[n_].ev_irq);
+ nvic_disable_irq (i2c_hardware[n_].ev_irq + 1);
+ I2C_CR1 (base) = 0;
+ // Turn off.
+ rcc_peripheral_disable_clock (&RCC_APB1ENR,
+ i2c_hardware[n_].rcc_en);
}
}
void
I2cHard::transfer (uint8_t addr, char *buf, int count)
{
- assert (count);
+ assert (enabled_ && count);
// No need to lock, master is not busy.
assert (master_status_ != STATUS_BUSY);
uint32_t base = i2c_hardware[n_].base;
@@ -203,7 +203,7 @@ I2cHard::register_data (uint8_t addr, DataHandler &data_handler)
assert ((addr & 1) == 0);
slave_addr_ = addr;
slave_data_handler_ = &data_handler;
- if (enable_)
+ if (enabled_)
{
uint32_t base = i2c_hardware[n_].base;
// Just in case a transfer is triggered right now.
diff --git a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh
index 866fc57e..a54f0ee5 100644
--- a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh
+++ b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh
@@ -33,12 +33,14 @@ namespace ucoo {
class I2cHard : public I2c
{
public:
- /// Initialise the Nth I2C.
- I2cHard (int n, bool enable, int speed = 100000);
+ /// Constructor for the Nth I2C.
+ I2cHard (int n);
/// Shutdown.
~I2cHard ();
- /// Enable or disable.
- void setup (bool enable, int speed = 100000);
+ /// Enable and setup
+ void enable (int speed = 100000);
+ /// Disable.
+ void disable ();
/// See I2cMaster::send.
void send (uint8_t addr, const char *buf, int count);
/// See I2cMaster::recv.
@@ -60,7 +62,7 @@ class I2cHard : public I2c
/// I2C number.
int n_;
/// Is it enabled?
- bool enable_;
+ bool enabled_;
/// Slave address.
uint8_t slave_addr_;
/// Handler called to source or sink data for slave exchanges.
diff --git a/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc b/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
index fda2b74f..dd043f32 100644
--- a/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
+++ b/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
@@ -169,10 +169,12 @@ main (int argc, const char **argv)
gpio_set_af (GPIOA, GPIO_AF4, GPIO8);
gpio_set_af (GPIOC, GPIO_AF4, GPIO9);
ucoo::I2cSlaveDataBufferSize<16, 16> data1, data2;
- ucoo::I2cHard i2c1 (0, true);
- ucoo::I2cHard i2c2 (2, true);
+ ucoo::I2cHard i2c1 (0);
+ ucoo::I2cHard i2c2 (2);
i2c1.register_data (a1, data1);
i2c2.register_data (a2, data2);
+ i2c1.enable ();
+ i2c2.enable ();
// Run tests.
test_basic (tsuite, i2c1, data2, a2);
test_basic (tsuite, i2c2, data1, a1);
diff --git a/digital/ucoolib/ucoolib/hal/spi/spi_soft.cc b/digital/ucoolib/ucoolib/hal/spi/spi_soft.cc
index af5ac124..796b8fbe 100644
--- a/digital/ucoolib/ucoolib/hal/spi/spi_soft.cc
+++ b/digital/ucoolib/ucoolib/hal/spi/spi_soft.cc
@@ -28,40 +28,39 @@
namespace ucoo {
-SpiSoftMaster::SpiSoftMaster (Io &sck, Io &mosi, Io &miso, int speed,
- SpiMode mode)
- : sck_ (sck), mosi_ (mosi), miso_ (miso)
+SpiSoftMaster::SpiSoftMaster (Io &sck, Io &mosi, Io &miso)
+ : sck_ (sck), mosi_ (mosi), miso_ (miso), enabled_ (false)
{
- setup (speed, mode);
}
SpiSoftMaster::~SpiSoftMaster ()
{
- setup (0);
+ disable ();
}
void
-SpiSoftMaster::setup (int speed, SpiMode mode)
+SpiSoftMaster::enable (int speed, SpiMode mode)
{
- if (speed)
- {
- // Take pins ownership, set SCK according to CPOL.
- sck_.set (mode >= SPI_MODE_2);
- sck_.output ();
- mosi_.reset ();
- mosi_.output ();
- miso_.input ();
- // Set clock period and clock phase.
- half_period_ns_ = 1000 * 1000 * 1000 / 2 / speed;
- cpha_ = mode & 1;
- }
- else
- {
- // Release pins.
- sck_.input ();
- sck_.reset ();
- mosi_.input ();
- }
+ enabled_ = true;
+ // Take pins ownership, set SCK according to CPOL.
+ sck_.set (mode >= SPI_MODE_2);
+ sck_.output ();
+ mosi_.reset ();
+ mosi_.output ();
+ miso_.input ();
+ // Set clock period and clock phase.
+ half_period_ns_ = 1000 * 1000 * 1000 / 2 / speed;
+ cpha_ = mode & 1;
+}
+
+void
+SpiSoftMaster::disable ()
+{
+ enabled_ = false;
+ // Release pins.
+ sck_.input ();
+ sck_.reset ();
+ mosi_.input ();
}
void
@@ -74,6 +73,7 @@ SpiSoftMaster::send_and_recv (const char *tx_buf, char *rx_buf, int count)
char
SpiSoftMaster::send_and_recv (char tx)
{
+ assert (enabled_);
uint8_t i, rx = 0;
// Depending on clock phase, sample is done on first transition or second
// transition.
diff --git a/digital/ucoolib/ucoolib/hal/spi/spi_soft.hh b/digital/ucoolib/ucoolib/hal/spi/spi_soft.hh
index dcf0441d..c9f7886a 100644
--- a/digital/ucoolib/ucoolib/hal/spi/spi_soft.hh
+++ b/digital/ucoolib/ucoolib/hal/spi/spi_soft.hh
@@ -32,13 +32,14 @@ namespace ucoo {
class SpiSoftMaster : public SpiMaster
{
public:
- /// Constructor, need all SPI pins. Speed is given in Hz.
- SpiSoftMaster (Io &sck, Io &mosi, Io &miso, int speed = 0,
- SpiMode mode = SPI_MODE_0);
- /// Destructor, release SPI pins.
+ /// Constructor, need all SPI pins.
+ SpiSoftMaster (Io &sck, Io &mosi, Io &miso);
+ /// Destructor, disable.
~SpiSoftMaster ();
- /// Change settings, use speed 0 to stop.
- void setup (int speed, SpiMode mode = SPI_MODE_0);
+ /// Enable and setup.
+ void enable (int speed_hz, SpiMode mode = SPI_MODE_0);
+ /// Disable.
+ void disable ();
/// See SpiMaster::send_and_recv.
void send_and_recv (const char *tx_buf, char *rx_buf, int count);
/// Send and receive one byte.
@@ -55,6 +56,7 @@ class SpiSoftMaster : public SpiMaster
Io &sck_, &mosi_, &miso_;
int half_period_ns_;
bool cpha_;
+ bool enabled_;
};
} // namespace ucoo
diff --git a/digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc b/digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc
index 6e229fd3..24ad5e0a 100644
--- a/digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc
+++ b/digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc
@@ -43,9 +43,10 @@ main (int argc, const char **argv)
| RCC_AHB1ENR_IOPEEN);
ucoo::Gpio ss (GPIOE, 3);
ss.set ();
- gpio_mode_setup (GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
+ ss.output ();
ucoo::Gpio sck (GPIOA, 5), mosi (GPIOA, 7), miso (GPIOA, 6);
- ucoo::SpiSoftMaster spi (sck, mosi, miso, 1000000, ucoo::SPI_MODE_3);
+ ucoo::SpiSoftMaster spi (sck, mosi, miso);
+ spi.enable (1000000, ucoo::SPI_MODE_3);
// Loop with simple IU.
char buf[64];
unsigned int r;
diff --git a/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc b/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
index d08d9323..217baf91 100644
--- a/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
+++ b/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
@@ -53,9 +53,12 @@ main (int argc, const char **argv)
{
ucoo::arch_init (argc, argv);
ucoo::Stream &ts = ucoo::test_stream ();
- ucoo::Uart u1 (0, 38400, ucoo::Uart::EVEN, 1);
- ucoo::Uart u3 (2, 38400, ucoo::Uart::EVEN, 1);
- ucoo::Uart u4 (3, 38400, ucoo::Uart::EVEN, 1);
+ ucoo::Uart u1 (0);
+ ucoo::Uart u3 (2);
+ ucoo::Uart u4 (3);
+ u1.enable (38400, ucoo::Uart::EVEN, 1);
+ u3.enable (38400, ucoo::Uart::EVEN, 1);
+ u4.enable (38400, ucoo::Uart::EVEN, 1);
// For this test, shorten B6 & B7 to have a loopback on UART1, shorten C10
// & C11 to connect UART3 to UART4.
rcc_peripheral_enable_clock (&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN
@@ -107,13 +110,13 @@ main (int argc, const char **argv)
u->write (buf, buf_i);
break;
case 'O':
- u->setup (38400, ucoo::Uart::ODD, 1);
+ u->enable (38400, ucoo::Uart::ODD, 1);
break;
case 'E':
- u->setup (38400, ucoo::Uart::EVEN, 1);
+ u->enable (38400, ucoo::Uart::EVEN, 1);
break;
case 'N':
- u->setup (38400, ucoo::Uart::NONE, 1);
+ u->enable (38400, ucoo::Uart::NONE, 1);
break;
default:
if (buf_i < static_cast<int> (sizeof (buf)))
diff --git a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
index 0fc97efe..980bc6b9 100644
--- a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
+++ b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
@@ -83,57 +83,61 @@ void usart6_isr () { ucoo::Uart::isr (5); }
namespace ucoo {
-Uart::Uart (int n, int speed, Parity parity, int stop_bits)
- : n_ (n), error_char_ (default_error_char)
+Uart::Uart (int n)
+ : n_ (n), error_char_ (default_error_char), enabled_ (false)
{
assert (n < uart_nb);
assert (!uart_instances[n]);
uart_instances[n] = this;
- setup (speed, parity, stop_bits);
}
Uart::~Uart ()
{
- setup (0);
+ disable ();
uart_instances[n_] = 0;
}
void
-Uart::setup (int speed, Parity parity, int stop_bits)
+Uart::enable (int speed, Parity parity, int stop_bits)
{
+ enabled_ = true;
uint32_t base = uart_hardware[n_].base;
- if (speed)
- {
- // Turn on.
- rcc_peripheral_enable_clock
- (uart_hardware[n_].apb == 1 ? &RCC_APB1ENR : &RCC_APB2ENR,
- uart_hardware[n_].rcc_en);
- // Set speed, rounded to nearest.
- int apb_freq = uart_hardware[n_].apb == 1 ? rcc_ppre1_frequency
- : rcc_ppre2_frequency;
- USART_BRR (base) = (2 * apb_freq + speed) / (2 * speed);
- // Set parameters and enable.
- if (stop_bits == 1)
- USART_CR2 (base) = USART_CR2_STOPBITS_1;
- else if (stop_bits == 2)
- USART_CR2 (base) = USART_CR2_STOPBITS_2;
- else
- assert_unreachable ();
- USART_CR3 (base) = 0;
- uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- if (parity != NONE)
- cr1 |= USART_CR1_M | USART_CR1_PCE;
- if (parity == ODD)
- cr1 |= USART_CR1_PS;
- USART_CR1 (base) = cr1;
- // Reset status.
- (void) USART_SR (base);
- (void) USART_DR (base);
- // Enable interrupts.
- nvic_enable_irq (uart_hardware[n_].irq);
- }
+ // Turn on.
+ rcc_peripheral_enable_clock
+ (uart_hardware[n_].apb == 1 ? &RCC_APB1ENR : &RCC_APB2ENR,
+ uart_hardware[n_].rcc_en);
+ // Set speed, rounded to nearest.
+ int apb_freq = uart_hardware[n_].apb == 1 ? rcc_ppre1_frequency
+ : rcc_ppre2_frequency;
+ USART_BRR (base) = (2 * apb_freq + speed) / (2 * speed);
+ // Set parameters and enable.
+ if (stop_bits == 1)
+ USART_CR2 (base) = USART_CR2_STOPBITS_1;
+ else if (stop_bits == 2)
+ USART_CR2 (base) = USART_CR2_STOPBITS_2;
else
+ assert_unreachable ();
+ USART_CR3 (base) = 0;
+ uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ if (parity != NONE)
+ cr1 |= USART_CR1_M | USART_CR1_PCE;
+ if (parity == ODD)
+ cr1 |= USART_CR1_PS;
+ USART_CR1 (base) = cr1;
+ // Reset status.
+ (void) USART_SR (base);
+ (void) USART_DR (base);
+ // Enable interrupts.
+ nvic_enable_irq (uart_hardware[n_].irq);
+}
+
+void
+Uart::disable ()
+{
+ if (enabled_)
{
+ enabled_ = false;
+ uint32_t base = uart_hardware[n_].base;
// Stop UART.
nvic_disable_irq (uart_hardware[n_].irq);
USART_CR1 (base) = 0;
@@ -153,6 +157,7 @@ Uart::set_error_char (char c)
int
Uart::read (char *buf, int count)
{
+ assert (enabled_);
if (block_)
while (rx_fifo_.empty ())
barrier ();
@@ -162,6 +167,7 @@ Uart::read (char *buf, int count)
int
Uart::write (const char *buf, int count)
{
+ assert (enabled_);
int left = count;
while (left)
{
diff --git a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
index e807e9e9..1bfbcdb3 100644
--- a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
+++ b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
@@ -42,12 +42,14 @@ class Uart : public Stream
/// Default error character.
static const char default_error_char = '~';
public:
- /// Initialise the Nth UART with given parameters.
- Uart (int n, int speed = 0, Parity parity = NONE, int stop_bits = 1);
+ /// Constructor for the Nth UART.
+ Uart (int n);
/// Shutdown UART.
~Uart ();
- /// Change UART settings, use speed 0 to stop UART.
- void setup (int speed, Parity parity = NONE, int stop_bits = 1);
+ /// Enable and setup UART.
+ void enable (int speed, Parity parity = NONE, int stop_bits = 1);
+ /// Disable.
+ void disable ();
/// Change the error character.
void set_error_char (char c);
/// See Stream::read.
@@ -67,6 +69,8 @@ class Uart : public Stream
Fifo<char, UCOO_CONFIG_HAL_UART_TX_BUFFER> tx_fifo_;
/// Error character, inserted in case of error.
char error_char_;
+ /// Is it enabled?
+ bool enabled_;
};
} // namespace ucoo