program to set the MCP4728 address for the SOLID amplifier board

Dependencies:   DevInterfaces I2Cinterfaces MCP4728setaddr mbed

Revision:
0:d97e8b3802b3
Child:
1:7e052cf2f2ee
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jan 12 14:43:00 2016 +0000
@@ -0,0 +1,197 @@
+#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       
+};
+