From eaf5d4799cc52e9dd1ebcaeafbf8f670658fea98 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 13 Jun 2017 21:10:37 +0100 Subject: inital commit --- app/i2c_hw.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 app/i2c_hw.c (limited to 'app/i2c_hw.c') diff --git a/app/i2c_hw.c b/app/i2c_hw.c new file mode 100644 index 0000000..11e796e --- /dev/null +++ b/app/i2c_hw.c @@ -0,0 +1,103 @@ +#include "project.h" + +#define SCL_GPIO GPIO_I2C1_SCL +#define SCL_BANK GPIOB + +#define SDA_GPIO GPIO_I2C1_SDA +#define SDA_BANK GPIOB + +#define I2C I2C1 + + +/* +void i2c1_isr(void) +{ +} +*/ + +void i2c1_er_isr (void) +{ +} + +void i2c1_ev_isr (void) +{ + static uint8_t reg; + static int device; + static int next_is_reg; + uint32_t sr1 = I2C_SR1 (I2C); + uint32_t v; + + if (sr1 & I2C_SR1_ADDR) { + v = I2C_SR2 (I2C); + device = !! (v & I2C_SR2_DUALF); + next_is_reg = 1; + } + + if (sr1 & I2C_SR1_TxE) { + if (device) { + v = ddc_read (reg++); + } else { + v = vuart_read (reg++); + } + + I2C_DR (I2C) = v; + } + + if (sr1 & I2C_SR1_RxNE) { + v = I2C_DR (I2C); + + if (next_is_reg) { + reg = v; + next_is_reg = 0; + } else { + if (reg == 0x10) { + vuart_write (0, v); + } else { + vuart_write (reg++, v); + } + } + } + + if (sr1 & I2C_SR1_STOPF) { + v = I2C_CR1 (I2C); + I2C_CR1 (I2C) = v; + } +} + +static void +i2c_clear_start (uint32_t i2c) +{ + I2C_CR1 (i2c) &= ~ (uint32_t) I2C_CR1_START; +} + + + +void +i2c_hw_init (void) +{ + i2c_peripheral_enable (I2C); + i2c_clear_start (I2C); + i2c_clear_stop (I2C); + i2c_reset (I2C); + i2c_peripheral_enable (I2C); + I2C_CR1 (I2C) |= I2C_CR1_SWRST; + delay_us (1000); + I2C_CR1 (I2C) &= ~I2C_CR1_SWRST; + gpio_set_mode (SCL_BANK, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, + SCL_GPIO); + gpio_set_mode (SDA_BANK, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, + SDA_GPIO); + i2c_set_clock_frequency (I2C, I2C_CR2_FREQ_36MHZ); + i2c_set_standard_mode (I2C); + i2c_set_ccr (I2C, 0x200); /* t_high=t_high=CCR * Tpclk1 */ + i2c_set_trise (I2C, 0x0b); + i2c_set_own_7bit_slave_address (I2C, 0x90 >> 1); + i2c_set_own_7bit_slave_address_two (I2C, 0xa0 >> 1); + i2c_enable_dual_addressing_mode (I2C); + i2c_peripheral_enable (I2C); + I2C_CR2 (I2C) |= I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN; + I2C_CR1 (I2C) |= I2C_CR1_ACK; + nvic_enable_irq (NVIC_I2C1_EV_IRQ); +} -- cgit v1.2.3