program to set the MCP4728 address for the SOLID amplifier board

Dependencies:   DevInterfaces I2Cinterfaces MCP4728setaddr mbed

main.cpp

Committer:
wbeaumont
Date:
2016-01-12
Revision:
0:d97e8b3802b3
Child:
1:7e052cf2f2ee

File content as of revision 0:d97e8b3802b3:

#include "mbed.h"
#include "I2C.h" 
#define TARGET TARGET_KL05Z
#if   defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
  PinName const SDA = PTE25;
  PinName const SCL = PTE24;
#elif defined (TARGET_KL05Z)
  PinName const SDA = PTB4;
  PinName const SCL = PTB3;
#elif defined (TARGET_K20D50M)
  PinName const SDA = PTB1;
  PinName const SCL = PTB0;
#else
  #error TARGET NOT DEFINED
#endif

#define MCP4728_readaddresscmd 0xC
#define MCP4728_baseaddr 0xC0


class I2CInterface {
public : 
    I2CInterface(){};   //Create an I2C Master interface
virtual void    frequency (int hz){};//  Set the frequency of the I2C interface.
virtual int     read (int address, char *data, int length, bool repeated=false){
            return 0;};//Read from an I2C slave.
virtual int     read (int ack){return 0;};// Read a single byte from the I2C bus.
virtual int     write (int address, const char *data, int length, bool repeated=false){
            return 0;
        };// Write to an I2C slave.
virtual int     write (int data){return 0;};//  Write single byte out on the I2C bus.
virtual void    start (void){};// Creates a start condition on the I2C bus.
virtual void    stop (void){};// Creates a stop condition on the I2C bus.
virtual int     transfer (int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false){
            return 0;
        };     //   Start non-blocking I2C transfer.     
    
}; 

class MBEDI2CInterface :public I2CInterface {
    
    I2C i2cdev;
    public :
        
    MBEDI2CInterface(PinName sda, PinName scl): i2cdev(sda,scl){} ;
    // next could perhaps more efficient  but not yet investigated 
virtual void    frequency (int hz){return i2cdev.frequency(hz) ;};
virtual int     read (int address, char *data, int length, bool repeated=false){
            return i2cdev.read ( address, data, length, repeated);};
 virtual int     read (int ack){return i2cdev.read ( ack);};// Read a single byte from the I2C bus.
 virtual int     write (int address, const char *data, int length, bool repeated=false){
            return i2cdev.write ( address, data, length, repeated);
        }
virtual int     write (int data){return i2cdev.write (data);};//  Write single byte out on the I2C bus.
virtual void    start (void){i2cdev.start ();};// Creates a start condition on the I2C bus.
virtual void    stop (void){i2cdev.stop();};// Creates a stop condition on the I2C bus.
virtual int     transfer (int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false){
            return  -1;  // seems transfer not supported in mbed or not correctly called below
           //  return i2cdev.transfer (address, tx_buffer,  tx_length, rx_buffer,  rx_length, callback,  event,  repeated);
        };    
    
    
    } ;


MBEDI2CInterface mbedi2c( SDA, SCL); 

MBEDI2CInterface* mbedi2cp=  &mbedi2c ;

I2CInterface* i2cdev= mbedi2cp;


DigitalOut LDAC(PTA6);
DigitalOut CntPin(PTA7);
 

I2CInterface* i2cif;


