diff --git a/adc.c b/adc.c index c147a8d..1704ccc 100644 --- a/adc.c +++ b/adc.c @@ -5,13 +5,13 @@ #include "adc.h" void adc_init(void) { - ADCSRA = 0b10000000; // Enable, the ADC, no interrupts, prescaler 2 + ADCSRA = 0b10000111; // Enable, the ADC, no interrupts, Prescaler 128 ADCSRB = 0x00; // Right adjusted, data } uint16_t adc_read_sync(uint8_t channel) { - ADMUX = 1 << REFS0 | channel; // Internal Ref | Select the channel - ADCSRA |= 1 << ADSC; // Start conversion - while(ADCSRA & (1 << ADSC)); // conversion running - return ADCL | ADCH << 8; // Low byte must be read first + ADMUX = 0b01u << 6 | channel; // Internal Ref | Select the channel + ADCSRA |= 1u << ADSC; // Start conversion + while(ADCSRA & (1u << ADSC)); // conversion running + return ADCL | (ADCH << 8u); // Low byte must be read first } diff --git a/spi.c b/spi.c index b493032..6657888 100644 --- a/spi.c +++ b/spi.c @@ -15,9 +15,10 @@ static volatile uint16_t _size = 0; static void (*_callback)(void) = 0; ISR(SPI_STC_vect) { - _buf[-1] = SPDR; + *_buf = SPDR; + ++_buf; if (_size > 0) { - SPDR = *_buf++; + SPDR = *_buf; --_size; } else { if (_callback != 0) { @@ -26,13 +27,17 @@ ISR(SPI_STC_vect) { } } -void spi_init(bool lsb_first, uint8_t f_bit) { +void spi_init(bool lsb_first, spi_prescaler_t prescaler) { SPCR = 0b11010000; // Enabled, Interrupts enabled, Slave mode if (lsb_first) { SPCR |= (1 << DORD); } - SPCR |= f_bit & 0b11; - SPSR = (f_bit >> 2) & 0b1; + SPCR |= prescaler & 0b11u; + SPSR = (prescaler >> 2u) & 0b1u; + +#if defined(__AVR_ATmega328P__) + DDRB |= (1 << 3u) | (1 << 5u); // MOSI and SCK as Output +#endif } void spi_tx_rx(uint8_t *buf, uint16_t size, void (*callback)(void)) { @@ -40,7 +45,17 @@ void spi_tx_rx(uint8_t *buf, uint16_t size, void (*callback)(void)) { _size = size; _callback = callback; if (_size > 0) { - SPDR = *_buf++; + SPDR = *_buf; --_size; } } + +void spi_set_prescaler(spi_prescaler_t prescaler) { + uint8_t spcr = SPCR; + uint8_t spsr = SPSR; + spcr &= ~(0b11u); // Mask away the old prescaler bits + spsr &= ~(0b1u); + + SPCR |= prescaler & 0b11u; + SPSR = (prescaler >> 2u) & 0b1u; +} diff --git a/spi.h b/spi.h index f2964df..5dfbf7a 100644 --- a/spi.h +++ b/spi.h @@ -11,12 +11,25 @@ #include #include +typedef enum { + DIV_2 = 0b100, + DIV_4 = 0b000, + DIV_8 = 0b101, + DIV_16 = 0b001, + DIV_32 = 0b110, + DIV_64 = 0b010, + DIV_64_2X = 0b111, + DIV_128 = 0b011 +} spi_prescaler_t; + /** * Initialize and enable the spi in master mode. * @param lsb_first true if the data should be send (and received) with the least significant bit first - * @param f_bit the 3 bits responsible for selecting the prescaler (refer to page 198 for more information) + * @param prescaler the 3 bits responsible for selecting the prescaler (refer to page 198 for more information) */ -void spi_init(bool lsb_first, uint8_t f_bit); +void spi_init(bool lsb_first, spi_prescaler_t prescaler); + +void spi_set_prescaler(spi_prescaler_t prescaler); /** * Send and receive a number of bytes via the interface. The buffer is used for reading the data to send diff --git a/timer8bit.c b/timer8bit.c index adca032..642d4f0 100644 --- a/timer8bit.c +++ b/timer8bit.c @@ -10,19 +10,38 @@ #include #include -static void (*_callback)(void); +typedef struct { + volatile timer_callback_t callback; + volatile uint8_t * const tccra, * const tccrb, * const timsk, * const tcnt; +} timer8bit_instance_t; +static volatile timer8bit_instance_t instance = { +#if defined(__AVR_ATmega328P__) + .tccra = &TCCR2A, .tccrb = &TCCR2B, .timsk = &TIMSK2, .tcnt = &TCNT2 +#elif defined (__AVR_ATmega2560__) + .tccra = &TCCR0A, .tccrb = &TCCR0B, .timsk = &TIMSK0, .tcnt = &TCNT0 +#else + #error "Please define a CPU, using the mmcpu flag" +#endif +}; + + + +#if defined(__AVR_ATmega328P__) +ISR(TIMER2_OVF_vect) { +#elif defined (__AVR_ATmega2560__) ISR(TIMER0_OVF_vect) { - if (_callback != 0) { - (*_callback)(); +#endif + if (instance.callback != 0) { + (*instance.callback)(); } } -void timer0_init(timer_clock_option_t timer_clock_option, void (*callback)(void)) { - _callback = callback; - TCCR0A = 0b00000000u; // Output compare disconnected, normal mode - TCCR0B = 0b00000000u | timer_clock_option; // No force override, normal mode, prescaler - TIMSK0 = 0b00000001u; // Overflow interrupt enabled +void timer_8bit_init(timer_clock_option_t timer_clock_option, timer_callback_t callback) { + instance.callback = callback; + *instance.tccra = 0b00000000u; // Output compare disconnected, normal mode + *instance.tccrb = 0b00000000u | timer_clock_option; // No force override, normal mode, prescaler + *instance.timsk = 0b00000001u; // Overflow interrupt enabled - TCNT0 = 0; // Set the counter to 0 + *instance.tcnt = 0; // Set the counter to 0 } diff --git a/timer8bit.h b/timer8bit.h index 521ce2c..7e072c4 100644 --- a/timer8bit.h +++ b/timer8bit.h @@ -8,7 +8,21 @@ #ifndef AVR_HAL_TIMER8BIT_H #define AVR_HAL_TIMER8BIT_H +typedef void (*timer_callback_t)(void); + +#include + typedef enum { +#if defined(__AVR_ATmega328P__) + no_clock = 0, + prescaler_1 = 1, + prescaler_8 = 2, + prescaler_32 = 3, + prescaler_64 = 4, + prescaler_128 = 5, + prescaler_256 = 6, + prescaler_1024 = 7 +#elif defined (__AVR_ATmega2560__) no_clock = 0, prescaler_1 = 1, prescaler_8 = 2, @@ -17,6 +31,7 @@ typedef enum { prescaler_1024 = 5, external_falling = 6, external_rising = 7 +#endif } timer_clock_option_t; /** @@ -24,6 +39,6 @@ typedef enum { * @param timer_clock_option the prescaler * @param callback a functor that gets called on every overflow */ -void timer0_init(timer_clock_option_t timer_clock_option, void (*callback)(void)); +void timer_8bit_init(timer_clock_option_t timer_clock_option, void (*callback)(void)); #endif //AVR_HAL_TIMER8BIT_H diff --git a/uart.c b/uart.c index 060bf04..988a5dd 100644 --- a/uart.c +++ b/uart.c @@ -13,6 +13,10 @@ #include #include +#ifndef UDR1 + #define SINGLE_UART 1 +#endif + #define RING_BUFFER_SIZE 64 #define MIN_U2X_BAUD (F_CPU/(16*(255 + 1)) + 1) @@ -69,17 +73,12 @@ void rx_handler(uint8_t id) { } } -#ifndef UDR0 // Only one UART +#if SINGLE_UART ISR(USART_RX_vect) { rx_handler(0); } ISR(USART_TX_vect) { tx_handler(0); } -#endif - -#ifdef UDR0 +#else ISR(USART0_RX_vect) { rx_handler(0); } ISR(USART0_TX_vect) { tx_handler(0); } -#endif - -#ifdef UDR1 ISR(USART1_RX_vect) { rx_handler(1); } ISR(USART1_TX_vect) { tx_handler(1); } #endif @@ -94,6 +93,9 @@ ISR(USART3_TX_vect) { tx_handler(3); } #endif void uart_init(uint8_t id, uint32_t baud, uart_parity_t parity, uint8_t stop_bits, uart_callback_t rx_callback) { +#if SINGLE_UART + id = 0; +#endif instances[id].callback = rx_callback; instances[id].tail = 0; instances[id].head = 0; @@ -115,6 +117,9 @@ void uart_init(uint8_t id, uint32_t baud, uart_parity_t parity, uint8_t stop_bit } void uart_send_byte(uint8_t id, uint8_t data) { +#if SINGLE_UART + id = 0; +#endif if (instances[id].ready) { // Can send directly instances[id].ready = false; *instances[id].udr = data;