basic reading and printing works
This commit is contained in:
parent
ba31b296eb
commit
d8bdcc3eed
47
analogin.c
Normal file
47
analogin.c
Normal 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
13
analogin.h
Normal 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
5
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
|
||||
|
|
95
main.c
95
main.c
|
@ -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;
|
||||
}
|
||||
|
|
25
ringbuffer.c
25
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;
|
||||
}
|
||||
|
|
|
@ -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
14
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)
|
||||
{
|
||||
|
|
4
time.h
4
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;
|
||||
|
|
26
usart.c
26
usart.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user