This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2553: interfacing SSD1306 with software i2c to the launchpad

Part Number: MSP430G2553

I am having challenges driving the SDD1306 OLED, I am using a Launchpad for debugging, it is software implementation as it was a late addition to the system and is not connected to the msp430’s hardware on my custom board, and those ports are used already for other comunication purposes.

 

According to the waveform it should be working, if I switch the code to hardware i2c it works, as I am using the lauchpad’s P1.6 and P1.7.

 

Anyways, does anyone of your team has expertise on those little OLEDs?

to switch from software to hardware "#define i2c_bitbang true|false // enable i2c bitbang"

thanks

here is the code

#include <msp430.h>
#include <stdint.h>

#include <stdio.h>
#include <string.h>

#include "fonts.h"

#define true 0x1
#define false 0x0

//######################################################################
//for Bitbang i2c
//######################################################################

/* Pin Definitions. These should be changed depending on the device that
* you are using.
*/
#define SWI2C_SCL BIT6
#define SWI2C_SDA BIT7
#define SWI2C_PxDIR P1DIR
#define SWI2C_PxOUT P1OUT
#define SWI2C_PxIN P1IN
#define SWI2C_SDA_LOW SWI2C_PxDIR |= SWI2C_SDA
#define SWI2C_SCL_LOW SWI2C_PxDIR |= SWI2C_SCL
#define SWI2C_SCL_HIGH SWI2C_PxDIR &= ~SWI2C_SCL
#define SWI2C_SDA_HIGH SWI2C_PxDIR &= ~SWI2C_SDA


#define I2C_BB_PORT P1 // port to use for I2C pins
#define I2C_BB_SCL BIT6 // pins to use on I2C port
#define I2C_BB_SDA BIT7 // pins to use on I2C port
#define I2C_BB_LED0 BIT0

// tricky macros, needed to get around macro expansion
#define out(r) _out(r)
#define _out(r) (r##OUT)
#define in(r) _in(r)
#define _in(r) (r##IN)
#define dir(r) _dir(r)
#define _dir(r) (r##DIR)

//I2C registers
#define I2C_BB_IN in(I2C_BB_PORT)
#define I2C_BB_OUT out(I2C_BB_PORT)
#define I2C_BB_DIR dir(I2C_BB_PORT)

//Function prototypes
void i2c_bb_setup(void);
void i2c_bb_start(void);
void i2c_bb_stop(void);
void i2c_bb_clear_OLED(void);
void i2c_bb_TransferBuffer(void);
short i2c_bb_tx_byte(unsigned char val);
void i2c_bb_set_OLED_home(void);
unsigned char i2c_bb_rx_byte(unsigned short ack);
short i2c_bb_tx(unsigned char addr,const char *dat,unsigned short len);
short i2c_bb_rx(unsigned char addr,unsigned char *dest,unsigned short len);
//###################### bitbang i2c end ##################################

typedef uint8_t boolean;
typedef uint8_t byte;

#define i2c_bitbang true // enable i2c bitbang

void begin(uint8_t contrast, boolean inverse);
void printS();
void printE();
void printC(const char* Array, unsigned int length);
void printD(const char Data);
void text(const char *s, uint8_t font_size);
uint8_t i, j; // used in: text()
void text__continue_cursor_to_end_of_row(const char *s, uint8_t font_size);
uint8_t width, rows;
uint16_t i2;

#define BBSCL BIT6
#define BBSDA BIT7

