summaryrefslogtreecommitdiffstats
path: root/app/not/i2c_bb.c
blob: 3076605ffcaad5a6b7ceb1d6a0677c1ed1bd167c (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "project.h"

#define SCL 	GPIO6
#define SDA	GPIO7

static uint8_t
set (uint8_t sda, uint8_t scl)
{
  uint8_t ret;
  if (sda)
    gpio_set (GPIOB, SDA);
  else
    gpio_clear (GPIOB, SDA);

  if (scl)
    gpio_set (GPIOB, SCL);
  else
    gpio_clear (GPIOB, SCL);

  delay_us (10);
  ret = (gpio_get (GPIOB, SDA) & SDA) ? 1 : 0;

  return ret;
}




uint8_t
i2cb_send (uint8_t wot)
{
  uint8_t i;

  printf ("%02x", wot);

  for (i = 0; i < 8; ++i)
    {
      set (wot & 0x80, 0);
      set (wot & 0x80, 1);
      set (wot & 0x80, 0);
      wot <<= 1;
    }
  set (1, 0);
  i = set (1, 1);
  set (1, 0);

  printf ("%c", i ? '!' : '.');
  return i;
}

uint8_t
i2cb_send_addr (uint8_t addr, uint8_t rnw)
{
  return i2cb_send (addr << 1 | rnw);
}

uint8_t
i2cb_read (uint8_t ack)
{
  uint8_t i, wot = 0;

  for (i = 0; i < 8; ++i)
    {
      wot <<= 1;
      set (1, 0);
      wot |= set (1, 1);
      set (1, 0);
    }
  set (ack, 0);
  set (ack, 1);
  set (ack, 0);
  return wot;
}


void
i2cb_start (void)
{
  printf ("S");
  set (1, 1);
  set (0, 1);
  set (0, 0);
}

void
i2cb_stop (void)
{
  printf ("R\n");
  set (0, 0);
  set (0, 1);
  set (1, 1);
}


int
i2cb_start_transaction (uint8_t a, uint8_t rnw)
{
  i2cb_start ();
  return i2cb_send_addr (a, rnw);

}


void
i2cb_reset (void)
{
  i2cb_start ();
  i2cb_stop ();
  i2cb_start ();
  i2cb_stop ();
}



void
i2cb_scan (void)
{
  uint8_t r;
  uint16_t i;

  i2cb_reset ();

  printf ("Probing bus\n");
  for (i = 0; i < 128; ++i)
    {
      i2cb_start ();
      i2cb_stop ();
      i2cb_start ();
      r = i2cb_send ((i << 1) | I2C_WRITE);
      i2cb_stop ();

      if (!r)
        printf ("Found device at address 0x%x\n", i);
    }
  printf ("Done\n");
  i2cb_reset ();

}

void
i2cb_init (void)
{
  gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
                 SCL);
  gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
                 SDA);

  set (1, 1);
#ifdef DEBUG_I2C
  printf ("T11 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
#endif
  set (0, 1);
#ifdef DEBUG_I2C
  printf ("T01 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
#endif
  set (1, 0);
#ifdef DEBUG_I2C
  printf ("T10 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
#endif
  set (1, 1);
#ifdef DEBUG_I2C
  printf ("T11 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
#endif
}