A part of the file bluevirq.c:
Please notice that there if hwsetup() was name init() the Arduino will work.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
//#define F_CPU 18432000
#ifndef F_CPU
#define F_CPU 16000000
#endif
#define BAUD 57600
#define PRESCALE1 8
#define BITTIME(x) ( ((x) * F_CPU) / PRESCALE1 / BAUD)
/*-------------------------------------------------------------------------*/
#define INMSGSIZE 24
unsigned char inbuf[256], v1buf[256];
volatile unsigned char v1head = 0, v1tail = 0, inhead = 0, intail = 0;
static volatile unsigned int bitcnt;
static unsigned int frametime;
// Time Slice processor
// This counts character times to find the slot to transmit.
// Each slot is 45 character times wide
// FIXME - doesn't try to resync or otherwise avoid collisions with other devices
ISR(TIMER4_COMPB_vect)
{
OCR4B += BITTIME(10);
frametime++;
if (frametime < 45 * slice)
return;
if (inmsgstate != 4) { // nothing for this frame
TIMSK4 &= ~_BV(OCIE4B); // slice processor off
UCSR3B &= ~_BV(TXEN0); // TX off - just in case
frametime = 0;
return;
}
if (
#ifdef ANYSLICE
(slice == 0 && frametime == 1) ||
#endif
frametime == 45 * slice) { // At current time slice
// Holdoff for late previous time slice
if (bitcnt)
frametime--;
else
UCSR3B |= _BV(TXEN0); // TX on
return;
}
if (frametime >= 45 * (slice + 1)) { // end of time slice
TIMSK4 &= ~_BV(OCIE4B); // slice processor off
UCSR3B &= ~_BV(TXEN0); // TX off
frametime = 0;
inmsgstate = 0;
return;
}
if (!(frametime & 1)) { // Data Out Pacing, every other frame until done
unsigned char ptr = (frametime - (45 * slice + 1)) >> 1;
if (ptr < inmsglen)
UDR3 = inmsgbuf[ptr];
if (ptr > inmsglen)
UCSR3B &= ~_BV(TXEN0); // TX off
}
}
static unsigned char outchar; // bitbang UART receive register
static unsigned char polarity; // which edge are we looking for
volatile unsigned legacy;
//Stopbit for software UART
ISR(TIMER4_COMPA_vect)
{
TIMSK4 &= ~_BV(OCIE4A); // disable
if (!polarity) { // not break condition
while (bitcnt < 10) { // fill in one bits up to stop bit
bitcnt++;
outchar >>= 1;
outchar |= 0x80;
}
if (transp)
UDR0 = outchar;
else
v1buf[v1head++] = outchar;
dostate(outchar);
if(legacy)
legacy--;
}
else { // break, reset things for next start bit
TCCR4B &= ~_BV(ICES1);
polarity = 0;
}
bitcnt = 0;
}
// Software UART via edges
char legbits[36] = "+medcbap87654321gfKALFFFSSSRRRIXMNOP";
unsigned long legimg;
ISR(TIMER4_CAPT_vect)
{
static unsigned lastedge;
unsigned thisedge = ICR4;
TCCR4B ^= _BV(ICES1);
unsigned width = thisedge - lastedge;
lastedge = thisedge;
polarity ^= 1;
// Legacy Mode
#define LEGABIT (504)
#define USTICS(us) ((us) * (F_CPU/PRESCALE1)/1000000)
if( legacy > 100 ) {
if( width < USTICS(LEGABIT)/5 ) { // normal bits for ESP
bitcnt = 0;
legacy--;
return;
}
if( width > USTICS(LEGABIT)*2 ) { // 9.58 mS nominal
PORTB ^= _BV(PB7);
bitcnt = 0;
;//UDR2 = UDR0 = '\n';
return;
}
if( polarity )
return;
++bitcnt;
legimg <<= 1;
if( width < USTICS(LEGABIT)/2 ) {
if( bitcnt < 37 ) {
;//UDR2 = UDR0 = legbits[bitcnt-1];
legimg |= 1;
}
return;
}
if(width > USTICS(LEGABIT) - 25 && width < USTICS(LEGABIT) + 25 ) {
if( (++legacy & 1023) == 0 ) {
PORTB ^= _BV(PB7);
UDR0 = 'L';
}
legacy &= 4095;
}
/* toggle interrupt on rising/falling edge */
if (polarity && !bitcnt) { // start bit
OCR4A = lastedge + BITTIME(9) + BITTIME(1) / 2;
TIFR4 |= _BV(OCF4A); /* clear compare match interrupt */
TIMSK4 |= _BV(OCIE4A); /* enable compare match interrupt */
bitcnt = 1;
return;
}
width += BITTIME(1) / 2; // round up
while (width >= BITTIME(1)) { // Shift in bits based on width
width -= BITTIME(1);
bitcnt++;
outchar >>= 1;
if (polarity)
outchar |= 0x80;
}
}
//void init() // GLOW: if it is 'void init()' it will work !!!!!!!!!!!!!!
void hwsetup()
{
cli();
v1state = inmsgstate = inmsglen = polarity = bitcnt = 0;
DDRB = _BV(PB7); // PB7/LED
// UART init
#include <util/setbaud.h>
UBRR3H = UBRR0H = UBRRH_VALUE;
UBRR3L = UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR3A = UCSR0A = _BV(U2X3);
#endif
UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31); // 8N1
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); // Enable TX and RX
// for UART1, only TX is enabled, and only when sending in the right timeslice
// Timer init
GTCCR = 0; //_BV(PSR10); /* reset prescaler */
// trigger on falling edge (default), noise cancel
// lower 3 bits is div, off,1,8,64,256,1024,extfall,extris ; CS12,11,10
TCCR4B = _BV(ICNC1) | _BV(CS11);
// clear and enable Input Capture interrupt
TIFR4 |= _BV(ICF4) | _BV(TOV4) | _BV(OCF4A) | _BV(OCF4B);
TIMSK4 = _BV(ICIE4); // enable input capture only
sei(); // enable interrupts
// and sleep between events
set_sleep_mode(SLEEP_MODE_IDLE);
}