started with the lcd_oled.h library, and tested the draw pixel command, it works for the example main.c main.h and cmake config please go in /dev/examples

master
kerem yollu 2 years ago
parent ec87722338
commit 855cd7c99d

@ -1 +1 @@
set(DRIVERS_LIST pf8574 max7219 max31865 ssd1306_i2c)
set(DRIVERS_LIST max7219 max31865 ssd1306_i2c)

@ -0,0 +1,75 @@
#ifndef _LCD_OLED_H_
#define _LCD_OLED_H_
#ifdef __cplusplus
extern "C" {
#endif
//#define WIDTH 128
//#define HEIGHT 64
#define FILLED 1
#define EMPTY 0
#define LCD_OLED_I2C
#define LCD_OLED_SIZE_X 128
#define LCD_OLED_SIZE_Y 64
#if defined LCD_OLED_I2C
#include "i2c.h"
void lcd_oled_init(i2c_t *i2c_dev, pinNo_t pinNo, uint8_t address);
#elif defined LCD_OLED_SPI
#include "spi.h"
void lcd_oled_init(spi_t *spi_dev, pinNo_t pinNo, uint8_t address);
#else
#error "Please Define The communication Methode in ked/drivers/lcd_oled/lcd_oled.h
#endif
void lcd_oled_enable();
void lcd_oled_disable();
void lcd_oled_reset_hard();
void lcd_oled_reset_soft();
uint8_t lcd_oled_is_ready();
void lcd_oled_sleep();
void lcd_oled_wake();
void lcd_oled_draw_pixel(uint16_t x, uint16_t y, uint8_t color);
void lcd_oled_draw_line(uint16_t x, uint16_t y, uint16_t angle, uint16_t lenght, uint8_t color);
void lcd_oled_draw_rectangle(uint16_t x, uint16_t y, uint16_t lenght, uint16_t width, uint8_t fill, uint8_t color);
void lcd_oled_draw_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t fill, uint8_t color);
void lcd_oled_scroll_right(uint16_t start, uint16_t stop);
void lcd_oled_scroll_left(uint16_t start, uint16_t stop);
void lcd_oled_scroll_up(uint16_t start, uint16_t stop);
void lcd_oled_scroll_down(uint16_t start, uint16_t stop);
void lcd_oled_set_font(uint8_t *font, uint8_t size, uint8_t spacing);
void lcd_oled_print_char(uint16_t x, uint16_t y, uint8_t c, uint8_t color);
void lcd_oled_print_text(uint16_t x, uint16_t y, uint8_t *text, uint16_t lenght, uint8_t color);
void lcd_oled_goto_pos(uint16_t x, uint16_t y);
uint8_t lcd_oled_display();
uint8_t lcd_oled_clear();
void lcd_oled_change_brightness(uint8_t brightness);
void lcd_oled_change_contrast(uint8_t contrast);
void lcd_oled_rotate(uint8_t angle);
void lcd_oled_inverse(uint8_t yseNo);
#ifdef __cplusplus
}
#endif
#endif /* _LCD_OLED_H_ */

@ -1,123 +0,0 @@
//////////////////////////////////////////////////////////
// Created by : Kerem Yollu
// Project : Multiprise conectée
// Nom : lcd.c
// Header : lcd.h
//_________________________Info_________________________
//
// Libraire pour le control d'un ecran lcd stadard (HD44780)
// controlée par un expandeur de port PCF8574 en I2C.
//
//////////////////////////////////////////////////////////
#include "pf8574.h"
// Fonction pour initialiser l'écran vide en mode 4 bits
uint16_t lcd_init(i2c_t *i2c_dev)
{
lcd_write(i2c_dev,0x03,CMD_MODE); // Mise en mode 4 bit avec 4 essai conssecutif
lcd_write(i2c_dev,0x03,CMD_MODE);
lcd_write(i2c_dev,0x03,CMD_MODE);
lcd_write(i2c_dev,0x02,CMD_MODE);
lcd_write(i2c_dev,LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE ,CMD_MODE);
lcd_write(i2c_dev,LCD_DISPLAYCONTROL | LCD_DISPLAYON ,CMD_MODE);
lcd_write(i2c_dev,LCD_CLEARDISPLAY ,CMD_MODE);
lcd_write(i2c_dev,LCD_ENTRYMODESET | LCD_ENTRYLEFT ,CMD_MODE);
return 1;
}
// Fonction qui vas afficher une pharse sur la ligne et colone qui lui est indiquée
// Attention la fonction est capable de calculer la liongeure d0ubn phrase mais il ne
// faut pas dépasser la limite d'une ligne totale qui est de 20 charactères max
//
// LCD 20x4
// -------------------------------------------
// ||# # # # # # # # # # # # # # # # # # # #||
// ||# # # # # # # # # # # # # # # # # # # #||
// ||# # # # # # # # # # # # # # # # # # # #||
// ||# # # # # # # # # # # # # # # # # # # #||
// -------------------------------------------
void lcd_display_string(i2c_t *i2c_dev, uint8_t line, uint8_t pos, uint8_t* charvalue, uint8_t lenght)
{
uint8_t setPosition = 0;
uint16_t i, S_length = 0;
S_length = lenght;
if (S_length > TOTAL_CHAR_CAP)
{
}
else
{
if(line == 1) // Selection de la ligne d'écriture
{
setPosition = pos;
}
else if(line ==2)
{
setPosition = 0x40 + pos;
}
else if(line ==3)
{
setPosition = 0x14 + pos;
}
else if(line ==4)
{
setPosition = 0x54 + pos;
}
else
{
setPosition = -1;
}
if(setPosition >= 0)
{
lcd_write(i2c_dev, LCD_SETDDRAMADDR + setPosition, CMD_MODE);
for(i = 0; i < lenght; i++ )
{
lcd_write(i2c_dev,charvalue[i],RS);
}
}
else
{
}
}
}
// Cette fonction nous permet d'envoyer un information de 8 bits sous format
// de 2x4 bites. Celà est necessaire du au fonctionnement de l'expendeur de port PCF8574
// qui est branché sur l'écran de facon a ce qu'il communiquer en 4 bits.
void lcd_write(i2c_t *i2c_dev, uint8_t cmd, uint8_t mode)
{
lcd_write_4bits(i2c_dev, mode | (cmd & 0xF0));
lcd_write_4bits(i2c_dev, mode | ((cmd << 4) & 0xF0));
}
// Fonction nous permettant d'nevoyer 4 bits dinformation sur le PC8574 ainsi que
// le rétroéclairage.
void lcd_write_4bits(i2c_t *i2c_dev,uint8_t data)
{
uint16_t address = LCD_ADDRS;
uint8_t i2c_data = 0;
i2c_set_transfer_counter(i2c_dev,3);
i2c_send_address_for_write(i2c_dev, &address);
i2c_data = data | LCD_BACKLIGHT;
i2c_send_data(i2c_dev, &i2c_data);
// Toggle LCD enbale pin.
i2c_data = data | EN |LCD_BACKLIGHT;
i2c_send_data(i2c_dev, &i2c_data);
delayMs(100);
i2c_data = ((data & ~EN) | LCD_BACKLIGHT);
i2c_send_data(i2c_dev, &i2c_data);
while(!i2c_is_transfer_complete(i2c_dev));
i2c_send_stop(i2c_dev);
delayMs(500);
}

