Last active
August 29, 2015 14:21
-
-
Save programmarchy/8ffa021301996750418e to your computer and use it in GitHub Desktop.
flow control test
This file contains hidden or 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
#include <asf.h> | |
#include <avr/io.h> | |
#include <avr/wdt.h> | |
#include <stdint.h> | |
#define PIN_SET_OUTPUT(ddr, id) ddr |= _BV(id) | |
#define PIN_SET_INPUT(ddr, id) ddr &= ~_BV(id) | |
#define PIN_SET_HIGH(port, id) port |= _BV(id) | |
#define PIN_SET_LOW(port, id) port &= ~_BV(id) | |
#define PIN_IS_HIGH(pins, id) bit_is_set(pins, id) | |
#define PIN_IS_LOW(pins, id) bit_is_clear(pins, id) | |
void bluetooth_init (void); | |
uint8_t bluetooth_is_connected (void); | |
void bluetooth_read (void); | |
void bluetooth_write (uint8_t); | |
void bluetooth_request_to_send (uint8_t); | |
uint8_t bluetooth_is_clear_to_send (void); | |
void leds_init (void); | |
void leds_blue_on (void); | |
void leds_blue_off (void); | |
void leds_green_on (void); | |
void leds_green_off (void); | |
void leds_red_on (void); | |
void leds_red_off (void); | |
void spin_loop (uint32_t); | |
void spin_trap (void); | |
void loop (void); | |
int main (void) | |
{ | |
board_init(); | |
bluetooth_init(); | |
leds_init(); | |
// Insert application code here, after the board has been initialized. | |
wdt_enable(WDTO_8S); | |
wdt_reset(); | |
while (1) | |
{ | |
if (bit_is_set(UCSR1A, DOR1)) | |
{ | |
leds_red_on(); | |
leds_green_on(); | |
leds_blue_on(); | |
spin_trap(); | |
} | |
loop(); | |
} | |
return 0; | |
} | |
void loop (void) | |
{ | |
wdt_reset(); | |
if (bluetooth_is_connected()) | |
{ | |
leds_blue_on(); | |
bluetooth_read(); | |
} | |
else | |
{ | |
leds_blue_off(); | |
} | |
} | |
void spin_trap (void) | |
{ | |
while (1) | |
{ | |
wdt_reset(); | |
asm("nop"); | |
} | |
} | |
void spin_loop (uint32_t ticks) | |
{ | |
for (uint32_t i = 0; i < ticks; ++i) | |
{ | |
wdt_reset(); | |
asm("nop"); | |
} | |
} | |
void bluetooth_init (void) | |
{ | |
// UART | |
UBRR1L = 25; // set baud rate to 38.4k | |
UCSR1A |= (1 << U2X1); // turn off double speed | |
UCSR1A |= (1 << TXC1); // clear any existing transmits | |
UCSR1B |= (1 << TXEN1) | (1 << RXEN1); // enable transmitter and receiver | |
UCSR1C = (1 << UMSEL11) | (1 << UCSZ11) | (1 << UCSZ10); // 8 data bits, 1 stop bit | |
// Reset pin | |
PIN_SET_OUTPUT(DDRC, 7); | |
PIN_SET_HIGH(PORTC, 7); | |
// RTS | |
PIN_SET_INPUT(DDRA, 2); | |
PIN_SET_LOW(PORTA, 2); | |
// CTS | |
PIN_SET_OUTPUT(DDRB, 1); | |
PIN_SET_LOW(PORTB, 1); | |
// Connection status pin | |
PIN_SET_INPUT(DDRC, 5); | |
PIN_SET_LOW(PORTC, 5); | |
} | |
void bluetooth_request_to_send (uint8_t rts) | |
{ | |
if (rts) | |
{ | |
PIN_SET_LOW(PORTB, 1); | |
} | |
else | |
{ | |
PIN_SET_HIGH(PORTB, 1); | |
} | |
} | |
uint8_t bluetooth_is_clear_to_send (void) | |
{ | |
if (PIN_IS_LOW(PINA, 2)) | |
{ | |
return 1; | |
} | |
else | |
{ | |
return 0; | |
} | |
} | |
void bluetooth_read (void) | |
{ | |
#define N 128 // number of bytes to buffer | |
#define M 4 // number of times to repeat buffer back to the client | |
static uint8_t buf[N]; // the buffer | |
static uint8_t p = 0; // buffer read index | |
static uint8_t q = 0; // buffer write index | |
static uint8_t r = 0; // repeat counter | |
bluetooth_request_to_send(1); // tell client to start sending data | |
while (bit_is_set(UCSR1A, RXC1) || p == N) // while there is data to receive | |
{ | |
if (p == N) // if buffer is full | |
{ | |
bluetooth_request_to_send(0); // tell client to stop sending data | |
while (r++ < M) // repeat `M` times | |
{ | |
while (q < p) // write the read buffer back to the client | |
{ | |
bluetooth_write(buf[q++]); | |
} | |
q = 0; | |
} | |
p = 0; | |
r = 0; | |
bluetooth_request_to_send(1); // tell client to start sending data again | |
} | |
else | |
{ | |
buf[p++] = UDR1; // receive a byte | |
} | |
} | |
} | |
void bluetooth_write (uint8_t write_byte) | |
{ | |
while (0 == bluetooth_is_clear_to_send()) // the client cannot receive data now | |
{ | |
leds_red_on(); // THIS IS WHERE THINGS GET STUCK | |
wdt_reset(); | |
continue; | |
} | |
while (bit_is_clear(UCSR1A, UDRE1)) | |
{ | |
wdt_reset(); | |
continue; | |
} | |
UDR1 = write_byte; | |
while (bit_is_clear(UCSR1A, TXC1)) | |
{ | |
wdt_reset(); | |
continue; | |
} | |
UCSR1A |= (1 << TXC1); | |
} | |
uint8_t bluetooth_is_connected (void) | |
{ | |
return PIN_IS_HIGH(PINC, 5); | |
} | |
void leds_init (void) | |
{ | |
// Blue LED | |
PIN_SET_OUTPUT(DDRC, 2); | |
PIN_SET_HIGH(PORTC, 2); | |
// Green LED | |
PIN_SET_OUTPUT(DDRA, 0); | |
PIN_SET_HIGH(PORTA, 0); | |
// Red LED | |
PIN_SET_OUTPUT(DDRA, 7); | |
PIN_SET_HIGH(PORTA, 7); | |
} | |
void leds_blue_on (void) | |
{ | |
PIN_SET_LOW(PORTC, 2); | |
} | |
void leds_blue_off (void) | |
{ | |
PIN_SET_HIGH(PORTC, 2); | |
} | |
void leds_green_on (void) | |
{ | |
PIN_SET_LOW(PORTA, 0); | |
} | |
void leds_green_off (void) | |
{ | |
PIN_SET_HIGH(PORTA, 0); | |
} | |
void leds_red_on (void) | |
{ | |
PIN_SET_LOW(PORTA, 7); | |
} | |
void leds_red_off (void) | |
{ | |
PIN_SET_HIGH(PORTA, 7); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment