Tool to recover from an I2C bus lockup on the KL25Z
Embed:
(wiki syntax)
Show/hide line numbers
I2C_busreset.cpp
00001 /************************************************************************************************** 00002 ***** ***** 00003 ***** Name: KL25Z I2C_busreset.cpp ***** 00004 ***** Date: 24/11/2013 ***** 00005 ***** Auth: Frank Vannieuwkerke ***** 00006 ***** Func: library for unblocking I2C bus on KL25Z board ***** 00007 ***** Info: MPL3115A2-AN4481 ***** 00008 **************************************************************************************************/ 00009 00010 #include "I2C_busreset.h" 00011 00012 void I2C_busreset(void) 00013 { 00014 if((PORTE->PCR[1] & PORT_PCR_MUX(6)) && (PORTE->PCR[0] & PORT_PCR_MUX(6))) 00015 { 00016 I2C1->C1 &= 0x7f; // Disable I2C1 bus 00017 PORTE->PCR[1] = PORT_PCR_MUX(1); // PTE1 Alt1 (pin) 00018 PORTE->PCR[0] = PORT_PCR_MUX(1); // PTE0 Alt1 (pin) 00019 if((PTE->PDIR & 0x3) != 3) // When PTE0 / PTE1 are not 1 : I2C1 bus lock-up 00020 { 00021 PTE->PDDR |= 0x2; // Set PTE1 as a GPIO output so we can bit bang it 00022 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; 00023 wait_ms(1); 00024 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus 00025 { 00026 PTE->PDOR &= 0xfffffffd; // Set PTE1 (SCL) pin low; 00027 wait_ms(1); 00028 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; 00029 wait_ms(1); 00030 } 00031 } 00032 // Reinstate I2C1 bus pins 00033 PORTE->PCR[1] = PORT_PCR_MUX(6); // PTE1 Alt6 (SCL) 00034 PORTE->PCR[0] = PORT_PCR_MUX(6); // PTE0 Alt6 (SDA) 00035 I2C1->C1 |= 0x80; // Enable I2C1 bus 00036 } 00037 00038 if((PORTE->PCR[24] & PORT_PCR_MUX(5)) && (PORTE->PCR[25] & PORT_PCR_MUX(5))) 00039 { 00040 I2C0->C1 &= 0x7f; // Disable I2C0 bus 00041 PORTE->PCR[24] = PORT_PCR_MUX(1); // PTE24 Alt1 (pin) 00042 PORTE->PCR[25] = PORT_PCR_MUX(1); // PTE25 Alt1 (pin) 00043 if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C0 bus lock-up 00044 { 00045 PTE->PDDR |= 0x01000000; // Set PTE24 as a GPIO output so we can bit bang it 00046 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; 00047 wait_ms(1); 00048 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus 00049 { 00050 PTE->PDOR &= 0xfeffffff; // Set PTE24 (SCL) pin low; 00051 wait_ms(1); 00052 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; 00053 wait_ms(1); 00054 } 00055 } 00056 // Reinstate I2C0 bus pins 00057 PORTE->PCR[24] = PORT_PCR_MUX(5); // PTE24 Alt6 (SCL) 00058 PORTE->PCR[25] = PORT_PCR_MUX(5); // PTE25 Alt6 (SDA) 00059 I2C0->C1 |= 0x80; // Enable I2C0 bus 00060 } 00061 }
Generated on Mon Jul 18 2022 05:11:37 by 1.7.2