Formatted in "Allman" style, added fat16 lib files

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

@ -27,7 +27,7 @@ uint8_t adc_read_byte(uint8_t channel)
sbi(ADMUX, ADLAR); // Align result to left
sbi(ADCSRA, ADSC); // Start conversion
while(bit_is_high(ADCSRA, ADSC)); // Wait for it...
while (bit_is_high(ADCSRA, ADSC)); // Wait for it...
return ADCH; // The upper 8 bits of ADC result
}
@ -40,7 +40,7 @@ uint16_t adc_read_word(uint8_t channel)
cbi(ADMUX, ADLAR); // Align result to right
sbi(ADCSRA, ADSC); // Start conversion
while(get_bit(ADCSRA, ADSC)); // Wait for it...
while (get_bit(ADCSRA, ADSC)); // Wait for it...
return ADCW; // The whole ADC word (10 bits)
}

@ -10,16 +10,17 @@
// --- HSL ---
#ifdef HSL_LINEAR
const uint8_t FADE_128[] = {
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,
14, 15, 16, 17, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36,
38, 39, 40, 41, 42, 44, 45, 46, 48, 49, 50, 52, 54, 56, 58, 59, 61, 63,
65, 67, 68, 69, 71, 72, 74, 76, 78, 80, 82, 85, 88, 90, 92, 95, 98, 100,
103, 106, 109, 112, 116, 119, 122, 125, 129, 134, 138, 142, 147, 151,
153, 156, 160, 163, 165, 170, 175, 180, 185, 190, 195, 200, 207, 214, 218,
221, 225, 228, 232, 234, 241, 248, 254, 255
};
const uint8_t FADE_128[] =
{
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,
14, 15, 16, 17, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36,
38, 39, 40, 41, 42, 44, 45, 46, 48, 49, 50, 52, 54, 56, 58, 59, 61, 63,
65, 67, 68, 69, 71, 72, 74, 76, 78, 80, 82, 85, 88, 90, 92, 95, 98, 100,
103, 106, 109, 112, 116, 119, 122, 125, 129, 134, 138, 142, 147, 151,
153, 156, 160, 163, 165, 170, 175, 180, 185, 190, 195, 200, 207, 214, 218,
221, 225, 228, 232, 234, 241, 248, 254, 255
};
#endif
// based on: https://github.com/lewisd32/avr-hsl2rgb
@ -30,19 +31,26 @@ xrgb_t hsl_xrgb(const hsl_t cc)
const uint8_t hue_mod = hh % 256;
uint8_t r_temp, g_temp, b_temp;
if (hh < 256) {
if (hh < 256)
{
r_temp = hue_mod ^ 255;
g_temp = hue_mod;
b_temp = 0;
} else if (hh < 512) {
}
else if (hh < 512)
{
r_temp = 0;
g_temp = hue_mod ^ 255;
b_temp = hue_mod;
} else if (hh < 768) {
}
else if (hh < 768)
{
r_temp = hue_mod;
g_temp = 0;
b_temp = hue_mod ^ 255;
} else {
}
else
{
r_temp = 0;
g_temp = 0;
b_temp = 0;
@ -56,7 +64,7 @@ xrgb_t hsl_xrgb(const hsl_t cc)
uint16_t t16;
#ifdef HSL_LINEAR
const uint8_t bri = FADE_128[cc.l>>1];
const uint8_t bri = FADE_128[cc.l >> 1];
#else
const uint8_t bri = cc.l;
#endif

@ -12,7 +12,8 @@
// Define HSL_LINEAR to get more linear brightness in hsl->rgb conversion
typedef struct {
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
@ -45,7 +46,8 @@ typedef uint32_t rgb24_t;
// HSL data structure
typedef struct {
typedef struct
{
uint8_t h;
uint8_t s;
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)
{
debo_slots[debo_next_slot] = (debo_slot_t){
debo_slots[debo_next_slot] = (debo_slot_t)({
.reg = reg,
.bit = bit | ((invert & 1) << 7) | (get_bit_p(reg, bit) << 6), // bit 7 = invert, bit 6 = state
.count = 0,
};
});
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. */
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)
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
if (debo_slots[i].count < DEBO_TICKS) {
if (debo_slots[i].count < DEBO_TICKS)
{
debo_slots[i].count++;
} else {
}
else
{
// overflown -> latch value
set_bit(debo_slots[i].bit, 6, value); // set state bit
debo_slots[i].count = 0;
}
} else {
}
else
{
debo_slots[i].count = 0; // reset the counter
}
}

@ -31,7 +31,7 @@
#include <stdbool.h>
#include "calc.h"
#include "pins.h"
#include "iopins.h"
// Your config file
#include "debo_config.h"
@ -42,7 +42,8 @@
/* Internal deboucer entry */
typedef struct {
typedef struct
{
PORT_P reg; // pointer to IO register
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

@ -7,7 +7,8 @@
#include <stdint.h>
#include <stdbool.h>
typedef struct {
typedef struct
{
int8_t temp;
int8_t rh;
} 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
bool _lcd_mode;
struct {
struct
{
uint8_t x;
uint8_t y;
} _pos;
enum {
enum
{
TEXT = 0,
CG = 1
} _addrtype;
@ -167,15 +169,18 @@ void lcd_command(uint8_t bb)
/** Write a data byte */
void lcd_write(uint8_t bb)
{
if (_addrtype == TEXT) {
if (bb == '\r') {
if (_addrtype == TEXT)
{
if (bb == '\r')
{
// CR
_pos.x = 0;
lcd_xy(_pos.x, _pos.y);
return;
}
if (bb == '\n') {
if (bb == '\n')
{
// LF
_pos.y++;
lcd_xy(_pos.x, _pos.y);
@ -227,7 +232,7 @@ void _lcd_write_byte(uint8_t bb)
void _lcd_wait_bf()
{
uint8_t d = 0;
while(d++ < 120 && lcd_read_bf_addr() & _BV(7))
while (d++ < 120 && lcd_read_bf_addr() & _BV(7))
_delay_us(1);
}
@ -318,7 +323,8 @@ void lcd_clear()
void lcd_glyph(const uint8_t index, const uint8_t* array)
{
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]);
}
@ -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)
{
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]));
}

@ -31,11 +31,14 @@ void _ow_tx_bit(const uint8_t pin, const bool bit)
as_output_n(pin);
pin_low_n(pin);
if (bit) {
if (bit)
{
_delay_us(6);
as_input_pu_n(pin);
_delay_us(64);
} else {
}
else
{
_delay_us(60);
as_input_pu_n(pin);
_delay_us(10);
@ -137,7 +140,7 @@ void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count)
// Dallas 1-wire 16-bit CRC calculation. Developed from Maxim Application Note 27.
/** Compute a CRC16 checksum */
uint16_t crc16( uint8_t *data, uint8_t len)
uint16_t crc16(uint8_t *data, uint8_t len)
{
uint16_t crc = 0;
@ -174,7 +177,7 @@ uint8_t crc8(uint8_t *addr, uint8_t len)
uint8_t mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix)
crc ^= 0x8C;
crc ^= 0x8C;
inbyte >>= 1;
}
@ -195,9 +198,12 @@ int16_t ds1820_read_temp(uint8_t pin)
ow_read_arr(pin, bytes, 9);
uint8_t crc = crc8(bytes, 8);
if (crc != bytes[8]) {
if (crc != bytes[8])
{
return TEMP_ERROR;
} else {
}
else
{
int16_t a = ((bytes[1] << 8) | bytes[0]) >> 1;
a = a << 4;
a += (16 - bytes[6]) & 0x0F;
@ -230,7 +236,8 @@ bool ds1820_single_measure(uint8_t pin)
ow_send(pin, SKIP_ROM);
ow_send(pin, CONVERT_T);
if(!ow_wait_ready(pin)) {
if (!ow_wait_ready(pin))
{
return false;
}

@ -27,7 +27,7 @@ bool ow_wait_ready(const uint8_t pin);
void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count);
/** Compute a CRC16 checksum */
uint16_t crc16( uint8_t *data, uint8_t len);
uint16_t crc16(uint8_t *data, uint8_t len);
/** Compute a CRC8 checksum */
uint8_t crc8(uint8_t *addr, uint8_t len);

@ -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->nrx = nrx;
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) &PIND): so->bank = 2; break;
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) &PIND):
so->bank = 2;
break;
}
}
@ -56,10 +65,19 @@ bool sonar_start(sonar_t* so)
TCNT1 = 0;
// Set up pin change interrupt mask for the RX pin
switch(so->bank) {
case 0: sbi(PCMSK0, so->nrx); break;
case 1: sbi(PCMSK1, so->nrx); break;
case 2: sbi(PCMSK2, so->nrx); break;
switch (so->bank)
{
case 0:
sbi(PCMSK0, so->nrx);
break;
case 1:
sbi(PCMSK1, so->nrx);
break;
case 2:
sbi(PCMSK2, so->nrx);
break;
}
// send positive pulse
@ -87,10 +105,19 @@ void _sonar_stop()
TCCR1B = 0;
// Disable RX pin interrupt mask
switch(_so->bank) {
case 0: PCMSK0 &= ~(1 << (_so->nrx)); break;
case 1: PCMSK1 &= ~(1 << (_so->nrx)); break;
case 2: PCMSK2 &= ~(1 << (_so->nrx)); break;
switch (_so->bank)
{
case 0:
PCMSK0 &= ~(1 << (_so->nrx));
break;
case 1:
PCMSK1 &= ~(1 << (_so->nrx));
break;
case 2:
PCMSK2 &= ~(1 << (_so->nrx));
break;
}
// Disable timer1 overflow interrupt
@ -115,11 +142,13 @@ inline bool sonar_handle_t1ovf()
/** Handle pin change interrupt (returns true if consumed) */
inline bool sonar_handle_pci()
{
if (!sonar_busy) {
if (!sonar_busy)
{
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
return false;
}

@ -25,7 +25,8 @@
// Sonar data object
typedef struct {
typedef struct
{
PORT_P port; // Tx PORT
uint8_t ntx; // Tx bit number
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)
{
char c;
while ((c = *str++)) {
while ((c = *str++))
{
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)
{
char c;
while ((c = pgm_read_byte(str++))) {
while ((c = pgm_read_byte(str++)))
{
p->tx(c);
}
}
@ -82,15 +84,22 @@ void put_i32(const STREAM *p, const int32_t num)
/** Print number as hex */
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);
for(uint8_t j = 0; j < 2; j++) {
for (uint8_t j = 0; j < 2; j++)
{
uint8_t x = high_nibble(b);
b = b << 4;
if (x < 0xA) {
if (x < 0xA)
{
p->tx('0' + x);
} else {
}
else
{
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 */
void put_i16f(const STREAM *p, const int16_t num, const uint8_t places)
{
if (num < 0) {
if (num < 0)
{
p->tx('-');
itoa(-num, tmpstr, 10);
} else {
}
else
{
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 */
void put_i32f(const STREAM *p, const int32_t num, const uint8_t places)
{
if (num < 0) {
if (num < 0)
{
p->tx('-');
ltoa(-num, tmpstr, 10);
} else {
}
else
{
ltoa(num, tmpstr, 10);
}
@ -178,15 +193,17 @@ void _putnf(const STREAM *p, const uint8_t places)
{
// measure text length
uint8_t len = 0;
while(tmpstr[len] != 0) len++;
while (tmpstr[len] != 0) len++;
int8_t at = len - places;
// print virtual zeros
if (at <= 0) {
if (at <= 0)
{
p->tx('0');
p->tx('.');
while(at <= -1) {
while (at <= -1)
{
p->tx('0');
at++;
}
@ -195,8 +212,10 @@ void _putnf(const STREAM *p, const uint8_t places)
// print the number
uint8_t i = 0;
while(i < len) {
if (at-- == 0) {
while (i < len)
{
if (at-- == 0)
{
p->tx('.');
}

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

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

@ -18,21 +18,26 @@ void ws_init()
}
/** Wait long enough for the colors to show */
void ws_show() {
void ws_show()
{
delay_ns_c(WS_T_LATCH, 0);
}
/** Send one byte to the RGB strip */
void ws_send_byte(const uint8_t bb)
{
for (volatile int8_t i = 7; i >= 0; --i) {
if ((bb) & (1 << i)) {
for (volatile int8_t i = 7; i >= 0; --i)
{
if ((bb) & (1 << i))
{
pin_high(WS_PIN);
delay_ns_c(WS_T_1H, -2);
pin_low(WS_PIN);
delay_ns_c(WS_T_1L, -10);
} else {
}
else
{
pin_high(WS_PIN);
delay_ns_c(WS_T_0H, -2);
@ -72,7 +77,8 @@ void ws_send_rgb24(rgb24_t rgb)
/** Send array of colors */
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];
ws_send_byte(c.g);
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 */
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];
ws_send_byte(rgb24_g(c));
ws_send_byte(rgb24_r(c));
@ -94,39 +101,39 @@ void ws_send_rgb24_array(const rgb24_t rgbs[], const uint8_t length)
//#define ws_send_rgb24_array(rgbs, length) __ws_send_array_proto((rgbs), (length), rgb24)
// prototype for sending array. it's ugly, sorry.
/*#define __ws_send_array_proto(rgbs, length, style) { \
for (uint8_t __rgb_sap_i = 0; __rgb_sap_i < length; __rgb_sap_i++) { \
style ## _t __rgb_sap2 = (rgbs)[__rgb_sap_i]; \
ws_send_ ## style(__rgb_sap2); \
} \
/*#define __ws_send_array_proto(rgbs, length, style) { \
for (uint8_t __rgb_sap_i = 0; __rgb_sap_i < length; __rgb_sap_i++) { \
style ## _t __rgb_sap2 = (rgbs)[__rgb_sap_i]; \
ws_send_ ## style(__rgb_sap2); \
} \
}*/
// /** Send a 2D array to a zig-zag display */
// #define ws_send_xrgb_array_zigzag(rgbs, width, height) { \
// int8_t __rgb_sxaz_y, __rgb_sxaz_x; \
// for(__rgb_sxaz_y = 0; __rgb_sxaz_y < (height); __rgb_sxaz_y ++) { \
// for(__rgb_sxaz_x = 0; __rgb_sxaz_x < (width); __rgb_sxaz_x++) { \
// ws_send_xrgb((rgbs)[__rgb_sxaz_y][__rgb_sxaz_x]); \
// } \
// __rgb_sxaz_y++; \
// for(__rgb_sxaz_x = (width) - 1; __rgb_sxaz_x >= 0; __rgb_sxaz_x--) { \
// ws_send_xrgb((rgbs)[__rgb_sxaz_y][__rgb_sxaz_x]); \
// } \
// } \
// #define ws_send_xrgb_array_zigzag(rgbs, width, height) { \
// int8_t __rgb_sxaz_y, __rgb_sxaz_x; \
// for(__rgb_sxaz_y = 0; __rgb_sxaz_y < (height); __rgb_sxaz_y ++) { \
// for(__rgb_sxaz_x = 0; __rgb_sxaz_x < (width); __rgb_sxaz_x++) { \
// ws_send_xrgb((rgbs)[__rgb_sxaz_y][__rgb_sxaz_x]); \
// } \
// __rgb_sxaz_y++; \
// for(__rgb_sxaz_x = (width) - 1; __rgb_sxaz_x >= 0; __rgb_sxaz_x--) { \
// ws_send_xrgb((rgbs)[__rgb_sxaz_y][__rgb_sxaz_x]); \
// } \
// } \
// }
// /* Send a linear array to a zig-zag display as a n*m board (row-by-row)
// #define ws_send_xrgb_array_zigzag_linear(rgbs, width, height) { \
// int8_t __rgb_sxazl_x, __rgb_sxazl_y; \
// for(__rgb_sxazl_y = 0; __rgb_sxazl_y < (height); __rgb_sxazl_y++) { \
// for(__rgb_sxazl_x = 0; __rgb_sxazl_x < (width); __rgb_sxazl_x++) { \
// ws_send_xrgb((rgbs)[__rgb_sxazl_y * (width) + __rgb_sxazl_x]); \
// } \
// __rgb_sxazl_y++; \
// for(__rgb_sxazl_x = width-1; __rgb_sxazl_x >=0; __rgb_sxazl_x--) { \
// ws_send_xrgb((rgbs)[__rgb_sxazl_y * (width) + __rgb_sxazl_x]); \
// } \
// } \
// #define ws_send_xrgb_array_zigzag_linear(rgbs, width, height) { \
// int8_t __rgb_sxazl_x, __rgb_sxazl_y; \
// for(__rgb_sxazl_y = 0; __rgb_sxazl_y < (height); __rgb_sxazl_y++) { \
// for(__rgb_sxazl_x = 0; __rgb_sxazl_x < (width); __rgb_sxazl_x++) { \
// ws_send_xrgb((rgbs)[__rgb_sxazl_y * (width) + __rgb_sxazl_x]); \
// } \
// __rgb_sxazl_y++; \
// for(__rgb_sxazl_x = width-1; __rgb_sxazl_x >=0; __rgb_sxazl_x--) { \
// ws_send_xrgb((rgbs)[__rgb_sxazl_y * (width) + __rgb_sxazl_x]); \
// } \
// } \
// }

Loading…
Cancel
Save