class MPC4728_address_set{
    I2CInterface *i2cd;
    DigitalOut *LDAC;
    DigitalOut *Cntout;
    InterruptIn cntin;
    int sclcnt;
    unsigned char oldaddress;
 void count_down( ){
        sclcnt--;
        *Cntout=1;
        *Cntout=0;
        if ( sclcnt==0){ 
            //disable this interrupt 
            int wait=10;  while ( wait--);
            *LDAC=0;
        }
 }
 
public:
 MPC4728_address_set(PinName sclcntpin, DigitalOut *LDACpin, I2CInterface* i2cdevice, DigitalOut *Cntoutpin   ): cntin(sclcntpin) {
        i2cd=i2cdevice;
        LDAC=LDACpin;
        Cntout=Cntoutpin;
        *Cntoutpin=0;
        *LDAC=1;
         i2cd->frequency(40000); // interrupt is slow, so set to 40 kHz 
        
 }        


int getsclcnt( ){return sclcnt;}

int readaddress(char* address, char *eepromaddr=0 , char *regaddr=0 ) {
          *LDAC=1;
        start_scl_cnt(18);// 1+9+8 faling edges 
        *address=0x0C; // not allowed value
        char cmd = MCP4728_readaddresscmd;
        int i2cresult=i2cd->write(0, &cmd, 1,true ); //1 byte don't send stop  
        if  ( i2cresult ) {  // <> 0 
            //i2cd->abort_transfer  (  );
            i2cd->stop();
            *address=0xFF;
            return i2cresult ;
        }
        i2cresult=i2cd->read(MCP4728_baseaddr, &cmd, 1,false ); 
        if ( i2cresult) *address=0xFE;
        else {
             *address=cmd;
             *regaddr= cmd >>1;
             *regaddr= *regaddr& 0x7;
             *eepromaddr = cmd>>5;
             *eepromaddr = *eepromaddr & 0x7 ;
        }
        *LDAC=1;
        return i2cresult ;
}    


  int setaddress(char currentaddress, char newaddress ){  // both address 
       *LDAC=1;
        char oldaddr=0x7 & currentaddress;oldaddr=oldaddr<<1;
        char newaddr=0x7 & newaddress; 
        newaddr= newaddr<<2;
        char address=MCP4728_baseaddr | oldaddr;oldaddr=oldaddr<<1;
        const char cmdtype= 0x60;  // 0x011000000   0x011AAA0
        char  data[3] ;
        data[0]= cmdtype | oldaddr | 1; //0x011OOO01
        data[1]= cmdtype | newaddr | 2; //0x011NNN10
        data[2]= cmdtype | newaddr | 3; //0x011NNN11
        printf( "cmd %x %x data %x %x %x \n\r", newaddress, newaddr,(int)data[0],(int)data[1],(int)data[2]);
         start_scl_cnt(18);//1+ 9+8 faling edges 
        int i2cresult=i2cd->write(address, data, 3,false ); //3 bytes sent and stop
        *LDAC=1;
        return i2cresult ;
   }

  void start_scl_cnt(int cnts) {
    sclcnt= cnts; 
    cntin.fall(this, &MPC4728_address_set::count_down);    
  }    

};//endclass 

int main(void){
  printf("\n\rMCP4728 set address program date : %s  time :%s\n\r",__DATE__,__TIME__); 

  LDAC=1;
  char oldaddr, eeaddr, regaddr, newaddr= 2;
  int newaddrint;
  MPC4728_address_set mpc4728(PTB0,&LDAC,i2cdev, &CntPin);
  int i2cresult =mpc4728.readaddress(&oldaddr, &eeaddr, &regaddr);
  if ( i2cresult ) {
    printf("failed to read current address error code: %d , scl cnt = %d  \n", i2cresult,mpc4728.getsclcnt() );
  }
  else { 
    printf( " current address = %d ,eeaddr %d , regaddr %d  sclcnt= %d  give new address :  ", (int) oldaddr,(int) eeaddr, (int)regaddr, mpc4728.getsclcnt());  
    scanf( "%d",&newaddrint);
    printf("\n\r");
    if ( newaddrint >= 0 && newaddrint <= 8 ) {
        newaddr= (char) newaddrint;
        i2cresult=mpc4728.setaddress(oldaddr,newaddr);
        if ( i2cresult ) printf("failed to set address to %d error : %d , sclcnt= %d  \n",newaddr, i2cresult,mpc4728.getsclcnt());
        else {
             printf("set new  address \n");
            i2cresult =mpc4728.readaddress(&oldaddr, &eeaddr, &regaddr);
            if ( i2cresult ) printf("failed to read (new)  address error : %d  \n", i2cresult);
            else     printf( "new address = %d ,eeaddr %d , regaddr %d  sclcnt= %d  \n\r", (int) oldaddr,(int) eeaddr, (int)regaddr, mpc4728.getsclcnt());  printf( " new address = %d \n", (int) oldaddr);
        }
    }    
    else {
        printf( " new address %d is not valid reset the up to restart the program \n", (int)newaddr );
    }
  }
  printf("restart !!!! \n\r");
  while (1);  
  //return 0; // never reach this       
};