Forked from Frank's excellent library and extended to include I2C0 on PTC8 & PTC9. "This tool allows you to recover from an I2C bus lockup on I2C0 (PTE24, PTE25) and I2C1 (PTE0, PTE1). The reset is only carried out when the corresponding I2C bus is enabled."
Fork of KL25Z_I2C_busreset by
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 #ifdef KL25Z 00010 00011 #include "I2C_busreset.h" 00012 00013 void I2C_busreset(void) 00014 { 00015 // Chris Heald [23 Feb 2015]: Adding I2C on PTC9, PTC8, PCR MUX 2.. 00016 if((PORTC->PCR[8] & PORT_PCR_MUX(2)) && (PORTC->PCR[9] & PORT_PCR_MUX(2))) 00017 { 00018 I2C0->C1 &= 0x7f; // Disable I2C0 bus 00019 PORTC->PCR[8] = PORT_PCR_MUX(1); // PTC8 Alt1 (pin) 00020 PORTC->PCR[9] = PORT_PCR_MUX(1); // PTC9 Alt1 (pin) 00021 if((PTC->PDIR & 0x3) != 3) // When PTC8 / PTC9 are not 1 : I2C0 bus lock-up 00022 { 00023 PTC->PDDR |= 0x2; // Set PTC8 as a GPIO output so we can bit bang it 00024 PTC->PDOR |= 0x2; // Set PTC8 (SCL) pin high; 00025 wait_ms(1); 00026 while(!(PTC->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus 00027 { 00028 PTC->PDOR &= 0xfffffffd; // Set PTC8 (SCL) pin low; 00029 wait_ms(1); 00030 PTC->PDOR |= 0x2; // Set PTC8 (SCL) pin high; 00031 wait_ms(1); 00032 } 00033 } 00034 // Reinstate I2C1 bus pins 00035 PORTC->PCR[8] = PORT_PCR_MUX(2); // PTC8 Alt2 (SCL) 00036 PORTC->PCR[9] = PORT_PCR_MUX(2); // PTC9 Alt2 (SDA) 00037 I2C0->C1 |= 0x80; // Enable I2C0 bus 00038 } 00039 00040 00041 if((PORTE->PCR[1] & PORT_PCR_MUX(6)) && (PORTE->PCR[0] & PORT_PCR_MUX(6))) 00042 { 00043 I2C1->C1 &= 0x7f; // Disable I2C1 bus 00044 PORTE->PCR[1] = PORT_PCR_MUX(1); // PTE1 Alt1 (pin) 00045 PORTE->PCR[0] = PORT_PCR_MUX(1); // PTE0 Alt1 (pin) 00046 if((PTE->PDIR & 0x3) != 3) // When PTE0 / PTE1 are not 1 : I2C1 bus lock-up 00047 { 00048 PTE->PDDR |= 0x2; // Set PTE1 as a GPIO output so we can bit bang it 00049 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; 00050 wait_ms(1); 00051 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus 00052 { 00053 PTE->PDOR &= 0xfffffffd; // Set PTE1 (SCL) pin low; 00054 wait_ms(1); 00055 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; 00056 wait_ms(1); 00057 } 00058 } 00059 // Reinstate I2C1 bus pins 00060 PORTE->PCR[1] = PORT_PCR_MUX(6); // PTE1 Alt6 (SCL) 00061 PORTE->PCR[0] = PORT_PCR_MUX(6); // PTE0 Alt6 (SDA) 00062 I2C1->C1 |= 0x80; // Enable I2C1 bus 00063 } 00064 00065 if((PORTE->PCR[24] & PORT_PCR_MUX(5)) && (PORTE->PCR[25] & PORT_PCR_MUX(5))) 00066 { 00067 I2C0->C1 &= 0x7f; // Disable I2C0 bus 00068 PORTE->PCR[24] = PORT_PCR_MUX(1); // PTE24 Alt1 (pin) 00069 PORTE->PCR[25] = PORT_PCR_MUX(1); // PTE25 Alt1 (pin) 00070 if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C0 bus lock-up 00071 { 00072 PTE->PDDR |= 0x01000000; // Set PTE24 as a GPIO output so we can bit bang it 00073 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; 00074 wait_ms(1); 00075 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus 00076 { 00077 PTE->PDOR &= 0xfeffffff; // Set PTE24 (SCL) pin low; 00078 wait_ms(1); 00079 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; 00080 wait_ms(1); 00081 } 00082 } 00083 // Reinstate I2C0 bus pins 00084 PORTE->PCR[24] = PORT_PCR_MUX(5); // PTE24 Alt6 (SCL) 00085 PORTE->PCR[25] = PORT_PCR_MUX(5); // PTE25 Alt6 (SDA) 00086 I2C0->C1 |= 0x80; // Enable I2C0 bus 00087 } 00088 } 00089 #endif
Generated on Thu Jul 14 2022 08:57:34 by 1.7.2