void begin(uint8_t contrast, boolean inverse) {
const char Init[] = { // www.adafruit.com/.../SSD1306.pdf
0xAE, // Display off

0x81, // Set Contrast Control for BANK0 (81h)
contrast, // This command sets the Contrast Setting of the display.
// The chip has 256 contrast steps from 00h to FFh.
// The segment output current increases as the contrast step value increases.

0x20, // Set Memory Adress Mode
0x00, // Horizontal Adressing Mode

0x21, // Set Column Adress
0x00, // Start Adress 0
0x7F, // End Adress 127

0x22, // Set Page Adress
0x00, // Start Adress 0
0x07, // End Adress 7

0x40, // Set start line adress 0

0xA1, // Set Segment Re-map (A0h/A1h) --set segment re-map 0 to 127
0xA8, // Set Multiplex Ratio (A8h) (1 to 64)
0x3F, // This command switches the default 63 multiplex mode to any multiplex ratio,
// ranging from 16 to 63.
// The output pads COM0~COM63 will be switched to the corresponding COM signal.

0xC8, // Set COM Output Scan Direction to normal mode

0xD3, // set display offset
0x00, // 0

0x8D, // Set Charge Pump Setting
0x14, // ON

0xDA, // Set COM Pins Hardware Configuration (DAh)
0x12, // alternative + disable remap

0xD5, // Set Display Clock Divide Ratio/ Oscillator Frequency (D5h)
0x80, // divide by 1 and medium freq

0xD9, // Set Pre-charge Period (D9h)
0x22, // medium (reset value)

0xDB, // Set Vcomh regulator output
0x20, // 0.77 x Vcc

(inverse==false?0xA6:0xA7), // Set Normal/Inverse Display (A6h/A7h)

0xA4, // Output follows RAM Content

0xAF // Display on
};

const char Mod[] = {0xA5}; // Display on

printC(Init,31);
//__delay_cycles(5000000);
__delay_cycles(500);
printC(Mod,1);
}

void i2c_bb_set_OLED_home(void){
const char home[] = {
0x20, // Set Memory Adress Mode
0x00, // Horizontal Adressing Mode

0x21, // Set Column Adress
0x00, // Start Adress 0
0x7F, // End Adress 127

0x22, // Set Page Adress
0x00, // Start Adress 0
0x07, // End Adress 7

0x40 // Set start line adress 0
};
printC(home,10);
}


void printC(const char* Array, unsigned int length){
unsigned int c;
if (i2c_bitbang){
short ack;
ack=i2c_bb_tx(0x3C,Array,length);
if (!ack) P1OUT |= I2C_BB_LED0;

// for(c = 0; c < length; c++){
// ack=i2c_bb_tx(0x3C,Array[c],1);
// }

}else{
P1OUT |= BIT0;
UCB0CTL1 = UCSWRST;
UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC; // I2C master mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 0x15; // < 400 kHz
UCB0I2CSA = 0x3C; // address
UCB0CTL1 &= ~UCSWRST;
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition

while (!(IFG2 & UCB0TXIFG));

for(c = 0; c < length; c++){
UCB0TXBUF = 0x80;
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = Array[c];
while (!(IFG2 & UCB0TXIFG));
}
UCB0CTL1 |= UCTXSTP;
P1OUT &= ~BIT0;
}
}

void printS(void){
if (i2c_bitbang){
short ack;
i2c_bb_start(); // Send start
P1OUT |= BIT5;
ack=i2c_bb_tx_byte(0x3C<<1); // Send address with W-bit=0
P1OUT &= ~BIT5;
if (!ack) P1OUT |= I2C_BB_LED0; //
P1OUT |= BIT5;
ack=i2c_bb_tx_byte(0x40); // Control byte D/C=1 next byte is data
if (!ack) P1OUT |= I2C_BB_LED0; //
P1OUT &= ~BIT5;
}else{
UCB0CTL1 = UCSWRST;
UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC; // I2C master mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 0x15; // < 400 kHz
UCB0I2CSA = 0x3C; // address
UCB0CTL1 &= ~UCSWRST;
P1OUT |= BIT5;
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
P1OUT &= ~BIT5;
while (!(IFG2 & UCB0TXIFG));
P1OUT |= BIT5;
UCB0TXBUF = 0x40;
while (!(IFG2 & UCB0TXIFG));
P1OUT &= ~BIT5;
}
}

void printE(void){
if (i2c_bitbang){
i2c_bb_stop();
}else{
while (!(IFG2 & UCB0TXIFG));
UCB0CTL1 |= UCTR + UCTXSTP;
}
}

