Add files via upload

This commit is contained in:
Marián 2020-10-13 10:45:09 +02:00 committed by GitHub
parent 3ab74e079f
commit d462ac8be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1295 additions and 0 deletions

121
Makefile Normal file
View File

@ -0,0 +1,121 @@
#
# @description Makefile for compiling, linking and flashing code into microcontroller atmega16
#
# @author Marian Hrinko
# @datum 06.097.2020
# @notes Suffix Replacement within a macro: $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
# For example $(DEPENDENCIES:.c=.o)
# @inspiration https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_makefiles.html
# https://wiki.hacdc.org/index.php/AVR_Makefile
#
# BASIC CONFIGURATION, SETTINGS
# ------------------------------------------------------------------
#
# Final file
TARGET = main
#
# Library directory
LIBDIR = lib
#
# Type of microcontroller
DEVICE = atmega16
#
# Frequency
FCPU = 16000000
#
# Optimization
OPTIMIZE = Os
#
# Type of compiler
CC = avr-gcc
#
# Compiler flags
CFLAGS = -g -Wall -DF_CPU=$(FCPU) -mmcu=$(DEVICE) -$(OPTIMIZE)
#
# Includes
INCLUDES = -I.
#
# Libraries
LIBS = -L$(LIBDIR)
#
# Object copy
OBJCOPY = avr-objcopy
#
# Objcopy, create hex file flags
# -R .eeprom -O ihex or -j .data -j .text -O ihex
OBJFLAGS = -j .data -j .text -O ihex
#
# Size of file
AVRSIZE = avr-size
#
# Size flags
SFLAGS = --mcu=$(DEVICE) --format=avr
#
# Target and dependencies .c
SOURCES := $(wildcard *.c $(LIBDIR)/*.c)
#
# Target and dependencies .o
OBJECTS = $(SOURCES:.c=.o)
# AVRDUDE CONFIGURATION, SETTINGS
# -------------------------------------------------------------------
#
# AVRDUDE
AVRDUDE = avrdude
#
# AVRDUDE DEVICE
AVRDUDE_MMCU = m16
#
# AVRDUDE PORT
AVRDUDE_PORT = /dev/ttyUSB0
#
# AVRDUDE PROGRAMMER
AVRDUDE_PROG = usbasp
#
# AVRDUDE BAUD RATE
AVRDUDE_BAUD = 57600
#
# AVRDUDE BAUD RATE
AVROBJ_FORMAT = ihex
#
# AVRDUDE FLAGS
AVRDUDE_FLAGS = -p $(AVRDUDE_MMCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROG) -b $(AVRDUDE_BAUD) -u -U
#
# Create file to programmer
main: $(TARGET).hex
#
# Create hex file
$(TARGET).hex: $(TARGET).elf
$(OBJCOPY) $(OBJFLAGS) $(TARGET).elf $(TARGET).hex
$(AVRSIZE) $(TARGET).elf
#
# Create .elf file
$(TARGET).elf:$(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(TARGET).elf
#
# Create object files
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
#
# Program avr - send file to programmer
flash:
$(AVRDUDE) $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i
#
# Clean
clean:
rm -f $(OBJECTS) $(TARGET).elf $(TARGET).map
#
# Cleanall
cleanall:
rm -f $(OBJECTS) $(TARGET).hex $(TARGET).elf $(TARGET).map

117
lib/font.c Normal file
View File

@ -0,0 +1,117 @@
/**
* ---------------------------------------------------------------+
* @desc FONTs
* ---------------------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 07.10.2020
* @file font.c
* @tested AVR Atmega16
*
* @depend
* ---------------------------------------------------------------+
*/
#include "font.h"
/** @array Charset */
const uint8_t FONTS[][5] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // 20 space
{ 0x81, 0x81, 0x18, 0x81, 0x81 }, // 21 !
// { 0x00, 0x00, 0x5f, 0x00, 0x00 }, // 21 !
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // 22 "
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // 23 #
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // 24 $
{ 0x23, 0x13, 0x08, 0x64, 0x62 }, // 25 %
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // 26 &
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // 27 '
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // 28 (
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // 29 )
{ 0x14, 0x08, 0x3e, 0x08, 0x14 }, // 2a *
{ 0x08, 0x08, 0x3e, 0x08, 0x08 }, // 2b +
{ 0x00, 0x50, 0x30, 0x00, 0x00 }, // 2c ,
{ 0x08, 0x08, 0x08, 0x08, 0x08 }, // 2d -
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // 2e .
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // 2f /
{ 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 30 0
{ 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 31 1
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 32 2
{ 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 33 3
{ 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 34 4
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 35 5
{ 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 36 6
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 37 7
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 38 8
{ 0x06, 0x49, 0x49, 0x29, 0x1e }, // 39 9
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // 3a :
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // 3b ;
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // 3c <
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // 3d =
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // 3e >
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // 3f ?
{ 0x32, 0x49, 0x79, 0x41, 0x3e }, // 40 @
{ 0x7e, 0x11, 0x11, 0x11, 0x7e }, // 41 A
{ 0x7f, 0x49, 0x49, 0x49, 0x36 }, // 42 B
{ 0x3e, 0x41, 0x41, 0x41, 0x22 }, // 43 C
{ 0x7f, 0x41, 0x41, 0x22, 0x1c }, // 44 D
{ 0x7f, 0x49, 0x49, 0x49, 0x41 }, // 45 E
{ 0x7f, 0x09, 0x09, 0x09, 0x01 }, // 46 F
{ 0x3e, 0x41, 0x49, 0x49, 0x7a }, // 47 G
{ 0x7f, 0x08, 0x08, 0x08, 0x7f }, // 48 H
{ 0x00, 0x41, 0x7f, 0x41, 0x00 }, // 49 I
{ 0x20, 0x40, 0x41, 0x3f, 0x01 }, // 4a J
{ 0x7f, 0x08, 0x14, 0x22, 0x41 }, // 4b K
{ 0x7f, 0x40, 0x40, 0x40, 0x40 }, // 4c L
{ 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // 4d M
{ 0x7f, 0x04, 0x08, 0x10, 0x7f }, // 4e N
{ 0x3e, 0x41, 0x41, 0x41, 0x3e }, // 4f O
{ 0x7f, 0x09, 0x09, 0x09, 0x06 }, // 50 P
{ 0x3e, 0x41, 0x51, 0x21, 0x5e }, // 51 Q
{ 0x7f, 0x09, 0x19, 0x29, 0x46 }, // 52 R
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // 53 S
{ 0x01, 0x01, 0x7f, 0x01, 0x01 }, // 54 T
{ 0x3f, 0x40, 0x40, 0x40, 0x3f }, // 55 U
{ 0x1f, 0x20, 0x40, 0x20, 0x1f }, // 56 V
{ 0x3f, 0x40, 0x38, 0x40, 0x3f }, // 57 W
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // 58 X
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // 59 Y
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // 5a Z
{ 0x00, 0x7f, 0x41, 0x41, 0x00 }, // 5b [
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, // 5c backslash
{ 0x00, 0x41, 0x41, 0x7f, 0x00 }, // 5d ]
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // 5e ^
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // 5f _
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // 60 `
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // 61 a
{ 0x7f, 0x48, 0x44, 0x44, 0x38 }, // 62 b
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // 63 c
{ 0x38, 0x44, 0x44, 0x48, 0x7f }, // 64 d
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // 65 e
{ 0x08, 0x7e, 0x09, 0x01, 0x02 }, // 66 f
{ 0x0c, 0x52, 0x52, 0x52, 0x3e }, // 67 g
{ 0x7f, 0x08, 0x04, 0x04, 0x78 }, // 68 h
{ 0x00, 0x44, 0x7d, 0x40, 0x00 }, // 69 i
{ 0x20, 0x40, 0x44, 0x3d, 0x00 }, // 6a j
{ 0x7f, 0x10, 0x28, 0x44, 0x00 }, // 6b k
{ 0x00, 0x41, 0x7f, 0x40, 0x00 }, // 6c l
{ 0x7c, 0x04, 0x18, 0x04, 0x78 }, // 6d m
{ 0x7c, 0x08, 0x04, 0x04, 0x78 }, // 6e n
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // 6f o
{ 0x7c, 0x14, 0x14, 0x14, 0x08 }, // 70 p
{ 0x08, 0x14, 0x14, 0x14, 0x7c }, // 71 q
{ 0x7c, 0x08, 0x04, 0x04, 0x08 }, // 72 r
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // 73 s
{ 0x04, 0x3f, 0x44, 0x40, 0x20 }, // 74 t
{ 0x3c, 0x40, 0x40, 0x20, 0x7c }, // 75 u
{ 0x1c, 0x20, 0x40, 0x20, 0x1c }, // 76 v
{ 0x3c, 0x40, 0x30, 0x40, 0x3c }, // 77 w
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // 78 x
{ 0x0c, 0x50, 0x50, 0x50, 0x3c }, // 79 y
{ 0x44, 0x64, 0x54, 0x4c, 0x44 }, // 7a z
{ 0x00, 0x08, 0x36, 0x41, 0x00 }, // 7b {
{ 0x00, 0x00, 0x7f, 0x00, 0x00 }, // 7c |
{ 0x00, 0x41, 0x36, 0x08, 0x00 }, // 7d }
{ 0x10, 0x08, 0x08, 0x10, 0x08 }, // 7e ~
{ 0x00, 0x00, 0x00, 0x00, 0x00 } // 7f
};

28
lib/font.h Normal file
View File

@ -0,0 +1,28 @@
/**
* ---------------------------------------------------------------+
* @desc FONTs
* ---------------------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 07.10.2020
* @file font.h
* @tested AVR Atmega16
*
* @depend
* ---------------------------------------------------------------+
*/
#include <avr/pgmspace.h>
#ifndef __FONT_H__
#define __FONT_H__
// Characters definition
// -----------------------------------
// number of columns for chars
#define CHARS_COLS_LENGTH 5
// @const Characters
extern const uint8_t FONTS[][CHARS_COLS_LENGTH];
#endif

508
lib/ssd1306.c Normal file
View File

@ -0,0 +1,508 @@
/**
* ---------------------------------------------------------------+
* @desc SSD1306 OLED Driver
* ---------------------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.10.2020
* @file ssd1306.h
* @tested AVR Atmega16
* ---------------------------------------------------------------+
*/
#include <avr/pgmspace.h>
#include "font.h"
#include "twi.h"
#include "ssd1306.h"
// +---------------------------+
// | Set MUX Ratio |
// +---------------------------+
// | 0xA8, 0x3F |
// +---------------------------+
// |
// +---------------------------+
// | Set Display Offset |
// +---------------------------+
// | 0xD3, 0x00 |
// +---------------------------+
// |
// +---------------------------+
// | Set Display Start Line |
// +---------------------------+
// | 0x40 |
// +---------------------------+
// |
// +---------------------------+
// | Set Segment Remap |
// +---------------------------+
// | 0xA0 / 0xA1 |
// +---------------------------+
// |
// +---------------------------+
// | Set COM Output Scan |
// | Direction |
// +---------------------------+
// | 0xC0 / 0xC8 |
// +---------------------------+
// |
// +---------------------------+
// | Set COM Pins hardware |
// | configuration |
// +---------------------------+
// | 0xDA, 0x02 |
// +---------------------------+
// |
// +---------------------------+
// | Set Contrast Control |
// +---------------------------+
// | 0x81, 0x7F |
// +---------------------------+
// |
// +---------------------------+
// | Disable Entire Display On |
// +---------------------------+
// | 0xA4 |
// +---------------------------+
// |
// +---------------------------+
// | Set Normal Display |
// +---------------------------+
// | 0xA6 |
// +---------------------------+
// |
// +---------------------------+
// | Set Osc Frequency |
// +---------------------------+
// | 0xD5, 0x80 |
// +---------------------------+
// |
// +---------------------------+
// | Enable charge pump |
// | regulator |
// +---------------------------+
// | 0x8D, 0x14 |
// +---------------------------+
// |
// +---------------------------+
// | Display On |
// +---------------------------+
// | 0xAF |
// +---------------------------+
/** @array Init command */
const uint8_t INIT_SSD1306[] PROGMEM = {
// number of initializers
16,
// 0xAE = Set Display OFF
// -----------------------------------
0, SSD1306_DISPLAY_OFF,
// 0x20 = Set Memory Addressing Mode
// -----------------------------------
// 0x00 - Horizontal Addressing Mode
// 0x01 - Vertical Addressing Mode
// 0x02 - Page Addressing Mode (RESET)
1, SSD1306_MEMORY_ADDR_MODE, 0x00,
// 0x21 = Set Column Address
// -----------------------------------
// 0x00 - Start Column Address
// 0xFF - End Column Address
2, SSD1306_SET_COLUMN_ADDR, START_COLUMN_ADDR, END_COLUMN_ADDR,
// 0x22 = Set Page Address
// -----------------------------------
// 0x00 - Start Column Address
// 0x07 - End Column Address
2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR,
1, SSD1306_SET_MUX_RATIO, 0x3F,
1, SSD1306_DISPLAY_OFFSET, 0x00,
// 0x40
0, SSD1306_SET_START_LINE,
// 0xA0
0, SSD1306_SEG_REMAP,
// 0xC0
0, SSD1306_COM_SCAN_DIR,
1, SSD1306_COM_PIN_CONF, 0x02,
1, SSD1306_SET_CONTRAST, 0xaF,
// 0xA4
0, SSD1306_DIS_ENT_DISP_ON,
// 0xA6
0, SSD1306_DIS_NORMAL,
1, SSD1306_SET_OSC_FREQ, 0x80,
1, SSD1306_SET_CHAR_REG, 0x14,
// 0xAF = Set Display ON
// -----------------------------------
0, SSD1306_DISPLAY_ON
};
// @var set area
volatile unsigned int set_area = (END_PAGE_ADDR - START_PAGE_ADDR + 1) * (END_COLUMN_ADDR - START_COLUMN_ADDR + 1);
/**
* @desc SSD1306 Init
*
* @param void
*
* @return char
*/
char SSD1306_Init(void)
{
// variables
const uint8_t *commands = INIT_SSD1306;
// number of commands
unsigned short int no_of_commands = pgm_read_byte(commands++);
// argument
char no_of_arguments;
// command
char command;
// init status
char status = INIT_STATUS;
// TWI: Init
// -------------------------
TWI_Init();
// TWI: start & SLAW
// -------------------------
status = SSD1306_Send_StartAndSLAW();
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// loop throuh commands
while (no_of_commands) {
// number of arguments
no_of_arguments = pgm_read_byte(commands++);
// command
command = pgm_read_byte(commands++);
// send command
// -------------------------
status = SSD1306_Send_Command(command);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// send arguments
// -------------------------
while (no_of_arguments--) {
// send command
status = SSD1306_Send_Command(pgm_read_byte(commands++));
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
}
// decrement
no_of_commands--;
}
// TWI: Stop
// -------------------------
TWI_Stop();
// success
return SSD1306_SUCCESS;
}
/**
* @desc SSD1306 Send Start and SLAW request
*
* @param void
*
* @return char
*/
char SSD1306_Send_StartAndSLAW(void)
{
// init status
char status = INIT_STATUS;
// TWI: start
// -------------------------
status = TWI_MT_Start();
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// TWI: send SLAW
// -------------------------
status = TWI_MT_Send_SLAW(SSD1306_ADDRESS);
// request - send SLAW
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// success
return SSD1306_SUCCESS;
}
/**
* @desc SSD1306 Send command
*
* @param char
*
* @return char
*/
char SSD1306_Send_Command(char command)
{
// init status
char status = INIT_STATUS;
// send control byte
// -------------------------
status = TWI_MT_Send_Data(SSD1306_COMMAND);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// send command
// -------------------------
status = TWI_MT_Send_Data(command);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// success
return SSD1306_SUCCESS;
}
/**
* @desc SSD1306 Send Command
*
* @param char
*
* @return char
*/
char SSD1306_ClearScreen(void)
{
// init status
char status = INIT_STATUS;
// TWI: start & SLAW
// -------------------------
status = SSD1306_Send_StartAndSLAW();
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// control byte data stream
// -------------------------
status = TWI_MT_Send_Data(SSD1306_DATA_STREAM);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// erase whole area
// -------------------------
while (set_area--) {
// send null data
status = TWI_MT_Send_Data(0x00);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
}
// stop TWI
TWI_Stop();
// success
return SSD1306_SUCCESS;
}
/**
* @desc SSD1306 Set Poisition
*
* @param char
* @param char
*
* @return char
*/
char SSD1306_SetPosition(char x, char y)
{
// variables
char status = INIT_STATUS;
// TWI: start & SLAW
// -------------------------
status = SSD1306_Send_StartAndSLAW();
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// SET COLUMN address
// ***************************************************
// set column addr
// -------------------------
status = SSD1306_Send_Command(SSD1306_SET_COLUMN_ADDR);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// start COLUMN
// -------------------------
status = SSD1306_Send_Command(x);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// end COLUMN
// -------------------------
status = SSD1306_Send_Command(END_COLUMN_ADDR);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// SET PAGE address
// ***************************************************
// set page addr
// -------------------------
status = SSD1306_Send_Command(SSD1306_SET_PAGE_ADDR);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// start PAGE
// -------------------------
status = SSD1306_Send_Command(y);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// end PAGE
// -------------------------
status = SSD1306_Send_Command(END_PAGE_ADDR);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// stop TWI
TWI_Stop();
// success
return SSD1306_SUCCESS;
}
/**
* @desc Draw character
*
* @param char
*
* @return void
*/
char SSD1306_DrawChar(char character)
{
// variables
uint8_t idxCol=0;
// init status
char status = INIT_STATUS;
// TWI: start & SLAW
// -------------------------
status = SSD1306_Send_StartAndSLAW();
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// control byte data stream
// -------------------------
status = TWI_MT_Send_Data(SSD1306_DATA_STREAM);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// loop through 5 bits
while (idxCol < CHARS_COLS_LENGTH) {
// send control byte data
// -------------------------
status = TWI_MT_Send_Data(pgm_read_byte(&FONTS[character-32][idxCol]));
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// decrement
idxCol++;
}
// empty row
// -------------------------
status = TWI_MT_Send_Data(CLEAR_COLOR);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
// stop TWI
TWI_Stop();
// success
return SSD1306_SUCCESS;
}
/**
* @desc SSD1306 Draw String
*
* @param char *
*
* @return void
*/
char SSD1306_DrawString(char *str)
{
// init status
char status = INIT_STATUS;
// init
int i = 0;
// loop through character of string
while (str[i] != '\0') {
// draw string
status = SSD1306_DrawChar(str[i++]);
// request - start TWI
if (SSD1306_SUCCESS != status) {
// error
return status;
}
}
// success
return SSD1306_SUCCESS;
}

141
lib/ssd1306.h Normal file
View File

@ -0,0 +1,141 @@
/**
* ---------------------------------------------------------------+
* @desc SSD1306 OLED Driver
* ---------------------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.10.2020
* @file ssd1306.h
* @tested AVR Atmega16
*
* @depend twi library
* ---------------------------------------------------------------+
*/
#ifndef __SSD1306_H__
#define __SSD1306_H__
#define SSD1306_SUCCESS 0
// Address definition
// -----------------------------------
#define SSD1306_ADDRESS 0x3C
// Command definition
// -----------------------------------
#define SSD1306_COMMAND 0x80 // Continuation bit=1, D/C=0; 1000 0000
#define SSD1306_COMMAND_STREAM 0x00 // Continuation bit=0, D/C=0; 0000 0000
#define SSD1306_DATA 0xC0 // Continuation bit=1, D/C=1; 1100 0000
#define SSD1306_DATA_STREAM 0x40 // Continuation bit=0, D/C=1; 0100 0000
#define SSD1306_SET_MUX_RATIO 0xA8
#define SSD1306_DISPLAY_OFFSET 0xD3
#define SSD1306_DISPLAY_ON 0xAF
#define SSD1306_DISPLAY_OFF 0xAE
#define SSD1306_DIS_ENT_DISP_ON 0xA4
#define SSD1306_DIS_NORMAL 0xA6
#define SSD1306_DIS_INVERSE 0xA7
#define SSD1306_DEACT_SCROLL 0x2E
#define SSD1306_ACTIVE_SCROLL 0x2F
#define SSD1306_SET_START_LINE 0x40
#define SSD1306_MEMORY_ADDR_MODE 0x20
#define SSD1306_SET_COLUMN_ADDR 0x21
#define SSD1306_SET_PAGE_ADDR 0x22
#define SSD1306_SEG_REMAP 0xA0
#define SSD1306_SEG_REMAP_OP 0xA1
#define SSD1306_COM_SCAN_DIR 0xC0
#define SSD1306_COM_SCAN_DIR_OP 0xC0
#define SSD1306_COM_PIN_CONF 0xDA
#define SSD1306_SET_CONTRAST 0x81
#define SSD1306_SET_OSC_FREQ 0xD5
#define SSD1306_SET_CHAR_REG 0x8D
// Characters definition
// -----------------------------------
// number of columns for chars
#define CHARS_COLS_LENGTH 5
// Clear Color
// -----------------------------------
#define CLEAR_COLOR 0x00
// Init Status
// -----------------------------------
#define INIT_STATUS 0xFF
// AREA definition
// -----------------------------------
#define START_PAGE_ADDR 0
#define END_PAGE_ADDR 7
#define START_COLUMN_ADDR 0
#define END_COLUMN_ADDR 127
// @var set area
volatile unsigned int set_area;
/**
* @desc SSD1306 Init
*
* @param void
*
* @return char
*/
char SSD1306_Init(void);
/**
* @desc SSD1306 Send Start and SLAW request
*
* @param void
*
* @return char
*/
char SSD1306_Send_StartAndSLAW(void);
/**
* @desc SSD1306 Send Command
*
* @param char
*
* @return char
*/
char SSD1306_Send_Command(char);
/**
* @desc SSD1306 Clear Screen
*
* @param void
*
* @return char
*/
char SSD1306_ClearScreen(void);
/**
* @desc SSD1306 Set Position
*
* @param char
* @param char
*
* @return char
*/
char SSD1306_SetPosition(char, char);
/**
* @desc SSD1306 Draw Character
*
* @param char
*
* @return char
*/
char SSD1306_DrawChar(char);
/**
* @desc SSD1306 Draw String
*
* @param char *
*
* @return char
*/
char SSD1306_DrawString(char *);
#endif

162
lib/twi.c Normal file
View File

@ -0,0 +1,162 @@
/**
* ---------------------------------------------------+
* @desc Two Wire Interface / I2C Communication
* ---------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.09.2020
* @file twi.c
* @tested AVR Atmega16
* ---------------------------------------------------
*/
// include libraries
#include "twi.h"
/**
* @desc TWI init - initialize frequency
*
* @param void
*
* @return void
*/
void TWI_Init(void)
{
// +++++++++++++++++++++++++++++++++++++++++++++
// Calculation fclk:
//
// fclk = (fcpu)/(16+2*TWBR*4^Prescaler)
// ---------------------------------------------
// Calculation TWBR:
//
// TWBR = {(fcpu/fclk) - 16 } / (2*4^Prescaler)
// +++++++++++++++++++++++++++++++++++++++++++++
// @param1 value of TWBR,
// fclk = 400 kHz; TWBR = 3
// fclk = 100 kHz; TWBR = 20
// @param2 value of Prescaler = 1
TWI_FREQ(20, 1);
}
/**
* @desc TWI MT Start
*
* @param void
*
* @return char
*/
char TWI_MT_Start(void)
{
// null status flag
TWI_TWSR &= ~0xA8;
// START
// ----------------------------------------------
// request for bus
TWI_START();
// wait till flag set
TWI_WAIT_TILL_TWINT_IS_SET();
// test if start or repeated start acknowledged
if ((TWI_STATUS != TWI_START_ACK) && (TWI_STATUS != TWI_REP_START_ACK)) {
// return status
return TWI_STATUS;
}
// success
return SUCCESS;
}
/**
* @desc TWI Send address + write
*
* @param char
*
* @return char
*/
char TWI_MT_Send_SLAW(char address)
{
// SLA+W
// ----------------------------------------------
TWI_TWDR = (address << 1);
// enable
TWI_ENABLE();
// wait till flag set
TWI_WAIT_TILL_TWINT_IS_SET();
// find
if (TWI_STATUS != TWI_MT_SLAW_ACK) {
// return status
return TWI_STATUS;
}
// return found device address
return SUCCESS;
}
/**
* @desc TWI Send data
*
* @param char
*
* @return char
*/
char TWI_MT_Send_Data(char data)
{
// DATA
// ----------------------------------------------
TWI_TWDR = data;
// enable
TWI_ENABLE();
// wait till flag set
TWI_WAIT_TILL_TWINT_IS_SET();
// find
if (TWI_STATUS != TWI_MT_DATA_ACK) {
// return status
return TWI_STATUS;
}
// return found device address
return SUCCESS;
}
/**
* @desc TWI Send address + read
*
* @param char
*
* @return char
*/
char TWI_MR_Send_SLAR(char address)
{
// SLA+R
// ----------------------------------------------
TWI_TWDR = (address << 1) | 0x01;
// enable
TWI_ENABLE();
// wait till flag set
TWI_WAIT_TILL_TWINT_IS_SET();
// find
if (TWI_STATUS != TWI_MR_SLAR_ACK) {
// return status
return TWI_STATUS;
}
// return found device address
return SUCCESS;
}
/**
* @desc TWI stop
*
* @param void
*
* @return void
*/
void TWI_Stop(void)
{
// End TWI
// -------------------------------------------------
// send stop sequence
TWI_STOP();
// wait for TWINT flag is set
// TWI_WAIT_TILL_TWINT_IS_SET();
}

171
lib/twi.h Normal file
View File

@ -0,0 +1,171 @@
/**
* ---------------------------------------------------+
* @desc Two Wire Interface / I2C Communication
* ---------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.09.2020
* @file twi.h
* @tested AVR Atmega16
* ---------------------------------------------------
*/
#include <stdio.h>
#include <avr/io.h>
#ifndef __TWI_H__
#define __TWI_H__
// define clock
#if defined(__AVR_ATmega8__)
#define _FCPU 8000000
#elif defined(__AVR_ATmega16__)
#define _FCPU 16000000
#endif
// define register for TWI communication
#if defined(__AVR_ATmega16__)
#define TWI_TWAR TWAR // TWI (Slave) Address Register
#define TWI_TWBR TWBR // TWI Bit Rate Register
#define TWI_TWDR TWDR // TWI Data Register
#define TWI_TWCR TWCR // TWI Control Register
#define TWI_TWSR TWSR // TWI Status Register
#endif
// TWI CLK frequency
// @param TWBR
// @param Prescaler
// TWPS1 TWPS0 - PRESCALER
// 0 0 - 1
// 0 1 - 4
// 1 0 - 16
// 1 1 - 64
#define TWI_FREQ(BIT_RATE, PRESCALER) { TWI_TWBR = BIT_RATE; TWI_TWSR |= (TWI_TWSR & 0x03) | PRESCALER; }
// TWI start condition
// (1 << TWEN) - TWI Enable
// (1 << TWINT) - TWI Interrupt Flag - must be cleared by set
// (1 << TWSTA) - TWI Start
#define TWI_START() { TWI_TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTA); }
// TWI enable
// (1 << TWEN) - TWI Enable
// (1 << TWINT) - TWI Interrupt Flag - must be cleared by set
#define TWI_ENABLE() { TWI_TWCR = (1 << TWEN) | (1 << TWINT); }
// TWI stop condition
// (1 << TWEN) - TWI Enable
// (1 << TWINT) - TWI Interrupt Flag - must be cleared by set
// (1 << TWSTO) - TWI Stop
#define TWI_STOP() { TWI_TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTO); }
// TWI test if TWINT Flag is set
#define TWI_WAIT_TILL_TWINT_IS_SET() { while (!(TWI_TWCR & (1 << TWINT))); }
// TWI status mask
#define TWI_STATUS (TWI_TWSR & 0xF8)
// success return value
#define SUCCESS 0
// success return value
#define ERROR 1
// ++++++++++++++++++++++++++++++++++++++++++
//
// M A S T E R M O D E
//
// ++++++++++++++++++++++++++++++++++++++++++
// Master Mode - Transmitter / Receiver
#define TWI_START_ACK 0x08 // A START condition has been transmitted
#define TWI_REP_START_ACK 0x10 // A repeated START condition has been transmitted
#define TWI_FLAG_ARB_LOST 0x38 // Arbitration lost in SLA+W or NOT ACK bit
// Master Transmitter Mode
#define TWI_MT_SLAW_ACK 0x18 // SLA+W has been transmitted; ACK has been received
#define TWI_MT_SLAW_NACK 0x20 // SLA+W has been transmitted; NOT ACK has been received
#define TWI_MT_DATA_ACK 0x28 // Data byte has been transmitted; ACK has been received
#define TWI_MT_DATA_NACK 0x30 // Data byte has been transmitted; NOT ACK has been received
// Master Receiver Mode
#define TWI_MR_SLAR_ACK 0x40 // SLA+R has been transmitted; ACK has been received
#define TWI_MR_SLAR_NACK 0x48 // SLA+R has been transmitted; NOT ACK has been received
#define TWI_MR_DATA_ACK 0x50 // Data byte has been received; ACK has been received
#define TWI_MR_DATA_NACK 0x58 // Data byte has been received; NOT ACK has been received
// ++++++++++++++++++++++++++++++++++++++++++
//
// S L A V E M O D E
//
// ++++++++++++++++++++++++++++++++++++++++++
// Slave Receiver Mode
#define TWI_SR_SLAW_ACK 0x60 // Own Slave address has been received; ACK returned
#define TWI_SR_ALMOA_ACK 0x68 // Arbitration Lost in SLA+R/W as Master; Own Slave address has been received; ACK returned
#define TWI_SR_GCALL_ACK 0x70 // General call address has been received; ACK returned
#define TWI_SR_ALMGA_ACK 0x78 // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK returned
#define TWI_SR_OA_DATA_ACK 0x80 // Previously addressed with own SLA+W; data has been received; ACK returned
#define TWI_SR_OA_DATA_NACK 0x88 // Previously addressed with own SLA+W; data has been received; NOT ACK returned
#define TWI_SR_GC_DATA_ACK 0x90 // Previously addressed with general call; data has been received; ACK returned
#define TWI_SR_GC_DATA_NACK 0x98 // Previously addressed with general call; data has been received; NOT ACK returned
#define TWI_SR_STOP_RSTART 0xA0 // A STOP condition or repeated START condition has been received while still addressed as Slave
// Slave Transmitter Mode
#define TWI_ST_OA_ACK 0xA8 // Own SLA+R has been received; ACK has been returned
#define TWI_ST_ALMOA_ACK 0xB0 // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been received
#define TWI_ST_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted; ACK has been received
#define TWI_ST_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted; NOT ACK has been received
#define TWI_ST_DATA_LOST_ACK 0xC8 // Last data byte in TWDR has been transmitted (TWEA = '0'); ACK has been received
/**
* @desc TWI init - initialise communication
*
* @param void
*
* @return void
*/
void TWI_Init(void);
/**
* @desc TWI MT Start
*
* @param void
*
* @return char
*/
char TWI_MT_Start(void);
/**
* @desc TWI Send SLAW
*
* @param void
*
* @return unsigned char
*/
char TWI_MT_Send_SLAW(char);
/**
* @desc TWI Send data
*
* @param char
*
* @return char
*/
char TWI_MT_Send_Data(char);
/**
* @desc TWI Send SLAR
*
* @param void
*
* @return unsigned char
*/
char TWI_MR_Send_SLAR(char);
/**
* @desc TWI stop
*
* @param void
*
* @return void
*/
void TWI_Stop(void);
#endif

47
main.c Normal file
View File

@ -0,0 +1,47 @@
/**
* -------------------------------------------------------------+
* @desc OLED SSD1306 example
* -------------------------------------------------------------+
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.10.2020
* @file main.c
* @tested AVR Atmega16
* -------------------------------------------------------------+
*/
// include libraries
#include "lib/ssd1306.h"
/**
* @desc Main
*
* @param void
*
* @return unsigned char
*/
int main(void)
{
// init ssd1306
SSD1306_Init();
// clear screen
SSD1306_ClearScreen();
// set position
SSD1306_SetPosition(5, 0);
// draw string
SSD1306_DrawString(" 0.96\" OLED SSD1306");
// set position
SSD1306_SetPosition(30, 1);
// draw string
SSD1306_DrawString("by Matiasus");
// return value
return 0;
}