Formatted in "Allman" style, added fat16 lib files

pull/1/head
Ondřej Hruška 10 years ago
parent 49c95d1b6d
commit 4e2d86f01d
  1. 18
      lib/color.c
  2. 6
      lib/color.h
  3. 21
      lib/debounce.c
  4. 5
      lib/debounce.h
  5. 3
      lib/dht11.h
  6. 1180
      lib/fat16.c
  7. 251
      lib/fat16.h
  8. 65
      lib/fat16_internal.h
  9. 21
      lib/lcd.c
  10. 17
      lib/onewire.c
  11. 57
      lib/sonar.c
  12. 3
      lib/sonar.h
  13. 47
      lib/stream.c
  14. 3
      lib/stream.h
  15. 104
      lib/uart.c
  16. 19
      lib/wsrgb.c

@ -10,7 +10,8 @@
// --- HSL --- // --- HSL ---
#ifdef HSL_LINEAR #ifdef HSL_LINEAR
const uint8_t FADE_128[] = { const uint8_t FADE_128[] =
{
0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4,
5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 12, 13, 14, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 12, 13, 14,
14, 15, 16, 17, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36, 14, 15, 16, 17, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36,
@ -30,19 +31,26 @@ xrgb_t hsl_xrgb(const hsl_t cc)
const uint8_t hue_mod = hh % 256; const uint8_t hue_mod = hh % 256;
uint8_t r_temp, g_temp, b_temp; uint8_t r_temp, g_temp, b_temp;
if (hh < 256) { if (hh < 256)
{
r_temp = hue_mod ^ 255; r_temp = hue_mod ^ 255;
g_temp = hue_mod; g_temp = hue_mod;
b_temp = 0; b_temp = 0;
} else if (hh < 512) { }
else if (hh < 512)
{
r_temp = 0; r_temp = 0;
g_temp = hue_mod ^ 255; g_temp = hue_mod ^ 255;
b_temp = hue_mod; b_temp = hue_mod;
} else if (hh < 768) { }
else if (hh < 768)
{
r_temp = hue_mod; r_temp = hue_mod;
g_temp = 0; g_temp = 0;
b_temp = hue_mod ^ 255; b_temp = hue_mod ^ 255;
} else { }
else
{
r_temp = 0; r_temp = 0;
g_temp = 0; g_temp = 0;
b_temp = 0; b_temp = 0;

@ -12,7 +12,8 @@
// Define HSL_LINEAR to get more linear brightness in hsl->rgb conversion // Define HSL_LINEAR to get more linear brightness in hsl->rgb conversion
typedef struct { typedef struct
{
uint8_t r; uint8_t r;
uint8_t g; uint8_t g;
uint8_t b; uint8_t b;
@ -45,7 +46,8 @@ typedef uint32_t rgb24_t;
// HSL data structure // HSL data structure
typedef struct { typedef struct
{
uint8_t h; uint8_t h;
uint8_t s; uint8_t s;
uint8_t l; uint8_t l;

@ -11,11 +11,11 @@ uint8_t debo_next_slot = 0;
uint8_t debo_register(PORT_P reg, uint8_t bit, bool invert) uint8_t debo_register(PORT_P reg, uint8_t bit, bool invert)
{ {
debo_slots[debo_next_slot] = (debo_slot_t){ debo_slots[debo_next_slot] = (debo_slot_t)({
.reg = reg, .reg = reg,
.bit = bit | ((invert & 1) << 7) | (get_bit_p(reg, bit) << 6), // bit 7 = invert, bit 6 = state .bit = bit | ((invert & 1) << 7) | (get_bit_p(reg, bit) << 6), // bit 7 = invert, bit 6 = state
.count = 0, .count = 0,
}; });
return debo_next_slot++; return debo_next_slot++;
} }
@ -24,21 +24,28 @@ uint8_t debo_register(PORT_P reg, uint8_t bit, bool invert)
/** Check debounced pins, should be called periodically. */ /** Check debounced pins, should be called periodically. */
void debo_tick() void debo_tick()
{ {
for (uint8_t i = 0; i < debo_next_slot; i++) { for (uint8_t i = 0; i < debo_next_slot; i++)
{
// current pin value (right 3 bits, xored with inverse bit) // current pin value (right 3 bits, xored with inverse bit)
bool value = get_bit_p(debo_slots[i].reg, debo_slots[i].bit & 0x7); bool value = get_bit_p(debo_slots[i].reg, debo_slots[i].bit & 0x7);
if (value != get_bit(debo_slots[i].bit, 6)) { if (value != get_bit(debo_slots[i].bit, 6))
{
// different pin state than last recorded state // different pin state than last recorded state
if (debo_slots[i].count < DEBO_TICKS) { if (debo_slots[i].count < DEBO_TICKS)
{
debo_slots[i].count++; debo_slots[i].count++;
} else { }
else
{
// overflown -> latch value // overflown -> latch value
set_bit(debo_slots[i].bit, 6, value); // set state bit set_bit(debo_slots[i].bit, 6, value); // set state bit
debo_slots[i].count = 0; debo_slots[i].count = 0;
} }
} else { }
else
{
debo_slots[i].count = 0; // reset the counter debo_slots[i].count = 0; // reset the counter
} }
} }

@ -31,7 +31,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "calc.h" #include "calc.h"
#include "pins.h" #include "iopins.h"
// Your config file // Your config file
#include "debo_config.h" #include "debo_config.h"
@ -42,7 +42,8 @@
/* Internal deboucer entry */ /* Internal deboucer entry */
typedef struct { typedef struct
{
PORT_P reg; // pointer to IO register PORT_P reg; // pointer to IO register
uint8_t bit; // bits 6 and 7 of this hold "state" & "invert" flag uint8_t bit; // bits 6 and 7 of this hold "state" & "invert" flag
uint8_t count; // number of ticks this was in the new state uint8_t count; // number of ticks this was in the new state

@ -7,7 +7,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
typedef struct { typedef struct
{
int8_t temp; int8_t temp;
int8_t rh; int8_t rh;
} dht11_result_t; } dht11_result_t;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,251 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
/**
* Abstract block device interface
*
* Populate this with pointers to your I/O functions.
*/
typedef struct
{
// Sequential read
void (*load)(void* dest, const uint16_t len);
// Sequential write
void (*store)(const void* src, const uint16_t len);
// Sequential byte write
void (*write)(const uint8_t b);
// Sequential byte read
uint8_t (*read)(void);
// Absolute seek
void (*seek)(const uint32_t);
// Relative seek
void (*rseek)(const int16_t);
} BLOCKDEV;
// -------------------------------
/**
* File types (values can be used for debug printing).
* Accessible using file->type
*/
typedef enum
{
FT_NONE = '-',
FT_DELETED = 'x',
FT_SUBDIR = 'D',
FT_PARENT = 'P',
FT_LABEL = 'L',
FT_LFN = '~',
FT_INVALID = '?', // not recognized weird file
FT_SELF = '.',
FT_FILE = 'F'
} FAT16_FT;
// Include definitions of fully internal structs
#include "fat16_internal.h"
/**
* File handle struct.
*
* File handle contains cursor, file name, type, size etc.
* Everything (files, dirs) is accessed using this.
*/
typedef struct __attribute__((packed))
{
/**
* Raw file name. Starting 0x05 was converted to 0xE5.
* To get PRINTABLE file name, use fat16_dispname()
*/
uint8_t name[11];
/**
* File attributes - bit field composed of FA_* flags
* (internal)
*/
uint8_t attribs;
// 14 bytes skipped (10 reserved, date, time)
/** First cluster of the file. (internal) */
uint16_t clu_start;
/**
* File size in bytes.
* This is the current allocated and readable file size.
*/
uint32_t size;
// --- the following fields are added when reading ---
/** File type. */
FAT16_FT type;
// --- INTERNAL FIELDS ---
// Cursor variables. (internal)
uint32_t cur_abs; // absolute position in device
uint32_t cur_rel; // relative position in file
uint16_t cur_clu; // cluster where the cursor is
uint16_t cur_ofs; // offset within the active cluster
// File position in the directory. (internal)
uint16_t clu; // first cluster of directory
uint16_t num; // file entry number
// Pointer to the FAT16 handle. (internal)
const FAT16* fat;
}
FAT16_FILE;
/** Initialize the file system - store into "fat" */
void fat16_init(const BLOCKDEV* dev, FAT16* fat);
/**
* Open the first file of the root directory.
* The file may be invalid (eg. a volume label, deleted etc),
* or blank (type FT_NONE) if the filesystem is empty.
*/
void fat16_root(const FAT16* fat, FAT16_FILE* file);
/**
* Resolve the disk label.
* That can be in the Boot Sector, or in the first root directory entry.
*/
char* fat16_disk_label(const FAT16* fat, char* label_out);
// ----------- FILE I/O -------------
/**
* Move file cursor to a position relative to file start
* Returns false on I/O error (bad file, out of range...)
*/
bool fat16_seek(FAT16_FILE* file, uint32_t addr);
/**
* Read bytes from file into memory
* Returns false on I/O error (bad file, out of range...)
*/
bool fat16_read(FAT16_FILE* file, void* target, uint32_t len);
/**
* Write into file at a "seek" position.
* "seek" cursor must be within (0..filesize)
*/
bool fat16_write(FAT16_FILE* file, void* source, uint32_t len);
/**
* Create a new file in given folder
*
* file ... open directory; new file is opened into this handle.
* name ... name of the new file, including extension
*/
bool fat16_mkfile(FAT16_FILE* file, const char* name);
/**
* Create a sub-directory of given name.
* Directory is allocated and populated with entries "." and ".."
*/
bool fat16_mkdir(FAT16_FILE* file, const char* name);
/**
* Set new file size.
* Allocates / frees needed clusters, does NOT erase them.
*
* Useful mainly for shrinking.
*/
void fat16_resize(FAT16_FILE* file, uint32_t size);
/**
* Delete a *FILE* and free it's clusters.
*/
bool fat16_rmfile(FAT16_FILE* file);
/**
* Delete an empty *DIRECTORY* and free it's clusters.
*/
bool fat16_rmdir(FAT16_FILE* file);
/**
* Delete a file or directory, even FT_LFN and FT_INVALID.
* Directories are deleted recursively (!)
*/
bool fat16_delete(FAT16_FILE* file);
// --------- NAVIGATION ------------
/** Go to previous file in the directory (false = no prev file) */
bool fat16_prev(FAT16_FILE* file);
/** Go to next file in directory (false = no next file) */
bool fat16_next(FAT16_FILE* file);
/**
* Open a subdirectory denoted by the file.
* Provided handle changes to the first entry of the directory.
*/
bool fat16_opendir(FAT16_FILE* dir);
/**
* Open a parent directory. Fails in root.
* Provided handle changes to the first entry of the parent directory.
*/
bool fat16_parent(FAT16_FILE* file);
/** Jump to first file in this directory */
void fat16_first(FAT16_FILE* file);
/**
* Find a file with given "display name" in this directory.
* If file is found, "dir" will contain it's handle.
* If file is NOT found, the handle points to the last entry of the directory.
*/
bool fat16_find(FAT16_FILE* dir, const char* name);
// -------- FILE INSPECTION -----------
/** Check if file is a valid entry, or long-name/label/deleted */
bool fat16_is_regular(const FAT16_FILE* file);
/**
* Resolve a file name, trim spaces and add null terminator.
* Returns the passed char*, or NULL on error.
*/
char* fat16_dispname(const FAT16_FILE* file, char* disp_out);
/**
* Convert filename to zero-padded fixed length one
* Returns the passed char*.
*/
char* fat16_rawname(const char* disp_in, char* raw_out);

@ -0,0 +1,65 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
// Internal types and stuff that is needed in the header for declarations,
// but is not a part of the public API.
/** Boot Sector structure */
typedef struct __attribute__((packed))
{
// Fields loaded directly from disk:
// 13 bytes skipped
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t num_fats;
uint16_t root_entries;
// 3 bytes skipped
uint16_t fat_size_sectors;
// 8 bytes skipped
uint32_t total_sectors; // if "short size sectors" is used, it's copied here too
// 7 bytes skipped
char volume_label[11]; // space padded, no terminator
// Added fields:
uint32_t bytes_per_cluster;
}
Fat16BootSector;
/** FAT filesystem handle */
typedef struct __attribute__((packed))
{
// Backing block device
const BLOCKDEV* dev;
// Root directory sector start
uint32_t rd_addr;
// Start of first cluster (number "2")
uint32_t data_addr;
// Start of fat table
uint32_t fat_addr;
// Boot sector data struct
Fat16BootSector bs;
}
FAT16;
/**
* File Attributes (bit flags)
* Accessible using file->attribs
*/
#define FA_READONLY 0x01 // read only file
#define FA_HIDDEN 0x02 // hidden file
#define FA_SYSTEM 0x04 // system file
#define FA_LABEL 0x08 // volume label entry, found only in root directory.
#define FA_DIR 0x10 // subdirectory
#define FA_ARCHIVE 0x20 // archive flag

@ -42,12 +42,14 @@ uint8_t _lcd_read_byte();
// 0 W, 1 R // 0 W, 1 R
bool _lcd_mode; bool _lcd_mode;
struct { struct
{
uint8_t x; uint8_t x;
uint8_t y; uint8_t y;
} _pos; } _pos;
enum { enum
{
TEXT = 0, TEXT = 0,
CG = 1 CG = 1
} _addrtype; } _addrtype;
@ -167,15 +169,18 @@ void lcd_command(uint8_t bb)
/** Write a data byte */ /** Write a data byte */
void lcd_write(uint8_t bb) void lcd_write(uint8_t bb)
{ {
if (_addrtype == TEXT) { if (_addrtype == TEXT)
if (bb == '\r') { {
if (bb == '\r')
{
// CR // CR
_pos.x = 0; _pos.x = 0;
lcd_xy(_pos.x, _pos.y); lcd_xy(_pos.x, _pos.y);
return; return;
} }
if (bb == '\n') { if (bb == '\n')
{
// LF // LF
_pos.y++; _pos.y++;
lcd_xy(_pos.x, _pos.y); lcd_xy(_pos.x, _pos.y);
@ -318,7 +323,8 @@ void lcd_clear()
void lcd_glyph(const uint8_t index, const uint8_t* array) void lcd_glyph(const uint8_t index, const uint8_t* array)
{ {
lcd_addr_cg(index * 8); lcd_addr_cg(index * 8);
for (uint8_t i = 0; i < 8; ++i) { for (uint8_t i = 0; i < 8; ++i)
{
lcd_write(array[i]); lcd_write(array[i]);
} }
@ -332,7 +338,8 @@ void lcd_glyph(const uint8_t index, const uint8_t* array)
void lcd_glyph_P(const uint8_t index, const uint8_t* array) void lcd_glyph_P(const uint8_t index, const uint8_t* array)
{ {
lcd_addr_cg(index * 8); lcd_addr_cg(index * 8);
for (uint8_t i = 0; i < 8; ++i) { for (uint8_t i = 0; i < 8; ++i)
{
lcd_write(pgm_read_byte(&array[i])); lcd_write(pgm_read_byte(&array[i]));
} }

@ -31,11 +31,14 @@ void _ow_tx_bit(const uint8_t pin, const bool bit)
as_output_n(pin); as_output_n(pin);
pin_low_n(pin); pin_low_n(pin);
if (bit) { if (bit)
{
_delay_us(6); _delay_us(6);
as_input_pu_n(pin); as_input_pu_n(pin);
_delay_us(64); _delay_us(64);
} else { }
else
{
_delay_us(60); _delay_us(60);
as_input_pu_n(pin); as_input_pu_n(pin);
_delay_us(10); _delay_us(10);
@ -195,9 +198,12 @@ int16_t ds1820_read_temp(uint8_t pin)
ow_read_arr(pin, bytes, 9); ow_read_arr(pin, bytes, 9);
uint8_t crc = crc8(bytes, 8); uint8_t crc = crc8(bytes, 8);
if (crc != bytes[8]) { if (crc != bytes[8])
{
return TEMP_ERROR; return TEMP_ERROR;
} else { }
else
{
int16_t a = ((bytes[1] << 8) | bytes[0]) >> 1; int16_t a = ((bytes[1] << 8) | bytes[0]) >> 1;
a = a << 4; a = a << 4;
a += (16 - bytes[6]) & 0x0F; a += (16 - bytes[6]) & 0x0F;
@ -230,7 +236,8 @@ bool ds1820_single_measure(uint8_t pin)
ow_send(pin, SKIP_ROM); ow_send(pin, SKIP_ROM);
ow_send(pin, CONVERT_T); ow_send(pin, CONVERT_T);
if(!ow_wait_ready(pin)) { if (!ow_wait_ready(pin))
{
return false; return false;
} }

@ -23,10 +23,19 @@ void _sonar_init_do(sonar_t* so, PORT_P port, uint8_t ntx, PORT_P pin, uint8_t n
so->pin = pin; so->pin = pin;
so->nrx = nrx; so->nrx = nrx;
switch((const uint16_t) pin) { switch ((const uint16_t) pin)
case ((const uint16_t) &PINB): so->bank = 0; break; {
case ((const uint16_t) &PINC): so->bank = 1; break; case ((const uint16_t) &PINB):
case ((const uint16_t) &PIND): so->bank = 2; break; so->bank = 0;
break;
case ((const uint16_t) &PINC):
so->bank = 1;
break;
case ((const uint16_t) &PIND):
so->bank = 2;
break;
} }
} }
@ -56,10 +65,19 @@ bool sonar_start(sonar_t* so)
TCNT1 = 0; TCNT1 = 0;
// Set up pin change interrupt mask for the RX pin // Set up pin change interrupt mask for the RX pin
switch(so->bank) { switch (so->bank)
case 0: sbi(PCMSK0, so->nrx); break; {
case 1: sbi(PCMSK1, so->nrx); break; case 0:
case 2: sbi(PCMSK2, so->nrx); break; sbi(PCMSK0, so->nrx);
break;
case 1:
sbi(PCMSK1, so->nrx);
break;
case 2:
sbi(PCMSK2, so->nrx);
break;
} }
// send positive pulse // send positive pulse
@ -87,10 +105,19 @@ void _sonar_stop()
TCCR1B = 0; TCCR1B = 0;
// Disable RX pin interrupt mask // Disable RX pin interrupt mask
switch(_so->bank) { switch (_so->bank)
case 0: PCMSK0 &= ~(1 << (_so->nrx)); break; {
case 1: PCMSK1 &= ~(1 << (_so->nrx)); break; case 0:
case 2: PCMSK2 &= ~(1 << (_so->nrx)); break; PCMSK0 &= ~(1 << (_so->nrx));
break;
case 1:
PCMSK1 &= ~(1 << (_so->nrx));
break;
case 2:
PCMSK2 &= ~(1 << (_so->nrx));
break;
} }
// Disable timer1 overflow interrupt // Disable timer1 overflow interrupt
@ -115,11 +142,13 @@ inline bool sonar_handle_t1ovf()
/** Handle pin change interrupt (returns true if consumed) */ /** Handle pin change interrupt (returns true if consumed) */
inline bool sonar_handle_pci() inline bool sonar_handle_pci()
{ {
if (!sonar_busy) { if (!sonar_busy)
{
return false; // nothing return false; // nothing
} }
if (bit_is_high_p(_so->pin, _so->nrx)) { if (bit_is_high_p(_so->pin, _so->nrx))
{
// rx is high, not our pin change event // rx is high, not our pin change event
return false; return false;
} }

@ -25,7 +25,8 @@
// Sonar data object // Sonar data object
typedef struct { typedef struct
{
PORT_P port; // Tx PORT PORT_P port; // Tx PORT
uint8_t ntx; // Tx bit number uint8_t ntx; // Tx bit number
PORT_P pin; // Rx PIN PORT_P pin; // Rx PIN

@ -12,7 +12,8 @@ static char tmpstr[20]; // buffer for number rendering
void put_str(const STREAM *p, char* str) void put_str(const STREAM *p, char* str)
{ {
char c; char c;
while ((c = *str++)) { while ((c = *str++))
{
p->tx(c); p->tx(c);
} }
} }
@ -21,7 +22,8 @@ void put_str(const STREAM *p, char* str)
void put_str_P(const STREAM *p, const char* str) void put_str_P(const STREAM *p, const char* str)
{ {
char c; char c;
while ((c = pgm_read_byte(str++))) { while ((c = pgm_read_byte(str++)))
{
p->tx(c); p->tx(c);
} }
} }
@ -82,15 +84,22 @@ void put_i32(const STREAM *p, const int32_t num)
/** Print number as hex */ /** Print number as hex */
void _print_hex(const STREAM *p, uint8_t* start, uint8_t bytes) void _print_hex(const STREAM *p, uint8_t* start, uint8_t bytes)
{ {
for (; bytes > 0; bytes--) { for (; bytes > 0; bytes--)
{
uint8_t b = *(start + bytes - 1); uint8_t b = *(start + bytes - 1);
for(uint8_t j = 0; j < 2; j++) { for (uint8_t j = 0; j < 2; j++)
{
uint8_t x = high_nibble(b); uint8_t x = high_nibble(b);
b = b << 4; b = b << 4;
if (x < 0xA) {
if (x < 0xA)
{
p->tx('0' + x); p->tx('0' + x);
} else { }
else
{
p->tx('A' + (x - 0xA)); p->tx('A' + (x - 0xA));
} }
} }
@ -140,10 +149,13 @@ void put_u16f(const STREAM *p, const uint16_t num, const uint8_t places)
/** Send signed int as float */ /** Send signed int as float */
void put_i16f(const STREAM *p, const int16_t num, const uint8_t places) void put_i16f(const STREAM *p, const int16_t num, const uint8_t places)
{ {
if (num < 0) { if (num < 0)
{
p->tx('-'); p->tx('-');
itoa(-num, tmpstr, 10); itoa(-num, tmpstr, 10);
} else { }
else
{
itoa(num, tmpstr, 10); itoa(num, tmpstr, 10);
} }
@ -162,10 +174,13 @@ void put_u32f(const STREAM *p, const uint32_t num, const uint8_t places)
/** Send signed long as float */ /** Send signed long as float */
void put_i32f(const STREAM *p, const int32_t num, const uint8_t places) void put_i32f(const STREAM *p, const int32_t num, const uint8_t places)
{ {
if (num < 0) { if (num < 0)
{
p->tx('-'); p->tx('-');
ltoa(-num, tmpstr, 10); ltoa(-num, tmpstr, 10);
} else { }
else
{
ltoa(num, tmpstr, 10); ltoa(num, tmpstr, 10);
} }
@ -183,10 +198,12 @@ void _putnf(const STREAM *p, const uint8_t places)
int8_t at = len - places; int8_t at = len - places;
// print virtual zeros // print virtual zeros
if (at <= 0) { if (at <= 0)
{
p->tx('0'); p->tx('0');
p->tx('.'); p->tx('.');
while(at <= -1) { while (at <= -1)
{
p->tx('0'); p->tx('0');
at++; at++;
} }
@ -195,8 +212,10 @@ void _putnf(const STREAM *p, const uint8_t places)
// print the number // print the number
uint8_t i = 0; uint8_t i = 0;
while(i < len) { while (i < len)
if (at-- == 0) { {
if (at-- == 0)
{
p->tx('.'); p->tx('.');
} }

@ -23,7 +23,8 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
/** Stream structure */ /** Stream structure */
typedef struct { typedef struct
{
void (*tx)(uint8_t b); void (*tx)(uint8_t b);
uint8_t (*rx)(void); uint8_t (*rx)(void);
} STREAM; } STREAM;

@ -14,7 +14,8 @@ static STREAM _uart_singleton;
STREAM* uart; STREAM* uart;
void _uart_init_do(uint16_t ubrr) { void _uart_init_do(uint16_t ubrr)
{
/*Set baud rate */ /*Set baud rate */
UBRR0H = (uint8_t)(ubrr >> 8); UBRR0H = (uint8_t)(ubrr >> 8);
UBRR0L = (uint8_t) ubrr; UBRR0L = (uint8_t) ubrr;
@ -76,7 +77,8 @@ uint8_t uart_rx()
/** Send string over UART */ /** Send string over UART */
void uart_puts(const char* str) void uart_puts(const char* str)
{ {
while (*str) { while (*str)
{
uart_tx(*str++); uart_tx(*str++);
} }
} }
@ -86,7 +88,8 @@ void uart_puts(const char* str)
void uart_puts_P(const char* str) void uart_puts_P(const char* str)
{ {
char c; char c;
while ((c = pgm_read_byte(str++))) { while ((c = pgm_read_byte(str++)))
{
uart_tx(c); uart_tx(c);
} }
} }
@ -96,7 +99,8 @@ void uart_puts_P(const char* str)
void uart_flush() void uart_flush()
{ {
uint8_t dummy; uint8_t dummy;
while (bit_is_high(UCSR0A, RXC0)) { while (bit_is_high(UCSR0A, RXC0))
{
dummy = UDR0; dummy = UDR0;
} }
} }
@ -149,9 +153,12 @@ void vt_move(int8_t x, int8_t y)
void vt_move_x(int8_t x) void vt_move_x(int8_t x)
{ {
if (x < 0) { if (x < 0)
{
vt_left(-x); vt_left(-x);
} else { }
else
{
vt_right(x); vt_right(x);
} }
} }
@ -159,9 +166,12 @@ void vt_move_x(int8_t x)
void vt_move_y(int8_t y) void vt_move_y(int8_t y)
{ {
if (y < 0) { if (y < 0)
{
vt_up(-y); vt_up(-y);
} else { }
else
{
vt_down(y); vt_down(y);
} }
} }
@ -209,13 +219,15 @@ void vt_right(uint8_t x)
void vt_scroll(int8_t y) void vt_scroll(int8_t y)
{ {
while (y < 0) { while (y < 0)
{
uart_tx(27); uart_tx(27);
uart_tx('D'); // up uart_tx('D'); // up
y++; y++;
} }
while (y > 0) { while (y > 0)
{
uart_tx(27); uart_tx(27);
uart_tx('M'); // down uart_tx('M'); // down
y--; y--;
@ -243,7 +255,8 @@ void vt_scroll_reset()
typedef struct { typedef struct
{
uint8_t flags; uint8_t flags;
uint8_t fg; uint8_t fg;
uint8_t bg; uint8_t bg;
@ -293,11 +306,16 @@ void vt_attr(uint8_t attribute, bool on)
{ {
// flags are powers of two // flags are powers of two
// so this can handle multiple OR'd flags // so this can handle multiple OR'd flags
for(uint8_t c = 1; c <= VT_FAINT; c *= 2) { for (uint8_t c = 1; c <= VT_FAINT; c *= 2)
if (attribute & c) { {
if (on) { if (attribute & c)
{
if (on)
{
current_style.flags |= c; current_style.flags |= c;
} else { }
else
{
current_style.flags &= ~c; current_style.flags &= ~c;
} }
} }
@ -351,27 +369,33 @@ inline void _vt_reset_attribs_do()
/** Send commands for text attribs */ /** Send commands for text attribs */
void _vt_style_do() void _vt_style_do()
{ {
if (current_style.flags & VT_BOLD) { if (current_style.flags & VT_BOLD)
{
uart_puts_P(PSTR("\x1B[1m")); uart_puts_P(PSTR("\x1B[1m"));
} }
if (current_style.flags & VT_FAINT) { if (current_style.flags & VT_FAINT)
{
uart_puts_P(PSTR("\x1B[2m")); uart_puts_P(PSTR("\x1B[2m"));
} }
if (current_style.flags & VT_ITALIC) { if (current_style.flags & VT_ITALIC)
{
uart_puts_P(PSTR("\x1B[3m")); uart_puts_P(PSTR("\x1B[3m"));
} }
if (current_style.flags & VT_UNDERLINE) { if (current_style.flags & VT_UNDERLINE)
{
uart_puts_P(PSTR("\x1B[4m")); uart_puts_P(PSTR("\x1B[4m"));
} }
if (current_style.flags & VT_BLINK) { if (current_style.flags & VT_BLINK)
{
uart_puts_P(PSTR("\x1B[5m")); uart_puts_P(PSTR("\x1B[5m"));
} }
if (current_style.flags & VT_REVERSE) { if (current_style.flags & VT_REVERSE)
{
uart_puts_P(PSTR("\x1B[7m")); uart_puts_P(PSTR("\x1B[7m"));
} }
} }
@ -508,7 +532,8 @@ void vt_set_key_handler(void (*handler)(uint8_t, bool))
// state machine states // state machine states
typedef enum { typedef enum
{
GROUND = 0, GROUND = 0,
ESC = 1, ESC = 1,
BR = 2, BR = 2,
@ -525,7 +550,8 @@ KSTATE _kstate = GROUND;
void _vt_kh_abort() void _vt_kh_abort()
{ {
switch (_kstate) { switch (_kstate)
{
case ESC: case ESC:
_vt_kh(VK_ESC, true); _vt_kh(VK_ESC, true);
break; break;
@ -564,9 +590,11 @@ void vt_handle_key(uint8_t c)
{ {
if (_vt_kh == NULL) return; if (_vt_kh == NULL) return;
switch (_kstate) { switch (_kstate)
{
case GROUND: case GROUND:
switch (c) { switch (c)
{
case 27: case 27:
_kstate = ESC; _kstate = ESC;
break; break;
@ -585,7 +613,8 @@ void vt_handle_key(uint8_t c)
break; // continue to next char break; // continue to next char
case ESC: case ESC:
switch (c) { switch (c)
{
case '[': case '[':
_kstate = BR; _kstate = BR;
break; // continue to next char break; // continue to next char
@ -603,7 +632,8 @@ void vt_handle_key(uint8_t c)
break; break;
case BR: case BR:
switch (c) { switch (c)
{
// arrows // arrows
case 65: case 65:
case 66: case 66:
@ -632,7 +662,8 @@ void vt_handle_key(uint8_t c)
break; break;
case O: case O:
switch (c) { switch (c)
{
// F keys // F keys
case 80: case 80:
case 81: case 81:
@ -653,11 +684,14 @@ void vt_handle_key(uint8_t c)
} }
case WAITING_TILDE: case WAITING_TILDE:
if (c != '~') { if (c != '~')
{
_vt_kh_abort(); _vt_kh_abort();
vt_handle_key(c); vt_handle_key(c);
return; return;
} else { }
else
{
_vt_kh(_before_wtilde, true); _vt_kh(_before_wtilde, true);
_kstate = GROUND; _kstate = GROUND;
return; return;
@ -665,13 +699,17 @@ void vt_handle_key(uint8_t c)
} }
// wait for next key // wait for next key
if (_kstate != GROUND) { if (_kstate != GROUND)
{
_delay_ms(2); _delay_ms(2);
if (!uart_rx_ready()) { if (!uart_rx_ready())
{
// abort receiving // abort receiving
_vt_kh_abort(); _vt_kh_abort();
} else { }
else
{
vt_handle_key(uart_rx()); vt_handle_key(uart_rx());
} }
} }

@ -18,21 +18,26 @@ void ws_init()
} }
/** Wait long enough for the colors to show */ /** Wait long enough for the colors to show */
void ws_show() { void ws_show()
{
delay_ns_c(WS_T_LATCH, 0); delay_ns_c(WS_T_LATCH, 0);
} }
/** Send one byte to the RGB strip */ /** Send one byte to the RGB strip */
void ws_send_byte(const uint8_t bb) void ws_send_byte(const uint8_t bb)
{ {
for (volatile int8_t i = 7; i >= 0; --i) { for (volatile int8_t i = 7; i >= 0; --i)
if ((bb) & (1 << i)) { {
if ((bb) & (1 << i))
{
pin_high(WS_PIN); pin_high(WS_PIN);
delay_ns_c(WS_T_1H, -2); delay_ns_c(WS_T_1H, -2);
pin_low(WS_PIN); pin_low(WS_PIN);
delay_ns_c(WS_T_1L, -10); delay_ns_c(WS_T_1L, -10);
} else { }
else
{
pin_high(WS_PIN); pin_high(WS_PIN);
delay_ns_c(WS_T_0H, -2); delay_ns_c(WS_T_0H, -2);
@ -72,7 +77,8 @@ void ws_send_rgb24(rgb24_t rgb)
/** Send array of colors */ /** Send array of colors */
void ws_send_xrgb_array(const xrgb_t rgbs[], const uint8_t length) void ws_send_xrgb_array(const xrgb_t rgbs[], const uint8_t length)
{ {
for (uint8_t i = 0; i < length; i++) { for (uint8_t i = 0; i < length; i++)
{
const xrgb_t c = rgbs[i]; const xrgb_t c = rgbs[i];
ws_send_byte(c.g); ws_send_byte(c.g);
ws_send_byte(c.r); ws_send_byte(c.r);
@ -83,7 +89,8 @@ void ws_send_xrgb_array(const xrgb_t rgbs[], const uint8_t length)
/** Send array of colors */ /** Send array of colors */
void ws_send_rgb24_array(const rgb24_t rgbs[], const uint8_t length) void ws_send_rgb24_array(const rgb24_t rgbs[], const uint8_t length)
{ {
for (uint8_t i = 0; i < length; i++) { for (uint8_t i = 0; i < length; i++)
{
const rgb24_t c = rgbs[i]; const rgb24_t c = rgbs[i];
ws_send_byte(rgb24_g(c)); ws_send_byte(rgb24_g(c));
ws_send_byte(rgb24_r(c)); ws_send_byte(rgb24_r(c));

Loading…
Cancel
Save