add firmware folder
This commit is contained in:
10
firmware/slider/CMakeLists.txt
Normal file
10
firmware/slider/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
set(AVR_MCU attiny84)
|
||||
include(avr-toolchain.cmake)
|
||||
|
||||
project(slider_firmware C)
|
||||
|
||||
add_subdirectory(../../libs/common ${CMAKE_CURRENT_BINARY_DIR}/libs EXCLUDE_FROM_ALL)
|
||||
add_avr_executable(slider_firmware main.c)
|
||||
target_link_libraries(slider_firmware DSPLAB_common)
|
||||
85
firmware/slider/avr-toolchain.cmake
Normal file
85
firmware/slider/avr-toolchain.cmake
Normal file
@@ -0,0 +1,85 @@
|
||||
# give info about target
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
SET(CMAKE_SYSTEM_PROCESSOR avr)
|
||||
|
||||
# find tools
|
||||
find_program(AVR_CC avr-gcc)
|
||||
find_program(AVR_CXX avr-g++)
|
||||
find_program(AVR_OBJCOPY avr-objcopy)
|
||||
find_program(AVR_SIZE_TOOL avr-size)
|
||||
|
||||
# set compiler (globally)
|
||||
SET(CMAKE_C_COMPILER ${AVR_CC})
|
||||
SET(CMAKE_CXX_COMPILER ${AVR_CXX})
|
||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
|
||||
|
||||
add_definitions(-mmcu=${AVR_MCU} -DF_CPU=8000000 --std=c99)
|
||||
|
||||
function(add_avr_executable EXECUTABLE_NAME)
|
||||
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}.")
|
||||
endif(NOT ARGN)
|
||||
|
||||
# set file names
|
||||
set(elf_file ${EXECUTABLE_NAME})
|
||||
set(hex_file ${EXECUTABLE_NAME}.hex)
|
||||
set(lst_file ${EXECUTABLE_NAME}.lst)
|
||||
set(map_file ${EXECUTABLE_NAME}.map)
|
||||
set(eeprom_image ${EXECUTABLE_NAME}_eeprom.hex)
|
||||
|
||||
# elf file
|
||||
add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN})
|
||||
|
||||
set_target_properties(
|
||||
${elf_file}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-mmcu=${AVR_MCU}"
|
||||
LINK_FLAGS "-mmcu=${AVR_MCU} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${hex_file}
|
||||
COMMAND
|
||||
${AVR_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file}
|
||||
COMMAND
|
||||
${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${lst_file}
|
||||
COMMAND
|
||||
${AVR_OBJDUMP} -d ${elf_file} > ${lst_file}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
# eeprom
|
||||
add_custom_command(
|
||||
OUTPUT ${eeprom_image}
|
||||
COMMAND
|
||||
${AVR_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load
|
||||
--change-section-lma .eeprom=0 --no-change-warnings
|
||||
-O ihex ${elf_file} ${eeprom_image}
|
||||
DEPENDS ${elf_file}
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
build_${EXECUTABLE_NAME}
|
||||
ALL
|
||||
DEPENDS ${hex_file} ${lst_file} ${eeprom_image}
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
build_${EXECUTABLE_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${elf_file}"
|
||||
)
|
||||
|
||||
# clean
|
||||
get_directory_property(clean_files ADDITIONAL_MAKE_CLEAN_FILES)
|
||||
set_directory_properties(
|
||||
PROPERTIES
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${map_file}"
|
||||
)
|
||||
endfunction(add_avr_executable)
|
||||
50482
firmware/slider/doc8183.pdf
Normal file
50482
firmware/slider/doc8183.pdf
Normal file
File diff suppressed because one or more lines are too long
154
firmware/slider/main.c
Normal file
154
firmware/slider/main.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
/* adc driver */
|
||||
void adc_init() {
|
||||
ADMUX = 0; // set channel, set reference to vdd
|
||||
ADCSRA = (1<<ADEN) | // enable adc
|
||||
(1<<ADIE); // enable adc interrupt
|
||||
}
|
||||
void adc_start() {}
|
||||
|
||||
enum {
|
||||
ADC_CHANNEL_1,
|
||||
ADC_CHANNEL_2,
|
||||
ADC_CHANNEL_3,
|
||||
ADC_CHANNEL_4,
|
||||
ADC_CHANNEL_5,
|
||||
ADC_CHANNEL_6,
|
||||
ADC_CHANNEL_7,
|
||||
ADC_CHANNEL_COUNT
|
||||
};
|
||||
|
||||
uint16_t adc_samples[ADC_CHANNEL_COUNT];
|
||||
uint8_t adc_current_sample;
|
||||
|
||||
ISR(ADC_vect) {
|
||||
uint16_t sample;
|
||||
adc_samples[adc_current_sample] = sample;
|
||||
|
||||
adc_current_sample = (adc_current_sample+1)/ADC_CHANNEL_COUNT;
|
||||
}
|
||||
|
||||
|
||||
/* led driver */
|
||||
#define LED_DDR DDRA
|
||||
#define LED_REG PORTA
|
||||
#define LED_PIN 1
|
||||
|
||||
static inline void led_toggle() {
|
||||
LED_REG ^= (1<<LED_PIN);
|
||||
}
|
||||
|
||||
static inline void led_off() {
|
||||
LED_REG &= ~(1<<LED_PIN);
|
||||
}
|
||||
|
||||
static inline void led_on() {
|
||||
LED_REG |= (1<<LED_PIN);
|
||||
}
|
||||
|
||||
void led_init() {
|
||||
LED_DDR |= (1<<LED_PIN);
|
||||
led_off();
|
||||
}
|
||||
|
||||
/* button driver */
|
||||
// TODO: make interrupt driven
|
||||
#define BUTTON_DDR DDRA
|
||||
#define BUTTON_REG PINA
|
||||
#define BUTTON_PIN 1
|
||||
|
||||
enum {
|
||||
BUTTON_RELEASED,
|
||||
BUTTON_PRESSED
|
||||
} button_state;
|
||||
|
||||
void button_init() {
|
||||
led_init();
|
||||
|
||||
BUTTON_DDR &= ~(1<<BUTTON_PIN);
|
||||
}
|
||||
|
||||
int button_set_state(int state) {
|
||||
if (state == BUTTON_PRESSED)
|
||||
led_on();
|
||||
else
|
||||
led_off();
|
||||
|
||||
button_state = state;
|
||||
return state;
|
||||
}
|
||||
|
||||
int button_is_pressed() {
|
||||
return BUTTON_REG&(1<<BUTTON_PIN);
|
||||
}
|
||||
|
||||
/* Communication driver */
|
||||
#define SLAVE_ENABLE_DDR DDRA
|
||||
#define SLAVE_ENABLE_REG PINA
|
||||
#define SLAVE_ENABLE_PIN 1
|
||||
|
||||
#include <common/interface.h>
|
||||
|
||||
void comm_write(iface_t * iface, byte_t byte) {
|
||||
// disable interrupt
|
||||
uint8_t temp = USICR;
|
||||
USICR &= ~(1<<USIOIE);
|
||||
|
||||
// write data register
|
||||
USIDR = byte;
|
||||
|
||||
// wait for buffer overflow
|
||||
while(!(USICR&(1<<USIOIE))) {}
|
||||
|
||||
// restore control register
|
||||
USICR = temp;
|
||||
}
|
||||
|
||||
iface_t comm_iface;
|
||||
|
||||
void comm_init() {
|
||||
// TODO: setup pins
|
||||
// TODO: setup USART in synchronous mode
|
||||
USICR = (1<<USIWM0)|(1<<USICS1);
|
||||
|
||||
comm_iface.write = comm_write;
|
||||
}
|
||||
|
||||
void comm_start() {
|
||||
// TODO: activate USART
|
||||
USICR |= (1<<USIOIE);
|
||||
}
|
||||
|
||||
ISR(USI_OVF_vect) {
|
||||
byte_t byte = USIBR;
|
||||
|
||||
// only operate when enabled
|
||||
if (SLAVE_ENABLE_REG & (1<<SLAVE_ENABLE_PIN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (comm_iface.on_read) {
|
||||
comm_iface.on_read(&comm_iface, byte, comm_iface.callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* main application code */
|
||||
void init() {
|
||||
adc_init();
|
||||
button_init();
|
||||
comm_init();
|
||||
|
||||
adc_start();
|
||||
comm_start();
|
||||
|
||||
// activate interrupts
|
||||
sei();
|
||||
}
|
||||
|
||||
int main() {
|
||||
init();
|
||||
|
||||
while(1) {}
|
||||
}
|
||||
Reference in New Issue
Block a user