This commit is contained in:
2022-10-30 23:00:53 +01:00
commit 7f087ae854
226 changed files with 27881 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
#include "twi.h"
#include "ssd1306.h"
#include "sevenseg.h"
void main() {
TWI_Init();
ssd1306_128x32_i2c_init();
// ssd1306_128x64_spi_init(-1, 0, 1); // Use this line for nano pi (RST not used, 0=CE, gpio1=D/C)
// ssd1306_128x64_spi_init(3,4,5); // Use this line for Atmega328p (3=RST, 4=CE, 5=D/C)
// ssd1306_128x64_spi_init(24, 0, 23); // Use this line for Raspberry (gpio24=RST, 0=CE, gpio23=D/C)
// ssd1306_128x64_spi_init(22, 5, 21); // Use this line for ESP32 (VSPI) (gpio22=RST, gpio5=CE for VSPI, gpio21=D/C)
// composite_video_128x64_mono_init(); // Use this line for ESP32 with Composite video support
ssd1306_clearScreen();
//ssd1306_drawLine(0,0, ssd1306_displayWidth() -1, ssd1306_displayHeight() -1);
const uint8_t charw = 18;
const uint8_t spacing = 6;
const uint8_t barw=4;
struct SevenSeg sseg = {
.x0 = 0,
.y0 = 0,
.charwidth = 17,
.thick = 3,
//.charwidth = 16,
//.thick = 1,
.spacing = 4,
};
uint16_t i = 0;
uint16_t v;
uint16_t w;
int drawing = false;
for (;;) {
sseg_number(&sseg, i, 5, 1);
i++;
if (i == 9999) i = 0;
_delay_ms(100);
}
}
+146
View File
@@ -0,0 +1,146 @@
/**
* TODO file description
*/
#include <avr/pgmspace.h>
#include "sevenseg.h"
#include "ssd1306.h"
void sseg_home(struct SevenSeg *disp) {
disp->x = 0;
}
enum SevenSegBars {
T=1, RT=2, RB=4, B=8, LB=16, LT=32, M=64
};
static const uint8_t PROGMEM seven[] = {
[0] = T|RT|RB|B|LB|LT,
[1] = RT|RB,
[2] = T|RT|M|LB|B,
[3] = T|RT|M|RB|B,
[4] = RT|RB|M|LT,
[5] = T|LT|M|RB|B,
[6] = T|LT|LB|B|RB|M,
[7] = T|RT|RB,
[8] = T|LT|RT|LB|RB|B|M,
[9] = T|LT|RT|RB|B|M,
};
static void draw_7seg_dig(uint8_t x, uint8_t y, uint8_t w, uint8_t th, uint8_t digit) {
uint8_t mask = digit == 255 ? 0 : pgm_read_byte(&seven[digit]);
const uint8_t v = w - th * 2;
const uint8_t subs = 1;
ssd1306_setColor((mask & T) ? 0xFFFF : 0);
ssd1306_fillRect(
x + th,
y + 0,
x + th + v - subs,
y + th - subs);
ssd1306_setColor((mask & M) ? 0xFFFF : 0);
ssd1306_fillRect(
x + th,
y + th + v,
x + th + v - subs,
y + th * 2 + v - subs);
ssd1306_setColor((mask & B) ? 0xFFFF : 0);
ssd1306_fillRect(
x + th,
y + th * 2 + v * 2,
x + th + v - subs,
y + th * 3 + v * 2 - subs);
ssd1306_setColor((mask & LT) ? 0xFFFF : 0);
ssd1306_fillRect(
x + 0,
y + th,
x + th - subs,
y + th + v - subs);
ssd1306_setColor((mask & RT) ? 0xFFFF : 0);
ssd1306_fillRect(
x + th + v,
y + th,
x + th * 2 + v - subs,
y + th + v - subs);
ssd1306_setColor((mask & LB) ? 0xFFFF : 0);
ssd1306_fillRect(
x + 0,
y + th * 2 + v,
x + th - subs,
y + th * 2 + v * 2 - subs);
ssd1306_setColor((mask & RB) ? 0xFFFF : 0);
ssd1306_fillRect(
x + th + v,
y + th * 2 + v,
x + th * 2 + v - subs,
y + th * 2 + v * 2 - subs);
}
static void draw_7seg_period(uint8_t x, uint8_t y, uint8_t w, uint8_t th) {
const uint8_t v = w - th * 2;
const uint8_t subs = 1;
ssd1306_setColor(0xFFFF);
ssd1306_fillRect(
x,
y + th * 2 + v * 2,
x + th - subs,
y + th * 3 + v * 2 - subs);
}
void sseg_digit(struct SevenSeg *disp, uint8_t digit) {
draw_7seg_dig(disp->x, disp->y0, disp->charwidth, disp->thick, digit);
disp->x += disp->charwidth + disp->spacing;
}
void sseg_blank(struct SevenSeg *disp) {
draw_7seg_dig(disp->x, disp->y0, disp->charwidth, disp->thick, 255);
disp->x += disp->charwidth + disp->spacing;
}
void sseg_period(struct SevenSeg *disp) {
draw_7seg_period(disp->x, disp->y0, disp->charwidth, disp->thick);
disp->x += disp->thick + disp->spacing;
}
void sseg_number(struct SevenSeg *disp, uint16_t num, uint8_t places, uint8_t decimals) {
uint8_t digits[5] = {};
uint8_t pos = 4;
while (num > 0) {
uint8_t res = num % 10;
num /= 10;
digits[pos] = res;
pos--;
}
sseg_home(disp);
bool drawing = false;
for (uint8_t i = 5 - places; i < 5; i++) {
uint8_t d = digits[i];
if (i == 5 - decimals) {
sseg_period(disp);
}
if (!drawing && d == 0) {
if (i == 5 - decimals - 1) {
sseg_digit(disp, d);
drawing = true;
} else {
sseg_blank(disp);
}
} else {
sseg_digit(disp, d);
drawing = true;
}
}
}
+30
View File
@@ -0,0 +1,30 @@
/**
* TODO file description
*/
#ifndef CPROJ_SEVENSEG_H
#define CPROJ_SEVENSEG_H
#include <stdbool.h>
struct SevenSeg {
uint8_t x0;
uint8_t y0;
uint8_t x;
uint8_t charwidth;
uint8_t thick;
uint8_t spacing;
};
void sseg_home(struct SevenSeg *disp);
void sseg_digit(struct SevenSeg *disp, uint8_t digit);
void sseg_blank(struct SevenSeg *disp);
void sseg_period(struct SevenSeg *disp);
void sseg_number(struct SevenSeg *disp, uint16_t num, uint8_t places, uint8_t decimals);
#endif //CPROJ_SEVENSEG_H
+166
View File
@@ -0,0 +1,166 @@
/**
* ---------------------------------------------------------------+
* @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, ATmega8, Atmega328
*
* @depend
* ---------------------------------------------------------------+
* @usage Master Transmit Operation
*/
// include libraries
#include <avr/io.h>
#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 = 400kHz (m16); TWBR = 3
// fclk = 100kHz (m16); TWBR = 20
// @param2 value of Prescaler = 1
TWI_FREQ (3, 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();
// test if SLA with WRITE acknowledged
if (TWI_STATUS != TWI_MT_SLAW_ACK) {
// return status
return TWI_STATUS;
}
// success
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();
// test if data acknowledged
if (TWI_STATUS != TWI_MT_DATA_ACK) {
// return status
return TWI_STATUS;
}
// success
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();
// test if SLA with READ acknowledged
if (TWI_STATUS != TWI_MR_SLAR_ACK) {
// return status
return TWI_STATUS;
}
// success
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();
}
+178
View File
@@ -0,0 +1,178 @@
/**
* ---------------------------------------------------------------+
* @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, ATmega8, Atmega328
*
* @depend
* ---------------------------------------------------------------+
* @usage Basic Master Transmit Operation
*/
#ifndef __TWI_H__
#define __TWI_H__
// define register for TWI communication
// -------------------------------------------
#if defined(__AVR_ATmega16__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
#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
// Success
// -------------------------------------------
#ifndef SUCCESS
#define SUCCESS 0
#endif
// Error
// -------------------------------------------
#ifndef ERROR
#define ERROR 1
#endif
// ++++++++++++++++++++++++++++++++++++++++++
//
// 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
// 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 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 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 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 )
/**
* @desc TWI init
*
* @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