From 552e3f309bd99e9b6ecd77566c95c5b545e9319a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Thu, 8 Jun 2017 01:06:41 +0200 Subject: [PATCH] work on the display, brightness adjust, ... --- CMakeLists.txt | 4 ++- Makefile | 1 + lib/adc.c | 49 +++++++++++++++++++++++++++++++++++ lib/adc.h | 32 +++++++++++++++++++++++ main.c | 70 ++++++++++++++++++++++++++++++++++++++++---------- pinout.h | 36 ++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 lib/adc.c create mode 100644 lib/adc.h create mode 100644 pinout.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac65ee..2e909fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,12 +10,14 @@ set(SOURCE_FILES lib/calc.h lib/iopins.c lib/iopins.h + lib/adc.c + lib/adc.h lib/nsdelay.h lib/spi.c lib/spi.h lib/usart.c lib/usart.h - ) + pinout.h) include_directories(lib /usr/avr/include/) diff --git a/Makefile b/Makefile index 72cc337..b79c0ff 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ OBJS = $(BINARY).o OBJS += lib/usart.o OBJS += lib/iopins.o OBJS += lib/spi.o +OBJS += lib/adc.o # Dirs with header files INCL_DIRS = . lib/ diff --git a/lib/adc.c b/lib/adc.c new file mode 100644 index 0000000..d2b1da7 --- /dev/null +++ b/lib/adc.c @@ -0,0 +1,49 @@ +#include +#include + +#include "calc.h" +#include "adc.h" + +/** Initialize the ADC */ +void adc_init(enum ADC_Prescaller presc) +{ + ADCSRA |= presc; // 128 prescaler -> 125 kHz + ADMUX |= _BV(REFS0); // Voltage reference + sbi(ADCSRA, ADEN); // Enable ADC +} + +/** Disable ADC */ +void adc_disable(void) +{ + cbi(ADCSRA, ADEN); +} + +/** Enable ADC */ +void adc_enable(void) +{ + sbi(ADCSRA, ADEN); +} + +static void adc_convert(uint8_t channel) +{ + set_low_nibble(ADMUX, channel); // Select channel to sample + sbi(ADMUX, ADLAR); // Align result to left + sbi(ADCSRA, ADSC); // Start conversion + + while (bit_is_high(ADCSRA, ADSC)); // Wait for it... +} + +/** Sample analog pin with 8-bit precision */ +uint8_t adc_read_byte(uint8_t channel) +{ + adc_convert(channel); + return ADCH; // The upper 8 bits of ADC result +} + + +/** Sample analog pin with 10-bit precision */ +uint16_t adc_read_word(uint8_t channel) +{ + adc_convert(channel); + return ADCW; // The whole ADC word (10 bits) +} diff --git a/lib/adc.h b/lib/adc.h new file mode 100644 index 0000000..f879b8a --- /dev/null +++ b/lib/adc.h @@ -0,0 +1,32 @@ +#pragma once + +// +// Utilities for build-in A/D converter +// + +#include + +enum ADC_Prescaller { + ADC_PRESC_2 = 1, + ADC_PRESC_4 = 2, + ADC_PRESC_8 = 3, + ADC_PRESC_16 = 4, + ADC_PRESC_32 = 5, + ADC_PRESC_64 = 6, + ADC_PRESC_128 = 7, +}; + +/** Initialize the ADC and enable it */ +void adc_init(enum ADC_Prescaller presc); + +/** Disable ADC (for power saving) */ +void adc_disable(void); + +/** Enable (already initialized) ADC */ +void adc_enable(void); + +/** Sample analog pin with 8-bit precision */ +uint8_t adc_read_byte(uint8_t channel); + +/** Sample analog pin with 10-bit precision */ +uint16_t adc_read_word(uint8_t channel); diff --git a/main.c b/main.c index 16861b1..88ce8d2 100644 --- a/main.c +++ b/main.c @@ -9,37 +9,79 @@ // Include stuff from the library #include "lib/iopins.h" #include "lib/usart.h" +#include "lib/spi.h" +#include "lib/adc.h" +#include "pinout.h" -// Pins -#define LED 13 +void setup_io(void) +{ + as_output(PIN_DISP_CP); + as_output(PIN_DISP_D); + as_output(PIN_DISP_STR); + as_input(PIN_KEY_1); + as_input(PIN_KEY_2); + as_input(PIN_KEY_3); + as_input(PIN_KEY_4); -// UART receive handler -ISR(USART_RX_vect) -{ - // "ECHO" function: - uint8_t b = usart_rx(); - usart_tx(b); // send back + as_output(PIN_NEOPIXEL); + as_output(PIN_DISP_OE); + + as_input(PIN_PWR_KEY); + as_output(PIN_PWR_HOLD); + + // PIN_LIGHT_SENSE is ADC exclusive, needs no config } +// --- LED display brightness control --- +#define DISP_BRIGHTNESS OCR2B +void setup_pwm(void) +{ + // PWM for LED display dimming + TCCR2A |= (1 << WGM20) | (1 << WGM21) | (1 << COM2B1); + TCCR2B |= (1 << CS20); + + DISP_BRIGHTNESS = 0x7F; +} void main() { usart_init(BAUD_115200); usart_isr_rx_enable(true); // enable RX interrupt handler - // configure pins - as_output(LED); + setup_io(); + setup_pwm(); + adc_init(ADC_PRESC_128); + + // SPI conf + spi_init_master(SPI_LSB_FIRST, + CPOL_1, CPHA_0, + SPI_DIV_2); - // globally enable interrupts (for the USART_RX handler) + // globally enable interrupts sei(); + uint8_t cnt = 0; + while (1) { - usart_puts("Hello World!\r\n"); + pin_down(PIN_DISP_STR); + spi_send(cnt); + spi_send(cnt); + pin_up(PIN_DISP_STR); + cnt++; - pin_toggle(13); // blink the LED + _delay_ms(100); - _delay_ms(500); + // Brightness directly proportional to light level + DISP_BRIGHTNESS = 255 - adc_read_byte(6); } } + +// UART receive handler +ISR(USART_RX_vect) +{ + // "ECHO" function: + uint8_t b = usart_rx(); + usart_tx(b); // send back +} diff --git a/pinout.h b/pinout.h new file mode 100644 index 0000000..d48d993 --- /dev/null +++ b/pinout.h @@ -0,0 +1,36 @@ +// +// Created by MightyPork on 2017/06/07. +// + +#ifndef FIRMWARE_PINOUT_H +#define FIRMWARE_PINOUT_H + +// Pinout defs +#include "lib/iopins.h" + +// 74HC4094 chain interface for dual 7seg +#define PIN_DISP_D D11 // MOSI +#define PIN_DISP_CP D13 // SCK +#define PIN_DISP_STR D10 // NSS, unused for SPI +#define PIN_DISP_OE D3 // SCK + +// Touch keys +#define PIN_KEY_1 A0 +#define PIN_KEY_2 A1 +#define PIN_KEY_3 A2 +#define PIN_KEY_4 A3 + +// We have a conflict with SPI SCK :( +//#define PIN_LED D13 + +// NeoPixel data +#define PIN_NEOPIXEL D2 + +// Power +#define PIN_PWR_KEY A4 // Direct input from the power key, used for power-off +#define PIN_PWR_HOLD A5 // Hold the buck enabled. Set 0 for shutdown + +// Ambient light sensor (Vdd -> 10k -> * -> phototransistor -> GND) +#define PIN_LIGHT_SENSE A6 // ADC exclusive pin + +#endif //FIRMWARE_PINOUT_H