basic reading and printing works

This commit is contained in:
Daniel Knüttel 2019-04-07 20:35:05 +02:00
parent ba31b296eb
commit d8bdcc3eed
10 changed files with 174 additions and 62 deletions

47
analogin.c Normal file
View File

@ -0,0 +1,47 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#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);
}

13
analogin.h Normal file
View File

@ -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

5
conf.h
View File

@ -1,8 +1,9 @@
#ifndef _CONF_H_ #ifndef _CONF_H_
#define _CONF_H_ #define _CONF_H_
#define F_CPU 8000000UL #define F_CPU 20000000UL
#define USART_BAUD 9600 #define USART_BAUD 19600
#define USART_BUFFER_SIZE 256 #define USART_BUFFER_SIZE 256
#define USART_U2X_EN
#endif #endif

95
main.c
View File

@ -6,46 +6,26 @@
#include <stdlib.h> #include <stdlib.h>
#include <avr/io.h> #include <avr/io.h>
volatile int measurement_complete;
volatile unsigned char channel_measured;
volatile unsigned int value_measured;
void void
on_channel_measured(unsigned char channel on_channel_measured(unsigned char channel
, unsigned int value) , unsigned int value)
{ {
// struct eigentime_s eigentime; measurement_complete = 1;
// get_eigentime(&eigentime); channel_measured = channel;
// char buffer[32]; value_measured = value;
// int i; PORTB ^= _BV(PB2);
//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);
} }
int main(void) int main(void)
{ {
unsigned char channel;
unsigned int value;
configuration_init(); configuration_init();
time_init(); time_init();
usart_init(); usart_init();
@ -53,21 +33,52 @@ int main(void)
DDRB |= _BV(PB1); DDRB |= _BV(PB1);
DDRB |= _BV(PB2); 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) 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; return 0;
} }

View File

@ -27,17 +27,18 @@ ringbuffer_new(size_t size)
int int
ringbuffer_nonempty(ringbuffer_t buffer) ringbuffer_nonempty(ringbuffer_t buffer)
{ {
return buffer->head != buffer->tail; return (buffer->head != buffer->tail) || buffer->ovf;
} }
unsigned char unsigned char
ringbuffer_get_char(ringbuffer_t buffer) ringbuffer_get_char(ringbuffer_t buffer)
{ {
unsigned char result; unsigned char result;
if(buffer->head == buffer->tail) if((buffer->head == buffer->tail) && !buffer->ovf)
{ {
return 0; return 0;
} }
buffer->ovf = 0;
result = buffer->buffer[buffer->tail]; result = buffer->buffer[buffer->tail];
buffer->tail = (buffer->tail + 1) % buffer->length; buffer->tail = (buffer->tail + 1) % buffer->length;
return result; return result;
@ -47,13 +48,29 @@ int
ringbuffer_put_char(ringbuffer_t buffer ringbuffer_put_char(ringbuffer_t buffer
, unsigned char c) , unsigned char c)
{ {
buffer->ovf = 0; if(buffer->ovf)
{
return 1;
}
buffer->buffer[buffer->head] = c; buffer->buffer[buffer->head] = c;
buffer->head = (buffer->head + 1) % buffer->length; buffer->head = (buffer->head + 1) % buffer->length;
if(buffer->head == buffer->tail) if(buffer->head == buffer->tail)
{ {
buffer->ovf = 1; 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;
}

View File

@ -20,4 +20,6 @@ ringbuffer_get_char(ringbuffer_t buffer);
int int
ringbuffer_put_char(ringbuffer_t buffer ringbuffer_put_char(ringbuffer_t buffer
, unsigned char c); , unsigned char c);
size_t ringbuffer_empty_bytes(ringbuffer_t buffer);
#endif #endif

14
time.c
View File

@ -11,6 +11,7 @@ time_init(void)
{ {
_eigentime_ms.low = 0; _eigentime_ms.low = 0;
_eigentime_ms.high = 0; _eigentime_ms.high = 0;
_eigentime_ms.tenth = 0;
// prescaler is 64. // prescaler is 64.
TCCR0B = _BV(CS00) | _BV(CS01); TCCR0B = _BV(CS00) | _BV(CS01);
TIMSK0 |= _BV(TOIE0); TIMSK0 |= _BV(TOIE0);
@ -28,7 +29,18 @@ get_eigentime(struct eigentime_s * time)
ISR(TIMER0_OVF_vect) ISR(TIMER0_OVF_vect)
{ {
unsigned int last_eigentime_low = _eigentime_ms.low; 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. // Handle the overflow.
if(_eigentime_ms.low < last_eigentime_low) if(_eigentime_ms.low < last_eigentime_low)
{ {

4
time.h
View File

@ -2,13 +2,13 @@
#define _TIME_H_ #define _TIME_H_
#include "conf.h" #include "conf.h"
// This is 2.04 = 2ms #define TIME_TENTH_MILLIS_PER_OVERFLOW (0xff * 10000UL * 64) / F_CPU
#define TIME_MILLIS_PER_OVERFLOW (0xff * 1000UL * 64) / F_CPU
// for 32bit eigentime // for 32bit eigentime
struct eigentime_s struct eigentime_s
{ {
unsigned int low, high; unsigned int low, high;
unsigned int tenth;
}; };
extern volatile struct eigentime_s _eigentime_ms; extern volatile struct eigentime_s _eigentime_ms;

26
usart.c
View File

@ -5,15 +5,18 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include <avr/interrupt.h> #include <avr/interrupt.h>
volatile ringbuffer_t usart_buffer; volatile ringbuffer_t usart_tx_buffer;
void void
usart_init(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); UBRR0H = (unsigned char)(UBRR_VALUE >> 8);
UBRR0L = (unsigned char)UBRR_VALUE; UBRR0L = (unsigned char)UBRR_VALUE;
#ifdef USART_U2X_EN
UCSR0A |= _BV(U2X0);
#endif
UCSR0B = _BV(TXEN0) | _BV(TXCIE0); UCSR0B = _BV(TXEN0) | _BV(TXCIE0);
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
sei(); sei();
@ -22,25 +25,28 @@ usart_init(void)
int int
usart_putc(char c) usart_putc(char c)
{ {
int result = ringbuffer_put_char(usart_buffer, c); // Basically this is really ugly,
// If the buffer is already emtpy there is no // 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. // need to wait for the interrupt.
// Also it is likely that the interrupt will never happen. // Also it is likely that the interrupt will never happen.
// (For instance because this is the first byte sent) // (For instance because this is the first byte sent)
if(UCSR0A & _BV(UDRE0)) 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) ISR(USART_TX_vect)
{ {
if(ringbuffer_nonempty(usart_buffer)) if(ringbuffer_nonempty(usart_tx_buffer))
{ {
UDR0 = ringbuffer_get_char(usart_buffer); UDR0 = ringbuffer_get_char(usart_tx_buffer);
UCSR0A |= _BV(TXC0);
} }
} }

View File

@ -2,7 +2,11 @@
#define _USART_H_ #define _USART_H_
#include "conf.h" #include "conf.h"
#ifndef USART_U2X_EN
#define UBRR_VALUE (F_CPU/16/USART_BAUD-1) #define UBRR_VALUE (F_CPU/16/USART_BAUD-1)
#else
#define UBRR_VALUE (F_CPU/8/USART_BAUD-1)
#endif
void void
usart_init(void); usart_init(void);
@ -10,5 +14,4 @@ usart_init(void);
int int
usart_putc(char c); usart_putc(char c);
#endif #endif