I am trying to use my SSD1309 display with STM32 Cube IDE (I cannot use Arduino as it is work-related). However, with each function using the u8g2 library, my screen displays artifacts as shown in the image. The same issue occurs with other libraries. I believe it is related to my initialization, but I’m not sure. As you can see on the drawn line, it seems that the first pixels of each page are correct (the first 8 correct ones), but the rest aren’t. My STM32 is a STM32G0 type.
uint8_t u8x8_gpio_and_delay_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT:
/* Insert codes for initialization */
HAL_Delay(1);
break;
case U8X8_MSG_DELAY_NANO:
for (uint16_t i = 0; i < arg_int; ++i)
;
break;
case U8X8_MSG_DELAY_MILLI:
/* ms Delay */
HAL_Delay(arg_int);
break;
case U8X8_MSG_GPIO_CS:
/* Insert codes for SS pin control */
//HAL_GPIO_WritePin(OLED_CS_GPIO_Port, OLED_CS_Pin, arg_int);
break;
case U8X8_MSG_GPIO_DC:
/* Insert codes for DC pin control */
//HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
break;
case U8X8_MSG_GPIO_RESET:
/* Insert codes for RST pin control */
//HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, arg_int);
break;
}
return 1;
}
uint8_t u8x8_byte_stm32_hw_i2c(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
static uint8_t buffer[32];
static uint8_t buf_idx;
static uint8_t dc = 0;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
buffer[buf_idx++] = *data;
data++;
arg_int--;
}
break;
case U8X8_MSG_BYTE_INIT:
/* add your custom code to init i2c subsystem */
u8g2->gpio_and_delay_cb(&u8g2, U8X8_MSG_DELAY_NANO,u8g2->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_SET_DC:
dc= arg_int;
//if(HAL_I2C_Mem_Write(&hi2c1, (DEVICE_ADDRESS << 1), 0x00,1, (uint8_t*) arg_ptr, arg_int,HAL_MAX_DELAY)!= HAL_OK) return 0;
break;
case U8X8_MSG_BYTE_START_TRANSFER:
buf_idx = 0;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
while (HAL_I2C_STATE_READY != HAL_I2C_GetState(&hi2c1)) {
};
if(HAL_I2C_Master_Transmit(&hi2c1, (DEVICE_ADDRESS << 1), buffer, buf_idx, TX_TIMEOUT) != HAL_OK) return 0;
//if(HAL_I2C_Mem_Write(&hi2c1, (DEVICE_ADDRESS << 1),0x40,1, (uint8_t*) arg_ptr, arg_int,HAL_MAX_DELAY)!= HAL_OK) return 0;
break;
default:
return 0;
}
return 1;
}
#define U8G2_H
#ifdef U8G2_H
static u8g2_t u8g2;
I2C_HandleTypeDef hi2c1;
#define width 128
#define height 64
#endif
#ifdef U8G2_H
u8g2_Setup_ssd1309_i2c_128x64_noname2_f(&u8g2, U8G2_R0, u8x8_byte_stm32_hw_i2c,u8x8_gpio_and_delay_stm32); // U8G2_R0 describes the rotation; this mode indicates no rotation, but you can rotate the screen if needed
//u8x8_d_ssd1309_128x64_noname2(&u8x8, U8X8_R0, u8x8_byte_stm32_hw_i2c,u8x8_gpio_and_delay_stm32);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
#endif
#ifdef U8G2_H
u8g2_FirstPage(&u8g2);
do {
u8g2_SetDrawColor(&u8g2,1);
u8g2_DrawLine(&u8g2, 0, 0, 127, 63);
} while (u8g2_NextPage(&u8g2));
#endif
My screen shows noises sometimes. It seems like the first pixels of each page are correct (the first 8), but the rest are not.
I have tried modifying the initialization. When using another library, I understand the commands for the screen (e.g., WriteCommand(0xAF) to turn on the display). However, most of the time, some areas of my screen are filled with noise.
If anyone can help, it would be incredible. Thanks!
Edit: A friend of mine made the screen works using another library but most importantly the parameter for the Init,
void OLED_Init()
{
//unsigned char i;
writeCommand(0xFD); // Set Command Lock
writeCommand(0X12); // Default => 0x12
// 0x12 => Driver IC interface is unlocked from entering command.
// 0x16 => All Commands are locked except 0xFD.
writeCommand(0XAE); // Set Display On/Off
// Default => 0xAE
// 0xAE => Display Off
// 0xAF => Display On
writeCommand(0xD5); // Set Display Clock Divide Ratio / Oscillator Frequency
writeCommand(0XA0); // Set Clock as 116 Frames/Sec
// Default => 0x70
// D[3:0] => Display Clock Divider
// D[7:4] => Oscillator Frequency
writeCommand(0xA8); // Set Multiplex Ratio
writeCommand(0X3F); // Default => 0x3F (1/64 Duty)
writeCommand(0xD3); // Set Display Offset
writeCommand(0X00); // Default => 0x00
writeCommand(0x40); // Set Mapping RAM Display Start Line (0x00~0x3F)
// Default => 0x40 (0x00)
writeCommand(0xD8); // Set Low Power Display Mode (0x04/0x05)
writeCommand(0x05); // Default => 0x04 (Normal Power Mode)
writeCommand(0x20); // Set Page Addressing Mode (0x00/0x01/0x02)
writeCommand(0x00); // Default => 0x02
// 0x00 => Horizontal Addressing Mode
// 0x01 => Vertical Addressing Mode
// 0x02 => Page Addressing Mode
writeCommand(0xA1); // Set SEG/Column Mapping (0xA0/0xA1)
// Default => 0xA0
// 0xA0 => Column Address 0 Mapped to SEG0
// 0xA1 => Column Address 0 Mapped to SEG127
writeCommand(0xC8); // Set COM/Row Scan Direction (0xC0/0xC8)
// Default => 0xC0
// 0xC0 => Scan from COM0 to 63
// 0xC8 => Scan from COM63 to 0
writeCommand(0xDA); // Set COM Pins Hardware Configuration
writeCommand(0x12); // Default => 0x12
// Alternative COM Pin Configuration
// Disable COM Left/Right Re-Map
writeCommand(0x81); // Set SEG Output Current
writeCommand(0x7f); //0x05); // Set Contrast Control for Bank 0
// Default => 0x7F
writeCommand(0xD9); // Set Pre-Charge as 2 Clocks & Discharge as 5 Clocks
writeCommand(0x25); // Default => 0x22 (2 Display Clocks [Phase 2] / 2 Display Clocks [Phase 1])
// D[3:0] => Phase 1 Period in 1~15 Display Clocks
// D[7:4] => Phase 2 Period in 1~15 Display Clocks
writeCommand(0xDB); // Set VCOMH Deselect Level
writeCommand(0x34); // Default => 0x34 (0.78*VCC)
writeCommand(0xA4); // Set Entire Display On / Off
// Default => 0xA4
// 0xA4 => Normal Display
// 0xA5 => Entire Display On
writeCommand(0xA6); // Set Inverse Display On/Off
// Default => 0xA6
// 0xA6 => Normal Display
// 0xA7 => Inverse Display On
fillRam(0x00); // Clear Screen
writeCommand(0XAF); // Display On (0xAE/0xAF)
}
Marshall eisele is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.