From 3a4bd5948939030b960c3363c04a33032d517fc7 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 24 Feb 2013 23:43:23 +0100 Subject: digital/ucoolib/ucoolib: change setup to enable/disable --- .../ucoolib/ucoolib/dev/avrisp/test/test_avrisp.cc | 4 +- digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc | 110 ++++++++++----------- digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.hh | 12 ++- digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc | 6 +- digital/ucoolib/ucoolib/hal/spi/spi_soft.cc | 50 +++++----- digital/ucoolib/ucoolib/hal/spi/spi_soft.hh | 14 +-- digital/ucoolib/ucoolib/hal/spi/test/test_spi.cc | 5 +- digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc | 15 +-- digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc | 76 +++++++------- digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh | 12 ++- 10 files changed, 162 insertions(+), 142 deletions(-) (limited to 'digital/ucoolib') 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 (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 tx_fifo_; /// Error character, inserted in case of error. char error_char_; + /// Is it enabled? + bool enabled_; }; } // namespace ucoo -- cgit v1.2.3