@ -1,94 +0,0 @@
/**
**************************************************************************************************
* @file max7219.h
* @author Kerem Yollu & Edwin Koch
* @date 25.08.2022
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
* @todo
**************************************************************************************************
*/
#ifndef _PF8574_H_
#define _PF8574_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "i2c.h"
#include "delay.h"
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags pour mode d'ecriture
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags pour ecran on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags pour display/decalage curseurr
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags pour function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x1DOTS 0x04
#define LCD_5x8DOTS 0x00
//flags pour le rétroeclairage
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
//Pins de gestion de donées.
#define EN 0x04 // Enable bit
#define RW 0x02 // Read/Write bit
#define RS 0x01 // Register select bit
//DIfferents mode enre commande est ecriture
#define CMD_MODE 0x00
#define CHAR_MODE 0x01
//adresse I2C du controlleur pour LCD
#define LCD_ADDRS 0x27
//Nombre max de uint8_t sur une ligne
#define TOTAL_CHAR_CAP 20
uint16_t lcd_init(i2c_t *i2c_dev);
void lcd_write_char(i2c_t *i2c_dev, uint8_t charvalue);
void lcd_display_string(i2c_t *i2c_dev, uint8_t line, uint8_t pos, uint8_t* charvalue, uint8_t lenght);
void lcd_write(i2c_t *i2c_dev, uint8_t cmd, uint8_t mode);
void lcd_write_4bits(i2c_t *i2c_de, uint8_t data);
#ifdef __cplusplus
}
#endif
#endif /* MAIN_H */

Binary file not shown.

