Created
March 30, 2016 11:42
-
-
Save shinoonodera/ef12ee67c0d579f9db5f3f1a48163a13 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// | |
// hello.44.led.c | |
// Shino Onodera | |
// 2016.03.30 | |
// | |
// 115200 baud FTDI character echo, with flash string | |
// | |
// set lfuse to 0x5E for 20 MHz xtal | |
// | |
// | |
#include <avr/io.h> | |
#include <util/delay.h> | |
#include <avr/pgmspace.h> | |
#define output(directions,pin) (directions |= pin) // set port direction for output | |
#define set(port,pin) (port |= pin) // set port pin | |
#define clear(port,pin) (port &= (‾pin)) // clear port pin | |
#define pin_test(pins,pin) (pins & pin) // test for port pin | |
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set | |
#define bit_delay_time 8.5 // bit delay for 115200 with overhead | |
#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay | |
#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay | |
#define char_delay() _delay_ms(5) // char delay | |
#define led_delay()_delay_ms(100) // LED blink | |
#define serial_port PORTA | |
#define serial_direction DDRA | |
#define serial_pins PINA | |
#define serial_pin_in (1 << PA0) | |
#define serial_pin_out (1 << PA1) | |
#define led_port PORTA | |
#define led_direction DDRA | |
#define led_pin (1 << PA2) | |
#define max_buffer 25 | |
void get_char(volatile unsigned char *pins, unsigned char pin, char *rxbyte) { | |
// | |
// read character into rxbyte on pins pin | |
// assumes line driver (inverts bits) | |
// | |
*rxbyte = 0; | |
while (pin_test(*pins,pin)) | |
// | |
// wait for start bit | |
// | |
; | |
// | |
// delay to middle of first data bit | |
// | |
half_bit_delay(); | |
bit_delay(); | |
// | |
// unrolled loop to read data bits | |
// | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 0); | |
else | |
*rxbyte |= (0 << 0); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 1); | |
else | |
*rxbyte |= (0 << 1); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 2); | |
else | |
*rxbyte |= (0 << 2); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 3); | |
else | |
*rxbyte |= (0 << 3); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 4); | |
else | |
*rxbyte |= (0 << 4); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 5); | |
else | |
*rxbyte |= (0 << 5); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 6); | |
else | |
*rxbyte |= (0 << 6); | |
bit_delay(); | |
if pin_test(*pins,pin) | |
*rxbyte |= (1 << 7); | |
else | |
*rxbyte |= (0 << 7); | |
// | |
// wait for stop bit | |
// | |
bit_delay(); | |
half_bit_delay(); | |
} | |
void put_char(volatile unsigned char *port, unsigned char pin, char txchar) { | |
// | |
// send character in txchar on port pin | |
// assumes line driver (inverts bits) | |
// | |
// start bit | |
// | |
clear(*port,pin); | |
bit_delay(); | |
// | |
// unrolled loop to write data bits | |
// | |
if bit_test(txchar,0) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,1) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,2) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,3) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,4) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,5) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,6) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
if bit_test(txchar,7) | |
set(*port,pin); | |
else | |
clear(*port,pin); | |
bit_delay(); | |
// | |
// stop bit | |
// | |
set(*port,pin); | |
bit_delay(); | |
// | |
// char delay | |
// | |
bit_delay(); | |
} | |
void put_string(volatile unsigned char *port, unsigned char pin, char *str) { | |
// | |
// print a null-terminated string | |
// | |
static int index; | |
index = 0; | |
do { | |
put_char(port, pin, str[index]); | |
++index; | |
} while (str[index] != 0); | |
} | |
void blink() { | |
static int i; | |
i = 0; | |
while(i < 10) { | |
set(led_port, led_pin); | |
led_delay(); | |
clear(led_port, led_pin); | |
led_delay(); | |
i++; | |
} | |
} | |
int main(void) { | |
// | |
// main | |
// | |
static char chr; | |
static char buffer[max_buffer] = {0}; | |
static int index; | |
// | |
// set clock divider to /1 | |
// | |
CLKPR = (1 << CLKPCE); | |
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); | |
// | |
// initialize output pins | |
// | |
set(serial_port, serial_pin_out); | |
output(serial_direction, serial_pin_out); | |
// | |
// main loop | |
// | |
index = 0; | |
while (1) { | |
get_char(&serial_pins, serial_pin_in, &chr); | |
buffer[index++] = chr; | |
if (chr =='t') | |
{ | |
put_string(&serial_port, serial_pin_out, "Traffic cone!"); | |
index = 0; | |
blink(); | |
put_char(&serial_port, serial_pin_out, 10); // new line | |
} | |
else | |
{ | |
put_string(&serial_port, serial_pin_out, "hmm..."); | |
index = 0; | |
put_string(&serial_port, serial_pin_out, buffer); | |
put_string(&serial_port, serial_pin_out, "? ( )raffic cone?"); | |
put_char(&serial_port, serial_pin_out, 10); // new line | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment