added devel folder..

master
Ondřej Hruška 10 years ago
parent f928a4ff8c
commit 033273b9d1
  1. 2
      .gitignore
  2. 5
      devel/README.md
  3. 147
      devel/dht11/Makefile
  4. 1
      devel/dht11/lib
  5. 35
      devel/dht11/main.c
  6. 137
      devel/iopins/Makefile
  7. BIN
      devel/iopins/avrlib_1-0-0.zip
  8. 276
      devel/iopins/iopins.c
  9. 190
      devel/iopins/iopins.h
  10. 1
      devel/iopins/lib
  11. 27
      devel/iopins/main.c
  12. 167
      devel/lcdsnake/Makefile
  13. 10
      devel/lcdsnake/README.md
  14. 5
      devel/lcdsnake/debo_config.h
  15. 13
      devel/lcdsnake/lcd_config.h
  16. 1
      devel/lcdsnake/lib
  17. 429
      devel/lcdsnake/main.c
  18. 141
      devel/onewire/Makefile
  19. 1
      devel/onewire/lib
  20. 38
      devel/onewire/main.c
  21. 170
      devel/rgb_hsl/Makefile
  22. 11
      devel/rgb_hsl/README.md
  23. 1
      devel/rgb_hsl/lib
  24. 69
      devel/rgb_hsl/main.c
  25. 147
      devel/sd_bad/Makefile
  26. 191
      devel/sd_bad/deployment.pri
  27. 57
      devel/sd_bad/main.c
  28. 10
      devel/sd_bad/main.h
  29. 467
      devel/sd_bad/sd.c
  30. 25
      devel/sd_bad/sd.h
  31. 25
      devel/sd_bad/sd_bad.pro
  32. 250
      devel/sd_bad/sd_bad.pro.user
  33. 152
      devel/sd_bad/sdcomm_spi.h
  34. 88
      devel/sd_bad/spi.c
  35. 15
      devel/sd_bad/spi.h
  36. 13
      devel/sd_bad/style.astylerc
  37. 147
      devel/sdcard/Makefile
  38. 191
      devel/sdcard/deployment.pri
  39. 1
      devel/sdcard/lib
  40. 64
      devel/sdcard/main.c
  41. 56
      devel/sdcard/sdcard.pro
  42. 250
      devel/sdcard/sdcard.pro.user
  43. 13
      devel/sdcard/style.astylerc
  44. 166
      devel/snake/Makefile
  45. 351
      devel/snake/lcd_default.asm
  46. 1
      devel/snake/lib
  47. 426
      devel/snake/main.c
  48. 147
      devel/try_ws/Makefile
  49. BIN
      devel/try_ws/client
  50. 1
      devel/try_ws/lib
  51. 32
      devel/try_ws/main.c
  52. 7
      devel/try_ws/ws_config.h
  53. 147
      devel/uart/Makefile
  54. BIN
      devel/uart/client
  55. 7
      devel/uart/clientd/Makefile
  56. BIN
      devel/uart/clientd/client
  57. 0
      devel/uart/clientd/main
  58. 37
      devel/uart/clientd/main.c
  59. 89
      devel/uart/clientd/serial.c
  60. 27
      devel/uart/clientd/serial.h
  61. 1
      devel/uart/lib
  62. 25
      devel/uart/main.c
  63. 25
      devel/uart/special_keys.txt
  64. 137
      devel/ultrasonic/Makefile
  65. 13
      devel/ultrasonic/lcd_config.h
  66. 1
      devel/ultrasonic/lib
  67. 91
      devel/ultrasonic/main.c
  68. 147
      devel/xxx/Makefile
  69. BIN
      devel/xxx/client
  70. 7
      devel/xxx/clientd/Makefile
  71. BIN
      devel/xxx/clientd/client
  72. 0
      devel/xxx/clientd/main
  73. 37
      devel/xxx/clientd/main.c
  74. 89
      devel/xxx/clientd/serial.c
  75. 27
      devel/xxx/clientd/serial.h
  76. 1112
      devel/xxx/fat16.c
  77. 260
      devel/xxx/fat16.h
  78. 1
      devel/xxx/lib
  79. 103
      devel/xxx/main.c

2
.gitignore vendored

@ -13,5 +13,3 @@
*.so *.so
*.out *.out
*.hex *.hex
devel/

@ -0,0 +1,5 @@
**Files in this folder are experimental, work-in-progress projects.**
Do not expect them to work.
For finished stuff, look into the /projects folder.

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c iopins.c stream.c adc.c dht11.c sonar.c onewire.c
#Files that need config file:
# EXTRA_SOURCE_FILES += lcd.c
# EXTRA_SOURCE_FILES += color.c wsrgb.c
# EXTRA_SOURCE_FILES += debouce.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash ser
ser:
gtkterm -p /dev/ttyUSB0
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,35 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "lib/iopins.h"
#include "lib/uart.h"
#include "lib/stream.h"
#include "lib/dht11.h"
void main()
{
uart_init(9600);
uart_puts_P(PSTR("*** DHT11 test ***\r\n"));
while(1)
{
dht11_result_t result;
if (dht11_read(2, &result)) {
// Temperature
put_i8(uart, result.temp);
uart_puts_P(PSTR(" °C, "));
// Humidity
put_i8(uart, result.rh);
uart_puts_P(PSTR(" %r.H\r\n"));
} else {
uart_puts_P(PSTR("Read error!\r\n"));
}
_delay_ms(500);
}
}

@ -0,0 +1,137 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c uart_ansi.c iopins.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

Binary file not shown.

@ -0,0 +1,276 @@
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>
#include "calc.h"
#include "iopins.h"
void set_dir_n(const uint8_t pin, const uint8_t d)
{
switch(pin) {
case 0: set_dir(0, d); return;
case 1: set_dir(1, d); return;
case 2: set_dir(2, d); return;
case 3: set_dir(3, d); return;
case 4: set_dir(4, d); return;
case 5: set_dir(5, d); return;
case 6: set_dir(6, d); return;
case 7: set_dir(7, d); return;
case 8: set_dir(8, d); return;
case 9: set_dir(9, d); return;
case 10: set_dir(10, d); return;
case 11: set_dir(11, d); return;
case 12: set_dir(12, d); return;
case 13: set_dir(13, d); return;
case 14: set_dir(14, d); return;
case 15: set_dir(15, d); return;
case 16: set_dir(16, d); return;
case 17: set_dir(17, d); return;
case 18: set_dir(18, d); return;
case 19: set_dir(19, d); return;
case 20: set_dir(20, d); return;
case 21: set_dir(21, d); return;
}
}
void as_input_n(const uint8_t pin)
{
switch(pin) {
case 0: as_input(0); return;
case 1: as_input(1); return;
case 2: as_input(2); return;
case 3: as_input(3); return;
case 4: as_input(4); return;
case 5: as_input(5); return;
case 6: as_input(6); return;
case 7: as_input(7); return;
case 8: as_input(8); return;
case 9: as_input(9); return;
case 10: as_input(10); return;
case 11: as_input(11); return;
case 12: as_input(12); return;
case 13: as_input(13); return;
case 14: as_input(14); return;
case 15: as_input(15); return;
case 16: as_input(16); return;
case 17: as_input(17); return;
case 18: as_input(18); return;
case 19: as_input(19); return;
case 20: as_input(20); return;
case 21: as_input(21); return;
}
}
void as_input_pu_n(const uint8_t pin)
{
switch(pin) {
case 0: as_input_pu(0); return;
case 1: as_input_pu(1); return;
case 2: as_input_pu(2); return;
case 3: as_input_pu(3); return;
case 4: as_input_pu(4); return;
case 5: as_input_pu(5); return;
case 6: as_input_pu(6); return;
case 7: as_input_pu(7); return;
case 8: as_input_pu(8); return;
case 9: as_input_pu(9); return;
case 10: as_input_pu(10); return;
case 11: as_input_pu(11); return;
case 12: as_input_pu(12); return;
case 13: as_input_pu(13); return;
case 14: as_input_pu(14); return;
case 15: as_input_pu(15); return;
case 16: as_input_pu(16); return;
case 17: as_input_pu(17); return;
case 18: as_input_pu(18); return;
case 19: as_input_pu(19); return;
case 20: as_input_pu(20); return;
case 21: as_input_pu(21); return;
}
}
void as_output_n(const uint8_t pin)
{
switch(pin) {
case 0: as_output(0); return;
case 1: as_output(1); return;
case 2: as_output(2); return;
case 3: as_output(3); return;
case 4: as_output(4); return;
case 5: as_output(5); return;
case 6: as_output(6); return;
case 7: as_output(7); return;
case 8: as_output(8); return;
case 9: as_output(9); return;
case 10: as_output(10); return;
case 11: as_output(11); return;
case 12: as_output(12); return;
case 13: as_output(13); return;
case 14: as_output(14); return;
case 15: as_output(15); return;
case 16: as_output(16); return;
case 17: as_output(17); return;
case 18: as_output(18); return;
case 19: as_output(19); return;
case 20: as_output(20); return;
case 21: as_output(21); return;
}
}
void set_pin_n(const uint8_t pin, const uint8_t v)
{
switch(pin) {
case 0: set_pin(0, v); return;
case 1: set_pin(1, v); return;
case 2: set_pin(2, v); return;
case 3: set_pin(3, v); return;
case 4: set_pin(4, v); return;
case 5: set_pin(5, v); return;
case 6: set_pin(6, v); return;
case 7: set_pin(7, v); return;
case 8: set_pin(8, v); return;
case 9: set_pin(9, v); return;
case 10: set_pin(10, v); return;
case 11: set_pin(11, v); return;
case 12: set_pin(12, v); return;
case 13: set_pin(13, v); return;
case 14: set_pin(14, v); return;
case 15: set_pin(15, v); return;
case 16: set_pin(16, v); return;
case 17: set_pin(17, v); return;
case 18: set_pin(18, v); return;
case 19: set_pin(19, v); return;
case 20: set_pin(20, v); return;
case 21: set_pin(21, v); return;
}
}
void set_low_n(const uint8_t pin)
{
switch(pin) {
case 0: set_low(0); return;
case 1: set_low(1); return;
case 2: set_low(2); return;
case 3: set_low(3); return;
case 4: set_low(4); return;
case 5: set_low(5); return;
case 6: set_low(6); return;
case 7: set_low(7); return;
case 8: set_low(8); return;
case 9: set_low(9); return;
case 10: set_low(10); return;
case 11: set_low(11); return;
case 12: set_low(12); return;
case 13: set_low(13); return;
case 14: set_low(14); return;
case 15: set_low(15); return;
case 16: set_low(16); return;
case 17: set_low(17); return;
case 18: set_low(18); return;
case 19: set_low(19); return;
case 20: set_low(20); return;
case 21: set_low(21); return;
}
}
void set_high_n(const uint8_t pin)
{
switch(pin) {
case 0: set_high(0); return;
case 1: set_high(1); return;
case 2: set_high(2); return;
case 3: set_high(3); return;
case 4: set_high(4); return;
case 5: set_high(5); return;
case 6: set_high(6); return;
case 7: set_high(7); return;
case 8: set_high(8); return;
case 9: set_high(9); return;
case 10: set_high(10); return;
case 11: set_high(11); return;
case 12: set_high(12); return;
case 13: set_high(13); return;
case 14: set_high(14); return;
case 15: set_high(15); return;
case 16: set_high(16); return;
case 17: set_high(17); return;
case 18: set_high(18); return;
case 19: set_high(19); return;
case 20: set_high(20); return;
case 21: set_high(21); return;
}
}
void toggle_pin_n(const uint8_t pin)
{
switch(pin) {
case 0: toggle_pin(0); return;
case 1: toggle_pin(1); return;
case 2: toggle_pin(2); return;
case 3: toggle_pin(3); return;
case 4: toggle_pin(4); return;
case 5: toggle_pin(5); return;
case 6: toggle_pin(6); return;
case 7: toggle_pin(7); return;
case 8: toggle_pin(8); return;
case 9: toggle_pin(9); return;
case 10: toggle_pin(10); return;
case 11: toggle_pin(11); return;
case 12: toggle_pin(12); return;
case 13: toggle_pin(13); return;
case 14: toggle_pin(14); return;
case 15: toggle_pin(15); return;
case 16: toggle_pin(16); return;
case 17: toggle_pin(17); return;
case 18: toggle_pin(18); return;
case 19: toggle_pin(19); return;
case 20: toggle_pin(20); return;
case 21: toggle_pin(21); return;
}
}
bool get_pin_n(const uint8_t pin)
{
switch(pin) {
case 0: return get_pin(0);
case 1: return get_pin(1);
case 2: return get_pin(2);
case 3: return get_pin(3);
case 4: return get_pin(4);
case 5: return get_pin(5);
case 6: return get_pin(6);
case 7: return get_pin(7);
case 8: return get_pin(8);
case 9: return get_pin(9);
case 10: return get_pin(10);
case 11: return get_pin(11);
case 12: return get_pin(12);
case 13: return get_pin(13);
case 14: return get_pin(14);
case 15: return get_pin(15);
case 16: return get_pin(16);
case 17: return get_pin(17);
case 18: return get_pin(18);
case 19: return get_pin(19);
case 20: return get_pin(20);
case 21: return get_pin(21);
}
return false;
}
bool is_low_n(const uint8_t pin)
{
return !get_pin_n(pin);
}
bool is_high_n(const uint8_t pin)
{
return get_pin_n(pin);
}

