diff options
Diffstat (limited to 'libmaple')
| -rw-r--r-- | libmaple/i2c.c | 54 | ||||
| -rw-r--r-- | libmaple/i2c.h | 5 | ||||
| -rw-r--r-- | libmaple/rcc.c | 2 | ||||
| -rw-r--r-- | libmaple/rcc.h | 2 | 
4 files changed, 48 insertions, 15 deletions
| diff --git a/libmaple/i2c.c b/libmaple/i2c.c index a6638be..efe4dce 100644 --- a/libmaple/i2c.c +++ b/libmaple/i2c.c @@ -49,6 +49,19 @@ static i2c_dev i2c_dev1 = {  i2c_dev* const I2C1 = &i2c_dev1; +static i2c_dev i2c_dev2 = { +    .regs         = I2C2_BASE, +    .gpio_port    = &gpiob, +    .sda_pin      = 11, +    .scl_pin      = 10, +    .clk_line     = RCC_I2C2, +    .ev_nvic_line = NVIC_I2C2_EV, +    .er_nvic_line = NVIC_I2C2_ER, +    .state        = I2C_STATE_IDLE +}; + +i2c_dev* const I2C2 = &i2c_dev2; +  struct crumb {      uint32 event;      uint32 sr1; @@ -140,7 +153,8 @@ static void i2c_irq_handler(i2c_dev *dev) {               * Master transmitter: write first byte to fill shift register.               * We should get another TXE interrupt immediately to fill DR again.               */ -            i2c_write(dev, msg->data[msg->xferred++]); +            if (msg->length != 1)  +                    i2c_write(dev, msg->data[msg->xferred++]);          }          sr1 = sr2 = 0;      } @@ -243,6 +257,10 @@ void __irq_i2c1_ev(void) {     i2c_irq_handler(&i2c_dev1);  } +void __irq_i2c2_ev(void) { +   i2c_irq_handler(&i2c_dev2); +} +  static void i2c_irq_error_handler(i2c_dev *dev) {      uint32 sr1 = dev->regs->SR1;      uint32 sr2 = dev->regs->SR2; @@ -257,6 +275,10 @@ void __irq_i2c1_er(void) {      i2c_irq_error_handler(&i2c_dev1);  } +void __irq_i2c2_er(void) { +    i2c_irq_error_handler(&i2c_dev2); +} +  static void i2c_bus_reset(const i2c_dev *dev) {      /* Release both lines */      gpio_write_bit(dev->gpio_port, dev->scl_pin, 1); @@ -301,8 +323,11 @@ static void i2c_bus_reset(const i2c_dev *dev) {   *      I2C_10BIT_ADDRESSING: Enable 10-bit addressing   */  void i2c_master_enable(i2c_dev *dev, uint32 flags) { +#define I2C_CLK                (PCLK1/1000000)  #define STANDARD_CCR           (PCLK1/(100000*2)) -#define STANDARD_TRISE         37 +#define STANDARD_TRISE         (I2C_CLK+1)   +#define FAST_CCR               (I2C_CLK/10) +#define FAST_TRISE             ((I2C_CLK*3)/10+1)      /* Reset the bus. Clock out any hung slaves. */      i2c_bus_reset(dev); @@ -313,17 +338,24 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) {      gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_AF_OUTPUT_OD);      /* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */ -    i2c_set_input_clk(dev, 36); +    i2c_set_input_clk(dev, I2C_CLK); -    /* 100 khz only for now */ -    i2c_set_clk_control(dev, STANDARD_CCR); +    if(flags & I2C_FAST_MODE) {  -    /* -     * Set scl rise time, standard mode for now. -     * Max rise time in standard mode: 1000 ns -     * Max rise time in fast mode: 300ns -     */ -    i2c_set_trise(dev, STANDARD_TRISE); +	/* 400 kHz for fast mode, set DUTY and F/S bits */ +        i2c_set_clk_control(dev, FAST_CCR|I2C_CCR_DUTY|I2C_CCR_FS); + +        /* Set scl rise time, max rise time in fast mode: 300ns */ +        i2c_set_trise(dev, FAST_TRISE); + +    } else { + +	/* 100 kHz for standard mode */ +        i2c_set_clk_control(dev, STANDARD_CCR); + +        /* Max rise time in standard mode: 1000 ns */ +        i2c_set_trise(dev, STANDARD_TRISE); +    }      /* Enable event and buffer interrupts */      nvic_irq_enable(dev->ev_nvic_line); diff --git a/libmaple/i2c.h b/libmaple/i2c.h index a17e144..07ee260 100644 --- a/libmaple/i2c.h +++ b/libmaple/i2c.h @@ -71,8 +71,8 @@ typedef struct i2c_dev {      i2c_msg *msg;  } i2c_dev; -  extern i2c_dev* const I2C1; +extern i2c_dev* const I2C2;  #define I2C1_BASE               (i2c_reg_map*)0x40005400  #define I2C2_BASE               (i2c_reg_map*)0x40005800 @@ -100,7 +100,8 @@ extern i2c_dev* const I2C1;  #define I2C_CR2_FREQ            0xFFF           // Peripheral input frequency  /* Clock control register bits */ -#define I2C_CCR_FS              BIT(15)         // Master mode selection +#define I2C_CCR_FS              BIT(15)         // Fast mode selection +#define I2C_CCR_DUTY            BIT(14)         // 16/9 duty ratio  #define I2C_CCR_CCR             0xFFF           // Clock control bits  /* Status register 1 bits  */ diff --git a/libmaple/rcc.c b/libmaple/rcc.c index 327e3ad..78abbcf 100644 --- a/libmaple/rcc.c +++ b/libmaple/rcc.c @@ -67,6 +67,7 @@ static const struct rcc_dev_info rcc_dev_table[] = {      [RCC_PWR]    = { .clk_domain = APB1, .line_num = 28},      [RCC_BKP]    = { .clk_domain = APB1, .line_num = 27},      [RCC_I2C1]   = { .clk_domain = APB1, .line_num = 21 }, +    [RCC_I2C2]   = { .clk_domain = APB1, .line_num = 22 },      [RCC_CRC]    = { .clk_domain = AHB,  .line_num = 6},      [RCC_FLITF]  = { .clk_domain = AHB,  .line_num = 4},      [RCC_SRAM]   = { .clk_domain = AHB,  .line_num = 2}, @@ -83,7 +84,6 @@ static const struct rcc_dev_info rcc_dev_table[] = {      [RCC_FSMC]   = { .clk_domain = AHB,  .line_num = 8 },      [RCC_DAC]    = { .clk_domain = APB1, .line_num = 29 },      [RCC_DMA2]   = { .clk_domain = AHB,  .line_num = 1 }, -    [RCC_I2C2]   = { .clk_domain = APB1, .line_num = 22 },      [RCC_SDIO]   = { .clk_domain = AHB,  .line_num = 10 },  #endif  #ifdef STM32_XL_DENSITY diff --git a/libmaple/rcc.h b/libmaple/rcc.h index e6fa196..91f77d0 100644 --- a/libmaple/rcc.h +++ b/libmaple/rcc.h @@ -449,6 +449,7 @@ typedef enum {      RCC_PWR,      RCC_BKP,      RCC_I2C1, +    RCC_I2C2,      RCC_CRC,      RCC_FLITF,      RCC_SRAM, @@ -465,7 +466,6 @@ typedef enum {      RCC_FSMC,      RCC_DAC,      RCC_DMA2, -    RCC_I2C2,      RCC_SDIO,  #endif  #ifdef STM32_XL_DENSITY | 
