aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/libboard/octsimtest/source/mcp23017.c
blob: 7013e1defcfaec480e9f4443ff6d1f0d80ae5418 (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
#include "board.h"
#include <stdbool.h>
#include "i2c.h"
#include "mcp23017.h"


//defines from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h under BSD license

// registers
#define MCP23017_IODIRA 0x00
#define MCP23017_IPOLA 0x02
#define MCP23017_GPINTENA 0x04
#define MCP23017_DEFVALA 0x06
#define MCP23017_INTCONA 0x08
#define MCP23017_IOCONA 0x0A
#define MCP23017_GPPUA 0x0C
#define MCP23017_INTFA 0x0E
#define MCP23017_INTCAPA 0x10
#define MCP23017_GPIOA 0x12
#define MCP23017_OLATA 0x14


#define MCP23017_IODIRB 0x01
#define MCP23017_IPOLB 0x03
#define MCP23017_GPINTENB 0x05
#define MCP23017_DEFVALB 0x07
#define MCP23017_INTCONB 0x09
#define MCP23017_IOCONB 0x0B
#define MCP23017_GPPUB 0x0D
#define MCP23017_INTFB 0x0F
#define MCP23017_INTCAPB 0x11
#define MCP23017_GPIOB 0x13
#define MCP23017_OLATB 0x15

#define MCP23017_INT_ERR 255


//bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
//uint8_t i2c_read_byte(bool nack, bool send_stop)
//static void i2c_stop_cond(void)

int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
{
	bool nack;

	WDT_Restart(WDT);

//	 Write slave address 
	nack = i2c_write_byte(true, false, slave << 1);
	if (nack)
		goto out_stop;
	nack = i2c_write_byte(false, false, addr);
	if (nack)
		goto out_stop;
	nack = i2c_write_byte(false, true, byte);
	if (nack)
		goto out_stop;

out_stop:
	i2c_stop_cond();
	if (nack)
		return -1;
	else
		return 0;
}

int mcp23017_read_byte(uint8_t slave, uint8_t addr)
{
	bool nack;

	WDT_Restart(WDT);

	// dummy write cycle
	nack = i2c_write_byte(true, false, slave << 1);
	if (nack)
		goto out_stop;
	nack = i2c_write_byte(false, false, addr);
	if (nack)
		goto out_stop;
	// Re-start with read
	nack = i2c_write_byte(true, false, (slave << 1) | 1);
	if (nack)
		goto out_stop;

	return i2c_read_byte(true, true);

out_stop:
	i2c_stop_cond();
	if (nack)
		return -1;
	else
		return 0;
}

int mcp23017_init(uint8_t slave, uint8_t iodira, uint8_t iodirb)
{
	TRACE_DEBUG("mcp23017_init\r\n");

	// all gpio input
	if (mcp23017_write_byte(slave, MCP23017_IODIRA, iodira))
		goto out_err;
	// msb of portb output, rest input
	if (mcp23017_write_byte(slave, MCP23017_IODIRB, iodirb))
		goto out_err;
	if (mcp23017_write_byte(slave, MCP23017_IOCONA, 0x20)) //disable SEQOP (autoinc addressing)
		goto out_err;

	TRACE_DEBUG("mcp23017 found\r\n");
	return 0;

out_err:
	TRACE_WARNING("mcp23017 NOT found!\r\n");
	return -1;
}

int mcp23017_test(uint8_t slave)
{
	printf("mcp23017_test\r\n");
	printf("GPIOA 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_GPIOA));
	printf("GPIOB 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_GPIOB));
	printf("IODIRA 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_IODIRA));
	printf("IODIRB 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_IODIRB));
	printf("IOCONA 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_IOCONA));
	printf("IOCONB 0x%x\r\n", mcp23017_read_byte(slave,MCP23017_IOCONB));

	return 0;
}

int mcp23017_set_output_a(uint8_t slave, uint8_t val)
{
	return mcp23017_write_byte(slave, MCP23017_OLATA, val);
}

int mcp23017_set_output_b(uint8_t slave, uint8_t val)
{
	return mcp23017_write_byte(slave, MCP23017_OLATB, val);
}

int mcp23017_toggle(uint8_t slave)
{
	// example writing MSB of gpio
	static bool foo=false;
	if (foo)
	{
		printf("+\r\n");
		mcp23017_write_byte(slave, MCP23017_OLATB, 0x80);
		foo=false;
	}
	else
	{
		printf("-\r\n");
		mcp23017_write_byte(slave, MCP23017_OLATB, 0x00);
		foo=true;
	}
	return 0;
}