@ -0,0 +1,190 @@
#pragma once
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>
#include "calc.h"
/** Pin numbering reference */
#define D0 0
#define D1 1
#define D2 2
#define D3 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
#define D8 8
#define D9 9
#define D10 10
#define D11 11
#define D12 12
#define D13 13
#define D14 14
#define D15 15
#define D16 16
#define D17 17
#define D18 18
#define D19 19
#define D20 20
#define D21 21
#define A0 14
#define A1 15
#define A2 16
#define A3 17
#define A4 18
#define A5 19
#define A6 20
#define A7 21
/** Set pin direction */
#define set_dir(pin, d) set_bit(_DDR_##pin, _PN_##pin, d)
void set_dir_n(const uint8_t pin, const uint8_t d);
/** Configure pin as input */
#define as_input(pin) cbi(_DDR_##pin, _PN_##pin)
void as_input_n(const uint8_t pin);
/** Configure pin as input, with pull-up enabled */
#define as_input_pu(pin) { as_input(pin); set_high(pin); }
void as_input_pu_n(const uint8_t pin);
/** Configure pin as output */
#define as_output(pin) sbi(_DDR_##pin, _PN_##pin)
void as_output_n(const uint8_t pin);
/** Write value to a pin */
#define set_pin(pin, v) set_bit(_PORT_##pin, _PN_##pin, v)
void set_pin_n(const uint8_t pin, const uint8_t v);
/** Write 0 to a pin */
#define set_low(pin) cbi(_PORT_##pin, _PN_##pin)
void set_low_n(const uint8_t pin);
/** Write 1 to a pin */
#define set_high(pin) sbi(_PORT_##pin, _PN_##pin)
void set_high_n(const uint8_t pin);
/** Toggle a pin state */
#define toggle_pin(pin) sbi(_PIN_##pin, _PN_##pin)
void toggle_pin_n(const uint8_t pin);
/** Read a pin value */
#define get_pin(pin) get_bit(_PIN_##pin, _PN_##pin)
bool get_pin_n(const uint8_t pin);
/** CHeck if pin is low */
#define is_low(pin) (get_pin(pin) == 0)
bool is_low_n(const uint8_t pin);
/** CHeck if pin is high */
#define is_high(pin) (get_pin(pin) != 0)
bool is_high_n(const uint8_t pin);
// Helper macros
#define _PORT_0 PORTD
#define _PORT_1 PORTD
#define _PORT_2 PORTD
#define _PORT_3 PORTD
#define _PORT_4 PORTD
#define _PORT_5 PORTD
#define _PORT_6 PORTD
#define _PORT_7 PORTD
#define _PORT_8 PORTB
#define _PORT_9 PORTB
#define _PORT_10 PORTB
#define _PORT_11 PORTB
#define _PORT_12 PORTB
#define _PORT_13 PORTB
#define _PORT_14 PORTC
#define _PORT_15 PORTC
#define _PORT_16 PORTC
#define _PORT_17 PORTC
#define _PORT_18 PORTC
#define _PORT_19 PORTC
#define _PORT_20 PORTC
#define _PORT_21 PORTC
#define _PIN_0 PIND
#define _PIN_1 PIND
#define _PIN_2 PIND
#define _PIN_3 PIND
#define _PIN_4 PIND
#define _PIN_5 PIND
#define _PIN_6 PIND
#define _PIN_7 PIND
#define _PIN_8 PINB
#define _PIN_9 PINB
#define _PIN_10 PINB
#define _PIN_11 PINB
#define _PIN_12 PINB
#define _PIN_13 PINB
#define _PIN_14 PINC
#define _PIN_15 PINC
#define _PIN_16 PINC
#define _PIN_17 PINC
#define _PIN_18 PINC
#define _PIN_19 PINC
#define _PIN_20 PINC
#define _PIN_21 PINC
#define _DDR_0 DDRD
#define _DDR_1 DDRD
#define _DDR_2 DDRD
#define _DDR_3 DDRD
#define _DDR_4 DDRD
#define _DDR_5 DDRD
#define _DDR_6 DDRD
#define _DDR_7 DDRD
#define _DDR_8 DDRB
#define _DDR_9 DDRB
#define _DDR_10 DDRB
#define _DDR_11 DDRB
#define _DDR_12 DDRB
#define _DDR_13 DDRB
#define _DDR_14 DDRC
#define _DDR_15 DDRC
#define _DDR_16 DDRC
#define _DDR_17 DDRC
#define _DDR_18 DDRC
#define _DDR_19 DDRC
#define _DDR_20 DDRC
#define _DDR_21 DDRC
#define _PN_0 0
#define _PN_1 1
#define _PN_2 2
#define _PN_3 3
#define _PN_4 4
#define _PN_5 5
#define _PN_6 6
#define _PN_7 7
#define _PN_8 0
#define _PN_9 1
#define _PN_10 2
#define _PN_11 3
#define _PN_12 4
#define _PN_13 5
#define _PN_14 0
#define _PN_15 1
#define _PN_16 2
#define _PN_17 3
#define _PN_18 4
#define _PN_19 5
#define _PN_20 6
#define _PN_21 7

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,27 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "lib/iopins.h"
void main()
{
for (int i = 2; i <= 5; i++) {
as_output_n(i);
}
as_input_pu(12);
while(1) {
for (int i = 2; i <= 5; i++) {
if (is_low(12)) {
set_high_n(i);
_delay_ms(100);
set_low_n(i);
}
}
}
}

@ -0,0 +1,167 @@
MCU = atmega328p
F_CPU = 16000000
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
MAIN = main.c
## If you've split your program into multiple files,
## include the additional .c source (in same directory) here
## (and include the .h files in your foo.c)
LOCAL_SOURCE =
## Here you can link to one more directory (and multiple .c files)
# EXTRA_SOURCE_DIR = ../AVR-Programming-Library/
EXTRA_SOURCE_DIR = lib/
EXTRA_SOURCE_FILES = debounce.c lcd.c adc.c
EXTRA_CFLAGS =
##########------------------------------------------------------##########
########## Programmer Defaults ##########
########## Set up once, then forget about it ##########
########## (Can override. See bottom of file.) ##########
##########------------------------------------------------------##########
#19200
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
##########------------------------------------------------------##########
########## Makefile Magic! ##########
########## Summary: ##########
########## We want a .hex file ##########
########## Compile source files into .elf ##########
########## Convert .elf file into .hex ##########
########## You shouldn't need to edit below. ##########
##########------------------------------------------------------##########
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## Compilation options, type man avr-gcc if you're curious.
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
CFLAGS += $(EXTRA_CFLAGS)
CFLAGS_BUILD = $(CFLAGS) -Os
# CFLAGS += -lm
## CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
## CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
## Lump target and extra source files together
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
## List of all header files
HEADERS = $(SRC:.c=.h)
## For every .c file, compile an .o object file
OBJ = $(SRC:.c=.o)
## Generic Makefile targets. (Only .hex file is necessary)
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Optionally create listing file from .elf
# This creates approximate assembly-language equivalent of your code.
# Useful for debugging time-sensitive bits,
# or making sure the compiler does what you want.
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
eeprom: $(TARGET).eeprom
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Optionally show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
squeaky_clean:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
##########------------------------------------------------------##########
########## Programmer-specific details ##########
########## Flashing code to AVR using avrdude ##########
##########------------------------------------------------------##########
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flash_eeprom: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
terminal:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
flash_arduino: PROGRAMMER_TYPE = arduino
flash_arduino: PROGRAMMER_ARGS =
flash_arduino: flash
flash_dragon_isp: PROGRAMMER_TYPE = dragon_isp
flash_dragon_isp: PROGRAMMER_ARGS =
flash_dragon_isp: flash
##########------------------------------------------------------##########
########## Fuse settings and suitable defaults ##########
##########------------------------------------------------------##########
## Generic
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
## Called with no extra definitions, sets to defaults
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,10 @@
Snake for HD44780
=================
This is a Snake game (known from old Nokia phones) played on a character display with HD44780.
Program tested on Arduino Pro Mini (flashed with avrdude using the Makefile).
**Connections** are `#define`d in `main.c`, board size and snake speed can also be adjusted. No external parts except the display and buttons required.
Best works with a gamepad, but any buttons will work.

@ -0,0 +1,5 @@
#pragma once
// Config file for debouncer
#define DEBO_CHANNELS 6
#define DEBO_TICKS 1

@ -0,0 +1,13 @@
#pragma once
// Config file for LCD.
#include "lib/arduino_pins.h"
#define LCD_RS D2
#define LCD_RW D3
#define LCD_E D4
#define LCD_D4 D5
#define LCD_D5 D6
#define LCD_D6 D7
#define LCD_D7 D8

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,429 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "lib/meta.h"
#include "lib/arduino_pins.h"
#include "lib/calc.h"
#include "lib/adc.h"
#include "lib/lcd.h"
#include "lib/debounce.h"
// Buttons (to ground)
#define BTN_LEFT A0
#define BTN_RIGHT A1
#define BTN_UP A2
#define BTN_DOWN A3
#define BTN_PAUSE A4
#define BTN_RESTART A5
// Debouncer channels for buttons
// (Must be added in this order to debouncer)
#define D_LEFT 0
#define D_RIGHT 1
#define D_UP 2
#define D_DOWN 3
#define D_PAUSE 4
#define D_RESTART 5
// Board size (!!! rows = 2x number of display lines, max 2*4 = 8 !!!)
#define ROWS 8
#define COLS 20
// Delay between snake steps, in 10 ms
#define STEP_DELAY 24
// proto
void update();
void init_cgram();
void init_gameboard();
void init()
{
// Randomize RNG
adc_init();
srand(adc_read_word(3));
// Init LCD
lcd_init();
init_cgram(); // load default glyphs
// Init game board.
init_gameboard();
// gamepad buttons
as_input_pu(BTN_LEFT);
as_input_pu(BTN_RIGHT);
as_input_pu(BTN_UP);
as_input_pu(BTN_DOWN);
as_input_pu(BTN_PAUSE);
as_input_pu(BTN_RESTART);
// add buttons to debouncer
debo_add_rev(BTN_LEFT);
debo_add_rev(BTN_RIGHT);
debo_add_rev(BTN_UP);
debo_add_rev(BTN_DOWN);
debo_add_rev(BTN_PAUSE);
debo_add_rev(BTN_RESTART);
// setup timer
TCCR0A = _BV(WGM01); // CTC
TCCR0B = _BV(CS02) | _BV(CS00); // prescaler 1024
OCR0A = 156; // interrupt every 10 ms
sbi(TIMSK0, OCIE0A);
sei();
}
/** timer 0 interrupt vector */
ISR(TIMER0_COMPA_vect)
{
debo_tick(); // poll debouncer
update(); // update and display
}
// sub-glyphs
#define _HEAD_ 15, 21, 21, 30
#define _BODY_ 15, 31, 31, 30
#define _FOOD_ 10, 21, 17, 14
//14, 17, 17, 14
#define _NONE_ 0, 0, 0, 0
// complete glyphs for loading into memory
// Only one food & one head glyph have to be loaded at a time.
// Body - Body
const uint8_t SYMBOL_BB[] PROGMEM = {_BODY_, _BODY_};
// Body - None
const uint8_t SYMBOL_BX[] PROGMEM = {_BODY_, _NONE_};
const uint8_t SYMBOL_XB[] PROGMEM = {_NONE_, _BODY_};
// Head - None
const uint8_t SYMBOL_HX[] PROGMEM = {_HEAD_, _NONE_};
const uint8_t SYMBOL_XH[] PROGMEM = {_NONE_, _HEAD_};
// Body - Head
const uint8_t SYMBOL_BH[] PROGMEM = {_BODY_, _HEAD_};
const uint8_t SYMBOL_HB[] PROGMEM = {_HEAD_, _BODY_};
// Head - Food
const uint8_t SYMBOL_HF[] PROGMEM = {_HEAD_, _FOOD_};
const uint8_t SYMBOL_FH[] PROGMEM = {_FOOD_, _HEAD_};
// Food - None
const uint8_t SYMBOL_FX[] PROGMEM = {_FOOD_, _NONE_};
const uint8_t SYMBOL_XF[] PROGMEM = {_NONE_, _FOOD_};
// Body - Food
const uint8_t SYMBOL_BF[] PROGMEM = {_BODY_, _FOOD_};
const uint8_t SYMBOL_FB[] PROGMEM = {_FOOD_, _BODY_};
// board block (snake, food...)
typedef enum {
bEMPTY = 0x00,
bHEAD = 0x01,
bFOOD = 0x02,
bBODY_LEFT = 0x80,
bBODY_RIGHT = 0x81,
bBODY_UP = 0x82,
bBODY_DOWN = 0x83,
} block_t;
// Snake direction
typedef enum {
dLEFT = 0x00,
dRIGHT = 0x01,
dUP = 0x02,
dDOWN = 0x03,
} dir_t;
// Coordinate on board
typedef struct {
int8_t x;
int8_t y;
} coord_t;
#define is_body(blk) (((blk) & 0x80) != 0)
#define mk_body_dir(dir) (0x80 + (dir))
// compare two coords
#define coord_eq(a, b) (((a).x == (b).x) && ((a).y == (b).y))
bool crashed;
uint8_t snake_len;
// y, x indexing
block_t board[ROWS][COLS];
coord_t head_pos;
coord_t tail_pos;
dir_t head_dir;
const uint8_t CODE_BB = 0;
const uint8_t CODE_BX = 1;
const uint8_t CODE_XB = 2;
const uint8_t CODE_H = 3; // glyph with head, dynamic
const uint8_t CODE_F = 4; // glyph with food, dynamic
const uint8_t CODE_XX = 32; // space
// Set a block in board
#define set_block_xy(x, y, block) do { board[y][x] = (block); } while(0)
#define get_block_xy(x, y) board[y][x]
#define get_block(pos) get_block_xy((pos).x, (pos).y)
#define set_block(pos, block) set_block_xy((pos).x, (pos).y, (block))
void init_cgram()
{
// those will be always the same
lcd_glyph_P(CODE_BB, SYMBOL_BB);
lcd_glyph_P(CODE_BX, SYMBOL_BX);
lcd_glyph_P(CODE_XB, SYMBOL_XB);
lcd_glyph_P(5, SYMBOL_XF);
}
void place_food()
{
while(1) {
const uint8_t xx = rand() % COLS;
const uint8_t yy = rand() % ROWS;
if (get_block_xy(xx, yy) == bEMPTY) {
set_block_xy(xx, yy, bFOOD);
break;
}
}
}
void init_gameboard()
{
//erase the board
for (uint8_t x = 0; x < COLS; x++) {
for (uint8_t y = 0; y < ROWS; y++) {
set_block_xy(x, y, bEMPTY);
}
}
lcd_clear();
tail_pos = (coord_t) {.x = 0, .y = 0};
set_block_xy(0, 0, bBODY_RIGHT);
set_block_xy(1, 0, bBODY_RIGHT);
set_block_xy(2, 0, bBODY_RIGHT);
set_block_xy(3, 0, bHEAD);
head_pos = (coord_t) {.x = 3, .y = 0};
snake_len = 4; // includes head
head_dir = dRIGHT;
crashed = false;
place_food();
}
uint8_t presc = 0;
bool restart_held;
bool pause_held;
bool paused;
void update()
{
if (debo_get_pin(D_RESTART)) {
if (!restart_held) {
// restart
init_gameboard();
presc = 0;
restart_held = true;
}
} else {
restart_held = false;
}
if (debo_get_pin(D_PAUSE)) {
if (!pause_held) {
paused ^= true;
pause_held = true;
}
} else {
pause_held = false;
}
if(!crashed && !paused) {
// resolve movement direction
if (debo_get_pin(D_LEFT))
head_dir = dLEFT;
else if (debo_get_pin(D_RIGHT))
head_dir = dRIGHT;
else if (debo_get_pin(D_UP))
head_dir = dUP;
else if (debo_get_pin(D_DOWN))
head_dir = dDOWN;
// time's up for a move
if (presc++ == STEP_DELAY) {
presc = 0;
// move snake
const coord_t oldpos = head_pos;
switch (head_dir) {
case dLEFT: head_pos.x--; break;
case dRIGHT: head_pos.x++; break;
case dUP: head_pos.y--; break;
case dDOWN: head_pos.y++; break;
}
bool do_move = false;
bool do_grow = false;
if (head_pos.x < 0 || head_pos.x >= COLS || head_pos.y < 0 || head_pos.y >= ROWS) {
// ouch, a wall!
crashed = true;
} else {
// check if tile occupied or not
if (coord_eq(head_pos, tail_pos)) {
// head moved in previous tail, that's OK.
do_move = true;
} else {
// moved to other tile than tail
switch (get_block(head_pos)) {
case bFOOD:
do_grow = true; // fall through
case bEMPTY:
do_move = true;
break;
default: // includes all BODY_xxx
crashed = true; // snake crashed into some block
}
}
}
if (do_move) {
// Move tail
if (do_grow) {
// let tail as is
snake_len++; // grow the counter
} else {
// tail dir
dir_t td = get_block(tail_pos) & 0xF;
// clean tail
set_block(tail_pos, bEMPTY);
// move tail based on old direction of tail block
switch (td) {
case dLEFT: tail_pos.x--; break;
case dRIGHT: tail_pos.x++; break;
case dUP: tail_pos.y--; break;
case dDOWN: tail_pos.y++; break;
}
}
// Move head
set_block(head_pos, bHEAD); // place head in new pos
set_block(oldpos, mk_body_dir(head_dir)); // directional body in old head pos
if (do_grow) {
// food eaten, place new
place_food();
}
}
}
} // end !crashed
// Render the board
for (uint8_t r = 0; r < ROWS / 2; r++) {
lcd_xy(0, r);
for (uint8_t c = 0; c < COLS; c++) {
const block_t t1 = get_block_xy(c, r * 2);
const block_t t2 = get_block_xy(c, (r * 2) + 1);
uint8_t code = '!'; // ! marks fail
if ((t1 == bEMPTY) && (t2 == bEMPTY)) {
code = CODE_XX;
if (crashed) code = '*';
} else if (is_body(t1) && is_body(t2))
code = CODE_BB;
else if (is_body(t1) && (t2 == bEMPTY))
code = CODE_BX;
else if (t1 == bEMPTY && is_body(t2))
code = CODE_XB;
else if ((t1 == bFOOD) || (t2 == bFOOD)) {
// one is food
code = CODE_F;
if (t1 == bFOOD) {
if (t2 == bEMPTY)
lcd_glyph_P(code, SYMBOL_FX);
else if (t2 == bHEAD)
lcd_glyph_P(code, SYMBOL_FH);
else if (is_body(t2))
lcd_glyph_P(code, SYMBOL_FB);
} else { // t2 is food
if (t1 == bEMPTY)
lcd_glyph_P(code, SYMBOL_XF);
else if (t1 == bHEAD)
lcd_glyph_P(code, SYMBOL_HF);
else if (is_body(t1))
lcd_glyph_P(code, SYMBOL_BF);
}
lcd_xy(c,r);
} else if ((t1 == bHEAD )|| (t2 == bHEAD)) {
// one is head
code = CODE_H;
if (t1 == bHEAD) {
if (t2 == bEMPTY)
lcd_glyph_P(code, SYMBOL_HX);
else if (is_body(t2))
lcd_glyph_P(code, SYMBOL_HB);
} else { // t2 is head
if (t1 == bEMPTY)
lcd_glyph_P(code, SYMBOL_XH);
else if (is_body(t1))
lcd_glyph_P(code, SYMBOL_BH);
}
lcd_xy(c,r);
}
lcd_putc(code);
}
}
}
void main()
{
init();
while(1); // timer does everything
}

