basic reading and printing works

master
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 100644
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 100644
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_
#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

95
main.c
View File

@ -6,46 +6,26 @@
#include <stdlib.h>
#include <avr/io.h>
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;
}

View File

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

View File

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

14
time.c
View File

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

4
time.h
View File

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

26
usart.c
View File

@ -5,15 +5,18 @@
#include "ringbuffer.h"
#include <avr/interrupt.h>
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);
}
}

View File

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