|
| 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