@ -0,0 +1,141 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c iopins.c stream.c onewire.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash ser
ser:
gtkterm -p /dev/ttyUSB0
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,38 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "lib/iopins.h"
#include "lib/uart.h"
#include "lib/stream.h"
#include "lib/onewire.h"
void main()
{
uart_init(9600);
uart_puts_P(PSTR("*** OneWire test ***\r\n"));
while(1)
{
_delay_ms(100);
if (ds1820_single_measure(2))
{
int16_t temp = ds1820_read_temp_c(2);
if (temp == TEMP_ERROR) {
// Checksum mismatch
uart_puts_P(PSTR("Corrupt data!\r\n"));
} else {
put_i16f(uart, temp, 1);
uart_puts_P(PSTR(" °C\r\n"));
}
} else {
uart_puts_P(PSTR("Device not connected!\r\n"));
}
}
}

@ -0,0 +1,170 @@
MCU = atmega328p
F_CPU = 16000000
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
MAIN = main.c
## If you've split your program into multiple files,
## include the additional .c source (in same directory) here
## (and include the .h files in your foo.c)
LOCAL_SOURCE =
## Here you can link to one more directory (and multiple .c files)
# EXTRA_SOURCE_DIR = ../AVR-Programming-Library/
EXTRA_SOURCE_DIR = lib/
EXTRA_SOURCE_FILES = adc.c hsl.c
EXTRA_FLAGS =
#-DHSL_LINEAR=1
##########------------------------------------------------------##########
########## Programmer Defaults ##########
########## Set up once, then forget about it ##########
########## (Can override. See bottom of file.) ##########
##########------------------------------------------------------##########
#19200
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
##########------------------------------------------------------##########
########## Makefile Magic! ##########
########## Summary: ##########
########## We want a .hex file ##########
########## Compile source files into .elf ##########
########## Convert .elf file into .hex ##########
########## You shouldn't need to edit below. ##########
##########------------------------------------------------------##########
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## Compilation options, type man avr-gcc if you're curious.
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -pedantic -Wfatal-errors
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
CFLAGS += $(EXTRA_FLAGS)
CFLAGS_BUILD = $(CFLAGS) -Os
# CFLAGS += -lm
## CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
## CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
## Lump target and extra source files together
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
## List of all header files
HEADERS = $(SRC:.c=.h)
## For every .c file, compile an .o object file
OBJ = $(SRC:.c=.o)
## Generic Makefile targets. (Only .hex file is necessary)
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Optionally create listing file from .elf
# This creates approximate assembly-language equivalent of your code.
# Useful for debugging time-sensitive bits,
# or making sure the compiler does what you want.
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
eeprom: $(TARGET).eeprom
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Optionally show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
squeaky_clean:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
##########------------------------------------------------------##########
########## Programmer-specific details ##########
########## Flashing code to AVR using avrdude ##########
##########------------------------------------------------------##########
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flash_eeprom: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
terminal:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
flash_arduino: PROGRAMMER_TYPE = arduino
flash_arduino: PROGRAMMER_ARGS =
flash_arduino: flash
flash_dragon_isp: PROGRAMMER_TYPE = dragon_isp
flash_dragon_isp: PROGRAMMER_ARGS =
flash_dragon_isp: flash
##########------------------------------------------------------##########
########## Fuse settings and suitable defaults ##########
##########------------------------------------------------------##########
## Generic
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
## Called with no extra definitions, sets to defaults
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,11 @@
Random color flasher, with fading.
Color is atm restricted to hues of blue-cyan.
Works with a 4x4 zigzag screen
0->1->2->3
7<-6<-5<-4
8->...
(But will work with any screen since there's no pattern to be preserved)

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,69 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdlib.h>
#include "lib/meta.h"
#include "lib/arduino_pins.h"
#include "lib/calc.h"
#include "lib/colors.h"
#include "lib/hsl.h"
#include "lib/adc.h"
#define WS_T_1H 650
#define WS_T_1L 200
#define WS_T_0H 120
#define WS_T_0L 650
#include "lib/ws_rgb.h"
#define WS1 D2
void SECTION(".init8") init()
{
adc_init();
srand(adc_read_word(0));
as_output(WS1);
}
void main()
{
#define WIDTH 4
#define HEIGHT 4
#define SIZE (WIDTH*HEIGHT)
hsl_t board[SIZE];
xrgb_t screen[SIZE];
for (uint8_t i = 0; i < SIZE; i++) {
board[i] = (hsl_t) {.h=0, .s=255, .l=0};
screen[i] = (xrgb_t) {.r=0, .g=0, .b=0};
}
while(1) {
for(uint8_t i = 0; i < SIZE; i++) {
if (board[i].l > 0) {
board[i].l--;
}
screen[i] = hsl2xrgb(board[i]);
}
if (rand() % 4 == 0) {
uint8_t i = rand() % SIZE;
if (board[i].l == 0) {
board[i].h = 125 + rand() % 57;
board[i].s = 200 + rand() % 56;
board[i].l = 150 + rand() % 106;
}
}
//ws_send_xrgb_array_zigzag_linear(WS1, screen, 4, 4);
ws_send_xrgb_array_zigzag_linear(WS1, screen, 4, 4);
_delay_ms(10);
}
}

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c iopins.c stream.c adc.c dht11.c sonar.c onewire.c
#Files that need config file:
# EXTRA_SOURCE_FILES += lcd.c
# EXTRA_SOURCE_FILES += color.c wsrgb.c
# EXTRA_SOURCE_FILES += debouce.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash ser
ser:
gtkterm -p /dev/ttyUSB0
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,191 @@
# This file was generated by an application wizard of Qt Creator.
# The code below handles deployment to Android and Maemo, aswell as copying
# of the application data to shadow build directories on desktop.
# It is recommended not to modify this file, since newer versions of Qt Creator
# may offer an updated version of it.
defineTest(qtcAddDeployment) {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
greaterThan(QT_MAJOR_VERSION, 4) {
itemsources = $${item}.files
} else {
itemsources = $${item}.sources
}
$$itemsources = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath= $$eval($${deploymentfolder}.target)
export($$itemsources)
export($$itempath)
DEPLOYMENT += $$item
}
MAINPROFILEPWD = $$PWD
android-no-sdk {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
target.path = /data/user/qt
export(target.path)
INSTALLS += target
} else:android {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = /assets/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
x86 {
target.path = /libs/x86
} else: armeabi-v7a {
target.path = /libs/armeabi-v7a
} else {
target.path = /libs/armeabi
}
export(target.path)
INSTALLS += target
} else:win32 {
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, /, \\)
sourcePathSegments = $$split(source, \\)
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
target = $$replace(target, /, \\)
target ~= s,\\\\\\.?\\\\,\\,
!isEqual(source,$$target) {
!isEmpty(copyCommand):copyCommand += &&
isEqual(QMAKE_DIR_SEP, \\) {
copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
} else {
source = $$replace(source, \\\\, /)
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
target = $$replace(target, \\\\, /)
copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
}
}
}
!isEmpty(copyCommand) {
copyCommand = @echo Copying application data... && $$copyCommand
copydeploymentfolders.commands = $$copyCommand
first.depends = $(first) copydeploymentfolders
export(first.depends)
export(copydeploymentfolders.commands)
QMAKE_EXTRA_TARGETS += first copydeploymentfolders
}
} else:ios {
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, \\\\, /)
target = $CODESIGNING_FOLDER_PATH/$$eval($${deploymentfolder}.target)
target = $$replace(target, \\\\, /)
sourcePathSegments = $$split(source, /)
targetFullPath = $$target/$$last(sourcePathSegments)
targetFullPath ~= s,/\\.?/,/,
!isEqual(source,$$targetFullPath) {
!isEmpty(copyCommand):copyCommand += &&
copyCommand += mkdir -p \"$$target\"
copyCommand += && cp -r \"$$source\" \"$$target\"
}
}
!isEmpty(copyCommand) {
copyCommand = echo Copying application data... && $$copyCommand
!isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";"
QMAKE_POST_LINK += "$$copyCommand"
export(QMAKE_POST_LINK)
}
} else:unix {
maemo5 {
desktopfile.files = $${TARGET}.desktop
desktopfile.path = /usr/share/applications/hildon
icon.files = $${TARGET}64.png
icon.path = /usr/share/icons/hicolor/64x64/apps
} else:!isEmpty(MEEGO_VERSION_MAJOR) {
desktopfile.files = $${TARGET}_harmattan.desktop
desktopfile.path = /usr/share/applications
icon.files = $${TARGET}80.png
icon.path = /usr/share/icons/hicolor/80x80/apps
} else { # Assumed to be a Desktop Unix
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, \\\\, /)
macx {
target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
} else {
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
}
target = $$replace(target, \\\\, /)
sourcePathSegments = $$split(source, /)
targetFullPath = $$target/$$last(sourcePathSegments)
targetFullPath ~= s,/\\.?/,/,
!isEqual(source,$$targetFullPath) {
!isEmpty(copyCommand):copyCommand += &&
copyCommand += $(MKDIR) \"$$target\"
copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
}
}
!isEmpty(copyCommand) {
copyCommand = @echo Copying application data... && $$copyCommand
copydeploymentfolders.commands = $$copyCommand
first.depends = $(first) copydeploymentfolders
export(first.depends)
export(copydeploymentfolders.commands)
QMAKE_EXTRA_TARGETS += first copydeploymentfolders
}
}
!isEmpty(target.path) {
installPrefix = $${target.path}
} else {
installPrefix = /opt/$${TARGET}
}
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
!isEmpty(desktopfile.path) {
export(icon.files)
export(icon.path)
export(desktopfile.files)
export(desktopfile.path)
INSTALLS += icon desktopfile
}
isEmpty(target.path) {
target.path = $${installPrefix}/bin
export(target.path)
}
INSTALLS += target
}
export (ICON)
export (INSTALLS)
export (DEPLOYMENT)
export (LIBS)
export (QMAKE_EXTRA_TARGETS)
}