@ -0,0 +1,801 @@
/*********************************************************************
SSD1306 I2C Library for Raspberry Pi.
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib
Modified by Ilia Penev
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
*********************************************************************/
/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen below must be included in any redistribution
*********************************************************************/
#include <stdint.h>
#include <string.h>
#include "ssd1306_i2c.h"
#include "oled_fonts.h"
#define true 1
#define false 0
#define rotation 0
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
int16_t cursor_y = 0;
int16_t cursor_x = 0;
// the memory buffer for the LCD. Displays Adafruit logo
uint16_t buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x80, 0x80,
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
0x80, 0x80, 0x00, 0xFF,
#if (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH > 96*16)
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
0x80, 0x80, 0x00, 0x00,
0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80,
0x80, 0x00, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84,
0x00, 0x00, 0x80, 0xF8,
0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xE0, 0xE0, 0xC0, 0x80,
0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0xFF, 0xC7, 0x01, 0x01,
0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01,
0x01, 0x01, 0x83, 0xFF,
0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7,
0xFF, 0xFF, 0x00, 0x00,
0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01,
0x00, 0x00, 0x7F, 0xFF,
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x01, 0xFF,
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE7, 0xC7, 0xC7, 0x8F,
0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0xFC, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00,
0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03,
0x03, 0x03, 0x01, 0x01,
0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
0x03, 0x03, 0x00, 0x00,
0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01,
0x00, 0x00, 0x00, 0x03,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
#if (SSD1306_LCDHEIGHT == 64)
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x3F, 0x1F, 0x0F,
0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8,
0xF8, 0x7C, 0x7D, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00,
0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xE0, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0x7F, 0x3F, 0x1F,
0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFE, 0xF8, 0xE0,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFE, 0xFE, 0x00, 0x00,
0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00,
0xF0, 0xF8, 0x1C, 0x0E,
0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00,
0x00, 0x00, 0x00, 0xFC,
0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00,
0x06, 0xFF, 0xFF, 0x06,
0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE,
0x00, 0x00, 0xC0, 0xF8,
0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76,
0xE6, 0xCE, 0xCC, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F,
0x3F, 0x1F, 0x0F, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x0F, 0x00, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
0x03, 0x07, 0x0E, 0x0C,
0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E,
0x0C, 0x18, 0x0C, 0x0F,
0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00,
0x00, 0x0F, 0x0F, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F,
0x00, 0x00, 0x00, 0x07,
0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C,
0x18, 0x0C, 0x0F, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
#endif
#endif
};
int16_t _vccstate;
int16_t i2cd;
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
// the most basic function, set a single pixel
void ssd1306_drawPixel(int16_t x, int16_t y, uint16_t color)
{
if ((x < 0) || (x >= WIDTH) || (y < 0) || (y >= HEIGHT))
return;
// check rotation, move pixel around if necessary
switch (rotation) {
case 1:
ssd1306_swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
ssd1306_swap(x, y);
y = HEIGHT - y - 1;
break;
}
// x is which column
switch (color) {
case WHITE:
buffer[x + (y / 8) * SSD1306_LCDWIDTH] |= (1 << (y & 7));
break;
case BLACK:
buffer[x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1 << (y & 7));
break;
case INVERSE:
buffer[x + (y / 8) * SSD1306_LCDWIDTH] ^= (1 << (y & 7));
break;
}
}
// Init SSD1306
void ssd1306_begin(i2c_t *i2c_dev, uint16_t vccstate, uint16_t i2caddr)
{
// I2C Init
_vccstate = vccstate;
// Init sequence
ssd1306_command(i2c_dev,SSD1306_DISPLAYOFF); // 0xAE
ssd1306_command(i2c_dev,SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306_command(i2c_dev,0x80); // the suggested ratio 0x80
ssd1306_command(i2c_dev,SSD1306_SETMULTIPLEX); // 0xA8
ssd1306_command(i2c_dev,SSD1306_LCDHEIGHT - 1);
ssd1306_command(i2c_dev,SSD1306_SETDISPLAYOFFSET); // 0xD3
ssd1306_command(i2c_dev,0x0); // no offset
ssd1306_command(i2c_dev,SSD1306_SETSTARTLINE | 0x0); // line #0
ssd1306_command(i2c_dev,SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC) {
ssd1306_command(i2c_dev,0x10);
} else {
ssd1306_command(i2c_dev,0x14);
}
ssd1306_command(i2c_dev,SSD1306_MEMORYMODE); // 0x20
ssd1306_command(i2c_dev,0x00); // 0x0 act like ks0108
ssd1306_command(i2c_dev,SSD1306_SEGREMAP | 0x1);
ssd1306_command(i2c_dev,SSD1306_COMSCANDEC);
#if defined SSD1306_128_32
ssd1306_command(i2c_dev,SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(i2c_dev,0x02);
ssd1306_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81
ssd1306_command(i2c_dev,0x8F);
#elif defined SSD1306_128_64
ssd1306_command(i2c_dev,SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(i2c_dev,0x12);
ssd1306_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC) {
ssd1306_command(i2c_dev,0x9F);
} else {
ssd1306_command(i2c_dev,0xCF);
}
#elif defined SSD1306_96_16
ssd1306_command(i2c_dev,SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(i2c_dev,0x2); // ada x12
ssd1306_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC) {
ssd1306_command(i2c_dev,0x10);
} else {
ssd1306_command(i2c_dev,0xAF);
}
#endif
ssd1306_command(i2c_dev,SSD1306_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306_EXTERNALVCC) {
ssd1306_command(i2c_dev,0x22);
} else {
ssd1306_command(i2c_dev,0xF1);
}
ssd1306_command(i2c_dev,SSD1306_SETVCOMDETECT); // 0xDB
ssd1306_command(i2c_dev,0x40);
ssd1306_command(i2c_dev,SSD1306_DISPLAYALLON_RESUME); // 0xA4
ssd1306_command(i2c_dev,SSD1306_NORMALDISPLAY); // 0xA6
ssd1306_command(i2c_dev,SSD1306_DEACTIVATE_SCROLL);
ssd1306_command(i2c_dev,SSD1306_DISPLAYON); // --turn on oled panel
}
void ssd1306_invertDisplay(i2c_t *i2c_dev, uint16_t i)
{
if (i) {
ssd1306_command(i2c_dev,SSD1306_INVERTDISPLAY);
} else {
ssd1306_command(i2c_dev,SSD1306_NORMALDISPLAY);
}
}
void ssd1306_command(i2c_t *i2c_dev,uint16_t c)
{
// I2C
uint16_t control = 0x00; // Co = 0, D/C = 0
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
i2c_write(i2c_dev, &address, &control, &c, &i2cDataLenght);
}
void ssd1306_display(i2c_t *i2c_dev)
{
ssd1306_command(i2c_dev,SSD1306_COLUMNADDR);
ssd1306_command(i2c_dev,0); // Column start address (0 = reset)
ssd1306_command(i2c_dev,SSD1306_LCDWIDTH - 1); // Column end address (127
// = reset)
ssd1306_command(i2c_dev,SSD1306_PAGEADDR);
ssd1306_command(i2c_dev,0); // Page start address (0 = reset)
#if SSD1306_LCDHEIGHT == 64
ssd1306_command(i2c_dev,7); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 32
ssd1306_command(i2c_dev,3); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 16
ssd1306_command(i2c_dev,1); // Page end address
#endif
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
uint8_t reg = 0x40;
// I2C
int16_t i;
for (i = 0; i < (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8); i++) {
i2c_write(i2c_dev, &address, &reg, &buffer[i], &i2cDataLenght);
//This sends byte by byte.
//Better to send all buffer without 0x40 first
//Should be optimized
}
}
// startscrollright
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,start);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,stop);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,0XFF);
ssd1306_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrollleft
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,start);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,stop);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,0XFF);
ssd1306_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrolldiagright
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,SSD1306_LCDHEIGHT);
ssd1306_command(i2c_dev,SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,start);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,stop);
ssd1306_command(i2c_dev,0X01);
ssd1306_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrolldiagleft
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,SSD1306_LCDHEIGHT);
ssd1306_command(i2c_dev,SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,start);
ssd1306_command(i2c_dev,0X00);
ssd1306_command(i2c_dev,stop);
ssd1306_command(i2c_dev,0X01);
ssd1306_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
void ssd1306_stopscroll(i2c_t *i2c_dev)
{
ssd1306_command(i2c_dev,SSD1306_DEACTIVATE_SCROLL);
}
// Dim the display
// dim = true: display is dimmed
// dim = false: display is normal
void ssd1306_dim(i2c_t *i2c_dev, uint16_t dim)
{
uint16_t contrast;
if (dim) {
contrast = 0; // Dimmed display
} else {
if (_vccstate == SSD1306_EXTERNALVCC) {
contrast = 0x9F;
} else {
contrast = 0xCF;
}
}
// the range of contrast to too small to be really useful
// it is useful to dim the display
ssd1306_command(i2c_dev,SSD1306_SETCONTRAST);
ssd1306_command(i2c_dev,contrast);
}
// clear everything
void ssd1306_clearDisplay(void)
{
memset(buffer, 0,
(SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8) * sizeof(int));
cursor_y = 0;
cursor_x = 0;
}
void ssd1306_drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color)
{
// Do bounds/limit checks
if (y < 0 || y >= HEIGHT) {
return;
}
// make sure we don't try to draw below 0
if (x < 0) {
w += x;
x = 0;
}
// make sure we don't go off the edge of the display
if ((x + w) > WIDTH) {
w = (WIDTH - x);
}
// if our width is now negative, punt
if (w <= 0) {
return;
}
// set up the pointer for movement through the buffer
uint16_t *pBuf = buffer;
// adjust the buffer pointer for the current row
pBuf += ((y / 8) * SSD1306_LCDWIDTH);
// and offset x columns in
pBuf += x;
uint16_t mask = 1 << (y & 7);
switch (color) {
case WHITE:
while (w--) {
*pBuf++ |= mask;
};
break;
case BLACK:
mask = ~mask;
while (w--) {
*pBuf++ &= mask;
};
break;
case INVERSE:
while (w--) {
*pBuf++ ^= mask;
};
break;
}
}
void ssd1306_drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color)
{
// do nothing if we're off the left or right side of the screen
if (x < 0 || x >= WIDTH) {
return;
}
// make sure we don't try to draw below 0
if (__y < 0) {
// __y is negative, this will subtract enough from __h to account
// for __y being 0
__h += __y;
__y = 0;
}
// make sure we don't go past the height of the display
if ((__y + __h) > HEIGHT) {
__h = (HEIGHT - __y);
}
// if our height is now negative, punt
if (__h <= 0) {
return;
}
// this display doesn't need ints for coordinates, use local byte
// registers for faster juggling
uint16_t y = __y;
uint16_t h = __h;
// set up the pointer for fast movement through the buffer
uint16_t *pBuf = buffer;
// adjust the buffer pointer for the current row
pBuf += ((y / 8) * SSD1306_LCDWIDTH);
// and offset x columns in
pBuf += x;
// do the first partial byte, if necessary - this requires some
// masking
uint16_t mod = (y & 7);
if (mod) {
// mask off the high n bits we want to set
mod = 8 - mod;
// note - lookup table results in a nearly 10% performance
// improvement in fill* functions
// register uint16_t mask = ~(0xFF >> (mod));
static uint16_t premask[8] =
{ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
uint16_t mask = premask[mod];
// adjust the mask if we're not going to reach the end of this
// byte
if (h < mod) {
mask &= (0XFF >> (mod - h));
}
switch (color) {
case WHITE:
*pBuf |= mask;
break;
case BLACK:
*pBuf &= ~mask;
break;
case INVERSE:
*pBuf ^= mask;
break;
}
// fast exit if we're done here!
if (h < mod) {
return;
}
h -= mod;
pBuf += SSD1306_LCDWIDTH;
}
// write solid bytes while we can - effectively doing 8 rows at a time
if (h >= 8) {
if (color == INVERSE) { // separate copy of the code so we don't
// impact performance of the black/white
// write version with an extra comparison
// per loop
do {
*pBuf = ~(*pBuf);
// adjust the buffer forward 8 rows worth of data
pBuf += SSD1306_LCDWIDTH;
// adjust h & y (there's got to be a faster way for me to
// do this, but this should still help a fair bit for now)
h -= 8;
}
while (h >= 8);
} else {
// store a local value to work with
register uint16_t val = (color == WHITE) ? 255 : 0;
do {
// write our value in
*pBuf = val;
// adjust the buffer forward 8 rows worth of data
pBuf += SSD1306_LCDWIDTH;
// adjust h & y (there's got to be a faster way for me to
// do this, but this should still help a fair bit for now)
h -= 8;
}
while (h >= 8);
}
}
// now do the final partial byte, if necessary
if (h) {
mod = h & 7;
// this time we want to mask the low bits of the byte, vs the high
// bits we did above
// register uint16_t mask = (1 << mod) - 1;
// note - lookup table results in a nearly 10% performance
// improvement in fill* functions
static uint16_t postmask[8] =
{ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
uint16_t mask = postmask[mod];
switch (color) {
case WHITE:
*pBuf |= mask;
break;
case BLACK:
*pBuf &= ~mask;
break;
case INVERSE:
*pBuf ^= mask;
break;
}
}
}
void ssd1306_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
{
uint16_t bSwap = false;
switch (rotation) {
case 0:
// 0 degree rotation, do nothing
break;
case 1:
// 90 degree rotation, swap x & y for rotation, then invert x
bSwap = true;
ssd1306_swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
// 180 degree rotation, invert x and y - then shift y around for
// height.
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
x -= (w - 1);
break;
case 3:
// 270 degree rotation, swap x & y for rotation, then invert y and
// adjust y for w (not to become h)
bSwap = true;
ssd1306_swap(x, y);
y = HEIGHT - y - 1;
y -= (w - 1);
break;
}
if (bSwap) {
ssd1306_drawFastVLineInternal(x, y, w, color);
} else {
ssd1306_drawFastHLineInternal(x, y, w, color);
}
}
void ssd1306_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{
uint16_t bSwap = false;
switch (rotation) {
case 0:
break;
case 1:
// 90 degree rotation, swap x & y for rotation, then invert x and
// adjust x for h (now to become w)
bSwap = true;
ssd1306_swap(x, y);
x = WIDTH - x - 1;
x -= (h - 1);
break;
case 2:
// 180 degree rotation, invert x and y - then shift y around for
// height.
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
y -= (h - 1);
break;
case 3:
// 270 degree rotation, swap x & y for rotation, then invert y
bSwap = true;
ssd1306_swap(x, y);
y = HEIGHT - y - 1;
break;
}
if (bSwap) {
ssd1306_drawFastHLineInternal(x, y, h, color);
} else {
ssd1306_drawFastVLineInternal(x, y, h, color);
}
}
void ssd1306_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t fillcolor)
{
// Bounds check
if ((x >= WIDTH) || (y >= HEIGHT))
return;
// Y bounds check
if (y + h > HEIGHT) {
h = HEIGHT - y - 1;
}
// X bounds check
if (x + w > WIDTH) {
w = WIDTH - x - 1;
}
switch (rotation) {
case 1:
swap_values(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
swap_values(x, y);
y = HEIGHT - y - 1;
break;
}
int16_t i;
for (i = 0; i < h; i++)
ssd1306_drawFastHLine(x, y + i, w, fillcolor);
}
int16_t textsize = 1;
int16_t wrap = 1;
void ssd1306_setTextSize(int16_t s)
{
textsize = (s > 0) ? s : 1;
}
void ssd1306_write(int16_t c)
{
if (c == '\n') {
cursor_y += textsize * 8;
cursor_x = 0;
} else if (c == '\r') {
// skip em
} else {
ssd1306_drawChar(cursor_x, cursor_y, c, WHITE, textsize);
cursor_x += textsize * 6;
if (wrap && (cursor_x > (WIDTH - textsize * 6))) {
cursor_y += textsize * 8;
cursor_x = 0;
}
}
}
void ssd1306_drawString(int8_t *str)
{
int16_t i, end;
end = 5;
for (i = 0; i < end; i++)
ssd1306_write(str[i]);
}
// Draw a character
void ssd1306_drawChar(int16_t x, int16_t y, uint8_t c, int16_t color, int16_t size)
{
if ((x >= WIDTH) || // Clip right
(y >= HEIGHT) || // Clip bottom
((x + 6 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
int16_t i;
int16_t j;
for (i = 0; i < 6; i++) {
int16_t line;
if (i == 5)
line = 0x0;
else
line = pgm_read_byte(font + (c * 5) + i);
for (j = 0; j < 8; j++) {
if (line & 0x1) {
if (size == 1) // default size
ssd1306_drawPixel(x + i, y + j, color);
else { // big size
ssd1306_fillRect(x + (i * size),
y + (j * size), size,
size, color);
}
}
line >>= 1;
}
}
}

@ -0,0 +1,167 @@
/*********************************************************************
SSD1306 I2C Library for Raspberry Pi.
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib.
Modified by Ilia Penev
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
*********************************************************************/
/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#ifndef SSD1306_I2C_H_
#define SSD1306_I2C_H_
#include "i2c.h"
#define BLACK 0
#define WHITE 1
#define INVERSE 2
#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
// Address for 128x32 is 0x3C
// Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
/*=========================================================================
SSD1306 Displays
-----------------------------------------------------------------------
The driver is used in multiple displays (128x64, 128x32, etc.).
Select the appropriate display below to create an appropriately
sized framebuffer, etc.
SSD1306_128_64 128x64 pixel display
SSD1306_128_32 128x32 pixel display
SSD1306_96_16
-----------------------------------------------------------------------*/
#define SSD1306_128_64
// #define SSD1306_128_32
// #define SSD1306_96_16
/*=========================================================================*/
#if defined SSD1306_128_32
#define WIDTH 128
#define HEIGHT 32
#endif
#if defined SSD1306_128_64
#define WIDTH 128
#define HEIGHT 64
#endif
#if defined SSD1306_96_16
#define WIDTH 96
#define HEIGHT 16
#endif
#if defined SSD1306_128_64 && defined SSD1306_128_32
#error "Only one SSD1306 display can be specified at once in SSD1306.h"
#endif
#if !defined SSD1306_128_64 && !defined SSD1306_128_32 && !defined SSD1306_96_16
#error "At least one SSD1306 display must be specified in SSD1306.h"
#endif
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#endif
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 32
#endif
#if defined SSD1306_96_16
#define SSD1306_LCDWIDTH 96
#define SSD1306_LCDHEIGHT 16
#endif
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR 0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
// Scrolling #defines
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
//switchvcc should be SSD1306_SWITCHCAPVCC
void ssd1306_begin(i2c_t *i2c_dev, uint16_t vccstate, uint16_t i2caddr);
void ssd1306_command(i2c_t *i2c_dev,uint16_t c);
void ssd1306_display(i2c_t *i2c_dev);
void ssd1306_invertDisplay(i2c_t *i2c_dev, uint16_t i);
void ssd1306_display(i2c_t *i2c_dev);
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop);
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_stopscroll(i2c_t *i2c_dev);
void ssd1306_dim(i2c_t *i2c_dev, uint16_t dim);
void ssd1306_drawPixel(int16_t x, int16_t y, uint16_t color);
void ssd1306_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void ssd1306_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
void ssd1306_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t fillcolor);
void ssd1306_setTextSize(int16_t s);
void ssd1306_drawString(int8_t *str);
void ssd1306_drawChar(int16_t x, int16_t y, uint8_t c, int16_t color, int16_t size);
#endif /* _SSD1306_I2C_H_ */

@ -35,10 +35,10 @@ All text above, and the splash screen below must be included in any redistributi
#define rotation 0
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
int cursor_y = 0;
int cursor_x = 0;
int16_t cursor_y = 0;
int16_t cursor_x = 0;
// the memory buffer for the LCD. Displays Adafruit logo
uint16_t buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8] = {
@ -176,13 +176,13 @@ uint16_t buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8] = {
#endif
};
int _vccstate;
int i2cd;
int16_t _vccstate;
int16_t i2cd;
#define ssd1306_swap(a, b) { int t = a; a = b; b = t; }
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
// the most basic function, set a single pixel
void ssd1306_drawPixel(int x, int y, unsigned int color)
void ssd1306_drawPixel(int16_t x, int16_t y, uint16_t color)
{
if ((x < 0) || (x >= WIDTH) || (y < 0) || (y >= HEIGHT))
return;
@ -218,7 +218,7 @@ void ssd1306_drawPixel(int x, int y, unsigned int color)
}
// Init SSD1306
void ssd1306_begin(i2c_t *i2c_dev, unsigned int vccstate, unsigned int i2caddr)
void ssd1306_begin(i2c_t *i2c_dev, uint16_t vccstate, uint16_t i2caddr)
{
// I2C Init
@ -289,7 +289,7 @@ void ssd1306_begin(i2c_t *i2c_dev, unsigned int vccstate, unsigned int i2caddr)
ssd1306_command(i2c_dev,SSD1306_DISPLAYON); // --turn on oled panel
}
void ssd1306_invertDisplay(i2c_t *i2c_dev, unsigned int i)
void ssd1306_invertDisplay(i2c_t *i2c_dev, uint16_t i)
{
if (i) {
ssd1306_command(i2c_dev,SSD1306_INVERTDISPLAY);
@ -298,12 +298,12 @@ void ssd1306_invertDisplay(i2c_t *i2c_dev, unsigned int i)
}
}
void ssd1306_command(i2c_t *i2c_dev,unsigned int c)
void ssd1306_command(i2c_t *i2c_dev,uint16_t c)
{
// I2C
unsigned int control = 0x00; // Co = 0, D/C = 0
unsigned char i2cDataLenght = 1; // Co = 0, D/C = 0
unsigned int address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
uint16_t control = 0x00; // Co = 0, D/C = 0
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
i2c_write(i2c_dev, &address, &control, &c, &i2cDataLenght);
}
@ -326,11 +326,11 @@ void ssd1306_display(i2c_t *i2c_dev)
ssd1306_command(i2c_dev,1); // Page end address
#endif
unsigned char i2cDataLenght = 1; // Co = 0, D/C = 0
unsigned int address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
uint8_t reg = 0x40;
// I2C
int i;
int16_t i;
for (i = 0; i < (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8); i++) {
i2c_write(i2c_dev, &address, &reg, &buffer[i], &i2cDataLenght);
//This sends byte by byte.
@ -343,7 +343,7 @@ void ssd1306_display(i2c_t *i2c_dev)
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollright(i2c_t *i2c_dev, unsigned int start, unsigned int stop)
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
@ -359,7 +359,7 @@ void ssd1306_startscrollright(i2c_t *i2c_dev, unsigned int start, unsigned int s
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollleft(i2c_t *i2c_dev,unsigned int start, unsigned int stop)
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(i2c_dev,0X00);
@ -375,7 +375,7 @@ void ssd1306_startscrollleft(i2c_t *i2c_dev,unsigned int start, unsigned int sto
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, unsigned int start, unsigned int stop)
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(i2c_dev,0X00);
@ -393,7 +393,7 @@ void ssd1306_startscrolldiagright(i2c_t *i2c_dev, unsigned int start, unsigned i
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, unsigned int start, unsigned int stop)
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(i2c_dev,0X00);
@ -415,9 +415,9 @@ void ssd1306_stopscroll(i2c_t *i2c_dev)
// Dim the display
// dim = true: display is dimmed
// dim = false: display is normal
void ssd1306_dim(i2c_t *i2c_dev, unsigned int dim)
void ssd1306_dim(i2c_t *i2c_dev, uint16_t dim)
{
unsigned int contrast;
uint16_t contrast;
if (dim) {
contrast = 0; // Dimmed display
@ -443,7 +443,7 @@ void ssd1306_clearDisplay(void)
cursor_x = 0;
}
void ssd1306_drawFastHLineInternal(int x, int y, int w, unsigned int color)
void ssd1306_drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color)
{
// Do bounds/limit checks
if (y < 0 || y >= HEIGHT) {
@ -463,13 +463,13 @@ void ssd1306_drawFastHLineInternal(int x, int y, int w, unsigned int color)
return;
}
// set up the pointer for movement through the buffer
unsigned int *pBuf = buffer;
uint16_t *pBuf = buffer;
// adjust the buffer pointer for the current row
pBuf += ((y / 8) * SSD1306_LCDWIDTH);
// and offset x columns in
pBuf += x;
unsigned int mask = 1 << (y & 7);
uint16_t mask = 1 << (y & 7);
switch (color) {
case WHITE:
@ -491,7 +491,7 @@ void ssd1306_drawFastHLineInternal(int x, int y, int w, unsigned int color)
}
}
void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
void ssd1306_drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color)
{
// do nothing if we're off the left or right side of the screen
@ -516,11 +516,11 @@ void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
}
// this display doesn't need ints for coordinates, use local byte
// registers for faster juggling
unsigned int y = __y;
unsigned int h = __h;
uint16_t y = __y;
uint16_t h = __h;
// set up the pointer for fast movement through the buffer
unsigned int *pBuf = buffer;
uint16_t *pBuf = buffer;
// adjust the buffer pointer for the current row
pBuf += ((y / 8) * SSD1306_LCDWIDTH);
// and offset x columns in
@ -528,17 +528,17 @@ void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
// do the first partial byte, if necessary - this requires some
// masking
unsigned int mod = (y & 7);
uint16_t mod = (y & 7);
if (mod) {
// mask off the high n bits we want to set
mod = 8 - mod;
// note - lookup table results in a nearly 10% performance
// improvement in fill* functions
// register unsigned int mask = ~(0xFF >> (mod));
static unsigned int premask[8] =
// register uint16_t mask = ~(0xFF >> (mod));
static uint16_t premask[8] =
{ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
unsigned int mask = premask[mod];
uint16_t mask = premask[mod];
// adjust the mask if we're not going to reach the end of this
// byte
@ -586,7 +586,7 @@ void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
while (h >= 8);
} else {
// store a local value to work with
register unsigned int val = (color == WHITE) ? 255 : 0;
register uint16_t val = (color == WHITE) ? 255 : 0;
do {
// write our value in
@ -607,12 +607,12 @@ void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
mod = h & 7;
// this time we want to mask the low bits of the byte, vs the high
// bits we did above
// register unsigned int mask = (1 << mod) - 1;
// register uint16_t mask = (1 << mod) - 1;
// note - lookup table results in a nearly 10% performance
// improvement in fill* functions
static unsigned int postmask[8] =
static uint16_t postmask[8] =
{ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
unsigned int mask = postmask[mod];
uint16_t mask = postmask[mod];
switch (color) {
case WHITE:
*pBuf |= mask;
@ -627,9 +627,9 @@ void ssd1306_drawFastVLineInternal(int x, int __y, int __h, unsigned int color)
}
}
void ssd1306_drawFastHLine(int x, int y, int w, unsigned int color)
void ssd1306_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
{
unsigned int bSwap = false;
uint16_t bSwap = false;
switch (rotation) {
case 0:
// 0 degree rotation, do nothing
@ -664,9 +664,9 @@ void ssd1306_drawFastHLine(int x, int y, int w, unsigned int color)
}
}
void ssd1306_drawFastVLine(int x, int y, int h, unsigned int color)
void ssd1306_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{
unsigned int bSwap = false;
uint16_t bSwap = false;
switch (rotation) {
case 0:
break;
@ -700,7 +700,7 @@ void ssd1306_drawFastVLine(int x, int y, int h, unsigned int color)
}
}
void ssd1306_fillRect(int x, int y, int w, int h, int fillcolor)
void ssd1306_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t fillcolor)
{
// Bounds check
@ -730,20 +730,20 @@ void ssd1306_fillRect(int x, int y, int w, int h, int fillcolor)
y = HEIGHT - y - 1;
break;
}
int i;
int16_t i;
for (i = 0; i < h; i++)
ssd1306_drawFastHLine(x, y + i, w, fillcolor);
}
int textsize = 1;
int wrap = 1;
int16_t textsize = 1;
int16_t wrap = 1;
void ssd1306_setTextSize(int s)
void ssd1306_setTextSize(int16_t s)
{
textsize = (s > 0) ? s : 1;
}
void ssd1306_write(int c)
void ssd1306_write(int16_t c)
{
if (c == '\n') {
cursor_y += textsize * 8;
@ -760,16 +760,16 @@ void ssd1306_write(int c)
}
}
void ssd1306_drawString(char *str)
void ssd1306_drawString(int8_t *str)
{
int i, end;
int16_t i, end;
end = 5;
for (i = 0; i < end; i++)
ssd1306_write(str[i]);
}
// Draw a character
void ssd1306_drawChar(int x, int y, unsigned char c, int color, int size)
void ssd1306_drawChar(int16_t x, int16_t y, uint8_t c, int16_t color, int16_t size)
{
if ((x >= WIDTH) || // Clip right
@ -777,10 +777,10 @@ void ssd1306_drawChar(int x, int y, unsigned char c, int color, int size)
((x + 6 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
int i;
int j;
int16_t i;
int16_t j;
for (i = 0; i < 6; i++) {
int line;
int16_t line;
if (i == 5)
line = 0x0;
else

@ -137,31 +137,31 @@ All text above, and the splash screen must be included in any redistribution
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
//switchvcc should be SSD1306_SWITCHCAPVCC
void ssd1306_begin(i2c_t *i2c_dev, unsigned int vccstate, unsigned int i2caddr);
void ssd1306_command(i2c_t *i2c_dev,unsigned int c);
void ssd1306_begin(i2c_t *i2c_dev, uint16_t vccstate, uint16_t i2caddr);
void ssd1306_command(i2c_t *i2c_dev,uint16_t c);
void ssd1306_display(i2c_t *i2c_dev);
void ssd1306_invertDisplay(i2c_t *i2c_dev, unsigned int i);
void ssd1306_invertDisplay(i2c_t *i2c_dev, uint16_t i);
void ssd1306_display(i2c_t *i2c_dev);
void ssd1306_startscrollright(i2c_t *i2c_dev, unsigned int start, unsigned int stop);
void ssd1306_startscrollleft(i2c_t *i2c_dev,unsigned int start, unsigned int stop);
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop);
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, unsigned int start, unsigned int stop);
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, unsigned int start, unsigned int stop);
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_stopscroll(i2c_t *i2c_dev);
void ssd1306_dim(i2c_t *i2c_dev, unsigned int dim);
void ssd1306_dim(i2c_t *i2c_dev, uint16_t dim);
void ssd1306_drawPixel(int x, int y, unsigned int color);
void ssd1306_drawPixel(int16_t x, int16_t y, uint16_t color);
void ssd1306_drawFastVLine(int x, int y, int h, unsigned int color);
void ssd1306_drawFastHLine(int x, int y, int w, unsigned int color);
void ssd1306_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void ssd1306_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
void ssd1306_fillRect(int x, int y, int w, int h, int fillcolor);
void ssd1306_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t fillcolor);
void ssd1306_setTextSize(int s);
void ssd1306_drawString(char *str);
void ssd1306_drawChar(int x, int y, unsigned char c, int color, int size);
void ssd1306_setTextSize(int16_t s);
void ssd1306_drawString(int8_t *str);
void ssd1306_drawChar(int16_t x, int16_t y, uint8_t c, int16_t color, int16_t size);
#endif /* _SSD1306_I2C_H_ */

@ -170,13 +170,51 @@ int main(int argc, char *argv[])
ssd1306_begin(&i2c_1, SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS);
ssd1306_display(&i2c_1); //Adafruit logo is visible
delayMs(1000);
ssd1306_clearDisplay(&i2c_1);
delayMs(2000);
ssd1306_display(&i2c_1);
ssd1306_drawChar(10, 5, 'K' , WHITE, 1);
ssd1306_drawChar(16, 5, 'E' , WHITE, 1);
ssd1306_drawChar(22, 5, 'D' , WHITE, 1);
i = 5;
ssd1306_drawChar(i, 5, 'K' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'E' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'D' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, ' ' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'W' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'E' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'L' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'C' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'O' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'M' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'E' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'S' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, ' ' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'Y' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'O' , WHITE, 1);
i += 6;
ssd1306_drawChar(i, 5, 'U' , WHITE, 1);
for(i = 15; i < 50; i++)
{
ssd1306_drawPixel(i,i,WHITE);
}
for(i = 15; i < 53; i++)
{
ssd1306_drawPixel(15,i,WHITE);
}
ssd1306_display(&i2c_1);
delayMs(2000);

Loading…
Cancel
Save