#include "wiring_private.h"
// Area modulo UART SW usw
#define USWNRXB 32
// Tau Baud Rate in TICKS: 833 per 300, 26 per 9600
#define USWBRT 26
#define USWSTA 13
volatile uint8_t uswtmp, uswmask, uswidx, uswbyte[USWNRXB];
volatile uint8_t uswtmr, uswmasr, uswidr, uswfer[USWNRXB/8+1];
volatile uint8_t uswtmt, uswmast, uswidt, uswntx, uswtxb, uswbytt[USWNRXB/8+1];
void setup() {
Serial.begin(9600);
// Inizializzazione Area UART
uswidx = uswmask = uswtmp = 0;
sbi(PCMSK2, PCINT18);
sbi(PCICR, PCIE2);
OCR0A = 0;
// cbi(TCCR0A, WGM00); // Normal Mode
// cbi(TCCR0A, WGM01); // Normal Mode
// cbi(TCCR0A, WGM02); // Normal Mode
// ~ <- (Alt + 126)
TCCR0A &=~(_BV(WGM02) | _BV(WGM01) | _BV(WGM00)); // Normal Mode
sbi(TIMSK0, OCIE0A);
// Output D3 per testing
sbi(DDRD, 3);
Serial.print("Salve, mondo\n");
delay(1000);
Serial.println(F_CPU);
for(uint8_t i = 0; i < uswidx; i++) {
Serial.write(uswbyte[i]);
if(uswfer[i] == 0) Serial.write('@');
}
Serial.write(10);
// Inizzializzazione modulo TX
sbi(DDRD, 3); // Normalmente TX
sbi(PORTD, 3); // Normalmente alto
OCR0B = 0;
uswtmt = 0;
uswmast = 0xff;
uswntx = uswidx;
OCR0B = TCNT0 + 1;
sbi(TIMSK0, OCIE0B);
}
void loop() {
}
ISR(TIMER0_COMPB_vect) {
if(uswntx) {
sbi(PORTD, 4);
if(uswmast) {
if(uswmast == 0xff) {
cbi(PORTD, 3); // Start bit
OCR0B = TCNT0 + USWBRT;
uswmast = 1;
uswtmt = uswbytt[uswidt++];
}
else {}
if(uswtmt & uswmast) sbi(PORTD, 3);
else cbi(PORTD,3);
uswmask <<= 1;
OCR0B += USWBRT;
}
else {
sbi(PORTD, 3); // Stop bit
OCR0B += USWBRT;
uswntx--;
uswidt--;
uswmast = 0xff;
}
cbi(PORTD, 4);
} else cbi(TIMSK0, OCIE0B);
}
ISR(TIMER0_COMPA_vect) {
// ISR(TIMER0_COMPA_vect, ISR_NAKED) {}
uint8_t mask = uswmask;
if(mask) {
sbi(PORTD, 3);
cbi(PORTD, 3);
asm("reti \n");
uint8_t tbit = PIND & 0x04; //
OCR0A += USWBRT;
if(mask == 0xff) {
uint8_t ie = uswidx >> 3;
uint8_t ie1 = uswidx &7;
if(ie1 == 0) uswfer[ie] = 0;
if(tbit == 0) uswfer[ie] |= (1 << ie1);
if(uswidx < USWNRXB) uswidx++;
}
else {
if(tbit) uswtmp |= uswmask;
uswmasr <<= 1;
if(uswmasr == 0) {
if(uswidr < USWNRXB/8+1) uswbyte[uswidx] = uswtmp;
uswmasr = 0xff;
// sbi(PCMSK2, PCINT18); // Riattiva interrupt su PC
}
}
uswmask = mask;
cbi(PORTD, 3);
};
}
ISR(PCINT2_vect){
if((PIND & 4) == 0) {
OCR0A = TCNT0 + USWBRT + USWSTA;
cbi(PCMSK2, PCINT18);
uswmask = 1;
uswtmp = 0;
}
}