@ -0,0 +1,57 @@
#include "main.h"
#include "sd.h"
#include "spi.h"
static uint8_t sd_buffer[512];
static sd_context_t sdc;
void main(void)
{
int j, ok;
ok = 0;
/* Stop the watchdog timer */
WDTCTL = WDTPW | WDTHOLD;
/* Set some reasonable values for the timeouts.
*/
sdc.timeout_write = PERIPH_CLOCKRATE / 8;
sdc.timeout_read = PERIPH_CLOCKRATE / 20;
sdc.busyflag = 0;
for (j = 0; j < SD_INIT_TRY && ok != 1; j++)
{
ok = do_sd_initialize(&sdc);
}
/* Read in the first block on the SD Card */
if (ok == 1)
{
sd_read_block(&sdc, 0, sd_buffer);
sd_wait_notbusy(&sdc);
}
/* Wait forever */
while (1) { }
}
int do_sd_initialize(sd_context_t *sdc)
{
/* Initialize the SPI controller */
spi_initialize();
/* Start out with a slow SPI clock, 400kHz, as required
by the SD spec
(for MMC compatibility). */
spi_set_divisor(PERIPH_CLOCKRATE / 400000);
/* Initialization OK? */
if (sd_initialize(sdc) != 1)
return 0;
/* Set the maximum SPI clock rate possible */
spi_set_divisor(2);
return 1;
}

@ -0,0 +1,10 @@
#ifndef MAIN_H
#define MAIN_H
#include "sdcomm_spi.h"
/* Peripheral clock rate, in Hz, used for timing. */
#define PERIPH_CLOCKRATE 8000000
int do_sd_initialize(sd_context_t *sdc);
#endif

@ -0,0 +1,467 @@
#include "main.h"
#include "sd.h"
#include "sdcomm_spi.h"
#include "spi.h"
static uint8_t response[5];
static uint8_t argument[4];
int sd_card_present()
{
return (!(P3IN & 0x01));
}
/* This function initializes the SD card. It returns 1 if
initialization was successful, 0 otherwise.
sd_context_t *sdc -- pointer to a data structure containing
information about the card. For now, the
timeouts MUST be specified in advance. This
function does not yet calculate them from the
card data.
*/
int sd_initialize(sd_context_t *sdc)
{
char i, j;
/* SPI SD initialization sequence:
* CMD0
* CMD55
* ACMD41
* CMD58
* (Note there is no CMD2 or CMD3 in SPI mode. These
* instructions are devoted to addressing on the SD bus.)
*
* SD memory card SD initialization sequence:
* CMD0
* CMD55
* ACMD41
* CMD2
* CMD3
*/
sdc->busyflag = 0;
for (i = 0; i < 4; i++)
argument[i] = 0;
/* Delay for at least 74 clock cycles. This means to actually
* *clock* out at least 74 clock cycles with no data present on
* the clock. In SPI mode, send at least 10 idle bytes (0xFF). */
spi_cs_assert();
sd_delay(100);
spi_cs_deassert();
sd_delay(2);
/* Put the card in the idle state */
if (sd_send_command(sdc, CMD0, CMD0_R, response, argument) == 0)
return 0;
/* Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX
times */
j = 0;
do
{
j++;
/* Flag the next command as an application-specific command */
if (sd_send_command(sdc, CMD55, CMD55_R, response, argument) == 1)
{
/* Tell the card to send its OCR */
sd_send_command(sdc, ACMD41, ACMD41_R, response, argument);
}
else
{
/* No response, bail early */
j = SD_IDLE_WAIT_MAX;
}
}
while ((response[0] & MSK_IDLE) == MSK_IDLE && j < SD_IDLE_WAIT_MAX);
/* As long as we didn’t hit the timeout, assume we’re OK. */
if (j >= SD_IDLE_WAIT_MAX)
return 0;
if (sd_send_command(sdc, CMD58, CMD58_R, response, argument) == 0)
return 0;
/* At a very minimum, we must allow 3.3V. */
if ((response[2] & MSK_OCR_33) != MSK_OCR_33)
return 0;
/* Set the block length */
if (sd_set_blocklen(sdc, SD_BLOCKSIZE) != 1)
return 0;
/* If we got this far, initialization was OK.
*/
return 1;
}
/*
This function reads a single block from the SD card at block
blockaddr. The buffer must be preallocated. Returns 1 if the
command was successful, zero otherwise.
This is an ASYNCHRONOUS call.
The transfer will not be complete when the function returns.
If you want to explicitly wait until any pending transfers are
finished, use the command sd_wait_notbusy(sdc).
sd_context_t *sdc
-- a pointer to an sd device context structure,
populated by the function sd_initialize()
u32 blockaddr
-- The block address to read from the card.
This is a block address, not a linear address.
uint8_t *data
-- The data, a pointer to an array of uint8_ts.
*/
int sd_read_block(sd_context_t *sdc, uint32_t blockaddr,
uint8_t *data)
{
unsigned long int i = 0;
uint8_t tmp;
uint8_t blank = 0xFF;
/* Adjust the block address to a linear address */
blockaddr <<= SD_BLOCKSIZE_NBITS;
/* Wait until any old transfers are finished */
sd_wait_notbusy(sdc);
/* Pack the address */
sd_packarg(argument, blockaddr);
/* Need to add size checking */
if (sd_send_command(sdc, CMD17, CMD17_R, response, argument) == 0)
return 0;
/* Check for an error, like a misaligned read */
if (response[0] != 0)
return 0;
/* Re-assert CS to continue the transfer */
spi_cs_assert();
/* Wait for the token */
i = 0;
do
{
tmp = spi_rcv_byte();
i++;
}
while ((tmp == 0xFF) && i < sdc->timeout_read);
if ((tmp & MSK_TOK_DATAERROR) == 0)
{
/* Clock out a byte before returning */
spi_send_byte(0xFF);
/* The card returned an error response. Bail and return 0 */
return 0;
}
/* Prime the interrupt flags so things happen in the correct order. */
IFG1 &= ~URXIFG0;
IFG1 &= ~UTXIFG0;
/* Get the block */
/* Source DMA address: receive register. */
DMA0SA = U0RXBUF_;
/* Destination DMA address: the user data buffer. */
DMA0DA = (unsigned short) data;
/* The size of the block to be transferred */
DMA0SZ = SD_BLOCKSIZE;
/* Configure the DMA transfer*/
DMA0CTL =
DMADT_0 | /* Single transfer mode */
DMASBDB | /* Byte mode */
DMAEN | /* Enable DMA */
DMADSTINCR1 | DMADSTINCR0; /* Increment the destination address */
/* We depend on the DMA priorities here. Both triggers occur at
the same time, since the source is identical. DMA0 is handled
first, and retrieves the byte. DMA1 is triggered next, and
sends the next byte. */
/* Source DMA address: constant 0xFF (don’t increment)*/
DMA1SA = (unsigned short) &blank;
/* Destination DMA address: the transmit buffer. */
DMA1DA = U0TXBUF_;
/* Increment the destination address */
/* The size of the block to be transferred */
DMA1SZ = SD_BLOCKSIZE - 1;
/* Configure the DMA transfer*/
DMA1CTL =
DMADT_0 | /* Single transfer mode */
DMASBDB | /* Byte mode */
DMAEN; /* Enable DMA */
/* DMA trigger is UART receive for both DMA0 and DMA1 */
DMACTL0 = DMA0TSEL_3 | DMA1TSEL_3;
/* Kick off the transfer by sending the first byte */
U0TXBUF = 0xFF;
return 1;
}
/*
This function writes a single block to the SD card at block
blockaddr. Returns 1 if the command was successful, zero
otherwise.
This is an ASYNCHRONOUS call. The transfer will not be complete
when the function returns. If you want to explicitly wait until
any pending transfers are finished, use the command
sd_wait_notbusy(sdc).
sd_context_t *sdc
-- a pointer to an sd device context structure,
populated by the function sd_initialize()
u32 blockaddr
-- The block address to read from the card.
This is a block address, not a linear address.
uint8_t *data
-- The data, a pointer to an array of unsigned
chars.
*/
int sd_write_block(sd_context_t *sdc, uint32_t blockaddr,
uint8_t *data)
{
/* Adjust the block address to a linear address */
blockaddr <<= SD_BLOCKSIZE_NBITS;
/* Wait until any old transfers are finished */
sd_wait_notbusy(sdc);
/* Pack the address */
sd_packarg(argument, blockaddr);
if (sd_send_command(sdc, CMD24, CMD24_R, response, argument) == 0)
return 0;
/* Check for an error, like a misaligned write */
if (response[0] != 0)
return 0;
/* Re-assert CS to continue the transfer */
spi_cs_assert();
/* The write command needs an additional 8 clock cycles before
* the block write is started. */
spi_rcv_byte();
/* Clear any pending flags */
IFG1 &= ~(URXIFG0 | UTXIFG0);
/* Get the block */
/* Source DMA address: the data buffer. */
DMA0SA = (unsigned short)data;
/* Destination DMA address: the UART send register. */
DMA0DA = U0TXBUF_;
/* The size of the block to be transferred */
DMA0SZ = SD_BLOCKSIZE;
/* Configure the DMA transfer*/
DMA0CTL =
DMADT_0 | /* Single transfer mode */
DMASBDB | /* Byte mode */
DMAEN | /* Enable DMA */
DMASRCINCR1 | DMASRCINCR0; /* Increment the source address */
/* DMA trigger is UART send */
DMACTL0 = DMA0TSEL_3;
/* Kick off the transfer by sending the first byte, the "start block"
* token */
U0TXBUF = SD_TOK_WRITE_STARTBLOCK;
/* Signal that the card may be busy, so any subsequent commands
should wait for the busy signalling to end (indicated by a
nonzero response). */
sdc->busyflag = 1;
return 1;
}
/*
This function synchronously waits until any pending block transfers
are finished. If your program needs to ensure a block has finished
transferring, call this function.
Note that sd_read_block() and sd_write_block() already call this
function internally before attempting a new transfer, so there are
only two times when a user would need to use this function.
1) When the processor will be shutting down. All pending
writes should be finished first.
2) When the user needs the results of an sd_read_block() call
right away.
*/
void sd_wait_notbusy(sd_context_t *sdc)
{
/* Just twiddle our thumbs until the transfer’s done */
while ((DMA0CTL & DMAEN) != 0) { }
/* Reset the DMA controller */
DMACTL0 = 0;
/* Ignore the checksum */
sd_delay(4);
/* Check for the busy flag (set on a write block) */
if (sdc->busyflag == 1)
{
while (spi_rcv_byte() != 0xFF);
}
sdc->busyflag = 0;
/* Deassert CS */
spi_cs_deassert();
/* Send some extra clocks so the card can resynchronize on the next
transfer */
sd_delay(2);
}
void sd_packarg(uint8_t *argument, uint32_t value)
{
argument[3] = (uint8_t)(value >> 24);
argument[2] = (uint8_t)(value >> 16);
argument[1] = (uint8_t)(value >> 8);
argument[0] = (uint8_t)(value);
}
int sd_send_command(sd_context_t *sdc,
uint8_t cmd, uint8_t response_type,
uint8_t *response, uint8_t *argument)
{
int i;
char response_length;
uint8_t tmp;
spi_cs_assert();
/* All data is sent MSB first, and MSb first */
/* Send the header/command */
/* Format:
cmd[7:6] : 01
cmd[5:0] : command */
spi_send_byte((cmd & 0x3F) | 0x40);
for (i = 3; i >= 0; i--)
{
spi_send_byte(argument[i]);
}
/* This is the CRC. It only matters what we put here for the first
command. Otherwise, the CRC is ignored for SPI mode unless we
enable CRC checking. */
spi_send_byte(0x95);
response_length = 0;
switch (response_type)
{
case R1:
case R1B:
response_length = 1;
break;
case R2:
response_length = 2;
break;
case R3:
response_length = 5;
break;
default:
break;
}
/* Wait for a response. A response can be recognized by the
start bit (a zero) */
i = 0;
do
{
tmp = spi_rcv_byte();
i++;
}
while (((tmp & 0x80) != 0) && i < SD_CMD_TIMEOUT);
/* Just bail if we never got a response */
if (i >= SD_CMD_TIMEOUT)
{
spi_cs_deassert();
return 0;
}
for (i = response_length - 1; i >= 0; i--)
{
response[i] = tmp;
/* This handles the trailing-byte requirement. */
tmp = spi_rcv_byte();
}
/* If the response is a "busy" type (R1B), then there’s some
* special handling that needs to be done. The card will
* output a continuous stream of zeros, so the end of the BUSY
* state is signaled by any nonzero response. The bus idles
* high.
*/
i = 0;
if (response_type == R1B)
{
do
{
i++;
tmp = spi_rcv_byte();
}
/* This should never time out, unless SDI is grounded.
* Dont bother forcing a timeout condition here. */
while (tmp != 0xFF);
spi_send_byte(0xFF);
}
spi_cs_deassert();
return 1;
}
void sd_delay(char number)
{
char i;
/* Null for now */
for (i = 0; i < number; i++)
{
/* Clock out an idle byte (0xFF) */
spi_send_byte(0xFF);
}
}
/* Set the block length for all future block transactions */
/* Returns 1 if the function was successful */
int sd_set_blocklen(sd_context_t *sdc, uint32_t length)
{
/* Pack the block length */
sd_packarg(argument, length);
return (sd_send_command(sdc, CMD16, CMD16_R, response, argument));
}

@ -0,0 +1,25 @@
#ifndef SD_H
#define SD_H
#include "sdcomm_spi.h"
#include <stdint.h>
#define SD_BLOCKSIZE 512
#define SD_BLOCKSIZE_NBITS 9
/* User functions */
int sd_card_present();
int sd_initialize(sd_context_t *sdc);
int sd_read_block(sd_context_t *sdc, uint32_t blockaddr, uint8_t *data);
int sd_write_block(sd_context_t *sdc, uint32_t blockaddr, uint8_t *data);
void sd_wait_notbusy(sd_context_t *sdc);
/* Internal functions, used for SD card communications. */
void sd_packarg(uint8_t *argument, uint32_t value);
int sd_set_blocklen(sd_context_t *sdc, uint32_t length);
int sd_send_command(sd_context_t *sdc,
uint8_t cmd, uint8_t response_type,
uint8_t *response, uint8_t *argument);
void sd_delay(char number);
#endif

