initial
This commit is contained in:
+46
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user