Skip to content

Commit f5524c6

Browse files
Add I2C target config and example.
1 parent 66b51bb commit f5524c6

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

custom_targets.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
"MCU_NRF52833"
88
],
99
"static_memory_defines": false,
10+
"device_has_add": [
11+
"I2CSLAVE"
12+
],
1013
"macros_add": [
1114
"TARGET_MCU_NRF52833",
1215
"NRFX_RNG_ENABLED=1",
16+
"NRFX_TWIS_ENABLED=1",
1317
"RNG_ENABLED=1",
1418
"NRF_QUEUE_ENABLED=1"
1519
],

examples/i2c_target.cpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright 2022 Micro:bit Educational Foundation and contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#include "mbed.h"
18+
#include "nrf_delay.h"
19+
20+
#if !DEVICE_I2CSLAVE
21+
#error [NOT_SUPPORTED] I2C Target mode is not supported
22+
#endif
23+
24+
#define BUTTON_PRESSED 0
25+
26+
27+
/*****************************************************************************/
28+
/* Serial */
29+
/*****************************************************************************/
30+
UnbufferedSerial pc(CONSOLE_TX, CONSOLE_RX, 115200);
31+
32+
FileHandle *mbed::mbed_override_console(int fd) {
33+
return &pc;
34+
}
35+
36+
/*****************************************************************************/
37+
/* I2C data to send between devices */
38+
/*****************************************************************************/
39+
#define TARGET_ADDR_8BIT (0xA0 << 1)
40+
const char MSG[] = "Slave!";
41+
const uint8_t MSG_LEN = 7;
42+
43+
/*****************************************************************************/
44+
/* LED functions */
45+
/*****************************************************************************/
46+
void conf_op_pin(PinName pin) {
47+
nrf_gpio_cfg(pin,
48+
NRF_GPIO_PIN_DIR_OUTPUT,
49+
NRF_GPIO_PIN_INPUT_DISCONNECT,
50+
NRF_GPIO_PIN_NOPULL,
51+
NRF_GPIO_PIN_H0H1,
52+
NRF_GPIO_PIN_NOSENSE);
53+
}
54+
55+
void set_led_1(bool set) {
56+
set ? nrf_gpio_pin_clear(COL_1) : nrf_gpio_pin_set(COL_1);
57+
}
58+
59+
void set_led_2(bool set) {
60+
set ? nrf_gpio_pin_clear(COL_2) : nrf_gpio_pin_set(COL_2);
61+
}
62+
63+
void leds_init() {
64+
conf_op_pin(COL_1);
65+
nrf_gpio_pin_clear(COL_1);
66+
conf_op_pin(COL_2);
67+
nrf_gpio_pin_clear(COL_2);
68+
conf_op_pin(ROW_1);
69+
nrf_gpio_pin_set(ROW_1);
70+
set_led_1(false);
71+
set_led_2(false);
72+
}
73+
74+
void error_loop() {
75+
while(1) {
76+
set_led_1(true);
77+
set_led_2(false);
78+
nrf_delay_ms(250);
79+
set_led_1(false);
80+
set_led_2(true);
81+
nrf_delay_ms(250);
82+
}
83+
}
84+
85+
/*****************************************************************************/
86+
/* I2C functions */
87+
/*****************************************************************************/
88+
void test_master() {
89+
I2C controller(I2C_SDA1, I2C_SCL1);
90+
91+
uint8_t rxData[MSG_LEN] = { 0 };
92+
int result = 0;
93+
94+
while (true) {
95+
const uint8_t I2C_MSG_SLEEP = 0xAB;
96+
uint8_t txData[1] = { I2C_MSG_SLEEP };
97+
result = controller.write(TARGET_ADDR_8BIT, (char *)&txData, 1, false);
98+
if (result != 0) {
99+
printf("Write error: %d\n", result);
100+
return;
101+
}
102+
103+
result = controller.read(TARGET_ADDR_8BIT, (char *)&rxData, MSG_LEN);
104+
if (result != 0) {
105+
printf("Read error: %d\n", result);
106+
return;
107+
}
108+
for (uint8_t i = 0; i < MSG_LEN; i++) {
109+
if (rxData[i] != MSG[i]) {
110+
printf("Message unexpected at chacter %d\n", i);
111+
printf("Read buffer: %s\n", rxData);
112+
return;
113+
}
114+
rxData[i] = 0; // Reset it for next iteration
115+
}
116+
nrf_delay_ms(250);
117+
}
118+
}
119+
120+
121+
void test_slave() {
122+
I2CSlave target(I2C_SDA1, I2C_SCL1);
123+
target.address(TARGET_ADDR_8BIT);
124+
125+
char buf[10];
126+
while (true) {
127+
int i = target.receive();
128+
switch (i) {
129+
case I2CSlave::ReadAddressed:
130+
target.write(MSG, MSG_LEN);
131+
printf("Received a read command");
132+
break;
133+
case I2CSlave::WriteGeneral:
134+
target.read(buf, 10);
135+
printf("Read General: %s\n", buf);
136+
break;
137+
case I2CSlave::WriteAddressed:
138+
target.read(buf, 10);
139+
printf("Read Address: %s\n", buf);
140+
break;
141+
}
142+
for(int i = 0; i < 10; i++) buf[i] = 0; // Clear buffer
143+
}
144+
}
145+
146+
/*****************************************************************************/
147+
/* main */
148+
/*****************************************************************************/
149+
int main(void) {
150+
printf("I2C programme starting.\r\n");
151+
152+
DigitalIn buttonA(BUTTONA);
153+
DigitalIn buttonB(BUTTONB);
154+
155+
leds_init();
156+
157+
while (true) {
158+
if (buttonA == BUTTON_PRESSED) {
159+
printf("MAIN device\r\n");
160+
set_led_1(true);
161+
test_master();
162+
break;
163+
}
164+
if (buttonB == BUTTON_PRESSED) {
165+
printf("SECONDARY device\r\n");
166+
set_led_2(true);
167+
test_slave();
168+
break;
169+
}
170+
}
171+
172+
// test functions only return on failure
173+
error_loop();
174+
}

0 commit comments

Comments
 (0)