@ -0,0 +1,25 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += /usr/avr/include
include(deployment.pri)
qtcAddDeployment()
DISTFILES += \
Makefile \
style.astylerc
HEADERS += \
main.h \
sd.h \
sdcomm_spi.h \
spi.h
SOURCES += \
main.c \
sd.c \
spi.c

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.4.1, 2015-06-09T22:29:35. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{dfe3cb4a-0f3e-4da9-9c52-5d2c464adafb}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">1</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="ClangProjectSettings">
<value type="QString" key="CustomPchFile"></value>
<value type="int" key="PchUsage">1</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ee748544-c6c0-4f44-9cef-fbb65dc2525a}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/git/avr-projects/devel/sdcard/</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/git/avr-projects/devel/sdcard/build-sdcard-Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">flash</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments">-p /dev/ttyUSB0</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">gtkterm</value>
<value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run gtkterm</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">sd_bad</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/ondra/git/avr-projects/devel/sd_bad/sd_bad.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">sd_bad.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

@ -0,0 +1,152 @@
#ifndef SDCOMM_SPI_H
#define SDCOMM_SPI_H
typedef struct
{
unsigned long int timeout_write;
unsigned long int timeout_read;
char busyflag;
} sd_context_t;
#define R1 1
#define R1B 2
#define R2 3
#define R3 4
#define MSK_IDLE 0x01
#define MSK_ERASE_RST 0x02
#define MSK_ILL_CMD 0x04
#define MSK_CRC_ERR 0x08
#define MSK_ERASE_SEQ_ERR 0x10
#define MSK_ADDR_ERR 0x20
#define MSK_PARAM_ERR 0x40
#define SD_TOK_READ_STARTBLOCK 0xFE
#define SD_TOK_WRITE_STARTBLOCK 0xFE
#define SD_TOK_READ_STARTBLOCK_M 0xFE
#define SD_TOK_WRITE_STARTBLOCK_M 0xFC
#define SD_TOK_STOP_MULTI 0xFD
/* Error token is 111XXXXX */
#define MSK_TOK_DATAERROR 0xE0
/* Bit fields */
#define MSK_TOK_ERROR 0x01
#define MSK_TOK_CC_ERROR 0x02
#define MSK_TOK_ECC_FAILED 0x04
#define MSK_TOK_CC_OUTOFRANGE 0x08
#define MSK_TOK_CC_LOCKED 0x10
/* Mask off the bits in the OCR corresponding to voltage range 3.2V to
* 3.4V, OCR bits 20 and 21 */
#define MSK_OCR_33 0xC0
/* Number of times to retry the probe cycle during initialization */
#define SD_INIT_TRY 50
/* Number of tries to wait for the card to go idle during initialization */
#define SD_IDLE_WAIT_MAX 100
/* Hardcoded timeout for commands. 8 words, or 64 clocks. Do 10
* words instead */
#define SD_CMD_TIMEOUT 100
/******************************** Basic command set **************************/
/* Reset cards to idle state */
#define CMD0 0
#define CMD0_R R1
/* Read the OCR (MMC mode, do not use for SD cards) */
#define CMD1 1
#define CMD1_R R1
/* Card sends the CSD */
#define CMD9 9
#define CMD9_R R1
/* Card sends CID */
#define CMD10 10
#define CMD10_R R1
/* Stop a multiple block (stream) read/write operation */
#define CMD12 12
#define CMD12_R R1B
/* Get the addressed card’s status register */
#define CMD13 13
#define CMD13_R R2
/***************************** Block read commands **************************/
/* Set the block length */
#define CMD16 16
#define CMD16_R R1
/* Read a single block */
#define CMD17 17
#define CMD17_R R1
/* Read multiple blocks until a CMD12 */
#define CMD18 18
#define CMD18_R R1
/***************************** Block write commands *************************/
/* Write a block of the size selected with CMD16 */
#define CMD24 24
#define CMD24_R R1
/* Multiple block write until a CMD12 */
#define CMD25 25
#define CMD25_R R1
/* Program the programmable bits of the CSD */
#define CMD27 27
#define CMD27_R R1
/***************************** Write protection *****************************/
/* Set the write protection bit of the addressed group */
#define CMD28 28
#define CMD28_R R1B
/* Clear the write protection bit of the addressed group */
#define CMD29 29
#define CMD29_R R1B
/* Ask the card for the status of the write protection bits */
#define CMD30 30
#define CMD30_R R1
/***************************** Erase commands *******************************/
/* Set the address of the first write block to be erased */
#define CMD32 32
#define CMD32_R R1
/* Set the address of the last write block to be erased */
#define CMD33 33
#define CMD33_R R1
/* Erase the selected write blocks */
#define CMD38 38
#define CMD38_R R1B
/***************************** Lock Card commands ***************************/
/* Commands from 42 to 54, not defined here */
/***************************** Application-specific commands ****************/
/* Flag that the next command is application-specific */
#define CMD55 55
#define CMD55_R R1
/* General purpose I/O for application-specific commands */
#define CMD56 56
#define CMD56_R R1
/* Read the OCR (SPI mode only) */
#define CMD58 58
#define CMD58_R R3
/* Turn CRC on or off */
#define CMD59 59
#define CMD59_R R1
/***************************** Application-specific commands ***************/
/* Get the SD card’s status */
#define ACMD13 13
#define ACMD13_R R2
/* Get the number of written write blocks (Minus errors ) */
#define ACMD22 22
#define ACMD22_R R1
/* Set the number of write blocks to be pre-erased before writing */
#define ACMD23 23
#define ACMD23_R R1
/* Get the card’s OCR (SD mode) */
#define ACMD41 41
#define ACMD41_R R1
/* Connect or disconnect the 50kOhm internal pull-up on CD/DAT[3] */
#define ACMD42 42
#define ACMD42_R R1
/* Get the SD configuration register */
#define ACMD51 42
#define ACMD51_R R1
#endif

@ -0,0 +1,88 @@
#include "main.h"
#include "spi.h"
/* Initialize and enable the SPI module */
void spi_initialize()
{
P3SEL = 0x00E; // Setup P3 for SPI mode
P3OUT |= 0x010; // Setup P3.4 as the SS signal, active low. So, initialize it high.
P3DIR |= 0x010; // Set up P3.4 as an output
U0CTL = (CHAR | SYNC | MM | SWRST); // 8-bit, SPI, Master
U0TCTL = (SSEL1 | STC | CKPH); // Normal polarity, 3-wire
U0BR0 = 0x002; // SPICLK = SMCLK/2 (2=Minimum divisor)
U0BR1 = 0x000;
U0MCTL = 0x000;
ME1 |= USPIE0; // Module enable
U0CTL &= ~SWRST; // SPI enable
}
/* Set the baud-rate divisor. The correct value is computed by dividing
the clock rate by the desired baud rate. The minimum divisor allowed
is 2. */
void spi_set_divisor(unsigned int divisor)
{
U0CTL |= SWRST; // Temporarily disable the SPI module
U0BR1 = divisor >> 8;
U0BR0 = divisor;
U0CTL &= ~SWRST; // Re-enable SPI
}
/* Assert the CS signal, active low (CS=0) */
void spi_cs_assert()
{
// Pin 3.4, Pin 32
P3OUT &= ~0x010;
}
/* Deassert the CS signal (CS=1) */
void spi_cs_deassert()
{
// Pin 3.4, Pin 32
P3OUT |= 0x010;
}
/* Send a single byte over the SPI port */
void spi_send_byte(uint8_t input)
{
IFG1 &= ~URXIFG0;
/* Send the byte */
TXBUF0 = input;
/* Wait for the byte to be sent */
while ((IFG1 & URXIFG0) == 0) { }
}
/* Receive a byte. Output an 0xFF (the bus idles high) to receive the byte */
uint8_t spi_rcv_byte()
{
uint8_t tmp;
IFG1 &= ~URXIFG0;
/* Send the byte */
TXBUF0 = 0xFF;
/* Wait for the byte to be received */
while ((IFG1 & URXIFG0) == 0) { }
tmp = U0RXBUF;
return (tmp);
}
/* Disable the SPI module. This function assumes the module had
* already been initialized. */
void spi_disable()
{
/* Put the SPI module in reset mode */
U0CTL |= SWRST;
/* Disable the USART module */
ME1 &= ~USPIE0;
}
void spi_enable()
{
/* Enable the USART module */
ME1 |= USPIE0;
/* Take the SPI module out of reset mode */
U0CTL &= ~SWRST;
}

@ -0,0 +1,15 @@
#ifndef SPI_H
#define SPI_H
#include <stdint.h>
void spi_initialize();
void spi_set_divisor(unsigned int divisor);
void spi_cs_assert();
void spi_cs_deassert();
void spi_send_byte(uint8_t input);
uint8_t spi_rcv_byte();
void spi_enable();
void spi_disable();
#endif

@ -0,0 +1,13 @@
style=allman
indent=tab
max-instatement-indent=60
convert-tabs
indent-switches
pad-oper
unpad-paren
pad-header
verbose

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c iopins.c stream.c adc.c dht11.c sonar.c onewire.c spi.c sd.c fat16.c
#Files that need config file:
# EXTRA_SOURCE_FILES += lcd.c
# EXTRA_SOURCE_FILES += color.c wsrgb.c
# EXTRA_SOURCE_FILES += debouce.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash ser
ser:
gtkterm -p /dev/ttyUSB0
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,191 @@
# This file was generated by an application wizard of Qt Creator.
# The code below handles deployment to Android and Maemo, aswell as copying
# of the application data to shadow build directories on desktop.
# It is recommended not to modify this file, since newer versions of Qt Creator
# may offer an updated version of it.
defineTest(qtcAddDeployment) {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
greaterThan(QT_MAJOR_VERSION, 4) {
itemsources = $${item}.files
} else {
itemsources = $${item}.sources
}
$$itemsources = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath= $$eval($${deploymentfolder}.target)
export($$itemsources)
export($$itempath)
DEPLOYMENT += $$item
}
MAINPROFILEPWD = $$PWD
android-no-sdk {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
target.path = /data/user/qt
export(target.path)
INSTALLS += target
} else:android {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = /assets/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
x86 {
target.path = /libs/x86
} else: armeabi-v7a {
target.path = /libs/armeabi-v7a
} else {
target.path = /libs/armeabi
}
export(target.path)
INSTALLS += target
} else:win32 {
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, /, \\)
sourcePathSegments = $$split(source, \\)
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
target = $$replace(target, /, \\)
target ~= s,\\\\\\.?\\\\,\\,
!isEqual(source,$$target) {
!isEmpty(copyCommand):copyCommand += &&
isEqual(QMAKE_DIR_SEP, \\) {
copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
} else {
source = $$replace(source, \\\\, /)
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
target = $$replace(target, \\\\, /)
copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
}
}
}
!isEmpty(copyCommand) {
copyCommand = @echo Copying application data... && $$copyCommand
copydeploymentfolders.commands = $$copyCommand
first.depends = $(first) copydeploymentfolders
export(first.depends)
export(copydeploymentfolders.commands)
QMAKE_EXTRA_TARGETS += first copydeploymentfolders
}
} else:ios {
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, \\\\, /)
target = $CODESIGNING_FOLDER_PATH/$$eval($${deploymentfolder}.target)
target = $$replace(target, \\\\, /)
sourcePathSegments = $$split(source, /)
targetFullPath = $$target/$$last(sourcePathSegments)
targetFullPath ~= s,/\\.?/,/,
!isEqual(source,$$targetFullPath) {
!isEmpty(copyCommand):copyCommand += &&
copyCommand += mkdir -p \"$$target\"
copyCommand += && cp -r \"$$source\" \"$$target\"
}
}
!isEmpty(copyCommand) {
copyCommand = echo Copying application data... && $$copyCommand
!isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";"
QMAKE_POST_LINK += "$$copyCommand"
export(QMAKE_POST_LINK)
}
} else:unix {
maemo5 {
desktopfile.files = $${TARGET}.desktop
desktopfile.path = /usr/share/applications/hildon
icon.files = $${TARGET}64.png
icon.path = /usr/share/icons/hicolor/64x64/apps
} else:!isEmpty(MEEGO_VERSION_MAJOR) {
desktopfile.files = $${TARGET}_harmattan.desktop
desktopfile.path = /usr/share/applications
icon.files = $${TARGET}80.png
icon.path = /usr/share/icons/hicolor/80x80/apps
} else { # Assumed to be a Desktop Unix
copyCommand =
for(deploymentfolder, DEPLOYMENTFOLDERS) {
source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
source = $$replace(source, \\\\, /)
macx {
target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
} else {
target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
}
target = $$replace(target, \\\\, /)
sourcePathSegments = $$split(source, /)
targetFullPath = $$target/$$last(sourcePathSegments)
targetFullPath ~= s,/\\.?/,/,
!isEqual(source,$$targetFullPath) {
!isEmpty(copyCommand):copyCommand += &&
copyCommand += $(MKDIR) \"$$target\"
copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
}
}
!isEmpty(copyCommand) {
copyCommand = @echo Copying application data... && $$copyCommand
copydeploymentfolders.commands = $$copyCommand
first.depends = $(first) copydeploymentfolders
export(first.depends)
export(copydeploymentfolders.commands)
QMAKE_EXTRA_TARGETS += first copydeploymentfolders
}
}
!isEmpty(target.path) {
installPrefix = $${target.path}
} else {
installPrefix = /opt/$${TARGET}
}
for(deploymentfolder, DEPLOYMENTFOLDERS) {
item = item$${deploymentfolder}
itemfiles = $${item}.files
$$itemfiles = $$eval($${deploymentfolder}.source)
itempath = $${item}.path
$$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
export($$itemfiles)
export($$itempath)
INSTALLS += $$item
}
!isEmpty(desktopfile.path) {
export(icon.files)
export(icon.path)
export(desktopfile.files)
export(desktopfile.path)
INSTALLS += icon desktopfile
}
isEmpty(target.path) {
target.path = $${installPrefix}/bin
export(target.path)
}
INSTALLS += target
}
export (ICON)
export (INSTALLS)
export (DEPLOYMENT)
export (LIBS)
export (QMAKE_EXTRA_TARGETS)
}

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,64 @@
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lib/uart.h"
#include "lib/stream.h"
#include "lib/sd.h"
void main()
{
uart_init(9600);
uart_puts_P(PSTR("*** SD CARD SPI TEST ***\r\n"));
if (!sd_init())
{
put_str_P(uart, PSTR("Failed to init."));
while (1);
}
uint8_t text[512];
put_str_P(uart, PSTR("\r\nReading...\r\n"));
if (sd_read(0, 0, text, 0, 512))
{
put_bytes(uart, text, 512);
put_nl(uart);
put_nl(uart);
for (uint8_t i = 0; i < 60; i++)
{
text[i] = ('A' + i);
}
put_str_P(uart, PSTR("\r\nWriting...\r\n"));
sd_write(1, text);
put_str_P(uart, PSTR("\r\nWrite done.\r\n"));
for (uint16_t i = 0; i < 512; i++)
{
text[i] = 0;
}
if (sd_read(1, 0, text, 0, 512))
{
put_str_P(uart, PSTR("\r\nWritten, result: \r\n"));
put_bytes(uart, text, 512);
put_nl(uart);
put_nl(uart);
}
else
{
put_str_P(uart, PSTR("\r\nRead failed.\r\n"));
}
}
else
{
put_str_P(uart, PSTR("Failed to read."));
while (1);
}
while (1);
}

