cdms_i2c_hardware_test
Dependencies: FreescaleIAP SimpleDMA mbed-rtos mbed
Fork of standaloneworkingi2c_cdms by
Diff: i2c.h
- Revision:
- 157:d99f525edc4c
- Parent:
- 155:80e7c7ff8aaf
- Child:
- 160:25a01d8da5d4
--- a/i2c.h Tue Apr 19 21:30:03 2016 +0000 +++ b/i2c.h Sat Jul 02 09:01:46 2016 +0000 @@ -11,58 +11,388 @@ char PL_I2C_DATA[134];//Payload i2c array uint8_t PL_TM_SIZE;//size of data to bev read from i2c +/************************************************************************************************** + ***** ***** + ***** Name: KL25Z I2C_busreset.cpp ***** + ***** Date: 24/11/2013 ***** + ***** Auth: Frank Vannieuwkerke ***** + ***** Func: library for unblocking I2C bus on KL25Z board ***** + ***** Info: MPL3115A2-AN4481 ***** + **************************************************************************************************/ + +/*void I2C_busreset(void) +{ + if((PORTE->PCR[1] & PORT_PCR_MUX(6)) && (PORTE->PCR[0] & PORT_PCR_MUX(6))) + { + I2C1->C1 &= 0x7f; // Disable I2C1 bus + PORTE->PCR[1] = PORT_PCR_MUX(1); // PTE1 Alt1 (pin) + PORTE->PCR[0] = PORT_PCR_MUX(1); // PTE0 Alt1 (pin) + if((PTE->PDIR & 0x3) != 3) // When PTE0 / PTE1 are not 1 : I2C1 bus lock-up + { + PTE->PDDR |= 0x2; // Set PTE1 as a GPIO output so we can bit bang it + PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; + wait_ms(1); + while(!(PTE->PDIR & 0x1)) // bit bang SCL until the offending device releases the bus + { + PTE->PDOR &= 0xfffffffd; // Set PTE1 (SCL) pin low; + wait_ms(1); + PTE->PDOR |= 0x2; // Set PTE1 (SCL) pin high; + wait_ms(1); + } + } + // Reinstate I2C1 bus pins + PORTE->PCR[1] = PORT_PCR_MUX(6); // PTE1 Alt6 (SCL) + PORTE->PCR[0] = PORT_PCR_MUX(6); // PTE0 Alt6 (SDA) + I2C1->C1 |= 0x80; // Enable I2C1 bus + } + + if((PORTE->PCR[24] & PORT_PCR_MUX(5)) && (PORTE->PCR[25] & PORT_PCR_MUX(5))) + { + uint8_t count =0; + printf("\n\rEntered"); + I2C0->C1 &= 0x7f; // Disable I2C0 bus + PORTE->PCR[24] = PORT_PCR_MUX(1); // PTE24 Alt1 (pin) + PORTE->PCR[25] = PORT_PCR_MUX(1); // PTE25 Alt1 (pin) + if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C0 bus lock-up + { + PTE->PDDR |= 0x01000000; // Set PTE24 as a GPIO output so we can bit bang it + PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; + wait_ms(1); + while((!(PTE->PDIR & 0x1))&&count<10) // bit bang SCL until the offending device releases the bus + { + PTE->PDOR &= 0xfeffffff; // Set PTE24 (SCL) pin low; + wait_ms(1); + PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; + wait_ms(1); + count++; + } + } + // Reinstate I2C0 bus pins + PORTE->PCR[24] = PORT_PCR_MUX(5); // PTE24 Alt5 (SCL) + PORTE->PCR[25] = PORT_PCR_MUX(5); // PTE25 Alt5 (SDA) + I2C0->C1 |= 0x80; // Enable I2C0 bus + } +}*/ +void debug() +{ + //gPC.printf("\n\rPORTE->PCR[24] = 0x%08X",PORTE->PCR[24]); + //gPC.printf("\n\rPORTE->PCR[25] = 0x%08X",PORTE->PCR[25]); + gPC.printf("\n\rPTE->PDIR = 0x%08X",PTE->PDIR); +} +void debug1() +{ + gPC.printf("\n\r Before disabling"); + debug(); + wait(2); + I2C0->C1 &= 0x7f; + gPC.printf("\n\r After disabling"); + debug(); + I2C0->C1 |= 0x80; + gPC.printf("\n\r After enabling"); + debug(); + gPC.printf("\n"); +} +/* +#define PORT_PCR_MUX_MASK2 0x00000700u + +void I2C_busreset(void) +{ + uint8_t count=0; + if(((PORTE->PCR[24]&(PORT_PCR_MUX_MASK2))==PORT_PCR_MUX(5)) && ((PORTE->PCR[24]&(PORT_PCR_MUX_MASK2))==PORT_PCR_MUX(5))) + { + gPC.printf("\n\rEntered\n\r"); + I2C0->C1 &= 0x7f; // Disable I2C0 bus + PORTE->PCR[24] &= (~(PORT_PCR_MUX_MASK2)); + PORTE->PCR[25] &= (~(PORT_PCR_MUX_MASK2)); + PORTE->PCR[24] |= PORT_PCR_MUX(1); // PTE24 Alt1 (pin) + PORTE->PCR[25] |= PORT_PCR_MUX(1); // PTE25 Alt1 (pin) + //1011=Interrupt on either edge, check later + if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C0 bus lock-up + { + PTE->PDDR |= 0x01000000; // Set PTE24 as a GPIO output so we can bit bang it + PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; + wait_ms(1); + while(((PTE->PDIR & 0x01000000) == 0x00000000) && count<10) // bit bang SCL until the offending device releases the bus + { + gPC.printf("Entered\n\r"); + PTE->PDOR &= 0xfeffffff; // Set PTE24 (SCL) pin low; + wait_ms(5); + PTE->PDOR |= 0x01000000; // Set PTE24 (SCL) pin high; + wait_ms(5); + count++; + } + } + PORTE->PCR[24] &= (~(PORT_PCR_MUX_MASK2)); + PORTE->PCR[25] &= (~(PORT_PCR_MUX_MASK2)); + PORTE->PCR[24] |= PORT_PCR_MUX(5); // PTE24 Alt5 (SCL) + PORTE->PCR[25] |= PORT_PCR_MUX(5); // PTE25 Alt5 (SDA) + I2C0->C1 |= 0x80; // Enable I2C0 bus + } + gPC.printf("Count %d\n",count); +}*/ +/*void I2C_reInit(void) +{ + if((PORTE->PCR[24] & PORT_PCR_MUX(5)) && (PORTE->PCR[25] & PORT_PCR_MUX(5))) + { + gPC.printf("\n\rRe-Initializing I2C"); + I2C0->C1 &= 0x7f; // Disable I2C0 bus + PORTE->PCR[24] = PORT_PCR_MUX(1); // PTE24 Alt1 (pin) + PORTE->PCR[25] = PORT_PCR_MUX(1); // PTE25 Alt1 (pin) + PTE->PDDR |= 0x03000000; // Set PTE24 as a GPIO output so we can bit bang it + //wait(5); + if((PTE->PDIR & 0x03000000) != 0x03000000) // When PTE24 / PTE25 are not 1 : I2C1 bus lock-up + { + gPC.printf("\nEntered\n"); + //PTE->PDOR |= 0x1; // Set PTE1 (SCL) pin high; + //wait_us(5); + //PTE->PDOR |= 0x2; // Set PTE0 (SDA) pin high; + //wait_us(5); + } + // Reinstate I2C0 bus pins + PORTE->PCR[24] = PORT_PCR_MUX(5); // PTE24 Alt6 (SCL) + PORTE->PCR[25] = PORT_PCR_MUX(5); // PTE25 Alt6 (SDA) + I2C0->C1 |= 0x80; // Enable I2C0 bus + //wait_ms(1); + } +}*/ +void debug2() +{ + gPC.printf("\n\rI2C0->A1 = 0x%02X",I2C0->A1); + gPC.printf("\n\rI2C0->F = 0x%02X",I2C0->F); + gPC.printf("\n\rI2C0->C1 = 0x%02X",I2C0->C1); + gPC.printf("\n\rI2C0->S = 0x%02X",I2C0->S); + gPC.printf("\n\rI2C0->D = 0x%02X",I2C0->D); + gPC.printf("\n\rI2C0->C2 = 0x%02X",I2C0->C2); + gPC.printf("\n\rI2C0->FLT = 0x%02X",I2C0->FLT); + gPC.printf("\n\rI2C0->RA = 0x%02X",I2C0->RA); + gPC.printf("\n\rI2C0->SMB = 0x%02X",I2C0->SMB); + gPC.printf("\n\rI2C0->A2 = 0x%02X",I2C0->A2); + gPC.printf("\n\rI2C0->SLTH = 0x%02X",I2C0->SLTH); + gPC.printf("\n\rI2C0->SLTL = 0x%02X\n",I2C0->SLTL); +} +void debug3() +{ + //gPC.printf("\n\r Resetting I2C"); + //debug2(); + //gPC.printf("\n\r SIM->SCGC4 = 0x%08X",SIM->SCGC4); + PORTE->PCR[1] &= 0xfffffffb; + PORTE->PCR[0] &= 0xfffffffb; + I2C0->C1 &= 0x7f; + //wait_ms(2); + SIM->SCGC4 &= 0xffffffbf; + //gPC.printf("\n\r SIM->SCGC4 = 0x%08X",SIM->SCGC4); + //wait_ms(10); + SIM->SCGC4 |= 0x00000040; + //gPC.printf("\n\r SIM->SCGC4 = 0x%08X",SIM->SCGC4); + //wait_ms(10); + I2C0->C1 |= 0x80; + PORTE->PCR[1] |= 0x00000004; + PORTE->PCR[0] |= 0x00000004; + //wait_us(0); + wait_ms(2); + //gPC.printf("\n\r After enabling clock"); + //debug2(); + //gPC.printf("\n"); +} +void I2C_busreset() +{ + //Thread::wait(1); + PORTE->PCR[1] &= 0xfffffffb; + //Thread::wait(1); + PORTE->PCR[0] &= 0xfffffffb; + //Thread::wait(1); + I2C0->C1 &= 0x7f; + //Thread::wait(1); + SIM->SCGC4 &= 0xffffffbf; + //Thread::wait(1); + SIM->SCGC4 |= 0x00000040; + //Thread::wait(1); + I2C0->C1 |= 0x80; + //Thread::wait(1); + PORTE->PCR[1] |= 0x00000004; + //Thread::wait(1); + PORTE->PCR[0] |= 0x00000004; + Thread::wait(1); +} +/* +#define I2C_busreset {\ + PORTE->PCR[1] &= 0xfffffffb;\ + Thread::wait(1);\ + PORTE->PCR[0] &= 0xfffffffb;\ + Thread::wait(1);\ + I2C0->C1 &= 0x7f;\ + Thread::wait(1);\ + SIM->SCGC4 &= 0xffffffbf;\ + Thread::wait(1);\ + SIM->SCGC4 |= 0x00000040;\ + Thread::wait(1);\ + I2C0->C1 |= 0x80;\ + Thread::wait(1);\ + PORTE->PCR[1] |= 0x00000004;\ + Thread::wait(1);\ + PORTE->PCR[0] |= 0x00000004;\ + Thread::wait(1);\ +} +*/ +Timer synch; void FCTN_I2C_WRITE_PL(char *data2,uint8_t tc_len2) { write_ack = master.write(addr_pl|0x00,data2,tc_len2);//address to be defined in payload if(write_ack == 1) { - printf("\n\rdata not sent\n"); - } + printf("\n\rData not sent"); + } else { - } + } } - +uint32_t pdirr1,pdirr2; +uint32_t pdirw1,pdirw2; -void FCTN_I2C_READ(char *data,int length) -{ +bool FCTN_I2C_READ(char *data,int length) +{ CDMS_I2C_GPIO = 1; + //gPC.printf("\n\n\rGiven TM Size : %d",length); //t_read.start(); + //gPC.printf("\n\rEntered read"); + //Thread::wait(1); read_ack = master.read(addr_bae|1,data,length); - //t_read.stop(); - + //gPC.printf("\n\rExited read"); + Thread::wait(1); //as per tests Thread::wait not required on master side. But its safe to give 1ms + pdirr1=PTE->PDIR; + uint8_t i2c_count = 0; if(read_ack == 0) - printf("\n\rData received from BAE %s \n",data); - if (read_ack == 1) { - printf("\n \r data not received \n"); + while(((pdirr1 & 0x03000000)!=0x03000000)&& i2c_count<10) + { + Thread::wait(1); + pdirr1=PTE->PDIR; + i2c_count++; + } + if(((pdirr1 & 0x03000000)==0x03000000)) + { + gPC.printf("\n\rData received from BAE"); + //printf("Telemetry : %d\n\r",data); + } + else + { + #if PRINT + gPC.printf("\n\rData not received"); + gPC.printf("\n\rPTE->DIR = 0x%08X",pdirr1); + #endif + I2C_busreset(); + pdirr2=PTE->PDIR; + #if PRINT + gPC.printf("\n\rPTE->DIR = 0x%08X",pdirr2); + #endif + read_ack = 1; + } + //gPC.printf("\n\rRead count:%d",i2c_count); } -//if(read_ack == 1) -//pc.printf("\n \r data not received \n"); - + else if (read_ack == 1) + { + //Thread::wait(10); + #if PRINT + gPC.printf("\n\rRead Ack failed"); + gPC.printf("\n\rPTE->DIR = 0x%08X",pdirr1); + #endif + I2C_busreset(); + //wait(1); + pdirr2=PTE->PDIR; + #if PRINT + gPC.printf("\n\rPTE->DIR = 0x%08X",pdirr2); + #endif + //wait_ms(30); + //gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + //debug3(); + //gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + //wait_ms(30); + } + //gPC.printf("\n\rPTE->DIR = 0x%08X",pdirr1); + //gPC.printf("\n\rPORTE->PCR[24] = 0x%08X",PORTE->PCR[24]); + //gPC.printf("\n\rPORTE->PCR[25] = 0x%08X",PORTE->PCR[25]); + + //if(temp==2) + //debug(); + //else + //debug(); CDMS_I2C_GPIO = 0; + i2c_count = 0; + return read_ack; //printf("\n\r %d \n",t.read_us()); //t.reset(); } -void FCTN_I2C_WRITE(char *data,uint8_t tc_len2) -{ +bool FCTN_I2C_WRITE(char *data,int tc_len2) +{ CDMS_I2C_GPIO = 1; + //synch.start(); //t.start(); - write_ack = master.write(addr_bae|0x00,data,tc_len2); + //wait_us(300); + //Thread::wait(1); + //synch.stop(); + temp_flag = 1; + write_ack = master.write(addr_bae|0x00,data,tc_len2); + if(temp_flag==1) + temp_flag = 0; + Thread::wait(1); //As per the tests Thread::wait is not required on master side but its safe to give 1ms + pdirw1=PTE->PDIR; + uint8_t i2c_count = 0; //t.stop(); + //gPC.printf("\n\n\rGiven TC Size : %d",tc_len2); + //printf("\n\rTelecommand: "); + //for(uint8_t j=0;j<11;j++) + //printf("%02x ",data[j]); if(write_ack == 0) - gPC.printf("\n\r data sent \n"); - -if (write_ack == 1) { -// led2 = 1; - gPC.printf("\n\r data not sent \n"); -// led2 = 0; + while(((pdirw1 & 0x03000000)!=0x03000000)&& i2c_count<10) + { + Thread::wait(1); + pdirw1=PTE->PDIR; + i2c_count++; + } + if(((pdirw1 & 0x03000000)==0x03000000)) + { + gPC.printf("\n\r Data sent"); + //gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + } + else + { + #if PRINT + gPC.printf("\n\r Data not sent"); + gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + #endif + I2C_busreset(); + //pdirw2=PTE->PDIR; + #if PRINT + gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + #endif + write_ack = 1; + } + //gPC.printf("\n\rWrite count:%d",i2c_count); + } + if (write_ack == 1) + { + #if PRINT + gPC.printf("\n\rWrite Ack failed"); + gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + #endif + I2C_busreset(); + //pdirw2=PTE->PDIR; + #if PRINT + gPC.printf("\n\rPTE->DIR = 0x%08X",PTE->PDIR); + #endif } + //gPC.printf("\n\rPTE->DIR = 0x%08X",pdirw1); + //wait_ms(10); + //debug(); CDMS_I2C_GPIO = 0; + i2c_count = 0; + //gPC.printf("Time after master.write() = %d",synch.read_us()); + //synch.reset(); + return write_ack; //gPC.printf("\n\r %d \n",t.read_us()); //t.reset(); }