|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- // -------------------------------------------------------------------------------------------
- // Loopback
- // -------------------------------------------------------------------------------------------
- //
- // This creates a device using one I2C bus as a Master and one or more I2C buses as Slaves.
- // When the buses are connected together in closed loopback, then it creates a closed test
- // environment which allows Master/Slave development on a single device.
- //
- // Wire will act as the Master device, and Wire1/2/3 will act as the Slave device(s).
- //
- // Pulling pin12 low will initiate a WRITE then READ transfer between Master and Slave(s).
- //
- // This example code is in the public domain.
- //
- // -------------------------------------------------------------------------------------------
-
- #include <i2c_t3.h>
-
-
- // -------------------------------------------------------------------------------------------
- // Defines - modify as needed for pin config
- //
- #define WIRE_PINS I2C_PINS_18_19
- #if defined(__MKL26Z64__) // LC
- #define WIRE1_PINS I2C_PINS_22_23
- #endif
- #if defined(__MK20DX256__) // 3.1-3.2
- #define WIRE1_PINS I2C_PINS_29_30
- #endif
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__) // 3.5/3.6
- #define WIRE1_PINS I2C_PINS_37_38
- #define WIRE2_PINS I2C_PINS_3_4
- #endif
- #if defined(__MK66FX1M0__) // 3.6
- #define WIRE3_PINS I2C_PINS_56_57
- #endif
-
-
- // Function prototypes and variables
- //
- void rwSlave(uint8_t target);
- void printWireStatus(void);
- void printStatus(i2c_status status);
- #define MEM_LEN 16
- uint8_t mem[MEM_LEN];
-
- #if I2C_BUS_NUM >= 2
- void receiveEvent1(size_t len);
- void requestEvent1(void);
- void printWire1Status(void);
- uint8_t mem1[MEM_LEN];
- #define TARGET1 0x1A
- #endif
-
- #if I2C_BUS_NUM >= 3
- void receiveEvent2(size_t len);
- void requestEvent2(void);
- void printWire2Status(void);
- uint8_t mem2[MEM_LEN];
- #define TARGET2 0x2B
- #endif
-
- #if I2C_BUS_NUM >= 4
- void receiveEvent3(size_t len);
- void requestEvent3(void);
- void printWire3Status(void);
- uint8_t mem3[MEM_LEN];
- #define TARGET3 0x3C
- #endif
-
-
- void setup()
- {
- pinMode(LED_BUILTIN,OUTPUT); // LED
- pinMode(12,INPUT_PULLUP); // Control for Test1
-
- // Wire - Setup for Master mode, external pullup, 400kHz, 200ms default timeout
- Wire.begin(I2C_MASTER, 0x00, WIRE_PINS, I2C_PULLUP_EXT, 400000);
- Wire.setDefaultTimeout(200000);
- memset(mem, 0, sizeof(mem));
-
- #if I2C_BUS_NUM >= 2
- // Wire1 - Setup for Slave mode, external pullup, 400kHz
- Wire1.begin(I2C_SLAVE, TARGET1, WIRE1_PINS, I2C_PULLUP_EXT, 400000);
- Wire1.onReceive(receiveEvent1);
- Wire1.onRequest(requestEvent1);
- memset(mem1, 0, sizeof(mem1));
- #endif
-
- #if I2C_BUS_NUM >= 3
- // Wire2 - Setup for Slave mode, external pullup, 400kHz
- Wire2.begin(I2C_SLAVE, TARGET2, WIRE2_PINS, I2C_PULLUP_EXT, 400000);
- Wire2.onReceive(receiveEvent2);
- Wire2.onRequest(requestEvent2);
- memset(mem2, 0, sizeof(mem2));
- #endif
-
- #if I2C_BUS_NUM >= 4
- // Wire3 - Setup for Slave mode, external pullup, 400kHz
- Wire3.begin(I2C_SLAVE, TARGET3, WIRE3_PINS, I2C_PULLUP_EXT, 400000);
- Wire3.onReceive(receiveEvent3);
- Wire3.onRequest(requestEvent3);
- memset(mem3, 0, sizeof(mem3));
- #endif
-
- Serial.begin(115200);
- }
-
-
- //
- // Master Loop
- //
- void loop()
- {
- if(digitalRead(12) == LOW)
- {
- Serial.print("------------------------------------------------------------\n");
- Serial.printf("Writing then reading a %d byte block from Slave device(s)\n", MEM_LEN);
- Serial.print("------------------------------------------------------------\n");
-
- digitalWrite(LED_BUILTIN,HIGH); // LED on
-
- #if I2C_BUS_NUM >= 2
- rwSlave(TARGET1);
- #endif
- #if I2C_BUS_NUM >= 3
- rwSlave(TARGET2);
- #endif
- #if I2C_BUS_NUM >= 4
- rwSlave(TARGET3);
- #endif
-
- delay(100); // delay to space out tests
- digitalWrite(LED_BUILTIN,LOW); // LED off
- }
- }
-
-
- //
- // Write/Read to Slave
- //
- void rwSlave(uint8_t target)
- {
- uint8_t fail=0, count, data;
-
- // Writing to Slave ------------------------------------------------------
- Wire.beginTransmission(target); // slave addr
- Serial.printf("I2C WRITE %d bytes to Slave 0x%0X : ", MEM_LEN, target);
- for(count = 0; count < MEM_LEN; count++) // prepare data to send
- {
- mem[count] = random(0xFF); // set random data
- Serial.printf("%02X ",mem[count]);
- Wire.write(mem[count]);
- }
- fail = Wire.endTransmission(); // blocking write
- Serial.print(" ");
- printWireStatus(); // print I2C final status
-
- // Reading from Slave ------------------------------------------------------
- if(!fail)
- {
- Wire.requestFrom(target,(size_t)MEM_LEN); // blocking read
- fail = Wire.getError();
-
- Serial.printf("I2C READ %d bytes from Slave 0x%0X : ", Wire.available(), target);
- for(count = 0; count < MEM_LEN && Wire.available(); count++) // verify block
- {
- data = Wire.readByte();
- Serial.printf("%02X ", data);
- if(mem[count] != data) fail++;
- }
- if(!fail)
- Serial.print(" OK ");
- else
- Serial.print(" FAIL ");
- printWireStatus(); // print I2C final status
- }
- }
-
-
- //
- // Slave ISR handlers
- //
- #if I2C_BUS_NUM >= 2
- void receiveEvent1(size_t count) // Handle Wire1 Slave Rx Event (incoming I2C request/data)
- {
- Wire1.read(mem1, count); // copy Rx data to databuf
- }
- void requestEvent1(void) // Handle Wire1 Tx Event (outgoing I2C data)
- {
- Wire1.write(mem1, MEM_LEN); // fill Tx buffer (send full mem)
- }
- #endif
-
- #if I2C_BUS_NUM >= 3
- void receiveEvent2(size_t count) // Handle Wire2 Slave Rx Event (incoming I2C request/data)
- {
- Wire2.read(mem2, count); // copy Rx data to databuf
- }
- void requestEvent2(void) // Handle Wire2 Tx Event (outgoing I2C data)
- {
- Wire2.write(mem2, MEM_LEN); // fill Tx buffer (send full mem)
- }
- #endif
-
- #if I2C_BUS_NUM >= 4
- void receiveEvent3(size_t count) // Handle Wire3 Slave Rx Event (incoming I2C request/data)
- {
- Wire3.read(mem3, count); // copy Rx data to databuf
- }
- void requestEvent3(void) // Handle Wire3 Tx Event (outgoing I2C data)
- {
- Wire3.write(mem3, MEM_LEN); // fill Tx buffer (send full mem)
- }
- #endif
-
-
- //
- // print I2C status
- //
- void printWireStatus(void) { printStatus(Wire.status()); }
- #if I2C_BUS_NUM >= 2
- void printWire1Status(void) { printStatus(Wire1.status()); }
- #endif
- #if I2C_BUS_NUM >= 3
- void printWire2Status(void) { printStatus(Wire2.status()); }
- #endif
- #if I2C_BUS_NUM >= 4
- void printWire3Status(void) { printStatus(Wire3.status()); }
- #endif
- void printStatus(i2c_status status)
- {
- switch(status)
- {
- case I2C_WAITING: Serial.print("I2C waiting, no errors\n"); break;
- case I2C_ADDR_NAK: Serial.print("Slave addr not acknowledged\n"); break;
- case I2C_DATA_NAK: Serial.print("Slave data not acknowledged\n"); break;
- case I2C_ARB_LOST: Serial.print("Bus Error: Arbitration Lost\n"); break;
- case I2C_TIMEOUT: Serial.print("I2C timeout\n"); break;
- case I2C_BUF_OVF: Serial.print("I2C buffer overflow\n"); break;
- default: Serial.print("I2C busy\n"); break;
- }
- }
-
|