void printD(const char Data){
P1OUT |= BIT5; // debug
if (i2c_bitbang){
short ack;
ack=i2c_bb_tx_byte(Data);
if (!ack) P1OUT |= I2C_BB_LED0; //
}else{
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = Data;
}
P1OUT &= ~BIT5; // debug

}

/******************************************************************************
* Usage: One call per row and the font size heights must be equal to 64.
* Example:
* myOLED.text("",2); // 3 rows -- 16x24 font size
* myOLED.text("----Hello World !----",0); // 1 row -- 5x 8 font size
* myOLED.text("",1); // 2 rows -- 11x16 font size
* myOLED.text("---------------------",0); // 1 row -- 5x 8 font size
* myOLED.text("",0); // 1 row -- 5x 8 font size
* //= 8 rows -- = 64 pixels
* s: The string you want to print.
* font_size: Choose a font size {0, 1, 2, 3}, one per row.
* 0 (5x8 pixels), 1 (11x16 pixels), 2 (16x24 pixels) or 3 (24x36 pixels).
*/
void text(const char *s, uint8_t font_size){
if (strlen(s) > 0){
if (font_size==0){
if (strlen(s) < 22){
for (j=0; j<strlen(s); j++){
for (i=0; i<5; i++) printD(Terminal6x8[s[j]-' '][i]);
printD(0x00); // put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);
}else
text("-ERROR:Exceeds row-",font_size);

}else if (font_size==1){
if(strlen(s) < 11){
// print first part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<11; i++) printD(Terminal11x16[s[j]-' '][2*i]);
printD(0x00); // put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print second part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<11; i++) printD(Terminal11x16[s[j]-' '][2*i+1]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);
}else
text("-ERR:long-",font_size);

}else if(font_size == 2){
if(strlen(s) < 8){
// print first part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<16; i++) printD(Arial16x24[s[j]-'0'][i*3]);
printD(0x00); // put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print second part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<16; i++) printD(Arial16x24[s[j]-'0'][i*3+1]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print third part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<16; i++) printD(Arial16x24[s[j]-'0'][i*3+2]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);
}
else
text("",font_size); // since this Arial font size only has numbers included, so instead of displaying an error-text, we display nothing

}else if(font_size == 3){
if(strlen(s) < 6){
// print first part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<24; i++) printD(Arial24x40[s[j]-'0'][i*5]);
printD(0x00); // put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print second part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<24; i++) printD(Arial24x40[s[j]-'0'][i*5+1]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print third part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<24; i++)
printD(Arial24x40[s[j]-'0'][i*5+2]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print fourth part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<24; i++) printD(Arial24x40[s[j]-'0'][i*5+3]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);

// print fifth part/row of the character(s)
for (j=0; j<strlen(s); j++){
for (i=0; i<24; i++) printD(Arial24x40[s[j]-'0'][i*5+4]);
printD(0x00); //put a distance of one pixel between the characters
}
text__continue_cursor_to_end_of_row(s,font_size);
}else
text("",font_size); // since this Arial font size only has numbers included, so instead of displaying an error-text, we display nothing
}
}else
text__continue_cursor_to_end_of_row("",font_size);
}

/************************************************************************
* After printing a string (or if no string is given (text(""))), put the
* cursor at the end of that row so that a next call of text() starts
* at the beginning of the next row.
************************************************************************/
void text__continue_cursor_to_end_of_row(const char *s, uint8_t font_size) {
if(font_size == 3) {
width = 24;
rows = 5;
}else if(font_size == 2) {
width = 16;
rows = 3;
}else if(font_size == 1) {
width = 11;
rows = 2;
}else if(font_size == 0) {
width = 5;
rows = 1;
}
if(strlen(s) > 0)
for(i2=0; i2<128 - width * strlen(s) - strlen(s); ++i2) printD(0x00);
else
for(i2=0; i2<128 * rows; ++i2) printD(0x00);
}

main(void){
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
uint32_t i=0;

BCSCTL1=CALBC1_16MHZ;
DCOCTL=CALDCO_16MHZ;
__delay_cycles(5000000);

if (i2c_bitbang){
P1OUT &= ~(I2C_BB_SDA+I2C_BB_SCL); // set output to low
P1DIR &= ~(I2C_BB_SDA+I2C_BB_SCL); // set pins as inputs
P1DIR |= BIT0+BIT5;
P1OUT &= ~(BIT0+BIT5);
}else{
P1SEL |= BBSDA + BBSCL; // Assign I2C pins to USCI_B0
P1SEL2 |= BBSDA + BBSCL; // Assign I2C pins to USCI_B0
P1DIR |= I2C_BB_LED0+BIT5;
P1OUT &= ~(I2C_BB_LED0+BIT5);
}

char str[42];
char str2[50];


begin(0xff, // contrast from 0x00 to 0xff (0~255)
false // inverse display
);

while(1){

P1OUT |= BIT0; // debug

//if (i2c_bitbang) i2c_bb_clear_OLED();
//if (i2c_bitbang) i2c_bb_set_OLED_home();
printS();
// Number of text() calls: The sum of font size heights must be 64.

//sprintf(str, "%lu", ++i);
sprintf(str2, "--- Hello ---");
//myOLED.text(str,1); // 3 rows == x24 font size
//myOLED.text("----Hello World !----",0); // 1 row == x 8 font size
//text(" testing new code ---",0); // 1 row == x 8 font size
// 8 rows == 64 pixels
// text(str,3); // x40 pixels
// text(str,2); // x24 pixels
//= 64 pixels

text("6290 9001",1); // 3 rows == x24 font size
text("Logpoint Operation",0); // 1 row == x 8 font size
text("1234567",2); // 2 rows == x16 font size
text("-----Lot Number------",0); // 1 row == x 8 font size
text("SmartRack WIP mngmnt",0); // 1 row == x 8 font size

// text("1testing new code L1 ",0); // 1 row == x 8 font size
// text("2testing new code L2 ",0); // 1 row == x 8 font size
// text("3testing new code L3 ",0); // 1 row == x 8 font size
// text("4testing new code L4 ",0); // 1 row == x 8 font size
// text("5testing new code L5 ",0); // 1 row == x 8 font size
// text("6testing new code L6 ",0); // 1 row == x 8 font size
// text("7testing new code L7 ",0); // 1 row == x 8 font size
// text("8testing new code L8 ",0); // 1 row == x 8 font size

printE(); //= 64 pixels
P1OUT &= ~BIT0; // debug

__delay_cycles(160000);
//while(1);
// //delay(10); // update OLED every 100 milliseconds
//
// printS();
// // Number of text() calls: The sum of font size heights must be 64.
//
// //sprintf(str, "%lu", ++i);
// sprintf(str2, "luis flores");
// //myOLED.text(str,1); // 3 rows == x24 font size
// //myOLED.text("----Hello World !----",0); // 1 row == x 8 font size
// //text(" testing new code ---",0); // 1 row == x 8 font size
// // 8 rows == 64 pixels
// // text(str,3); // x40 pixels
// // text(str,2); // x24 pixels
// //= 64 pixels
//
//// text("6290 9001",1); // 3 rows == x24 font size
//// text("Logpoint Operation",0); // 1 row == x 8 font size
//// text("1234567",2); // 2 rows == x16 font size
//// text("-----Lot Number------",0); // 1 row == x 8 font size
//// text(" SmartRack WIP mngmnt",0); // 1 row == x 8 font size
//
// text("1testing new code L1 ",0); // 1 row == x 8 font size
// text("2testing new code L2 ",0); // 1 row == x 8 font size
// text("3testing new code L3 ",0); // 1 row == x 8 font size
// text("4testing new code L4 ",0); // 1 row == x 8 font size
// text("5testing new code L5 ",0); // 1 row == x 8 font size
// text("6testing new code L6 ",0); // 1 row == x 8 font size
// text("7testing new code L7 ",0); // 1 row == x 8 font size
// text("8testing new code L8 ",0); // 1 row == x 8 font size
//
// printE(); //= 64 pixels
//
// __delay_cycles(160000);

//delay(10); // update OLED every 100 milliseconds
}
}

//setup bit bang I2C pins
void i2c_bb_setup(void){
SWI2C_PxOUT &= ~(SWI2C_SCL | SWI2C_SDA);
SWI2C_SCL_HIGH;
SWI2C_SDA_HIGH;
P1DIR |= BIT0|BIT5;
P1OUT &= ~(BIT0|BIT5);
}

//wait for 1/2 of I2C clock period
void i2c_bb_hc(void){
//_delay_cycles(800); // wait for 0.05ms
__delay_cycles(1); // wait for 0.05ms
}

void i2c_bb_start(void){
// I2C_BB_DIR |= I2C_BB_SDA; // pull SDA low
// i2c_bb_hc(); // wait for 1/2 clock first
// I2C_BB_DIR |= I2C_BB_SCL; // pull SCL low chly
// while (!(I2C_BB_IN&I2C_BB_SCL)) { // Clock stretching
// // You should add timeout to this loop
// }

SWI2C_SDA_LOW;
i2c_bb_hc(); // wait for 1/2 clock first
SWI2C_SCL_LOW;

}

void i2c_bb_stop(void){
// I2C_BB_DIR |= I2C_BB_SDA; // pull SDA low
// i2c_bb_hc(); // wait for 1/2 clock for end of start
// I2C_BB_DIR &= ~I2C_BB_SCL; // float SCL or SCL high
// i2c_bb_hc(); // wait for 1/2 clock for end of start
// I2C_BB_DIR &= ~I2C_BB_SDA; // float SDA or SDA high
// i2c_bb_hc(); // wait for 1/2 clock


SWI2C_SDA_LOW;
i2c_bb_hc(); // wait for 1/2 clock first
i2c_bb_hc(); // wait for 1/2 clock first
SWI2C_SCL_HIGH;
i2c_bb_hc(); // wait for 1/2 clock first
i2c_bb_hc(); // wait for 1/2 clock first
while(!(SWI2C_PxIN & SWI2C_SCL)); // Waiting for our clock line to go high if the slave is stretching
SWI2C_SCL_LOW;
i2c_bb_hc(); // wait for 1/2 clock first
i2c_bb_hc(); // wait for 1/2 clock first
SWI2C_SCL_HIGH;
i2c_bb_hc(); // wait for 1/2 clock first
i2c_bb_hc(); // wait for 1/2 clock first
while(!(SWI2C_PxIN & SWI2C_SCL)); // Waiting for our clock line to go high if the slave is stretching
SWI2C_SDA_HIGH;

i2c_bb_hc(); // wait for 1/2 clock first
}

//send value over I2C return 1 if slave ACKed
short i2c_bb_tx_byte(unsigned char val){
unsigned char i;

for(i=0;i<8;i++){ // shift out bits
if (val&0x80) SWI2C_SDA_HIGH; // check bit, float SDA
else SWI2C_SDA_LOW; // pull SDA low
i2c_bb_hc(); // wait for 1/2 clock
SWI2C_SCL_HIGH; // float SCL
val<<=1; // shift
i2c_bb_hc(); // wait for 1/2 clock
i2c_bb_hc(); // wait for 1/2 clock
SWI2C_SCL_LOW; // pull SCL low chly
i2c_bb_hc(); // wait for 1/2 clock
}

SWI2C_SDA_HIGH;
i2c_bb_hc(); // wait for 1/2 clock
SWI2C_SCL_HIGH;
while(!(SWI2C_PxIN & SWI2C_SCL)); // Waiting for our clock line to go high if the slave is stretching
val= I2C_BB_IN&I2C_BB_SDA; // sample SDA
i2c_bb_hc(); // wait for 1/2 clock
//SWI2C_SDA_LOW;
SWI2C_SCL_LOW; // pull SCL low
i2c_bb_hc(); // wait for 1/2 clock
return !val; // return sampled value
}

short i2c_bb_tx(unsigned char addr,const char *dat,unsigned short len){
short ack;
unsigned char i;
i2c_bb_start(); // send start
ack=i2c_bb_tx_byte(addr<<1); // send address with W bit
if (!ack) P1OUT |= I2C_BB_LED0; //
for(i=0;i<len && ack;i++){ //
ack|=i2c_bb_tx_byte(0x80); // control byte
ack|=i2c_bb_tx_byte(dat[i]); // transmit next byte
}
i2c_bb_stop(); // transmit stop
if (!ack) P1OUT |= I2C_BB_LED0; //
return ack; // return if slave NACKed
}

//receive value over I2C return 1 if slave ACKed
unsigned char i2c_bb_rx_byte(unsigned short ack){
unsigned char val;
int i;
for(i=0;i<8;i++){ // shift out bits
I2C_BB_DIR |= I2C_BB_SCL; // pull SCL low

i2c_bb_hc(); // wait for 1/2 clock
I2C_BB_DIR &= ~I2C_BB_SCL; // float SCL

while (!(I2C_BB_IN&I2C_BB_SCL)) { // Clock stretching
// You should add timeout to this loop
}

i2c_bb_hc(); // wait for 1/2 clock
val<<=1; // shift value to make room
if(I2C_BB_IN&I2C_BB_SDA) val|=1; // sample data
}
//check ack bit
I2C_BB_DIR |= I2C_BB_SCL; // pull SCL low
if(ack){ // check if we are ACKing this byte
I2C_BB_DIR |= I2C_BB_SDA; // pull SDA low for ACK
}else{
I2C_BB_DIR &= ~I2C_BB_SDA; // float SDA for NACK
}
i2c_bb_hc(); // wait for 1/2 clock
I2C_BB_DIR &= ~I2C_BB_SCL; // float SCL
i2c_bb_hc(); // wait for 1/2 clock
I2C_BB_DIR |= I2C_BB_SCL; // float SDA
//I2C_BB_DIR &=~ I2C_BB_SDA;
return val; // return value
}

short i2c_bb_rx(unsigned char addr,unsigned char *dest,unsigned short len){
int i;
i2c_bb_start(); // send start
if(!i2c_bb_tx_byte((addr<<1)|BIT0)){ // send address with R bit
return 0; // got NACK return error
}

for(i=0;i<len;i++){ // send data bytes
dest[i]=i2c_bb_tx_byte(i==len-1); // transmit next byte
}
i2c_bb_stop(); //transmit stop
return 1; //return if slave NACKed
}

void i2c_bb_clear_OLED(void){
short ack;
int c;
i2c_bb_start(); // send start
ack=i2c_bb_tx_byte( 0x3C<<1 ); // send address with plus W-bit=0, write
ack=i2c_bb_tx_byte(0x40); // Control byte D/C=1 next byte is data
for(c = 0; c>1024; c++){
ack=i2c_bb_tx_byte(0x00); // Data byte
}
i2c_bb_stop();
}

  • Hi Luis, 

    There isn't anyone with expertise in OLED displays but I can certainly help you with I2C communication issues. Also, I'm not able to debug your code because I don't have one of the SDD1306 displays on hand. 

    Luis Flores said:
    those ports are used already for other comunication purposes.

    Are these pins being used for I2C with another device? If so you can have multiple slaves on the same I2C bus and take advantage of the I2C hardware. 

    If a software implementation is a must, I recommend starting with the Software I2C on MSP430 MCUs application report. This application report also provides source code that could be modified for your application. 

    Next, if you're still having troubles I recommend using a logic analyzer to view the activity on the I2C bus when using software and when using hardware. Then comparing the two results looking for differences. This will probably be the most helpful way of analyzing what is going on in your code. Let's start work from here. Let me know if you have any follow-up questions. 

    Best regards, 
    Caleb Overbay

  • Well It turned out that the configuratoin part of the code was issuing a DISPLAYON = A5H command to the OLED, for some reason the harware I2C does not send it out but the sodtware does, they both use the same routines... the problem with an all-on-display was actually a feature of the display itself... thanks Caleb for helping me comparing the I2C comunication on the software vs hardware and finding that out.

    duh.. =)

    printC(Init,31);

    __delay_cycles(500);

    // const char Mod[] = {0xA5}; // Display on

    // printC(Mod,1);

**Attention** This is a public forum