--- a/src/hello.c Thu Apr 03 19:44:13 2014 +0300
+++ b/src/hello.c Thu Apr 03 19:44:53 2014 +0300
@@ -1,116 +1,34 @@
#include <avr/io.h>
-#include "stdlib.h"
-
-#include <avr/interrupt.h>
-
-#define TIMER_FLAGS GPIOR0
-#define TIMER1_BUSY 1
-
-/*
- * Setup timers.
- */
-void timer_init (void)
-{
- TCCR1A = (
- // OC1A output pin disconnected
- 0b00 << COM1A0
- // OC1B output pin disconnected
- | 0b00 << COM1B0
- // no PWM
- | 0b00 << WGM10
- );
- TCCR1B = (
- // CTC mode
- 0b01 << WGM12
- );
- TCCR1C = 0;
-}
-
-void timer1_start (short cycles)
-{
- // count up from zero...
- TCNT1 = 0;
-
- // ...to the given number of timer cycles
- OCR1A = cycles;
-
- // start!
- sbi(&TIMER_FLAGS, TIMER1_BUSY);
- TIMSK1 = (
- // OCA interrupt
- 0b1 << OCIE1A // enable
- );
- TCCR1B = (
- // WGM
- 0b01 << WGM12 // CTC
- // clocksource
- | 0b101 << CS10 // 1024'th
- );
-}
-
-static void timer1_stop ()
-{
- // WGM: normal
- // clocksource: stop
- TCCR1B = 0;
-
- cbi(&TIMER_FLAGS, TIMER1_BUSY);
-}
-
-ISR(TIMER1_COMPA_vect)
-{
- timer1_stop();
-
- // XXX: cpu will automatically wake up from sleep()
-}
-
-/*
- * Sleep on timer1 interrupt.
- */
-void timer_sleep (int cycles)
-{
- // set timer
- timer1_start(cycles);
-
- // sleep
- // TODO: PRR
- SMCR = (
- // idle sleep
- (0b00 << SM0)
-
- // enable sleep
- | (0b1 << SE)
- );
-
- // sleep
- while (tbi(&TIMER_FLAGS, TIMER1_BUSY)) {
- __asm__ ( "sleep" :: );
- }
-
- // cleanup
- SMCR = 0;
-}
+#include "stdlib.h"
+#include "timer.c" // XXX
+#include "serial.c" // XXX
int main (void)
{
timer_init();
+ serial_init();
// LED
sbi(&DDRB, DDB5);
+ serial_enable();
sei();
// blink
+ char c = 'X';
short timeout = 1000;
short delta = 10;
while (true) {
+ serial_write(c);
+
// bitflip
xbi(&PORTB, PORTB5);
- timer_sleep(timeout);
+ //timer_sleep(timeout);
+ //timeout += delta;
- timeout += delta;
+ c = serial_read();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/serial.c Thu Apr 03 19:44:53 2014 +0300
@@ -0,0 +1,88 @@
+
+static enum {
+ SERIAL_MODE_ASYNC = 0b00,
+} serial_mode = SERIAL_MODE_ASYNC;
+
+static enum {
+ SERIAL_BAUD_9600 = 103,
+
+} serial_baud = SERIAL_BAUD_9600;
+
+static enum {
+ SERIAL_PARITY_N = 0b00,
+
+} serial_parity = SERIAL_PARITY_N;
+
+static enum {
+ SERIAL_STOPBITS_1 = 0b0,
+
+} serial_stopbits = SERIAL_STOPBITS_1;
+
+static enum {
+ SERIAL_CHARS_8 = 0b011,
+} serial_chars = SERIAL_CHARS_8;
+
+/*
+ * Setup the UART for serial mode.
+ */
+void serial_init ()
+{
+ UCSR0A = (
+ // Double the USART Transmission Speed
+ (0b0 << U2X0) // single speed
+
+ // Multi-processor Communication Mode
+ | (0b0 << MPCM0) // off
+ );
+ UCSR0B = (
+ // Character Size
+ ((serial_chars >> 2) << UCSZ02) // standard character sizes
+ );
+ UCSR0C = (
+ // USART Mode Select
+ (serial_mode << UMSEL00) // async
+
+ // Parity Mode
+ | (serial_parity << UPM00)
+
+ // Stop Bit Select
+ | (serial_stopbits << USBS0)
+
+ // Character Size
+ | ((serial_chars & 0b11) << UCSZ00)
+
+ // Clock Polarity
+ | (0b0 << UCPOL0)
+ );
+ UBRR0 = serial_baud;
+}
+
+void serial_enable ()
+{
+ UCSR0B = (
+ // Receiver Enable
+ (0b1 << RXEN0) // enabled
+
+ // Transmitter Enable
+ | (0b1 << TXEN0) // enabled
+
+ // Character Size
+ | ((serial_chars >> 2) << UCSZ02) // standard character sizes
+ );
+}
+
+char serial_read ()
+{
+ while (!tbi(&UCSR0A, RXC0))
+ ;
+
+ return UDR0;
+}
+
+void serial_write (char c)
+{
+ while (!tbi(&UCSR0A, UDRE0))
+ ;
+
+ UDR0 = c;
+}
--- a/src/stdlib.h Thu Apr 03 19:44:13 2014 +0300
+++ b/src/stdlib.h Thu Apr 03 19:44:53 2014 +0300
@@ -1,5 +1,3 @@
-#include <util/delay.h>
-
#define false 0
#define true 1
@@ -24,9 +22,3 @@
{
*port ^= (1 << bit);
}
-
-void delay_1s ()
-{
- // busyloop
- _delay_ms(1000);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timer.c Thu Apr 03 19:44:53 2014 +0300
@@ -0,0 +1,92 @@
+#include <avr/interrupt.h>
+
+#define TIMER_FLAGS GPIOR0
+#define TIMER1_BUSY 1
+
+/*
+ * Setup timers.
+ */
+void timer_init (void)
+{
+ TCCR1A = (
+ // OC1A output pin disconnected
+ 0b00 << COM1A0
+ // OC1B output pin disconnected
+ | 0b00 << COM1B0
+ // no PWM
+ | 0b00 << WGM10
+ );
+ TCCR1B = (
+ // CTC mode
+ 0b01 << WGM12
+ );
+ TCCR1C = 0;
+}
+
+void timer1_start (short cycles)
+{
+ // count up from zero...
+ TCNT1 = 0;
+
+ // ...to the given number of timer cycles
+ OCR1A = cycles;
+
+ // start!
+ sbi(&TIMER_FLAGS, TIMER1_BUSY);
+ TIMSK1 = (
+ // OCA interrupt
+ 0b1 << OCIE1A // enable
+ );
+ TCCR1B = (
+ // WGM
+ 0b01 << WGM12 // CTC
+
+ // clocksource
+ | 0b101 << CS10 // 1024'th
+ );
+}
+
+static void timer1_stop ()
+{
+ // WGM: normal
+ // clocksource: stop
+ TCCR1B = 0;
+
+ cbi(&TIMER_FLAGS, TIMER1_BUSY);
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+ timer1_stop();
+
+ // XXX: cpu will automatically wake up from sleep()
+}
+
+/*
+ * Sleep on timer1 interrupt.
+ */
+void timer_sleep (int cycles)
+{
+ // set timer
+ timer1_start(cycles);
+
+ // sleep
+ // TODO: PRR
+ SMCR = (
+ // idle sleep
+ (0b00 << SM0)
+
+ // enable sleep
+ | (0b1 << SE)
+ );
+
+ // sleep
+ while (tbi(&TIMER_FLAGS, TIMER1_BUSY)) {
+ __asm__ ( "sleep" :: );
+ }
+
+ // cleanup
+ SMCR = 0;
+}
+
+