@ -0,0 +1,56 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += /usr/avr/include
SOURCES += main.c \
lib/adc.c \
lib/color.c \
lib/debounce.c \
lib/dht11.c \
lib/iopins.c \
lib/lcd.c \
lib/onewire.c \
lib/sonar.c \
lib/stream.c \
lib/uart.c \
lib/wsrgb.c \
sd/main.c \
sd/sd.c \
sd/spi.c \
lib/fat16.c \
lib/sd.c \
lib/spi.c
include(deployment.pri)
qtcAddDeployment()
HEADERS += \
lib/adc.h \
lib/calc.h \
lib/color.h \
lib/debounce.h \
lib/dht11.h \
lib/iopins.h \
lib/lcd.h \
lib/nsdelay.h \
lib/onewire.h \
lib/sonar.h \
lib/stream.h \
lib/uart.h \
lib/wsrgb.h \
sd/main.h \
sd/sd.h \
sd/sdcomm_spi.h \
sd/spi.h \
lib/fat16.h \
lib/fat16_internal.h \
lib/spi.h \
lib/sd.h
DISTFILES += \
Makefile \
style.astylerc

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.4.1, 2015-06-10T00:54:58. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{dfe3cb4a-0f3e-4da9-9c52-5d2c464adafb}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">1</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="ClangProjectSettings">
<value type="QString" key="CustomPchFile"></value>
<value type="int" key="PchUsage">1</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ee748544-c6c0-4f44-9cef-fbb65dc2525a}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/git/avr-projects/devel/sdcard/</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">-B</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/git/avr-projects/devel/sdcard/build-sdcard-Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">flash -B</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">sdcard</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">sdcard2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/ondra/git/avr-projects/devel/sdcard/sdcard.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">sdcard.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments">-p /dev/ttyUSB0</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">gtkterm</value>
<value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run gtkterm</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

@ -0,0 +1,13 @@
style=allman
indent=tab
max-instatement-indent=60
convert-tabs
indent-switches
pad-oper
unpad-paren
pad-header
verbose

