Other Parts Discussed in Thread: C2000WARE
Tool/software: Code Composer Studio
I've been working on LaunchPad F28377S for a while now. I recently got an OLED I2C display to work with. In TMS320F28377S technical reference guide, they mentioned GPIOs 42,43 and GPIOs 91,92 both for I2C-A. But I decided to settle on the GPIOs 42 and 43. I couldn't get any output at those pins (neither clock nor data). I've tried GPIOs 91, 92 but in vain. Here's my code:
#include "F28x_Project.h" /** * main.c */ #define OLED_I2C_ADDRESS 0x3C // Control byte #define OLED_CONTROL_BYTE_CMD_SINGLE 0x0080 #define OLED_CONTROL_BYTE_CMD_STREAM 0x0000 #define OLED_CONTROL_BYTE_DATA_STREAM 0x0040 // Fundamental commands (pg.28) #define OLED_CMD_SET_CONTRAST 0x0081 // follow with 0x7F #define OLED_CMD_DISPLAY_RAM 0x00A4 #define OLED_CMD_DISPLAY_ALLON 0x00A5 #define OLED_CMD_DISPLAY_NORMAL 0x00A6 #define OLED_CMD_DISPLAY_INVERTED 0x00A7 #define OLED_CMD_DISPLAY_OFF 0x00AE #define OLED_CMD_DISPLAY_ON 0x00AF // Addressing Command Table (pg.30) #define OLED_CMD_SET_MEMORY_ADDR_MODE 0x0020 // follow with 0x00 = HORZ mode = Behave like a KS108 graphic LCD #define OLED_CMD_SET_COLUMN_RANGE 0x0021 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F = COL127 #define OLED_CMD_SET_PAGE_RANGE 0x0022 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 = PAGE7 // Hardware Config (pg.31) #define OLED_CMD_SET_DISPLAY_START_LINE 0x0040 #define OLED_CMD_SET_SEGMENT_REMAP 0x00A1 #define OLED_CMD_SET_MUX_RATIO 0x00A8 // follow with 0x3F = 64 MUX #define OLED_CMD_SET_COM_SCAN_MODE 0x00C8 #define OLED_CMD_SET_DISPLAY_OFFSET 0x00D3 // follow with 0x00 #define OLED_CMD_SET_COM_PIN_MAP 0x00DA // follow with 0x12 #define OLED_CMD_NOP 0x00E3 // NOP // Timing and Driving Scheme (pg.32) #define OLED_CMD_SET_DISPLAY_CLK_DIV 0x00D5 // follow with 0x80 #define OLED_CMD_SET_PRECHARGE 0x00D9 // follow with 0xF1 #define OLED_CMD_SET_VCOMH_DESELCT 0x00DB // follow with 0x30 // Charge Pump (pg.62) #define OLED_CMD_SET_CHARGE_PUMP 0x008D // follow with 0x14 void oled_init(Uint16 Slave_address); void I2C_Write(Uint16 Slave_address, Uint16 No_of_databytes, Uint16 Write_Array[]); void I2C_WriteByte(Uint16 Slave_address, Uint16 databyte); Uint16 pattern1[17] = {0x0040,0x0000,0x007E,0x0042,0x0042,0x0042,0x0042,0x007E,0x0000,0x0000,0x007E,0x0042,0x0042,0x0042,0x0042,0x007E,0x0000}; void i2c_a_gpio_init (void); void I2CA_Init(); int main(void) {uint32_t i; InitSysCtrl(); InitGpio(); i2c_a_gpio_init (); InitPieCtrl(); InitPieVectTable(); I2CA_Init(); I2caRegs.I2CMDR.bit.IRS = 0; I2caRegs.I2CPSC.all = 19; // I2C clock should be between 7Mhz-12Mhz I2caRegs.I2CCLKL = 45; // Prescalers set for 100kHz bit rate I2caRegs.I2CCLKH = 45; // At a 10Mhz I2C clock I2caRegs.I2CMDR.bit.IRS = 1; Uint16 Slave_address = 0x003C; oled_init(Slave_address); Uint16 write_array[7] = {OLED_CONTROL_BYTE_CMD_STREAM,OLED_CMD_SET_COLUMN_RANGE,0x0000,0x007F,OLED_CMD_SET_PAGE_RANGE,0x0000,0x0007}; I2C_Write(Slave_address, 7, write_array); I2C_Write(Slave_address,17, pattern1); return 0; } void I2C_Write(Uint16 Slave_address, Uint16 No_of_databytes, Uint16 Write_Array[]) { /*Uint16 i = 0; I2caRegs.I2CSAR.all = Slave_address; while(I2caRegs.I2CMDR.bit.STP != 0); I2caRegs.I2CMDR.all = 0x2620; I2caRegs.I2CCNT = No_of_databytes; // Data Bytes to be transmitted while(i < No_of_databytes) { while(I2caRegs.I2CSTR.bit.XRDY != 1); DSP28x_usDelay(5000); if (I2caRegs.I2CSTR.bit.XRDY == 1) { I2caRegs.I2CDXR.all = Write_Array[i++]; // Lower 16 address bits } } while(I2caRegs.I2CSTR.bit.SCD != 1); I2caRegs.I2CSTR.bit.SCD = 1; // Clear stop condition */ I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C // Make sure I2C is not busy and has stopped while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit) while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop I2caRegs.I2CSAR.all = Slave_address; // I2C slave address while (I2caRegs.I2CSTR.bit.BB == 1); // still busy? I2caRegs.I2CCNT = No_of_databytes; // assume register address = 1 byte, and data is 1 byte //I2caRegs.I2CMDR.all = 0x6E20; // start, stop, no rm, reset i2c 01101110 00100000 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 1; // Run free I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 1; // Transmitter mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte Uint16 i; for(i=0;i<No_of_databytes;i++) { while(I2caRegs.I2CSTR.bit.XRDY == 0); // Do nothing till bus is free I2caRegs.I2CDXR.all = Write_Array[i]; // data to be sent (1 byte) } I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0 while(!I2caRegs.I2CSTR.bit.SCD); // wait for STOP condition } void I2C_WriteByte(Uint16 Slave_address, Uint16 databyte) { Uint16 arr[1] = {databyte}; I2C_Write(Slave_address, 1, arr); } void oled_init(Uint16 Slave_address) { I2C_WriteByte(Slave_address,OLED_CONTROL_BYTE_CMD_STREAM); // Follow instructions on pg.64 of the dataSheet for software configuration of the SSD1306 // Turn the Display OFF I2C_WriteByte(Slave_address,OLED_CMD_DISPLAY_OFF); // Set mux ration tp select max number of rows - 64 I2C_WriteByte(Slave_address,OLED_CMD_SET_MUX_RATIO); I2C_WriteByte(Slave_address,0x3F); // Set the display offset to 0 I2C_WriteByte(Slave_address,OLED_CMD_SET_DISPLAY_OFFSET); I2C_WriteByte(Slave_address,0x00); // Display start line to 0 I2C_WriteByte(Slave_address,OLED_CMD_SET_DISPLAY_START_LINE); // Mirror the x-axis. In case you set it up such that the pins are north. // I2C_WriteByte(Slave_address,0xA0); - in case pins are south - default I2C_WriteByte(Slave_address,OLED_CMD_SET_SEGMENT_REMAP); // Mirror the y-axis. In case you set it up such that the pins are north. // I2C_WriteByte(Slave_address,0xC0); - in case pins are south - default I2C_WriteByte(Slave_address,OLED_CMD_SET_COM_SCAN_MODE); // Default - alternate COM pin map I2C_WriteByte(Slave_address,OLED_CMD_SET_COM_PIN_MAP); I2C_WriteByte(Slave_address,0x12); // set contrast I2C_WriteByte(Slave_address,OLED_CMD_SET_CONTRAST); I2C_WriteByte(Slave_address,0x7F); // Set display to enable rendering from GDDRAM (Graphic Display Data RAM) I2C_WriteByte(Slave_address,OLED_CMD_DISPLAY_RAM); // Normal mode! I2C_WriteByte(Slave_address,OLED_CMD_DISPLAY_NORMAL); // Default oscillator clock I2C_WriteByte(Slave_address,OLED_CMD_SET_DISPLAY_CLK_DIV); I2C_WriteByte(Slave_address,0x80); // Enable the charge pump I2C_WriteByte(Slave_address,OLED_CMD_SET_CHARGE_PUMP); I2C_WriteByte(Slave_address,0x14); // Set precharge cycles to high cap type I2C_WriteByte(Slave_address,OLED_CMD_SET_PRECHARGE); I2C_WriteByte(Slave_address,0x22); // Set the V_COMH deselect volatage to max I2C_WriteByte(Slave_address,OLED_CMD_SET_VCOMH_DESELCT); I2C_WriteByte(Slave_address,0x30); // Horizonatal addressing mode - same as the KS108 GLCD I2C_WriteByte(Slave_address,OLED_CMD_SET_MEMORY_ADDR_MODE); I2C_WriteByte(Slave_address,0x00); // Turn the Display ON I2C_WriteByte(Slave_address,OLED_CMD_DISPLAY_ON); } void I2CA_Init() { I2caRegs.I2CMDR.all = 0x0000; I2caRegs.I2CPSC.all = 8; // Prescaler - need 7-12 Mhz on module clk I2caRegs.I2CCLKL = 10; // NOTE: must be non zero I2caRegs.I2CCLKH = 5; // NOTE: must be non zero //I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts 0010 0100 I2caRegs.I2CIER.bit.AAS = 0; // Addressed as slave interrupt enable bit I2caRegs.I2CIER.bit.SCD = 1; // Stop condition detected interrupt enable bit I2caRegs.I2CIER.bit.XRDY = 1; // Transmit-data-ready interrupt enable bit I2caRegs.I2CIER.bit.XRDY = 1; // Receive-data-ready interrupt enable bit I2caRegs.I2CIER.bit.ARDY = 1; // Register-access-ready interrupt enable bit I2caRegs.I2CIER.bit.NACK = 0; // No-acknowledgment interrupt enable bit I2caRegs.I2CIER.bit.ARBL = 0; // Arbitration-lost interrupt enable bit //I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset,Stop I2C when suspended I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 0; // START condition bit I2caRegs.I2CMDR.bit.STP = 0; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Slave mode I2caRegs.I2CMDR.bit.TRX = 1; // Receiver mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte // FIFO not used return; } void i2c_a_gpio_init (void) { EALLOW; // Set qualification for the selected I2C pins GpioCtrlRegs.GPBQSEL1.bit.GPIO42 = 3; GpioCtrlRegs.GPBQSEL1.bit.GPIO43 = 3; GpioCtrlRegs.GPBDIR.bit.GPIO43 = 1; // Configure which of the possible GPIO pins will be I2C_A pins // using GPIO registers GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 6; GpioCtrlRegs.GPBMUX1.bit.GPIO43= 6; GpioCtrlRegs.GPBPUD.bit.GPIO43=0; GpioCtrlRegs.GPBPUD.bit.GPIO42=0; //GPIO_SetupPinMux(42, GPIO_MUX_CPU1,6); //GPIO_SetupPinMux(43, GPIO_MUX_CPU1,6); EDIS; }