/* I2C_DAC_MCP4725 via I2C * * The program generates sinewave output through DAC. * I2C1SCL PA6 * I2C1SDA PA7 * Put speaker jumper on DAC and you will hear the tone. * * Built and tested with Keil MDK-ARM v5.24a and TM4C_DFP v1.1.0 */ #include "TM4C123GH6PM.h" #define SLAVE_ADDR 0x60 // 1100 xx0. void I2C1_init(void); int I2C1_burstWrite(int slaveAddr, char command, int byteCount, const char* data); void delayMs(int n); static int I2C_wait_till_done(void); void MCP4725_data(int n); const static int sineWave[] = {2047,3071,3820,4094,3820,3071, 2047,1024, 274, 0, 274,1024}; int main(void) { short i; I2C1_init(); for (;;) { /* infinite loop */ for (i = 0; i < 12; i++) { MCP4725_data(sineWave[i]); } } } void MCP4725_data(int n) { char data[2]; data[1] = (n << 4) & 0xFF; data[0] = (n >> 4) & 0xFF; I2C1_burstWrite(SLAVE_ADDR, 0x40, 2, data); } // initialize I2C1 as master and the port pins void I2C1_init(void) { SYSCTL->RCGCI2C |= 0x02; // enable clock to I2C1 SYSCTL->RCGCGPIO |= 0x01; // enable clock to GPIOA // PORTA 7, 6 for I2C1 GPIOA->AFSEL |= 0xC0; // PORTA 7, 6 for I2C1 GPIOA->PCTL &= ~0xFF000000; // PORTA 7, 6 for I2C1 GPIOA->PCTL |= 0x33000000; GPIOA->DEN |= 0xC0; // PORTA 7, 6 as digital pins GPIOA->ODR |= 0x80; // PORTA 7 as open drain I2C1->MCR = 0x10; // master mode I2C1->MTPR = 24; // 100 kHz @ 50 MHz } // Wait until I2C master is not busy and return error code // If there is no error, return 0 static int I2C_wait_till_done(void) { while(I2C1->MCS & 1); // wait until I2C master is not busy return I2C1->MCS & 0xE; // return I2C error code } // Use burst write to write multiple bytes to consecutive locations // burst write: S-(saddr+w)-ACK-command-ACK-data-ACK-data-ACK-...-data-ACK-P int I2C1_burstWrite(int slaveAddr, char command, int byteCount, const char* data) { char error; if (byteCount <= 0) return -1; // no write was performed // send slave address and starting address I2C1->MSA = slaveAddr << 1; I2C1->MDR = command; I2C1->MCS = 3; // S-(saddr+w)-ACK-maddr-ACK error = I2C_wait_till_done(); // wait until write is complete if (error) return error; // send data one byte at a time while (byteCount > 1) { I2C1->MDR = *data++; // write the next byte I2C1->MCS = 1; // -data-ACK- error = I2C_wait_till_done(); if (error) return error; byteCount--; } // send last byte and a STOP I2C1->MDR = *data++; // write the last byte I2C1->MCS = 5; // -data-ACK-P error = I2C_wait_till_done(); while(I2C1->MCS & 0x40); // wait until bus is not busy if (error) return error; return 0; // no error } /* delay n milliseconds (50 MHz CPU clock) */ void delayMs(int n) { int i, j; for(i = 0 ; i< n; i++) for(j = 0; j < 6265; j++) {} /* do nothing for 1 ms */ }