Hi,
I'm running a SSD1306 OLED 128x64 on my ATMega328p. As you can see in the picture below I can't show up anything. I only get this weired snow like thing.
The display is connected via SPI.
These are the startup sequenses I'm using:
/*
//ADAFRUIT-LIB
static const uint8_t oledConfig[] = {
0xAE,
0xD5,
0x80,
0x8A,
0xD3,
0x00,
0x40 | 0x0,
0x8D,
0x14,
0x20,
0x00,
0xA0 | 0x1,
0xC8,
0xDA,
0x12,
0x81,
0xCF,
0xD9,
0xF1,
0xDB,
0x40,
0xA4,
0xA6,
0x2E,
0xAF
};
*/
//DATASHEET
static const uint8_t oledConfig[] = {
0xA8, 0x3F,
0xD3, 0x00,
0x20, 00,
0x40 | 0,
0xA0, //0xA0?0xA1,
0xC0, //0xC0?0xC8,
0xDA, 0x12,
0x81, 0x7F,
0xA5,
0xA6,
0xD5, 0x80,
0xA4,
0xAF
};
Any ideas why it isn't working?
thanks and regards.
just pushing the buffer through the spi:
void oled_flush() {
resetPosition();
CHIPSELECT(MODE_DATA) {
for( int i=0; i<FRAME_BUFFER_SIZE; i++ ) {
uint8_t next = oledBuffer[i]; // Load next byte
//oledBuffer[i] = 0x00; // Clear buffer byte
__builtin_avr_delay_cycles(8);
SPSR; // Need to read register to clear SPIF
SPDR = next; // Send byte
}
// After sending the last byte the for loop exits, so we need to wait for the transfer to finish here
__builtin_avr_delay_cycles(14);
SPSR;
}
}
and filling the buffer:
for(int i=0;i<FRAME_BUFFER_SIZE;i++) {
oledBuffer[i] = 0xFF;
}
thanks.
the code is from http://blog.zakkemble.co.uk/diy-digital-wristwatch/ (http://blog.zakkemble.co.uk/diy-digital-wristwatch/) just to do a "quick" check of the display.
the DC line is pulled high/low correctly in the code. I have no oscilloscop to check it on the board.
when I send cmd 0xA5 the display turnes completly on. When I change the value from 0xA8 I get different patterns but no correct picture.
dc generation:
static bool oled_select( void ) {
spi_enable();
spiSelect();
return true;
}
static bool oled_deselect( void ) {
spiDeselect();
spi_disable();
return false;
}
#define cmdMode() (pinWrite(DC, LOW))
#define dataMode() (pinWrite(DC, HIGH))
#define MODE_CMD (cmdMode())
#define MODE_DATA (dataMode())
#define CHIPSELECT(mode) mode; \
for(bool cs = oled_select(); cs; cs = oled_deselect())
I don't know if this is correct data. But there is a change as supposed to be.
adding them in the resetposition doesn't change anything.....
int main( void ) {
for(int i=0; i<FRAME_BUFFER_SIZE; i++) {
oledBuffer[i] = 0x0F;
}
spi_init();
oled_init();
beep(false);
/* Replace with your application code */
while (1) {
for(int i=0; i<FRAME_BUFFER_SIZE; i++) {
oledBuffer[i] ^= 0xFF;
}
oled_flush();
delay(500);
}
}
this code generates a switching black and white bar in the area without snow. So I guess this little area is working as supposed.
It looks to me your OLED does not have an SSD1306 but some other variant.
Try this code (it should be already in your file, disabled by the #if OLED_CONTROLLER == OLED_CONTROLLER_SSD1306 / #else in oled_flush()):
uint16_t buffer = 0;
uint16_t start;
for(uint8_t i=0;i<8;i++)
{
start = buffer;
buffer += 128;
// Need to manually set page and column with SH1106 :/
CHIPSELECT(MODE_CMD)
{
spi_transfer_nr(0xB0 + i); // Set page
spi_transfer_nr(0x02); // Set column lower 4 bits
spi_transfer_nr(0x10); // Set column higher 4 bits
}
CHIPSELECT(MODE_DATA)
{
for(uint16_t i=start;i<buffer;i++)
{
uint8_t next = oledBuffer[i]; // Load next byte
oledBuffer[i] = 0x00; // Clear buffer byte
__builtin_avr_delay_cycles(8);
SPSR; // Need to read register to clear SPIF
SPDR = next; // Send byte
}
__builtin_avr_delay_cycles(14);
SPSR;
}
}
This variant sets the adress for each page and does not rely on the adressing mode selected in the display.
@bktemp:
thank you!
with some little logic tweaking (i/i2) it works nearly as supposed to!
there are just some little parts without pixels...
uint16_t buffer = 0;
uint16_t start;
for(uint8_t i=0; i<8; i++) {
start = buffer;
buffer += 128;
// Need to manually set page and column with SH1106 :/
CHIPSELECT( MODE_CMD ) {
spi_transfer_nr( 0xB0 + i ); // Set page
spi_transfer_nr( 0x02 ); // Set column lower 4 bits
spi_transfer_nr( 0x10 ); // Set column higher 4 bits
}
CHIPSELECT( MODE_DATA ) {
for(uint16_t i2=start; i2<buffer; i2++) {
uint8_t next = oledBuffer[i+i2]; // Load next byte
//oledBuffer[i] = 0x00; // Clear buffer byte
__builtin_avr_delay_cycles(8);
SPSR; // Need to read register to clear SPIF
SPDR = next; // Send byte
}
__builtin_avr_delay_cycles(14);
SPSR;
}
}