@ -0,0 +1,166 @@
MCU = atmega328p
F_CPU = 16000000
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
MAIN = main.c
## If you've split your program into multiple files,
## include the additional .c source (in same directory) here
## (and include the .h files in your foo.c)
LOCAL_SOURCE =
## Here you can link to one more directory (and multiple .c files)
# EXTRA_SOURCE_DIR = ../AVR-Programming-Library/
EXTRA_SOURCE_DIR =
EXTRA_SOURCE_FILES =
##########------------------------------------------------------##########
########## Programmer Defaults ##########
########## Set up once, then forget about it ##########
########## (Can override. See bottom of file.) ##########
##########------------------------------------------------------##########
#19200
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
##########------------------------------------------------------##########
########## Makefile Magic! ##########
########## Summary: ##########
########## We want a .hex file ##########
########## Compile source files into .elf ##########
########## Convert .elf file into .hex ##########
########## You shouldn't need to edit below. ##########
##########------------------------------------------------------##########
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = sudo avrdude
## Compilation options, type man avr-gcc if you're curious.
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
CFLAGS_BUILD = $(CFLAGS) -Os
# CFLAGS += -lm
## CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
## CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
## Lump target and extra source files together
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
## List of all header files
HEADERS = $(SRC:.c=.h)
## For every .c file, compile an .o object file
OBJ = $(SRC:.c=.o)
## Generic Makefile targets. (Only .hex file is necessary)
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Optionally create listing file from .elf
# This creates approximate assembly-language equivalent of your code.
# Useful for debugging time-sensitive bits,
# or making sure the compiler does what you want.
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
eeprom: $(TARGET).eeprom
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Optionally show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
squeaky_clean:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
##########------------------------------------------------------##########
########## Programmer-specific details ##########
########## Flashing code to AVR using avrdude ##########
##########------------------------------------------------------##########
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flash_eeprom: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
terminal:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
flash_arduino: PROGRAMMER_TYPE = arduino
flash_arduino: PROGRAMMER_ARGS =
flash_arduino: flash
flash_dragon_isp: PROGRAMMER_TYPE = dragon_isp
flash_dragon_isp: PROGRAMMER_ARGS =
flash_dragon_isp: flash
##########------------------------------------------------------##########
########## Fuse settings and suitable defaults ##########
##########------------------------------------------------------##########
## Generic
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
## Called with no extra definitions, sets to defaults
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,351 @@
; Zapojeni (Připojen DMC-50399 v 4-bitovem modu):
; +------u------+
; Vcc -> reset --+ /RST Vcc +-- napajeni +5V
; --+ PD0 PB7 +-- RS (0=instr W, BF+addr R; 1=data W/R)
; --+ PD1 PB6 +-- R/W (1=read,0=write)
; --+ PA1 PB5 +-- E (clock, active falling edge)
; --+ PA0 PB4 +--
; --+ PD2 PB3 +-- DATA 7
; --+ PD3 PB2 +-- DATA 6
; --+ PD4 PB1 +-- DATA 5
; --+ PD5 PB0 +-- DATA 4
; GND --+ GND PD6 +--
; +-------------+
;DMC-50399:
; 1 - GND
; 2 - +5V
; 3 - 0V (lcd driver)
; 4 - RS
; 5 - R/W
; 6 - E
; 7 - DATA 0
; 8 - DATA 1
;...
;14 - DATA 7
.device attiny2313
;běží na 4MHz, ckdiv8=1 (vypnuto)
;250x16=1ms=1000us
;LFUSE: 0xE2 -U lfuse:w:0xE2:m
;HFUSE: 0xDF -U hfuse:w:0xDF:m
;K O N S T A N T Y + P R E Z D I V K Y P O R T U A P I N U
.equ LCDPORT = PORTB
.equ LCDPIN = PINB
.equ LCDDDR = DDRB
.equ RS = 7
.equ RW = 6
.equ E = 5
.equ LCD_CLEAR = 0b00000001
.equ LCD_HOME = 0b00000010
.equ LCD_MODE_INC_NOSHIFT = 0b00000110
.equ LCD_MODE_INC_SHIFT = 0b00000111
.equ LCD_MODE_DEC_NOSHIFT = 0b00000100
.equ LCD_MODE_DEC_SHIFT = 0b00000101
.equ LCD_DISPLAY_DISABLED = 0b00001000
.equ LCD_DISPLAY_NOCURSOR = 0b00001100
.equ LCD_DISPLAY_CURSOR = 0b00001110
.equ LCD_DISPLAY_ALTER = 0b00001101
.equ LCD_DISPLAY_CURSOR_ALTER = 0b00001111
.equ LCD_CURSOR_LEFT = 0b00010000
.equ LCD_CURSOR_RIGHT = 0b00010100
.equ LCD_SHIFT_LEFT = 0b00011000
.equ LCD_SHIFT_RIGHT = 0b00011100
;5x7 font, 1-line
.equ LCD_MODE_4BIT_1LINE = 0b00100000
;.equ LCD_MODE_8BIT_1LINE = 0b00110000
;5x7 font, 2-line
.equ LCD_MODE_4BIT_2LINE = 0b00101000
;.equ LCD_MODE_8BIT_2LINE = 0b00111000
.equ ROW1_ADDR = 0x00
.equ ROW2_ADDR = 0x40
.equ ROW3_ADDR = 0x14
.equ ROW4_ADDR = 0x54
;aliases
.def ZH = r31
.def ZL = r30
.def YH = r29
.def YL = r28
.def XH = r27
.def XL = r26
; Z A C A T E K P R O G R A M U
;vektory preruseni
.org 0x0000 ;RESET
rjmp RESET ;skok na start po resetu
.org 0x0013
;nastaveni po resetu
.DB "HD44780 INTERFACE" ;(nazev programu)
RESET:
ldi r16,low(RAMEND) ;nastavi stack pointer
out SPL,r16
cli ;zakazat vsechna preruseni
; Nastaveni portu
;PORTB = LCDPORT
ldi r16,0b11111111 ;smer portu B
out LCDDDR,r16
ldi r16,0b00000000 ;vypnout B
out LCDPORT,r16
sei ;Global Interrupt Enable
; == display init ==
rcall LCD_INIT
ldi r17,LCD_MODE_INC_NOSHIFT
rcall TX_INSTR
ldi r17,LCD_DISPLAY_NOCURSOR
rcall TX_INSTR
; == load user-defined characters to CGRAM == (default, array label named MYCHARS, end-mark=0xFE)
ldi r17,0
rcall CGRAM_SET_ADDR
ldi ZH,high(MYCHARS*2)
ldi ZL,low(MYCHARS*2)
CGRAM_loop:
lpm r17,Z+
cpi r17,0xFE
breq CGRAM_loop_end
rcall TX_DATA
rjmp CGRAM_loop
CGRAM_loop_end:
; == pgm body ==
;load text to DDRAM
ldi r17,ROW1_ADDR
rcall DDRAM_SET_ADDR
ldi ZH,high(MYTEXT1*2)
ldi ZL,low(MYTEXT1*2)
DDRAM_loop:
lpm r17,Z+
cpi r17,0xFE
breq DDRAM_loop_end
rcall TX_DATA
rjmp DDRAM_loop
DDRAM_loop_end:
;load text to DDRAM
ldi r17,ROW2_ADDR
rcall DDRAM_SET_ADDR
ldi ZH,high(MYTEXT2*2)
ldi ZL,low(MYTEXT2*2)
DDRAM2_loop:
lpm r17,Z+
cpi r17,0xFE
breq DDRAM2_loop_end
rcall TX_DATA
rjmp DDRAM2_loop
DDRAM2_loop_end:
;direct write to X,Y - example
ldi r16,3 ;Y, zacina 0 a roste smerem dolu
ldi r17,5 ;X, zacina nulou a roste smerem doprava
rcall LCD_CURSOR_XY
ldi r17,"%"
rcall TX_DATA
ldi r17,"%"
rcall TX_DATA
ldi r17,"%"
rcall TX_DATA
;infinite loop
loop: rjmp loop
MYTEXT1:
.DB 0,0,0," POKUSNY TEXT ",0,0,0,0xFE
MYTEXT2:
.DB "Opravdu pekny text!",0xFE
; == USER-DEFINED CHARS ==
MYCHARS:
; 5x8, first 3 bits are not used
;end of mychars
.DB 0xe,0x1f,0x15,0x1f,0x1f,0x1f,0x15 ;smajlik
;konec
.DB 0xFE
;r16=Y
;r17=X
LCD_CURSOR_XY:
cpi r16,0
brne test1
fail: ldi r16,ROW1_ADDR
rjmp addrdone
test1:
cpi r16,1
brne test2
ldi r16,ROW2_ADDR
rjmp addrdone
test2:
cpi r16,2
brne test3
ldi r16,ROW3_ADDR
rjmp addrdone
test3:
cpi r16,3
brne fail
ldi r16,ROW4_ADDR
addrdone:
add r17,r16
rcall DDRAM_SET_ADDR
ret
;r16=počet ms (cca)
delay:
push r17 ;2
push r18 ;2
d1:
ldi r17,250 ;1
d2:
ldi r18,14 ;1
d3:
dec r18 ;1
nop
brne d3 ;2 (1
dec r17 ; +1)
brne d2 ;2 (1
dec r16 ; +1)
brne d1 ;2 (1)
pop r18 ;2
pop r17 ;2
ret
LCD_INIT:
ldi r16,16
rcall delay
ldi r16,0b00000010 ;4bit
out PORTB,r16
rcall LCD_CLK
ldi r16,5
rcall delay
ldi r17,LCD_MODE_4BIT_2LINE ;set 4-bit mode
rcall TX_INSTR
ret
;r17
TX_INSTR:
swap r17 ;send high nibble
mov r16,r17
andi r16,0b00001111
out LCDPORT,r16
rcall LCD_CLK
swap r17 ;send low nibble
mov r16,r17
andi r16,0b00001111
out LCDPORT,r16
rcall LCD_CLK
ret
;r17
TX_DATA:
swap r17 ;send high nibble
mov r16,r17
andi r16,0b00001111
sbr r16,(1<<RS)
out LCDPORT,r16
rcall LCD_CLK
swap r17 ;send low nibble
mov r16,r17
andi r16,0b00001111
sbr r16,(1<<RS)
out LCDPORT,r16
rcall LCD_CLK
ret
;r17 disabled to reduce code size
;RX_DATA:
; ;input
; ldi r16,0b11110000 ;LCDPORT dirrection (RS RW E n.c.) output, (D7 D6 D5 D4) input
; out LCDDDR,r16
; ldi r16,0b00001111 ;pullups to data pins enabled
; out LCDPORT,r16
;
; clr r17
; ldi r16,(1<<RW)|(1<<RS)
; out LCDPORT,r16 ;set LCD to read mode, for data
;
; rcall LCD_CLK ;receive high nibble
; in r16,LCDPIN
; andi r16,0b00001111
; or r17,r16
; swap r17 ;store high nibble
;
; rcall LCD_CLK ;receive low nibble
; in r16,LCDPIN
; andi r16,0b00001111
; or r17,r16 ;store low nibble
;
; ;output
; ldi r16,0b11111111 ;LCDPORT as output (RS RW E n.c. D7 D6 D5 D4)
; out LCDDDR,r16
; ldi r16,0b00000000 ;LCDPORT off
; out LCDPORT,r16
;
; ;r17=received value (D7 D6 D5 D4 D3 D2 D1 D0)
; ret
LCD_CLK:
sbi LCDPORT,E ;EXECUTE on
nop
nop
nop
cbi LCDPORT,E ;EXECUTE off
ldi r16,150 ;pause: 100 for 4MHZ
clkw:
dec r16
brne clkw
ret
;r17
;7 bitu (1.radek zacina 00,druhej 40)
DDRAM_SET_ADDR:
clr r16
sbr r16,0b10000000
or r17,r16
rcall TX_INSTR
ret
;r17
;6 bitu (5,4,3 = znak, 2,1,0 = radek - shora)
CGRAM_SET_ADDR:
clr r16
sbr r16,0b01000000
or r17,r16
rcall TX_INSTR
ret

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,426 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "lib/meta.h"
#include "lib/arduino_pins.h"
#include "lib/calc.h"
#include "lib/adc.h"
#define LCD_PIN_RS D10
#define LCD_PIN_RW D11
#define LCD_PIN_E D12
#define LCD_PIN_D4 D13
#define LCD_PIN_D5 D14
#define LCD_PIN_D6 D15
#define LCD_PIN_D7 D16
// D17 = A3 = source of entropy for random.
#include "lib/lcd.h"
// Buttons (to ground)
#define BTN_LEFT D2
#define BTN_RIGHT D3
#define BTN_UP D4
#define BTN_DOWN D5
#define BTN_SELECT D6
#define BTN_RESTART D7
// Debouncer channels for buttons
// (Must be added in this order to debouncer)
#define D_LEFT 0
#define D_RIGHT 1
#define D_UP 2
#define D_DOWN 3
#define D_SELECT 4
#define D_RESTART 5
#define DEBO_CHANNELS 6
#define DEBO_TICKS 1 // in 0.01s
#include "lib/debounce.h"
// Board size (!!! rows = 2x number of display lines, max 2*4 = 8 !!!)
#define ROWS 4
#define COLS 20
// Delay between snake steps, in 10 ms
#define STEP_DELAY 24
// proto
void update();
void init_cgram();
void init_gameboard();
void SECTION(".init8") init()
{
// Randomize RNG
adc_init();
srand(adc_read_word(3));
// Init LCD
lcd_init();
init_cgram(); // load default glyphs
// Init game board.
init_gameboard();
// gamepad buttons
as_input_pu(BTN_LEFT);
as_input_pu(BTN_RIGHT);
as_input_pu(BTN_UP);
as_input_pu(BTN_DOWN);
as_input_pu(BTN_SELECT);
as_input_pu(BTN_RESTART);
// add buttons to debouncer
debo_add_rev(BTN_LEFT);
debo_add_rev(BTN_RIGHT);
debo_add_rev(BTN_UP);
debo_add_rev(BTN_DOWN);
debo_add_rev(BTN_SELECT);
debo_add_rev(BTN_RESTART);
// setup timer
TCCR0A = _BV(WGM01); // CTC
TCCR0B = _BV(CS02) | _BV(CS00); // prescaler 1024
OCR0A = 156; // interrupt every 10 ms
sbi(TIMSK0, OCIE0A);
sei();
}
/** timer 0 interrupt vector */
ISR(TIMER0_COMPA_vect)
{
debo_tick(); // poll debouncer
update(); // update and display
}
// sub-glyphs
#define _HEAD_ 15, 21, 21, 30
#define _BODY_ 15, 31, 31, 30
#define _FOOD_ 10, 21, 17, 14
//14, 17, 17, 14
#define _NONE_ 0, 0, 0, 0
// complete glyphs for loading into memory
// Only one food & one head glyph have to be loaded at a time.
// Body - Body
const uint8_t SYMBOL_BB[] PROGMEM = {_BODY_, _BODY_};
// Body - None
const uint8_t SYMBOL_BX[] PROGMEM = {_BODY_, _NONE_};
const uint8_t SYMBOL_XB[] PROGMEM = {_NONE_, _BODY_};
// Head - None
const uint8_t SYMBOL_HX[] PROGMEM = {_HEAD_, _NONE_};
const uint8_t SYMBOL_XH[] PROGMEM = {_NONE_, _HEAD_};
// Body - Head
const uint8_t SYMBOL_BH[] PROGMEM = {_BODY_, _HEAD_};
const uint8_t SYMBOL_HB[] PROGMEM = {_HEAD_, _BODY_};
// Head - Food
const uint8_t SYMBOL_HF[] PROGMEM = {_HEAD_, _FOOD_};
const uint8_t SYMBOL_FH[] PROGMEM = {_FOOD_, _HEAD_};
// Food - None
const uint8_t SYMBOL_FX[] PROGMEM = {_FOOD_, _NONE_};
const uint8_t SYMBOL_XF[] PROGMEM = {_NONE_, _FOOD_};
// Body - Food
const uint8_t SYMBOL_BF[] PROGMEM = {_BODY_, _FOOD_};
const uint8_t SYMBOL_FB[] PROGMEM = {_FOOD_, _BODY_};
// board block (snake, food...)
typedef enum {
bEMPTY = 0x00,
bHEAD = 0x01,
bFOOD = 0x02,
bBODY_LEFT = 0x80,
bBODY_RIGHT = 0x81,
bBODY_UP = 0x82,
bBODY_DOWN = 0x83,
} block_t;
// Snake direction
typedef enum {
dLEFT = 0x00,
dRIGHT = 0x01,
dUP = 0x02,
dDOWN = 0x03,
} dir_t;
// Coordinate on board
typedef struct {
int8_t x;
int8_t y;
} coord_t;
#define is_body(blk) (((blk) & 0x80) != 0)
#define mk_body_dir(dir) (0x80 + (dir))
// compare two coords
#define coord_eq(a, b) (((a).x == (b).x) && ((a).y == (b).y))
bool crashed;
uint8_t snake_len;
// y, x indexing
block_t board[ROWS][COLS];
coord_t head_pos;
coord_t tail_pos;
dir_t head_dir;
const uint8_t CODE_BB = 0;
const uint8_t CODE_BX = 1;
const uint8_t CODE_XB = 2;
const uint8_t CODE_H = 3; // glyph with head, dynamic
const uint8_t CODE_F = 4; // glyph with food, dynamic
const uint8_t CODE_XX = 32; // space
// Set a block in board
#define set_block_xy(x, y, block) do { board[y][x] = (block); } while(0)
#define get_block_xy(x, y) board[y][x]
#define get_block(pos) get_block_xy((pos).x, (pos).y)
#define set_block(pos, block) set_block_xy((pos).x, (pos).y, (block))
void init_cgram()
{
// those will be always the same
lcd_define_glyph_pgm(CODE_BB, SYMBOL_BB);
lcd_define_glyph_pgm(CODE_BX, SYMBOL_BX);
lcd_define_glyph_pgm(CODE_XB, SYMBOL_XB);
lcd_define_glyph_pgm(5, SYMBOL_XF);
}
void place_food()
{
while(1) {
const uint8_t xx = rand() % COLS;
const uint8_t yy = rand() % ROWS;
if (get_block_xy(xx, yy) == bEMPTY) {
set_block_xy(xx, yy, bFOOD);
break;
}
}
}
void init_gameboard()
{
//erase the board
for (uint8_t x = 0; x < COLS; x++) {
for (uint8_t y = 0; y < ROWS; y++) {
set_block_xy(x, y, bEMPTY);
}
}
lcd_clear();
tail_pos = (coord_t) {.x = 0, .y = 0};
set_block_xy(0, 0, bBODY_RIGHT);
set_block_xy(1, 0, bBODY_RIGHT);
set_block_xy(2, 0, bBODY_RIGHT);
set_block_xy(3, 0, bHEAD);
head_pos = (coord_t) {.x = 3, .y = 0};
snake_len = 4; // includes head
head_dir = dRIGHT;
crashed = false;
place_food();
}
uint8_t presc = 0;
bool restart_held;
void update()
{
if (debo_get_pin(D_RESTART)) {
if (!restart_held) {
// restart
init_gameboard();
presc = 0;
restart_held = true;
}
} else {
restart_held = false;
}
if(!crashed) {
// resolve movement direction
if (debo_get_pin(D_LEFT))
head_dir = dLEFT;
else if (debo_get_pin(D_RIGHT))
head_dir = dRIGHT;
else if (debo_get_pin(D_UP))
head_dir = dUP;
else if (debo_get_pin(D_DOWN))
head_dir = dDOWN;
// time's up for a move
if (presc++ == STEP_DELAY) {
presc = 0;
// move snake
const coord_t oldpos = head_pos;
switch (head_dir) {
case dLEFT: head_pos.x--; break;
case dRIGHT: head_pos.x++; break;
case dUP: head_pos.y--; break;
case dDOWN: head_pos.y++; break;
}
bool do_move = false;
bool do_grow = false;
if (head_pos.x < 0 || head_pos.x >= COLS || head_pos.y < 0 || head_pos.y >= ROWS) {
// ouch, a wall!
crashed = true;
} else {
// check if tile occupied or not
if (coord_eq(head_pos, tail_pos)) {
// head moved in previous tail, that's OK.
do_move = true;
} else {
// moved to other tile than tail
switch (get_block(head_pos)) {
case bFOOD:
do_grow = true; // fall through
case bEMPTY:
do_move = true;
break;
default: // includes all BODY_xxx
crashed = true; // snake crashed into some block
}
}
}
if (do_move) {
// Move tail
if (do_grow) {
// let tail as is
snake_len++; // grow the counter
} else {
// tail dir
dir_t td = get_block(tail_pos) & 0xF;
// clean tail
set_block(tail_pos, bEMPTY);
// move tail based on old direction of tail block
switch (td) {
case dLEFT: tail_pos.x--; break;
case dRIGHT: tail_pos.x++; break;
case dUP: tail_pos.y--; break;
case dDOWN: tail_pos.y++; break;
}
}
// Move head
set_block(head_pos, bHEAD); // place head in new pos
set_block(oldpos, mk_body_dir(head_dir)); // directional body in old head pos
if (do_grow) {
// food eaten, place new
place_food();
}
}
}
} // end !crashed
// Render the board
for (uint8_t r = 0; r < ROWS / 2; r++) {
lcd_xy(0, r);
for (uint8_t c = 0; c < COLS; c++) {
const block_t t1 = get_block_xy(c, r * 2);
const block_t t2 = get_block_xy(c, (r * 2) + 1);
uint8_t code = '!'; // ! marks fail
if ((t1 == bEMPTY) && (t2 == bEMPTY)) {
code = CODE_XX;
if (crashed) code = '*';
} else if (is_body(t1) && is_body(t2))
code = CODE_BB;
else if (is_body(t1) && (t2 == bEMPTY))
code = CODE_BX;
else if (t1 == bEMPTY && is_body(t2))
code = CODE_XB;
else if ((t1 == bFOOD) || (t2 == bFOOD)) {
// one is food
code = CODE_F;
if (t1 == bFOOD) {
if (t2 == bEMPTY)
lcd_define_glyph_pgm(code, SYMBOL_FX);
else if (t2 == bHEAD)
lcd_define_glyph_pgm(code, SYMBOL_FH);
else if (is_body(t2))
lcd_define_glyph_pgm(code, SYMBOL_FB);
} else { // t2 is food
if (t1 == bEMPTY)
lcd_define_glyph_pgm(code, SYMBOL_XF);
else if (t1 == bHEAD)
lcd_define_glyph_pgm(code, SYMBOL_HF);
else if (is_body(t1))
lcd_define_glyph_pgm(code, SYMBOL_BF);
}
lcd_xy(c,r);
} else if ((t1 == bHEAD )|| (t2 == bHEAD)) {
// one is head
code = CODE_H;
if (t1 == bHEAD) {
if (t2 == bEMPTY)
lcd_define_glyph_pgm(code, SYMBOL_HX);
else if (is_body(t2))
lcd_define_glyph_pgm(code, SYMBOL_HB);
} else { // t2 is head
if (t1 == bEMPTY)
lcd_define_glyph_pgm(code, SYMBOL_XH);
else if (is_body(t1))
lcd_define_glyph_pgm(code, SYMBOL_BH);
}
lcd_xy(c,r);
}
lcd_char(code);
}
}
}
void main() { while(1); } // timer does everything

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c iopins.c color.c wsrgb.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash ser
ser:
gtkterm -p /dev/ttyUSB0
cl:
./client /dev/ttyUSB0 9600
fcl: all flash
./client /dev/ttyUSB0 9600
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

Binary file not shown.

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,32 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "lib/iopins.h"
#include "lib/wsrgb.h"
#include "lib/uart.h"
void main()
{
ws_init();
xrgb_t c[3];
c[0] = xrgb(255, 0, 255);
c[1] = xrgb(0, 255, 255);
c[2] = xrgb(255, 255, 0);
while(1) {
ws_send_xrgb_array(c, 3);
ws_show();
c[0].r++;
c[1].b++;
c[2].g++;
_delay_ms(10);
}
}

@ -0,0 +1,7 @@
#define WS_T_1H 700
#define WS_T_1L 150
#define WS_T_0H 150
#define WS_T_0L 700
#define WS_T_LATCH 7000
#define WS_PIN 2

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c uart_ansi.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash serial
ser:
gtkterm -p /dev/ttyUSB0
cl:
./client /dev/ttyUSB0 9600
fcl: all flash
./client /dev/ttyUSB0 9600
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

Binary file not shown.

@ -0,0 +1,7 @@
all: client
client: main.c
gcc -std=gnu99 main.c serial.c -o client
run: client
./client /dev/ttyUSB0 9600

