blob: 98da58c768e106f8569c2647c6bf9ad44c06e01a (
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
|
/*
* i2c_slave example.cpp
*
* Created on: 4 Sep 2012
* Author: Barry Carter <barry.carter@gmail.com>
*/
#include <wirish/wirish.h>
#include <i2c.h>
#define USE_BUFFERED_EXAMPLE 1
i2c_msg msg;
i2c_msg *pmsg = &msg;
uint8 buffer[255];
uint8 value_to_print = 'A';
void funcrx(i2c_msg *msg)
{
// Received length will be in msg->length
char return_data = msg->data[0];
value_to_print = return_data;
}
#if USE_BUFFERED_EXAMPLE == 1
/* We ARE using a buffer to transmit the data out.
* Make sure you fill the buffer with the data AND you set the length correctly
*/
void functx(i2c_msg *msg)
{
// Cheeky. We are using the received byte of the data which is currently in
// byte 0 to echo it back to the master device
//msg->data[0] = 0x01; // We are re-using the rx buffer here to echo the request back
msg->data[1] = 0x02;
msg->data[2] = 0x03;
msg->data[3] = 0x04;
msg->data[4] = 0x05;
msg->length = 5;
}
#else
/* We are NOT using the buffered data transmission
* We will get this callback for each outgoing packet. Make sure to call i2c_write
* Strickly speaking, we should be sending a NACk on the last byte we want to send
* but for this test example I am going to assume the master will NACK it when it
* wants to stop.
*/
void functx(i2c_msg *msg)
{
i2c_write(I2C1, msg->data[0]);
}
#endif
void setup() {
SerialUSB.begin();
SerialUSB.println("I2C Slave example");
// attach the buffer
msg.data = buffer;
/* Init slave mode. Enables master too
* We are going to configure the slave device to
* - enable fast I2C (400khz)
* - dual addresses (can have 2 addresses per module)
* general call (accepts data writes to 0x00 on a broadcast basis)
*
* If the buffered example is enabled, then we also enable the
* buffer for rx and tx.
* Note you can independently enable/disable RX and TX buffers to
* allow a buffered read and direct writes. Useful if you don't know how
* much the master will read.
*/
#if USE_BUFFERED_EXAMPLE == 1
i2c_slave_enable(I2C1, I2C_FAST_MODE | I2C_SLAVE_DUAL_ADDRESS | I2C_SLAVE_GENERAL_CALL | I2C_SLAVE_USE_RX_BUFFER | I2C_SLAVE_USE_TX_BUFFER);
#else
i2c_slave_enable(I2C1, I2C_FAST_MODE | I2C_SLAVE_DUAL_ADDRESS | I2C_SLAVE_GENERAL_CALL);
#endif
// attach receive handler
i2c_slave_attach_recv_handler(I2C1, &msg, funcrx);
// attach transmit handler
i2c_slave_attach_transmit_handler(I2C1, &msg, functx);
// set addresss 1 to 16
i2c_slave_set_own_address(I2C1, 0x10);
// set addresss 2 to 32
i2c_slave_set_own_address2(I2C1, 0x20);
}
void loop() {
SerialUSB.print("Last byte: ");
SerialUSB.println(value_to_print);
}
// Force init() to be called before anything else.
__attribute__((constructor)) void premain() {
init();
}
int main(void) {
setup();
while (true) {
loop();
}
return 0;
}
|