#include "wiring_private.h"
// Area UART SW (usw)
#define USWNRXB 32
#define USWNTXB 32
// Tau Baud Rate in TICKS: 833 per 300, 26 per 9600
#define USWBRT 26 // define è la sostituzione letterale delle costanti
#define USWSTART 13
volatile uint8_t uswbuffer, uswmask, uswidx, uswbyte[USWNRXB];
volatile uint8_t uswtmr, uswmasr, uswidr, uswfer[USWNRXB/8+1];
volatile uint8_t uswtmt, uswmast, uswidt, uswntx, uswbytt[USWNRXB];
//
void setup() {
Serial.begin(9600);
// Inizializzazione Area UART usw
uswidx=uswmask=uswbuffer=uswidr=0;
uswmasr=1;
// Abilito l'interrupt
sbi(PCMSK2, PCINT18);
sbi(PCICR, PCIE2);
OCR0A=0;
// Abilito l'interrupt
// cbi(TCCR0A, WGM00); // Normal mode
// cbi(TCCR0A, WGM01); // Normal mode
TCCR0A &=~(_BV(WGM02)|_BV(WGM01)|_BV(WGM00)); // Normal mode
sbi(TIMSK0, OCIE0A);
// Output D4 per testing
sbi(DDRD, 4);
//
Serial.print("Salve, mondo\n");
delay(1000);
Serial.println(F_CPU);
for (uint8_t i=0; i<uswidx; i++){
Serial.write(uswbyte[i]);
uswbytt[i] = uswbyte[i];
if (uswfer[uswidx >>3] & (1 << uswidx&7)) Serial.write('@');
}
Serial.write(10);
// Inizializzazione modulo TX (Trasmettitore)
sbi(DDRD, 3); // TX Pin
sbi(PORTD, 3); // Normalmente alto H
uswidt=0;
uswmast=0xff; // bit di start
uswntx = uswidx;
OCR0B=TCNT0+USWBRT;
cbi(TIFR0,OCF0B);
sbi(TIMSK0, OCIE0B); // Active Interrupt
delay(1000);
while(Serial.available()) Serial.write(Serial.read());
}
void loop() {
}
ISR(TIMER0_COMPB_vect) {
if (uswntx) {
sbi(PORTD,4);
if (uswmast) {
if (uswmast == 0xff) {
cbi(PORTD,3); // Start del bit (bit di start)
OCR0B=TCNT0+USWBRT;
uswmast=1;
uswtmt = uswbytt[uswidt];
} else {
if(uswtmt & uswmast) sbi(PORTD,3); else cbi(PORTD, 3);
uswmast <<=1;
OCR0B += USWBRT;
}
} else {
sbi(PORTD,3); // Stop bit
OCR0B += USWBRT;
uswntx--; uswidt++;
uswmast=0xff;
}
cbi(PORTD,4);
} else cbi(TIMSK0, OCIE0B); // Disable Interrupt
}
ISR(TIMER0_COMPA_vect) {
// ISR(TIMER0_COMPA_vect, ISR_NAKED) {
uint8_t mask = uswmask;
// Costruzione del byte
if(mask){
// sbi(PORTD,4); // sul 3 faccio uscire un segnale alto
uint8_t tbit = PIND & 0x04;
OCR0A += USWBRT;
if(mask == 0xff) { // uswfer[uswidx >>3] |= 1 << uswidx&7
if (tbit == 0) uswtmr |= uswmasr;
uswmasr <<=1;
if(uswmasr == 0) {
if (uswidr < USWNRXB/8+1) uswfer[uswidr++] = uswtmr;
uswmasr=1;
uswtmr=0;
}
if (uswidx < USWNRXB) uswidx++;
mask = 0;
sbi(PCMSK2, PCINT18); // Riattiva interrupt su PC
} else {
if(tbit) uswbuffer |= mask;
mask <<=1;
if (mask == 0) {
if (uswidx < USWNRXB) uswbyte[uswidx]=uswbuffer;
// if (uswidx < USWNRXB) *puswbyte++ =uswbuffer; // Occupa più dell'opzione sopra
mask=0xff; // Riattiva interrupt su PC
}
}
uswmask=mask;
// cbi(PORTD,4);
}
}
// Macro stantard/direttiva interrupt service routine
ISR(PCINT2_vect){
if ((PIND & 4) == 0) {
OCR0A = TCNT0+USWBRT+USWSTART;
// Azzero l'interrupt
cbi(PCMSK2,PCINT18);
uswmask = 1;
uswbuffer = 0;
}
}