Skip to content

Instantly share code, notes, and snippets.

@programmarchy
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save programmarchy/8ffa021301996750418e to your computer and use it in GitHub Desktop.
Save programmarchy/8ffa021301996750418e to your computer and use it in GitHub Desktop.
flow control test
#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