PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
7.2KB

  1. // -------------------------------------------------------------------------------------------
  2. // Loopback
  3. // -------------------------------------------------------------------------------------------
  4. //
  5. // This creates a device using one I2C bus as a Master and one or more I2C buses as Slaves.
  6. // When the buses are connected together in closed loopback, then it creates a closed test
  7. // environment which allows Master/Slave development on a single device.
  8. //
  9. // Wire will act as the Master device, and Wire1/2/3 will act as the Slave device(s).
  10. //
  11. // Pulling pin12 low will initiate a WRITE then READ transfer between Master and Slave(s).
  12. //
  13. // This example code is in the public domain.
  14. //
  15. // -------------------------------------------------------------------------------------------
  16. #include <i2c_t3.h>
  17. // -------------------------------------------------------------------------------------------
  18. // Defines - modify as needed for pin config
  19. //
  20. #define WIRE_PINS I2C_PINS_18_19
  21. #if defined(__MKL26Z64__) // LC
  22. #define WIRE1_PINS I2C_PINS_22_23
  23. #endif
  24. #if defined(__MK20DX256__) // 3.1-3.2
  25. #define WIRE1_PINS I2C_PINS_29_30
  26. #endif
  27. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) // 3.5/3.6
  28. #define WIRE1_PINS I2C_PINS_37_38
  29. #define WIRE2_PINS I2C_PINS_3_4
  30. #endif
  31. #if defined(__MK66FX1M0__) // 3.6
  32. #define WIRE3_PINS I2C_PINS_56_57
  33. #endif
  34. // Function prototypes and variables
  35. //
  36. void rwSlave(uint8_t target);
  37. void printWireStatus(void);
  38. void printStatus(i2c_status status);
  39. #define MEM_LEN 16
  40. uint8_t mem[MEM_LEN];
  41. #if I2C_BUS_NUM >= 2
  42. void receiveEvent1(size_t len);
  43. void requestEvent1(void);
  44. void printWire1Status(void);
  45. uint8_t mem1[MEM_LEN];
  46. #define TARGET1 0x1A
  47. #endif
  48. #if I2C_BUS_NUM >= 3
  49. void receiveEvent2(size_t len);
  50. void requestEvent2(void);
  51. void printWire2Status(void);
  52. uint8_t mem2[MEM_LEN];
  53. #define TARGET2 0x2B
  54. #endif
  55. #if I2C_BUS_NUM >= 4
  56. void receiveEvent3(size_t len);
  57. void requestEvent3(void);
  58. void printWire3Status(void);
  59. uint8_t mem3[MEM_LEN];
  60. #define TARGET3 0x3C
  61. #endif
  62. void setup()
  63. {
  64. pinMode(LED_BUILTIN,OUTPUT); // LED
  65. pinMode(12,INPUT_PULLUP); // Control for Test1
  66. // Wire - Setup for Master mode, external pullup, 400kHz, 200ms default timeout
  67. Wire.begin(I2C_MASTER, 0x00, WIRE_PINS, I2C_PULLUP_EXT, 400000);
  68. Wire.setDefaultTimeout(200000);
  69. memset(mem, 0, sizeof(mem));
  70. #if I2C_BUS_NUM >= 2
  71. // Wire1 - Setup for Slave mode, external pullup, 400kHz
  72. Wire1.begin(I2C_SLAVE, TARGET1, WIRE1_PINS, I2C_PULLUP_EXT, 400000);
  73. Wire1.onReceive(receiveEvent1);
  74. Wire1.onRequest(requestEvent1);
  75. memset(mem1, 0, sizeof(mem1));
  76. #endif
  77. #if I2C_BUS_NUM >= 3
  78. // Wire2 - Setup for Slave mode, external pullup, 400kHz
  79. Wire2.begin(I2C_SLAVE, TARGET2, WIRE2_PINS, I2C_PULLUP_EXT, 400000);
  80. Wire2.onReceive(receiveEvent2);
  81. Wire2.onRequest(requestEvent2);
  82. memset(mem2, 0, sizeof(mem2));
  83. #endif
  84. #if I2C_BUS_NUM >= 4
  85. // Wire3 - Setup for Slave mode, external pullup, 400kHz
  86. Wire3.begin(I2C_SLAVE, TARGET3, WIRE3_PINS, I2C_PULLUP_EXT, 400000);
  87. Wire3.onReceive(receiveEvent3);
  88. Wire3.onRequest(requestEvent3);
  89. memset(mem3, 0, sizeof(mem3));
  90. #endif
  91. Serial.begin(115200);
  92. }
  93. //
  94. // Master Loop
  95. //
  96. void loop()
  97. {
  98. if(digitalRead(12) == LOW)
  99. {
  100. Serial.print("------------------------------------------------------------\n");
  101. Serial.printf("Writing then reading a %d byte block from Slave device(s)\n", MEM_LEN);
  102. Serial.print("------------------------------------------------------------\n");
  103. digitalWrite(LED_BUILTIN,HIGH); // LED on
  104. #if I2C_BUS_NUM >= 2
  105. rwSlave(TARGET1);
  106. #endif
  107. #if I2C_BUS_NUM >= 3
  108. rwSlave(TARGET2);
  109. #endif
  110. #if I2C_BUS_NUM >= 4
  111. rwSlave(TARGET3);
  112. #endif
  113. delay(100); // delay to space out tests
  114. digitalWrite(LED_BUILTIN,LOW); // LED off
  115. }
  116. }
  117. //
  118. // Write/Read to Slave
  119. //
  120. void rwSlave(uint8_t target)
  121. {
  122. uint8_t fail=0, count, data;
  123. // Writing to Slave ------------------------------------------------------
  124. Wire.beginTransmission(target); // slave addr
  125. Serial.printf("I2C WRITE %d bytes to Slave 0x%0X : ", MEM_LEN, target);
  126. for(count = 0; count < MEM_LEN; count++) // prepare data to send
  127. {
  128. mem[count] = random(0xFF); // set random data
  129. Serial.printf("%02X ",mem[count]);
  130. Wire.write(mem[count]);
  131. }
  132. fail = Wire.endTransmission(); // blocking write
  133. Serial.print(" ");
  134. printWireStatus(); // print I2C final status
  135. // Reading from Slave ------------------------------------------------------
  136. if(!fail)
  137. {
  138. Wire.requestFrom(target,(size_t)MEM_LEN); // blocking read
  139. fail = Wire.getError();
  140. Serial.printf("I2C READ %d bytes from Slave 0x%0X : ", Wire.available(), target);
  141. for(count = 0; count < MEM_LEN && Wire.available(); count++) // verify block
  142. {
  143. data = Wire.readByte();
  144. Serial.printf("%02X ", data);
  145. if(mem[count] != data) fail++;
  146. }
  147. if(!fail)
  148. Serial.print(" OK ");
  149. else
  150. Serial.print(" FAIL ");
  151. printWireStatus(); // print I2C final status
  152. }
  153. }
  154. //
  155. // Slave ISR handlers
  156. //
  157. #if I2C_BUS_NUM >= 2
  158. void receiveEvent1(size_t count) // Handle Wire1 Slave Rx Event (incoming I2C request/data)
  159. {
  160. Wire1.read(mem1, count); // copy Rx data to databuf
  161. }
  162. void requestEvent1(void) // Handle Wire1 Tx Event (outgoing I2C data)
  163. {
  164. Wire1.write(mem1, MEM_LEN); // fill Tx buffer (send full mem)
  165. }
  166. #endif
  167. #if I2C_BUS_NUM >= 3
  168. void receiveEvent2(size_t count) // Handle Wire2 Slave Rx Event (incoming I2C request/data)
  169. {
  170. Wire2.read(mem2, count); // copy Rx data to databuf
  171. }
  172. void requestEvent2(void) // Handle Wire2 Tx Event (outgoing I2C data)
  173. {
  174. Wire2.write(mem2, MEM_LEN); // fill Tx buffer (send full mem)
  175. }
  176. #endif
  177. #if I2C_BUS_NUM >= 4
  178. void receiveEvent3(size_t count) // Handle Wire3 Slave Rx Event (incoming I2C request/data)
  179. {
  180. Wire3.read(mem3, count); // copy Rx data to databuf
  181. }
  182. void requestEvent3(void) // Handle Wire3 Tx Event (outgoing I2C data)
  183. {
  184. Wire3.write(mem3, MEM_LEN); // fill Tx buffer (send full mem)
  185. }
  186. #endif
  187. //
  188. // print I2C status
  189. //
  190. void printWireStatus(void) { printStatus(Wire.status()); }
  191. #if I2C_BUS_NUM >= 2
  192. void printWire1Status(void) { printStatus(Wire1.status()); }
  193. #endif
  194. #if I2C_BUS_NUM >= 3
  195. void printWire2Status(void) { printStatus(Wire2.status()); }
  196. #endif
  197. #if I2C_BUS_NUM >= 4
  198. void printWire3Status(void) { printStatus(Wire3.status()); }
  199. #endif
  200. void printStatus(i2c_status status)
  201. {
  202. switch(status)
  203. {
  204. case I2C_WAITING: Serial.print("I2C waiting, no errors\n"); break;
  205. case I2C_ADDR_NAK: Serial.print("Slave addr not acknowledged\n"); break;
  206. case I2C_DATA_NAK: Serial.print("Slave data not acknowledged\n"); break;
  207. case I2C_ARB_LOST: Serial.print("Bus Error: Arbitration Lost\n"); break;
  208. case I2C_TIMEOUT: Serial.print("I2C timeout\n"); break;
  209. case I2C_BUF_OVF: Serial.print("I2C buffer overflow\n"); break;
  210. default: Serial.print("I2C busy\n"); break;
  211. }
  212. }