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 --- 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 +- 3 files changed, 66 insertions(+), 62 deletions(-) (limited to 'digital/ucoolib/ucoolib/hal/i2c') 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); -- cgit v1.2.3