123

Dependencies:   mbed

Fork of LG by igor Apu

DeviceI2C.c

Committer:
Diletant
Date:
2016-06-05
Revision:
167:bedc0a9d559a
Parent:
161:efd949e8d536
Child:
183:c7a9c309086c

File content as of revision 167:bedc0a9d559a:

#include "Device.h"

//I2C Control Set Register
#define I2CONSET_I2EN  0x0000040
#define I2CONSET_AA    0x0000004
#define I2CONSET_SI    0x0000008
#define I2CONSET_STO   0x0000010
#define I2CONSET_STA   0x0000020
//I2C Control clear Register
#define I2CONCLR_AAC   0x0000004
#define I2CONCLR_SIC   0x0000008
#define I2CONCLR_STAC  0x0000020
#define I2CONCLR_I2ENC 0x0000040
//I2C SCL Duty Cycle High Reg
#define I2SCLH_SCLH    0x00000080 //High
#define I2SCLL_SCLL    0x00000080 //Low
//Address
#define I2C_A_ADDRESS  0x0000005E //address of slave potentiometer A (table 6-2 of pot's manual)
#define I2C_B_ADDRESS  0x0000005C //address of slave potentiometer B (table 6-2 of pot's manual)
#define I2C_WRITE_CMD  0x00000000 //address of wiper0 register in memory map
//Timeout
#define I2C_TIMEOUT    1000

extern Device device;

//
//Warning!!!
//  Different LPC17xx.h versions declare different I2C registers names:
//    LPC_I2C0->CONCLR (Keil?)/ LPC_I2C0->I2CONCLR (mbed)
//    ...
//

void InitI2CDefaultSettings(void){
  device.controller.I2C.settings.trigger = 1000;
}

void InitI2CState(void) {
  device.controller.I2C.state.buffer[0] = I2C_A_ADDRESS;
  device.controller.I2C.state.buffer[1] = I2C_WRITE_CMD;
  device.controller.I2C.state.buffer[2] = device.isacs.potentiometers.settings.a;
  device.controller.I2C.state.buffer[3] = I2C_B_ADDRESS;
  device.controller.I2C.state.buffer[4] = I2C_WRITE_CMD;
  device.controller.I2C.state.buffer[5] = device.isacs.potentiometers.settings.b;
  device.controller.I2C.state.position = 0;
  device.controller.I2C.state.counter = 0;
  device.controller.I2C.state.trigger = device.controller.I2C.settings.trigger;
}

void DeviceStartI2C(void) {
  LPC_SC->PCONP |= (1 << 7);//I2C0 on
  //LPC_SC->PCONP |= (1 << 19);//I2C1 on

  // set PIO0.27 and PIO0.28 to I2C0 SDA and SCK
  // function to 01 on both SDA and SCK
  LPC_PINCON->PINSEL1 &= ~0x03C00000; //P0.27 - SDA
  LPC_PINCON->PINSEL1 |= 0x01400000;  //P0.28 - SCK
  
  LPC_I2C0->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC; //Master mode
  //LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC; //Master mode

  LPC_I2C0->SCLL   = I2SCLL_SCLL; // - счетчик scl low time period
  //LPC_I2C0->I2SCLL   = I2SCLL_SCLL; // - счетчик scl low time period
  LPC_I2C0->SCLH   = I2SCLH_SCLH; // - счетчик scl high time period
  //LPC_I2C0->I2SCLH   = I2SCLH_SCLH; // - счетчик scl high time period
  
  LPC_I2C0->CONSET = I2CONSET_I2EN; //включение интерфейса I2C
  //LPC_I2C0->I2CONSET = I2CONSET_I2EN; //включение интерфейса I2C
  
  device.controller.I2C.state.CON0 = LPC_I2C0->CONSET & (~LPC_I2C0->CONCLR);
  //device.controller.I2C.state.CON0 = LPC_I2C0->I2CONSET & (~LPC_I2C0->I2CONCLR);
}

