blob: 167bf3408837c9b9be3beab157f7f88c059b7cb8 [file] [log] [blame]
Joachim Steigerb1a81c12019-07-26 22:13:51 +02001#include "board.h"
2#include <stdbool.h>
3#include "i2c.h"
4#include "mcp23017.h"
5
6
7//defines from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h under BSD license
8
9// registers
10#define MCP23017_IODIRA 0x00
11#define MCP23017_IPOLA 0x02
12#define MCP23017_GPINTENA 0x04
13#define MCP23017_DEFVALA 0x06
14#define MCP23017_INTCONA 0x08
15#define MCP23017_IOCONA 0x0A
16#define MCP23017_GPPUA 0x0C
17#define MCP23017_INTFA 0x0E
18#define MCP23017_INTCAPA 0x10
19#define MCP23017_GPIOA 0x12
20#define MCP23017_OLATA 0x14
21
22
23#define MCP23017_IODIRB 0x01
24#define MCP23017_IPOLB 0x03
25#define MCP23017_GPINTENB 0x05
26#define MCP23017_DEFVALB 0x07
27#define MCP23017_INTCONB 0x09
28#define MCP23017_IOCONB 0x0B
29#define MCP23017_GPPUB 0x0D
30#define MCP23017_INTFB 0x0F
31#define MCP23017_INTCAPB 0x11
32#define MCP23017_GPIOB 0x13
33#define MCP23017_OLATB 0x15
34
35#define MCP23017_INT_ERR 255
36
37
38//bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
39//uint8_t i2c_read_byte(bool nack, bool send_stop)
40//static void i2c_stop_cond(void)
41
42int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
43{
44 bool nack;
45
46 WDT_Restart(WDT);
47
48// Write slave address
49 nack = i2c_write_byte(true, false, slave << 1);
50 if (nack)
51 goto out_stop;
52 nack = i2c_write_byte(false, false, addr);
53 if (nack)
54 goto out_stop;
55 nack = i2c_write_byte(false, true, byte);
56 if (nack)
57 goto out_stop;
58
59out_stop:
60 i2c_stop_cond();
61 if (nack)
62 return -1;
63 else
64 return 0;
65}
66
67int mcp23017_read_byte(uint8_t slave, uint8_t addr)
68{
69 bool nack;
70
71 WDT_Restart(WDT);
72
73 // dummy write cycle
74 nack = i2c_write_byte(true, false, slave << 1);
75 if (nack)
76 goto out_stop;
77 nack = i2c_write_byte(false, false, addr);
78 if (nack)
79 goto out_stop;
80 // Re-start with read
81 nack = i2c_write_byte(true, false, (slave << 1) | 1);
82 if (nack)
83 goto out_stop;
84
85 return i2c_read_byte(true, true);
86
87out_stop:
88 i2c_stop_cond();
89 if (nack)
90 return -1;
91 else
92 return 0;
93}
94
95int mcp23017_init(uint8_t slave)
96{
Joachim Steigerf7f1ea82019-10-24 18:09:05 +020097 printf("mcp23017_init\n\r");
Joachim Steigerb1a81c12019-07-26 22:13:51 +020098 // all gpio input
99 if (mcp23017_write_byte(slave, MCP23017_IODIRA, 0xff))
100 return false;
Joachim Steigerf7f1ea82019-10-24 18:09:05 +0200101 // msb of portb output, rest input
102 if (mcp23017_write_byte(slave, MCP23017_IODIRB, 0x7f))
Joachim Steigerb1a81c12019-07-26 22:13:51 +0200103 return false;
Joachim Steigerf7f1ea82019-10-24 18:09:05 +0200104 if (mcp23017_write_byte(slave, MCP23017_IOCONA, 0x20)) //disable SEQOP (autoinc addressing)
105 return false;
106 printf("mcp23017 found\n\r");
Joachim Steigerb1a81c12019-07-26 22:13:51 +0200107 return true;
108}
109
Joachim Steigerf7f1ea82019-10-24 18:09:05 +0200110int mcp23017_test(uint8_t slave)
111{
112 printf("mcp23017_test\n\r");
113 printf("GPIOA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_GPIOA));
114 printf("GPIOB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_GPIOB));
115 printf("IODIRA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IODIRA));
116 printf("IODIRB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IODIRB));
117 printf("IOCONA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IOCONA));
118 printf("IOCONB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IOCONB));
119
120 return 0;
121}
122
123int mcp23017_toggle(uint8_t slave)
124{
125 // example writing MSB of gpio
126 static bool foo=false;
127 if (foo)
128 {
129 printf("+\n\r");
130 mcp23017_write_byte(slave, MCP23017_OLATB, 0x80);
131 foo=false;
132 }
133 else
134 {
135 printf("-\n\r");
136 mcp23017_write_byte(slave, MCP23017_OLATB, 0x00);
137 foo=true;
138 }
139 return 0;
140}