Silence warning.
[bertos.git] / bertos / cpu / cortex-m3 / drv / i2c_stm32.c
index ee3a60e0843a36d93240af0afe60c3c055b619b0..381471626a1a4a1d9c199ccd4e15103480000371 100644 (file)
@@ -26,7 +26,7 @@
  * invalidate any other reasons why the executable file might be covered by
  * the GNU General Public License.
  *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
  *
  * -->
  *
 #include <cfg/macros.h> // BV()
 #include <cfg/module.h>
 
+#include <drv/gpio_stm32.h>
+#include <drv/irq_cm3.h>
+#include <drv/clock_stm32.h>
 #include <drv/i2c.h>
 
+#include <io/stm32.h>
+
+struct stm32_i2c *i2c = (struct stm32_i2c *)I2C1_BASE;
+
+INLINE uint32_t get_status(struct stm32_i2c *base)
+{
+       return ((base->SR1 | (base->SR2 << 16)) & 0x00FFFFFF);
+}
+
 /**
  * Send START condition on the bus.
  *
  */
 static bool i2c_builtin_start(void)
 {
+       i2c->CR1 |= CR1_ACK_SET;
+       i2c->CR1 |= CR1_PE_SET;
+       i2c->CR1 |= CR1_START_SET;
+       
+       while (get_status(i2c) != I2C_EVENT_MASTER_MODE_SELECT);
 
-       return false;
+       return true;
 }
 
 
@@ -68,7 +85,14 @@ static bool i2c_builtin_start(void)
  */
 bool i2c_builtin_start_w(uint8_t id)
 {
-       return false;
+       id &= OAR1_ADD0_RESET;
+
+       i2c_builtin_start();
+
+       i2c->DR = id;
+       while (get_status(i2c) != I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
+       
+       return true;
 }
 
 
@@ -81,8 +105,14 @@ bool i2c_builtin_start_w(uint8_t id)
  */
 bool i2c_builtin_start_r(uint8_t id)
 {
+       id |=  OAR1_ADD0_SET;
+
+       i2c_builtin_start();
+
+       i2c->DR = id;
+       while (get_status(i2c) != I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
 
-       return false;
+       return true;
 }
 
 
@@ -91,7 +121,8 @@ bool i2c_builtin_start_r(uint8_t id)
  */
 void i2c_builtin_stop(void)
 {
-
+       i2c->CR1 |= CR1_STOP_SET;
+       i2c->CR1 &= CR1_PE_RESET;
 }
 
 
@@ -103,6 +134,8 @@ void i2c_builtin_stop(void)
  */
 bool i2c_builtin_put(const uint8_t data)
 {
+       i2c->DR = data;
+       while (get_status(i2c) != I2C_EVENT_MASTER_BYTE_TRANSMITTED);
 
        return true;
 }
@@ -117,16 +150,44 @@ bool i2c_builtin_put(const uint8_t data)
  */
 int i2c_builtin_get(bool ack)
 {
+       while (get_status(i2c) != I2C_EVENT_MASTER_BYTE_RECEIVED);
 
-       return 0;
+       return i2c->DR;
 }
 
+
 MOD_DEFINE(i2c);
 
 /**
- * Initialize TWI module.
+ * Initialize I2C module.
  */
 void i2c_builtin_init(void)
 {
        MOD_INIT(i2c);
+
+       RCC->APB2ENR |= RCC_APB2_GPIOB;
+       RCC->APB1ENR |= RCC_APB1_I2C1;
+
+       stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_I2C1_SCL_PIN,
+                               GPIO_MODE_AF_OD, GPIO_SPEED_50MHZ);
+
+       stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_I2C1_SDA_PIN,
+                               GPIO_MODE_AF_OD, GPIO_SPEED_50MHZ);
+
+       i2c->CR1 = 0;
+       i2c->CR2 = 0;
+       i2c->CCR = 0;
+       i2c->TRISE = 0;
+       i2c->OAR1 = 0;
+
+       i2c->CR2 |= CR2_FREQ_36MHZ;
+
+       /* Configure spi in standard mode */
+       #if CONFIG_I2C_FREQ <= 100000
+               i2c->CCR |= (uint16_t)((CR2_FREQ_36MHZ * 1000000) / (CONFIG_I2C_FREQ << 1));
+               i2c->TRISE |= (CR2_FREQ_36MHZ + 1);
+       #else
+               #error fast mode not supported
+       #endif
+
 }