Chris Heald / KL25Z_I2C_busreset

Fork of KL25Z_I2C_busreset by Frank Vannieuwkerke

Committer:
frankvnk
Date:
Wed Feb 19 19:18:49 2014 +0000
Revision:
0:e9beb537cf77
Child:
1:fe493f707844
Initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 0:e9beb537cf77 1 /**************************************************************************************************
frankvnk 0:e9beb537cf77 2 ***** *****
frankvnk 0:e9beb537cf77 3 ***** Name: KL25Z I2C_busreset.cpp *****
frankvnk 0:e9beb537cf77 4 ***** Date: 24/11/2013 *****
frankvnk 0:e9beb537cf77 5 ***** Auth: Frank Vannieuwkerke *****
frankvnk 0:e9beb537cf77 6 ***** Func: library for unblocking I2C bus on KL25Z board *****
frankvnk 0:e9beb537cf77 7 ***** Info: MPL3115A2-AN4481 *****
frankvnk 0:e9beb537cf77 8 **************************************************************************************************/
frankvnk 0:e9beb537cf77 9
frankvnk 0:e9beb537cf77 10 #include "I2C_busreset.h"
frankvnk 0:e9beb537cf77 11
frankvnk 0:e9beb537cf77 12 void I2C_busreset(void)
frankvnk 0:e9beb537cf77 13 {
frankvnk 0:e9beb537cf77 14 if((PORTE->PCR[1] & PORT_PCR_MUX(6)) && (PORTE->PCR[0] & PORT_PCR_MUX(6)))
frankvnk 0:e9beb537cf77 15 {
frankvnk 0:e9beb537cf77 16 I2C1->C1 &= 0x7f; // Disable I2C1 bus
frankvnk 0:e9beb537cf77 17 PORTE->PCR[1] = PORT_PCR_MUX(1); // PTE1 Alt1 (pin)
frankvnk 0:e9beb537cf77 18 PORTE->PCR[0] = PORT_PCR_MUX(1); // PTE0 Alt1 (pin)
frankvnk 0:e9beb537cf77 19 if((PTE->PDIR & 0x3) != 3) // When PTE0 / PTE1 are not 1 : I2C1 bus lock-up
frankvnk 0:e9beb537cf77 20 {
frankvnk 0:e9beb537cf77 21 PTE->PDDR |= 0x2; // Set PTE1 as a GPIO output so we can bit bang it
frankvnk 0:e9beb537cf77 22 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high;
frankvnk 0:e9beb537cf77 23 wait_ms(1);
frankvnk 0:e9beb537cf77 24 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus
frankvnk 0:e9beb537cf77 25 {
frankvnk 0:e9beb537cf77 26 PTE->PDOR &= 0xfffffffd; // Set PTE1 (SCL) pin low;
frankvnk 0:e9beb537cf77 27 wait_ms(1);
frankvnk 0:e9beb537cf77 28 PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high;
frankvnk 0:e9beb537cf77 29 wait_ms(1);
frankvnk 0:e9beb537cf77 30 }
frankvnk 0:e9beb537cf77 31 }
frankvnk 0:e9beb537cf77 32 // Reinstate I2C1 bus pins
frankvnk 0:e9beb537cf77 33 PORTE->PCR[1] = PORT_PCR_MUX(6); // PTE1 Alt6 (SCL)
frankvnk 0:e9beb537cf77 34 PORTE->PCR[0] = PORT_PCR_MUX(6); // PTE0 Alt6 (SDA)
frankvnk 0:e9beb537cf77 35 I2C1->C1 |= 0x80; // Enable I2C1 bus
frankvnk 0:e9beb537cf77 36 }
frankvnk 0:e9beb537cf77 37
frankvnk 0:e9beb537cf77 38 if((PORTE->PCR[24] & PORT_PCR_MUX(5)) && (PORTE->PCR[25] & PORT_PCR_MUX(5)))
frankvnk 0:e9beb537cf77 39 {
frankvnk 0:e9beb537cf77 40 I2C0->C1 &= 0x7f; // Disable I2C0 bus
frankvnk 0:e9beb537cf77 41 PORTE->PCR[24] = PORT_PCR_MUX(1); // PTE24 Alt1 (pin)
frankvnk 0:e9beb537cf77 42 PORTE->PCR[25] = PORT_PCR_MUX(1); // PTE25 Alt1 (pin)
frankvnk 0:e9beb537cf77 43 if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C0 bus lock-up
frankvnk 0:e9beb537cf77 44 {
frankvnk 0:e9beb537cf77 45 PTE->PDDR |= 0x01000000; // Set PTE24 as a GPIO output so we can bit bang it
frankvnk 0:e9beb537cf77 46 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high;
frankvnk 0:e9beb537cf77 47 wait_ms(1);
frankvnk 0:e9beb537cf77 48 while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus
frankvnk 0:e9beb537cf77 49 {
frankvnk 0:e9beb537cf77 50 PTE->PDOR &= 0xfeffffff; // Set PTE24 (SCL) pin low;
frankvnk 0:e9beb537cf77 51 wait_ms(1);
frankvnk 0:e9beb537cf77 52 PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high;
frankvnk 0:e9beb537cf77 53 wait_ms(1);
frankvnk 0:e9beb537cf77 54 }
frankvnk 0:e9beb537cf77 55 }
frankvnk 0:e9beb537cf77 56 // Reinstate I2C0 bus pins
frankvnk 0:e9beb537cf77 57 PORTE->PCR[24] = PORT_PCR_MUX(5); // PTE24 Alt6 (SCL)
frankvnk 0:e9beb537cf77 58 PORTE->PCR[25] = PORT_PCR_MUX(5); // PTE25 Alt6 (SDA)
frankvnk 0:e9beb537cf77 59 I2C0->C1 |= 0x80; // Enable I2C0 bus
frankvnk 0:e9beb537cf77 60 }
frankvnk 0:e9beb537cf77 61 }