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.

176 lines
5.9KB

  1. // -------------------------------------------------------------------------------------------
  2. // I2C Advanced Bus Scanner
  3. // -------------------------------------------------------------------------------------------
  4. //
  5. // This creates an I2C master device which will scan the address space and report all
  6. // devices which ACK. It does not attempt to transfer data, it only reports which devices
  7. // ACK their address.
  8. //
  9. // This version will sweep all existing I2C buses (eg. Wire, Wire1, Wire2, Wire3).
  10. //
  11. // Pull the control pin low to initiate the scan. Result will output to Serial.
  12. //
  13. // This example code is in the public domain.
  14. // -------------------------------------------------------------------------------------------
  15. #include <i2c_t3.h>
  16. // -------------------------------------------------------------------------------------------
  17. // Defines - modify as needed for sweep range and bus pin config
  18. //
  19. #define TARGET_START 0x01
  20. #define TARGET_END 0x7F
  21. #define WIRE_PINS I2C_PINS_18_19
  22. #if defined(__MKL26Z64__) // LC
  23. #define WIRE1_PINS I2C_PINS_22_23
  24. #endif
  25. #if defined(__MK20DX256__) // 3.1-3.2
  26. #define WIRE1_PINS I2C_PINS_29_30
  27. #endif
  28. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) // 3.5/3.6
  29. #define WIRE1_PINS I2C_PINS_37_38
  30. #define WIRE2_PINS I2C_PINS_3_4
  31. #endif
  32. #if defined(__MK66FX1M0__) // 3.6
  33. #define WIRE3_PINS I2C_PINS_56_57
  34. #endif
  35. // -------------------------------------------------------------------------------------------
  36. // Function prototypes
  37. void scan_bus(i2c_t3& Wire, uint8_t all);
  38. void print_bus_status(i2c_t3& Wire);
  39. void print_scan_status(struct i2cStruct* i2c, uint8_t target, uint8_t& found, uint8_t all);
  40. // -------------------------------------------------------------------------------------------
  41. void setup()
  42. {
  43. pinMode(LED_BUILTIN,OUTPUT); // LED
  44. pinMode(12,INPUT_PULLUP); // pull pin 12 low to show ACK only results
  45. pinMode(11,INPUT_PULLUP); // pull pin 11 low for a more verbose result (shows both ACK and NACK)
  46. // Setup for Master mode, all buses, external pullups, 400kHz, 10ms default timeout
  47. //
  48. Wire.begin(I2C_MASTER, 0x00, WIRE_PINS, I2C_PULLUP_EXT, 400000);
  49. Wire.setDefaultTimeout(10000); // 10ms
  50. #if I2C_BUS_NUM >= 2
  51. Wire1.begin(I2C_MASTER, 0x00, WIRE1_PINS, I2C_PULLUP_EXT, 400000);
  52. Wire1.setDefaultTimeout(10000); // 10ms
  53. #endif
  54. #if I2C_BUS_NUM >= 3
  55. Wire2.begin(I2C_MASTER, 0x00, WIRE2_PINS, I2C_PULLUP_EXT, 400000);
  56. Wire2.setDefaultTimeout(10000); // 10ms
  57. #endif
  58. #if I2C_BUS_NUM >= 4
  59. Wire3.begin(I2C_MASTER, 0x00, WIRE3_PINS, I2C_PULLUP_EXT, 400000);
  60. Wire3.setDefaultTimeout(10000); // 10ms
  61. #endif
  62. Serial.begin(115200);
  63. }
  64. // -------------------------------------------------------------------------------------------
  65. void loop()
  66. {
  67. // Scan I2C addresses
  68. //
  69. if(digitalRead(12) == LOW || digitalRead(11) == LOW)
  70. {
  71. uint8_t all = (digitalRead(11) == LOW);
  72. Serial.print("---------------------------------------------------\n");
  73. Serial.print("Bus Status Summary\n");
  74. Serial.print("==================\n");
  75. Serial.print(" Bus Mode SCL SDA Pullup Clock\n");
  76. print_bus_status(Wire);
  77. #if I2C_BUS_NUM >= 2
  78. print_bus_status(Wire1);
  79. #endif
  80. #if I2C_BUS_NUM >= 3
  81. print_bus_status(Wire2);
  82. #endif
  83. #if I2C_BUS_NUM >= 4
  84. print_bus_status(Wire3);
  85. #endif
  86. scan_bus(Wire, all);
  87. #if I2C_BUS_NUM >= 2
  88. scan_bus(Wire1, all);
  89. #endif
  90. #if I2C_BUS_NUM >= 3
  91. scan_bus(Wire2, all);
  92. #endif
  93. #if I2C_BUS_NUM >= 4
  94. scan_bus(Wire3, all);
  95. #endif
  96. Serial.print("---------------------------------------------------\n\n\n");
  97. delay(500); // delay to space out tests
  98. }
  99. }
  100. // -------------------------------------------------------------------------------------------
  101. // scan bus
  102. //
  103. void scan_bus(i2c_t3& Wire, uint8_t all)
  104. {
  105. uint8_t target, found = 0;
  106. Serial.print("---------------------------------------------------\n");
  107. if(Wire.bus == 0)
  108. Serial.print("Starting scan: Wire\n");
  109. else
  110. Serial.printf("Starting scan: Wire%d\n",Wire.bus);
  111. digitalWrite(LED_BUILTIN,HIGH); // LED on
  112. for(target = TARGET_START; target <= TARGET_END; target++) // sweep addr, skip general call
  113. {
  114. Wire.beginTransmission(target); // slave addr
  115. Wire.endTransmission(); // no data, just addr
  116. print_scan_status(Wire.i2c, target, found, all);
  117. }
  118. digitalWrite(LED_BUILTIN,LOW); // LED off
  119. if(!found) Serial.print("No devices found.\n");
  120. }
  121. // -------------------------------------------------------------------------------------------
  122. // print bus status
  123. //
  124. void print_bus_status(i2c_t3& Wire)
  125. {
  126. struct i2cStruct* i2c = Wire.i2c;
  127. if(Wire.bus == 0)
  128. Serial.print("Wire ");
  129. else
  130. Serial.printf("Wire%d ",Wire.bus);
  131. switch(i2c->currentMode)
  132. {
  133. case I2C_MASTER: Serial.print("MASTER "); break;
  134. case I2C_SLAVE: Serial.print(" SLAVE "); break;
  135. }
  136. Serial.printf(" %2d %2d ", Wire.i2c->currentSCL, Wire.i2c->currentSDA);
  137. switch(i2c->currentPullup)
  138. {
  139. case I2C_PULLUP_EXT: Serial.print("External "); break;
  140. case I2C_PULLUP_INT: Serial.print("Internal "); break;
  141. }
  142. Serial.printf("%d Hz\n",i2c->currentRate);
  143. }
  144. // -------------------------------------------------------------------------------------------
  145. // print scan status
  146. //
  147. void print_scan_status(struct i2cStruct* i2c, uint8_t target, uint8_t& found, uint8_t all)
  148. {
  149. switch(i2c->currentStatus)
  150. {
  151. case I2C_WAITING: Serial.printf("Addr: 0x%02X ACK\n",target); found=1; break;
  152. case I2C_ADDR_NAK: if(all) { Serial.printf("Addr: 0x%02X\n",target); } break;
  153. case I2C_TIMEOUT: if(all) { Serial.printf("Addr: 0x%02X Timeout\n",target); } break;
  154. default: break;
  155. }
  156. }