diff --git a/analogin.c b/analogin.c new file mode 100644 index 0000000..c3798fc --- /dev/null +++ b/analogin.c @@ -0,0 +1,47 @@ +#include +#include +#include "analogin.h" +#include "configuration.h" + +//#define ADC_RESULT (ADCL | (ADCH << 8)) + +volatile unsigned char _current_pin; +volatile unsigned char _continue_at; + +void +analogin_init(void) +{ + _current_pin = 0; + + ADMUX = _BV(REFS0); + ADCSRA = _BV(ADEN) + | _BV(ADATE) + | _BV(ADIE) + | _BV(ADSC) + // XXX + // This is only for testing (maybe I will keep it a little) + // (or do something with configure.... idk) + // Sets the prescaler to 128, we might need more time to transmit + // the data. + | _BV(ADPS0) + | _BV(ADPS1) + | _BV(ADPS2); + ADCSRB = 0; + sei(); +} + +ISR(ADC_vect, ISR_NOBLOCK) +{ + int ADC_RESULT, last_pin; + + ADC_RESULT = ADCL; + ADC_RESULT |= ADCH << 8; + + last_pin = (_current_pin + 3) % 4; + + _current_pin = (_current_pin + 1) % 4; + ADMUX &= 0xf0; + ADMUX |= _current_pin; + + on_channel_measured(last_pin, ADC_RESULT); +} diff --git a/analogin.h b/analogin.h new file mode 100644 index 0000000..c16ab36 --- /dev/null +++ b/analogin.h @@ -0,0 +1,13 @@ +#ifndef _ANALOGIN_H_ +#define _ANALOGIN_H_ + +#include "conf.h" + +void +analogin_init(void); + +extern void +on_channel_measured(unsigned char channel + , unsigned int value); + +#endif diff --git a/conf.h b/conf.h index d833817..79c8a36 100644 --- a/conf.h +++ b/conf.h @@ -1,8 +1,9 @@ #ifndef _CONF_H_ #define _CONF_H_ -#define F_CPU 8000000UL -#define USART_BAUD 9600 +#define F_CPU 20000000UL +#define USART_BAUD 19600 #define USART_BUFFER_SIZE 256 +#define USART_U2X_EN #endif diff --git a/main.c b/main.c index 750222e..4a472ec 100644 --- a/main.c +++ b/main.c @@ -6,46 +6,26 @@ #include #include +volatile int measurement_complete; +volatile unsigned char channel_measured; +volatile unsigned int value_measured; + void on_channel_measured(unsigned char channel , unsigned int value) { -// struct eigentime_s eigentime; -// get_eigentime(&eigentime); -// char buffer[32]; -// int i; - //utoa(eigentime.high, buffer, 16); - //i = 0; - //while(buffer[i]) - //{ - // usart_putc(buffer[i++]); - //} - //usart_putc(','); - //utoa(eigentime.low, buffer, 16); - //i = 0; - //while(buffer[i]) - //{ - // usart_putc(buffer[i++]); - //} - //usart_putc(','); - //usart_putc('0' + channel); - //usart_putc(','); - - //utoa(value, buffer, 16); - //i = 0; - //while(buffer[i]) - //{ - // usart_putc(buffer[i++]); - //} - //usart_putc('r'); - //usart_putc('0' + channel); - //usart_putc('\n'); - PORTB ^= _BV(PB1); + measurement_complete = 1; + channel_measured = channel; + value_measured = value; + PORTB ^= _BV(PB2); } int main(void) { + unsigned char channel; + unsigned int value; + configuration_init(); time_init(); usart_init(); @@ -53,21 +33,52 @@ int main(void) DDRB |= _BV(PB1); DDRB |= _BV(PB2); - //usart_putc('s'); - //usart_putc('t'); - //usart_putc('a'); - //usart_putc('r'); - //usart_putc('t'); - //usart_putc(' '); - //usart_putc('o'); - //usart_putc('k'); - //usart_putc('\n'); while(1) { - _delay_ms(100); + if(measurement_complete) + { + measurement_complete = 0; + + channel = channel_measured; + value = value_measured; + + struct eigentime_s eigentime; + get_eigentime(&eigentime); + char buffer[32]; + int i; + + utoa(eigentime.high, buffer, 16); + i = 0; + while(buffer[i]) + { + usart_putc(buffer[i++]); + } + usart_putc(','); + utoa(eigentime.low, buffer, 16); + i = 0; + while(buffer[i]) + { + usart_putc(buffer[i++]); + } + usart_putc(','); + usart_putc('0' + channel); + usart_putc(','); + + utoa(value, buffer, 16); + i = 0; + while(buffer[i]) + { + usart_putc(buffer[i++]); + } + for(i = 0; i < 3; i++) + { + usart_putc('\n'); + } + PORTB ^= _BV(PB1); + + } - PORTB ^= _BV(PB2); } return 0; } diff --git a/ringbuffer.c b/ringbuffer.c index 7f373f4..5ed30b5 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -27,17 +27,18 @@ ringbuffer_new(size_t size) int ringbuffer_nonempty(ringbuffer_t buffer) { - return buffer->head != buffer->tail; + return (buffer->head != buffer->tail) || buffer->ovf; } unsigned char ringbuffer_get_char(ringbuffer_t buffer) { unsigned char result; - if(buffer->head == buffer->tail) + if((buffer->head == buffer->tail) && !buffer->ovf) { return 0; } + buffer->ovf = 0; result = buffer->buffer[buffer->tail]; buffer->tail = (buffer->tail + 1) % buffer->length; return result; @@ -47,13 +48,29 @@ int ringbuffer_put_char(ringbuffer_t buffer , unsigned char c) { - buffer->ovf = 0; + if(buffer->ovf) + { + return 1; + } buffer->buffer[buffer->head] = c; buffer->head = (buffer->head + 1) % buffer->length; if(buffer->head == buffer->tail) { buffer->ovf = 1; } - return buffer->ovf; + return 0; } +size_t ringbuffer_empty_bytes(ringbuffer_t buffer) +{ + if(buffer->ovf) + { + return 0; + } + int raw_empty = buffer->length - (buffer->head - buffer->tail); + if(raw_empty > buffer->length) + { + return raw_empty - buffer->length; + } + return raw_empty; +} diff --git a/ringbuffer.h b/ringbuffer.h index c1fa67d..986f4fb 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -20,4 +20,6 @@ ringbuffer_get_char(ringbuffer_t buffer); int ringbuffer_put_char(ringbuffer_t buffer , unsigned char c); + +size_t ringbuffer_empty_bytes(ringbuffer_t buffer); #endif diff --git a/time.c b/time.c index 16c9782..fbc3da4 100644 --- a/time.c +++ b/time.c @@ -11,6 +11,7 @@ time_init(void) { _eigentime_ms.low = 0; _eigentime_ms.high = 0; + _eigentime_ms.tenth = 0; // prescaler is 64. TCCR0B = _BV(CS00) | _BV(CS01); TIMSK0 |= _BV(TOIE0); @@ -28,7 +29,18 @@ get_eigentime(struct eigentime_s * time) ISR(TIMER0_OVF_vect) { unsigned int last_eigentime_low = _eigentime_ms.low; - _eigentime_ms.low += TIME_MILLIS_PER_OVERFLOW; + unsigned int ms; + + // well basically at 20Mhz milliseconds are not precise enough. + _eigentime_ms.tenth += TIME_TENTH_MILLIS_PER_OVERFLOW; + if(_eigentime_ms.tenth > 10) + { + ms = _eigentime_ms.tenth / 10; + _eigentime_ms.low += ms; + _eigentime_ms.tenth -= 10 * ms; + } + + // Handle the overflow. if(_eigentime_ms.low < last_eigentime_low) { diff --git a/time.h b/time.h index ef88cb9..6f73acd 100644 --- a/time.h +++ b/time.h @@ -2,13 +2,13 @@ #define _TIME_H_ #include "conf.h" -// This is 2.04 = 2ms -#define TIME_MILLIS_PER_OVERFLOW (0xff * 1000UL * 64) / F_CPU +#define TIME_TENTH_MILLIS_PER_OVERFLOW (0xff * 10000UL * 64) / F_CPU // for 32bit eigentime struct eigentime_s { unsigned int low, high; + unsigned int tenth; }; extern volatile struct eigentime_s _eigentime_ms; diff --git a/usart.c b/usart.c index b6aaf01..f2c9927 100644 --- a/usart.c +++ b/usart.c @@ -5,15 +5,18 @@ #include "ringbuffer.h" #include -volatile ringbuffer_t usart_buffer; +volatile ringbuffer_t usart_tx_buffer; void usart_init(void) { - usart_buffer = ringbuffer_new(USART_BUFFER_SIZE); + usart_tx_buffer = ringbuffer_new(USART_BUFFER_SIZE); UBRR0H = (unsigned char)(UBRR_VALUE >> 8); UBRR0L = (unsigned char)UBRR_VALUE; +#ifdef USART_U2X_EN + UCSR0A |= _BV(U2X0); +#endif UCSR0B = _BV(TXEN0) | _BV(TXCIE0); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); sei(); @@ -22,25 +25,28 @@ usart_init(void) int usart_putc(char c) { - int result = ringbuffer_put_char(usart_buffer, c); - // If the buffer is already emtpy there is no + // Basically this is really ugly, + // but there is no other way to do it. + // We let the main thread wait until the + // sender thread has cleared one byte. + while(ringbuffer_put_char(usart_tx_buffer, c)); + + // If the data register is already emtpy there is no // need to wait for the interrupt. // Also it is likely that the interrupt will never happen. // (For instance because this is the first byte sent) if(UCSR0A & _BV(UDRE0)) { - UDR0 = ringbuffer_get_char(usart_buffer); + UDR0 = ringbuffer_get_char(usart_tx_buffer); } - return result; + return 0; } - ISR(USART_TX_vect) { - if(ringbuffer_nonempty(usart_buffer)) + if(ringbuffer_nonempty(usart_tx_buffer)) { - UDR0 = ringbuffer_get_char(usart_buffer); - UCSR0A |= _BV(TXC0); + UDR0 = ringbuffer_get_char(usart_tx_buffer); } } diff --git a/usart.h b/usart.h index be7099d..cc0d319 100644 --- a/usart.h +++ b/usart.h @@ -2,7 +2,11 @@ #define _USART_H_ #include "conf.h" +#ifndef USART_U2X_EN #define UBRR_VALUE (F_CPU/16/USART_BAUD-1) +#else +#define UBRR_VALUE (F_CPU/8/USART_BAUD-1) +#endif void usart_init(void); @@ -10,5 +14,4 @@ usart_init(void); int usart_putc(char c); - #endif