Binary file not shown.

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include "serial.h"
int main(int argc, char const *argv[])
{
if (argc < 2) { fprintf(stderr, "Missing parameter <device>\n"); return 1; }
int baud = 9600;
if (argc == 3) sscanf(argv[2], "%d", &baud);
int fd = serial_open(argv[1], baud);
// Wait for the Arduino to start
usleep(1500000);
// Redirecting stdin/stdout to arduino
while(1) {
char buf[1];
if (fread(buf, 1, 1, stdin) > 0) {
serial_write(fd, buf[0]);
fflush(stdout);
}
char c;
c = serial_read(fd, 10);
if (c > 0) {
putchar(c);
fflush(stdout);
}
}
}

@ -0,0 +1,89 @@
#define _POSIX_SOURCE
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "serial.h"
/** Open a serial port */
int serial_open(const char* port, const unsigned int baud)
{
int fd = open(port, O_RDWR | O_NONBLOCK);
struct termios tio;
memset(&tio, 0, sizeof(tio));
speed_t bd = baud;
switch(bd) {
case 1200: bd = B1200; break;
case 1800: bd = B1800; break;
case 2400: bd = B2400; break;
case 4800: bd = B4800; break;
case 9600: bd = B9600; break;
case 19200: bd = B19200; break;
case 38400: bd = B38400; break;
}
tio.c_cflag = bd | CS8 | CLOCAL | CREAD | CRTSCTS;
tio.c_iflag = IGNPAR;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &tio);
return fd;
}
/** Close a serial port */
int serial_close(int fd)
{
return close(fd);
}
/** Write a byte. Returns false on failure */
int serial_write(int fd, uint8_t b)
{
return write(fd, &b, 1);
}
int serial_puts(int fd, const char* str)
{
int len = strlen(str);
return write(fd, str, len);
}
uint8_t serial_read(int fd, int timeout)
{
uint8_t b[1];
do {
int n = read(fd, b, 1);
if (n == -1) return -1;
if (n == 0) {
usleep(1 * 1000); // wait 1 ms
timeout--;
continue;
}
return b[0];
} while(timeout > 0);
return -1;
}
int serial_flush(int fd)
{
sleep(2);
return tcflush(fd, TCIOFLUSH);
}

@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
/** Open a serial port */
int serial_open(const char* port, const unsigned int baud);
/** Close a serial port */
int serial_close(int fd);
/** Write a byte. Returns false on failure */
int serial_write(int fd, uint8_t b);
/** Send a string */
int serial_puts(int fd, const char* str);
/** Read a byte */
uint8_t serial_read(int fd, int timeout);
/** Flush */
int serial_flush(int fd);

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,25 @@
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "lib/uart.h"
ISR(USART_RX_vect)
{
uint8_t x = uart_rx();
uart_tx(x);
}
void main()
{
uart_init(9600);
uart_isr_rx(1);
sei();
while(1) {
//uart_puts_P(PSTR("TEST"));
}
}

@ -0,0 +1,25 @@
Es [ ?
left 27 91 68
right 27 91 67
up 27 91 65
down 27 91 66
Es [ ? ~
insert 27 91 50 126
delete 27 91 51 126
pgup 27 91 53 126
pgdn 27 91 54 126
Es O ?
f1 27 79 80
f2 27 79 81
f3 27 79 82
f4 27 79 83
home 27 79 72
end 27 79 70
back 8
tab 9
enter 13
esc 27

@ -0,0 +1,137 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE =
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES = uart.c uart_ansi.c sonar.c
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

@ -0,0 +1,13 @@
#pragma once
// Pin config file for LCD.
#include "lib/arduino_pins.h"
#define LCD_RS D2
#define LCD_RW D3
#define LCD_E D4
#define LCD_D4 D5
#define LCD_D5 D6
#define LCD_D6 D7
#define LCD_D7 D8

@ -0,0 +1 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,91 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "lib/calc.h"
#include "lib/uart.h"
#include "lib/uart_ansi.h"
#include "lib/pins.h"
#include "lib/arduino_pins.h"
#include "lib/sonar.h"
ISR(PCINT0_vect)
{
if (sonar_handle_pci()) return;
}
// All PCINT vectors must call sonar_handle_pci
// This way, they are linked to PCINT0
// so we can avoid code duplication
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
// Timer overflow - if sonar has a timeout -> 0xFFFF in result.
ISR(TIMER1_OVF_vect)
{
if (sonar_handle_t1ovf()) return;
}
void main()
{
uart_init(9600);
vt_init();
sonar_t so;
sonar_t so2;
sonar_init(&so, A0, A1);
sonar_init(&so2, A2, A3);
sei();
// end
int16_t res;
while(1) {
vt_clear();
vt_home();
uart_puts_pgm(PSTR("SONAR\r\n==================="));
// first
vt_goto(99, 99); // move cursor away
sonar_start(&so);
while(sonar_busy());
res = sonar_result();
// print value
vt_goto(0, 2);
uart_puts_pgm(PSTR("A: "));
if (res < 0) {
uart_puts_pgm(PSTR("No Obstacle"));
} else {
uart_puti(res, 1);
uart_puts_pgm(PSTR(" cm"));
}
// second
vt_goto(99, 99); // move cursor away
sonar_start(&so2);
while(sonar_busy());
res = sonar_result();
// print value
vt_goto(0, 3);
uart_puts_pgm(PSTR("B: "));
if (res < 0) {
uart_puts_pgm(PSTR("No Obstacle"));
} else {
uart_puti(res, 1);
uart_puts_pgm(PSTR(" cm"));
}
vt_goto(99, 99); // move cursor away
_delay_ms(200);
}
}

@ -0,0 +1,147 @@
## === CPU settings ===
# CPU type
MCU = atmega328p
# CPU frequency
F_CPU = 16000000
# Fuses
LFUSE = 0xFF
HFUSE = 0xDE
EFUSE = 0x05
## === Source files ===
# Main C file
MAIN = main.c
# Extra C files in this folder
LOCAL_SOURCE = fat16.c
# Library directory (with C files)
EXTRA_SOURCE_DIR = lib/
# C files in the library directory
EXTRA_SOURCE_FILES =
## === Programmer ===
PROGRAMMER_TYPE = arduino
PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
## === C flags ===
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
CFLAGS_BUILD = $(CFLAGS) -Os
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
## === File lists ===
TARGET = $(strip $(basename $(MAIN)))
SRC1 = $(TARGET).c
SRC = $(SRC1)
EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
SRC += $(EXTRA_SOURCE)
SRC += $(LOCAL_SOURCE)
HEADERS = $(SRC:.c=.h)
OBJ = $(SRC:.c=.o)
## === File generation ===
all: $(TARGET).hex size
pre: $(TARGET).pre
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.elf: $(SRC)
$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
%.pre: $(SRC1)
$(CC) $(CFLAGS) -E $(SRC1) --output $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
%.lst: %.elf
$(OBJDUMP) -S $< > $@
# Show debug info
debug:
@echo
@echo "Source files:" $(SRC)
@echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD)
@echo
# Disassemble the ELF
disassemble: $(TARGET).lst
dis: disassemble
lst: disassemble
# Make eeprom file
eeprom: $(TARGET).eeprom
# Show how big the resulting program is
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
# Clean all produced trash
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
# Clean all trash
purge:
rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
## === avrdude ===
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
fser: all flash serial
ser:
gtkterm -p /dev/ttyUSB0
cl:
./client /dev/ttyUSB0 9600
fcl: all flash
./client /dev/ttyUSB0 9600
# === fuses ===
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
$(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses: fuses

Binary file not shown.

@ -0,0 +1,7 @@
all: client
client: main.c
gcc -std=gnu99 main.c serial.c -o client
run: client
./client /dev/ttyUSB0 9600

Binary file not shown.

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include "serial.h"
int main(int argc, char const *argv[])
{
if (argc < 2) { fprintf(stderr, "Missing parameter <device>\n"); return 1; }
int baud = 9600;
if (argc == 3) sscanf(argv[2], "%d", &baud);
int fd = serial_open(argv[1], baud);
// Wait for the Arduino to start
usleep(1500000);
// Redirecting stdin/stdout to arduino
while(1) {
char buf[1];
if (fread(buf, 1, 1, stdin) > 0) {
serial_write(fd, buf[0]);
fflush(stdout);
}
char c;
c = serial_read(fd, 10);
if (c > 0) {
putchar(c);
fflush(stdout);
}
}
}

@ -0,0 +1,89 @@
#define _POSIX_SOURCE
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "serial.h"
/** Open a serial port */
int serial_open(const char* port, const unsigned int baud)
{
int fd = open(port, O_RDWR | O_NONBLOCK);
struct termios tio;
memset(&tio, 0, sizeof(tio));
speed_t bd = baud;
switch(bd) {
case 1200: bd = B1200; break;
case 1800: bd = B1800; break;
case 2400: bd = B2400; break;
case 4800: bd = B4800; break;
case 9600: bd = B9600; break;
case 19200: bd = B19200; break;
case 38400: bd = B38400; break;
}
tio.c_cflag = bd | CS8 | CLOCAL | CREAD | CRTSCTS;
tio.c_iflag = IGNPAR;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &tio);
return fd;
}
/** Close a serial port */
int serial_close(int fd)
{
return close(fd);
}
/** Write a byte. Returns false on failure */
int serial_write(int fd, uint8_t b)
{
return write(fd, &b, 1);
}
int serial_puts(int fd, const char* str)
{
int len = strlen(str);
return write(fd, str, len);
}
uint8_t serial_read(int fd, int timeout)
{
uint8_t b[1];
do {
int n = read(fd, b, 1);
if (n == -1) return -1;
if (n == 0) {
usleep(1 * 1000); // wait 1 ms
timeout--;
continue;
}
return b[0];
} while(timeout > 0);
return -1;
}
int serial_flush(int fd)
{
sleep(2);
return tcflush(fd, TCIOFLUSH);
}

@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
/** Open a serial port */
int serial_open(const char* port, const unsigned int baud);
/** Close a serial port */
int serial_close(int fd);
/** Write a byte. Returns false on failure */
int serial_write(int fd, uint8_t b);
/** Send a string */
int serial_puts(int fd, const char* str);
/** Read a byte */
uint8_t serial_read(int fd, int timeout);
/** Flush */
int serial_flush(int fd);

File diff suppressed because it is too large Load Diff

@ -0,0 +1,260 @@
#pragma once
/** Abstract block device interface */
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 don't matter) */
typedef enum
{
FT_NONE = '-',
FT_DELETED = 'x',
FT_SUBDIR = 'D',
FT_PARENT = 'P',
FT_LABEL = 'L',
FT_LFN = '~',
FT_INVALID = 'i', // not recognized weird file
FT_SELF = '.',
FT_FILE = 'F'
} FAT16_FT;
// File Attributes (bit flags)
#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
/** Boot Sector structure - INTERNAL! */
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 - private fields! */
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 handle struct */
typedef struct __attribute__((packed))
{
// Fields loaded directly from disk:
uint8_t name[11]; // Starting 0x05 converted to 0xE5, other "magic chars" left intact
uint8_t attribs; // composed of FA_* constants
// 14 bytes skipped
uint16_t clu_start;
uint32_t size;
// Added fields:
FAT16_FT type;
// --- Private fields ---
// Cursor
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
uint16_t clu; // first cluster of directory
uint16_t num; // fiel entry number
// pointer to FAT
const FAT16* fat;
}
FAT16_FILE;
/** Initialize a filesystem */
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.
*
* Either way, the prev and next functions will work as expected.
*/
void fat16_root(const FAT16* fat, FAT16_FILE* file);
/**
* Resolve the disk label.
*/
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_fseek(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_fread(FAT16_FILE* file, void* target, uint32_t len);
/**
* Write into file at a "seek" position.
* "seek" cursor must be within (0..filesize)
*/
bool fat16_fwrite(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);
/**
* Write new file size (also to the disk).
* Allocates / frees needed clusters, does not erase them.
*/
void fat16_resize(FAT16_FILE* file, uint32_t size);
/**
* Delete a file entry and free clusters.
* Does NOT work on folders.
*/
bool fat16_rmfile(FAT16_FILE* file);
/**
* Delete an empty directory.
* Calling with non-subfolder entry or non-empty directory will cause error.
*/
bool fat16_rmdir(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 first entry of the directory.
*/
bool fat16_opendir(FAT16_FILE* file);
/**
* Open a parent directory. Fails in root.
*/
bool fat16_parent(FAT16_FILE* file);
/** Rewind to first file in 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.
* Either way, "dir" gets modified and you may need to rewind it afterwards.
*/
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_file_valid(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 @@
/home/ondra/git/avr-lib/lib

@ -0,0 +1,103 @@
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "fat16.h"
BLOCKDEV test;
void test_seek(const uint32_t pos)
{
asm volatile ("");
}
void test_rseek(const int16_t pos)
{
asm volatile ("");
}
void test_load(void* dest, const uint16_t len)
{
asm volatile ("");
}
void test_store(const void* source, const uint16_t len)
{
asm volatile ("");
}
void test_write(const uint8_t b)
{
asm volatile ("");
}
uint8_t test_read()
{
return 0;
}
void test_open()
{
test.read = &test_read;
test.write = &test_write;
test.load = &test_load;
test.store = &test_store;
test.seek = &test_seek;
test.rseek = &test_rseek;
}
void main()
{
test_open();
// Initialize the FS
FAT16 fat;
fat16_init(&test, &fat);
FAT16_FILE file;
fat16_root(&fat, &file);
char str[10];
fat16_disk_label(&fat, str);
// ----------- FILE I/O -------------
/**
* Move file cursor to a position relative to file start
* Returns false on I/O error (bad file, out of range...)
*/
fat16_fseek(&file, 1234);
/**
* Read bytes from file into memory
* Returns false on I/O error (bad file, out of range...)
*/
fat16_fread(&file, str, 10);
/**
* Write into file at a "seek" position.
* "seek" cursor must be within (0..filesize)
*/
fat16_fwrite(&file, str, 10);
/** Go to next file in directory (false = no next file) */
fat16_next(&file);
while(1) {
//uart_puts_P(PSTR("TEST"));
}
}
Loading…
Cancel
Save