aboutsummaryrefslogtreecommitdiffstats
path: root/app/i2c_hw.c
blob: 3efb862bd5d5c82bf5f9db798477b76e8867dbbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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, 36);
  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);
}