void DeviceI2CTransmit(void) {
  if (!device.controller.I2C.state.enabled) return;                   //Transmission disabled, go away

  device.controller.I2C.state.counter++;
  if (device.controller.I2C.state.counter > device.controller.I2C.state.trigger){//Time out, go away
    device.controller.I2C.state.counter = 0;
    device.controller.I2C.state.enabled = 0;
    LPC_I2C0->CONSET = I2CONSET_STO;                     //Set Stop flag
    //LPC_I2C0->I2CONSET = I2CONSET_STO;                     //Set Stop flag
    LPC_I2C0->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC;
    //LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC;
    return;
  }
  
  if (!(LPC_I2C0->CONSET & I2CONSET_SI)) return;         //State of I2C bus has not been changed
  //if (!(LPC_I2C0->I2CONSET & I2CONSET_SI)) return;         //State of I2C bus has not been changed

  uint32_t StatValue = LPC_I2C0->STAT;
  //uint32_t StatValue = LPC_I2C0->I2STAT;
  switch ( StatValue ) {
    //Start condition issued (write data for the first potentiometer) 
    case 0x08:
      device.controller.I2C.state.position = 0;                       //Init buffer position
      device.controller.I2C.state.counter = 0;                 //Init countdown
      LPC_I2C0->DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send address
      //LPC_I2C0->I2DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send address
      LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //Clear interrupt bit and start bit
      //LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //Clear interrupt bit and start bit
    break;
    
    //Repeated started is issued (write data for the second potentiometer) 
    case 0x10:
      LPC_I2C0->DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send address
      //LPC_I2C0->I2DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send address
      LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //Clear interrupt bit and start bit
      //LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //Clear interrupt bit and start bit
    break;

    //ACK after slave address reading
    case 0x18:
      LPC_I2C0->DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send another byte
      //LPC_I2C0->I2DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];  //Send another byte
      LPC_I2C0->CONCLR = I2CONCLR_SIC;                   //Clear interrupt bit
      //LPC_I2C0->I2CONCLR = I2CONCLR_SIC;                   //Clear interrupt bit
    break;

    //ACK after data byte
    case 0x28:
      if  (device.controller.I2C.state.position == I2C_BUFFER_LENGTH) {                   //Data transmission finished
        device.controller.I2C.state.enabled = 0;
        LPC_I2C0->CONSET = I2CONSET_STO;                 //Set Stop flag
        //LPC_I2C0->I2CONSET = I2CONSET_STO;                 //Set Stop flag
       //Output.Str.Cnt_Dif = 300;
      } else if (device.controller.I2C.state.position == 3) {
       LPC_I2C0->CONSET = I2CONSET_STA;
       //LPC_I2C0->I2CONSET = I2CONSET_STA;
       //Output.Str.Cnt_Dif = 200;
      } else {
        LPC_I2C0->DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];//Send another byte   
        //LPC_I2C0->I2DAT = device.controller.I2C.state.buffer[device.controller.I2C.state.position++];//Send another byte   
        //Output.Str.Cnt_Dif = 100;
      }
      LPC_I2C0->CONCLR = I2CONCLR_SIC;                   //Clear interrupt bit
      //LPC_I2C0->I2CONCLR = I2CONCLR_SIC;                   //Clear interrupt bit
    break;

    //No acknoledgement after address transmitting
    case 0x20:
    //No acknoledgement after data block transmitting
    case 0x30:
      LPC_I2C0->CONSET = I2CONSET_STO;                   //Set Stop flag
      //LPC_I2C0->I2CONSET = I2CONSET_STO;                   //Set Stop flag
      LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
      //LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
      device.controller.I2C.state.enabled = 0;                        //Disable transmission
    break;
  }
}

void StartI2CTransmission(void){
  device.controller.I2C.state.position = 0;
  device.controller.I2C.state.counter = I2C_TIMEOUT;
  LPC_I2C0->CONSET = I2CONSET_STA; //Set start flag
  //LPC_I2C0->I2CONSET = I2CONSET_STA; //Set start flag
  device.controller.I2C.state.enabled = 1;      //Enable transmission
}