Parcourir la source

Implement missing AVR SPI register emulation on Teensy 3.x

main
PaulStoffregen il y a 7 ans
Parent
révision
8f137ff3ff
1 fichiers modifiés avec 53 ajouts et 24 suppressions
  1. +53
    -24
      teensy3/avr_emulation.h

+ 53
- 24
teensy3/avr_emulation.h Voir le fichier

@@ -884,16 +884,31 @@ public:
uint32_t ctar = SPI0_CTAR0;
if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband
if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
if ((val & 3) == 1) {
// TODO: implement - is this ever really needed
} else if ((val & 3) == 2) {
// TODO: implement - is this ever really needed
} else if ((val & 3) == 3) {
// TODO: implement - is this ever really needed
}
if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) {
ctar |= SPI_CTAR_CPHA;
// TODO: clear SPI_CTAR_CSSCK, set SPI_CTAR_ASC
ctar &= 0xFFFF00FF;
ctar |= SPI_CTAR_ASC(ctar & 15);
}
if ((val & 3) != 0) {
uint32_t br = ctar & 15;
uint32_t priorval;
if (br <= 1) priorval = 0;
else if (br <= 4) priorval = 1;
else if (br <= 6) priorval = 2;
else priorval = 3;
uint32_t newval = priorval | (val & 3);
if (newval != priorval) {
if (newval == 0) br = 1;
else if (newval == 0) br = 4;
else if (newval == 0) br = 6;
else br = 7;
ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
if ((ctar & SPI_CTAR_CPHA)) {
ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
} else {
ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
}
}
}
update_ctar(ctar);
}
@@ -922,16 +937,31 @@ public:
uint32_t ctar = SPI0_CTAR0;
if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband
if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL;
if ((val & 3) == 0) {
// TODO: implement - is this ever really needed
} else if ((val & 3) == 1) {
// TODO: implement - is this ever really needed
} else if ((val & 3) == 2) {
// TODO: implement - is this ever really needed
}
if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) {
ctar &= ~SPI_CTAR_CPHA;
// TODO: set SPI_CTAR_ASC, clear SPI_CTAR_CSSCK
ctar &= 0xFFFF00FF;
ctar |= SPI_CTAR_CSSCK(ctar & 15);
}
if ((val & 3) != 3) {
uint32_t br = ctar & 15;
uint32_t priorval;
if (br <= 1) priorval = 0;
else if (br <= 4) priorval = 1;
else if (br <= 6) priorval = 2;
else priorval = 3;
uint32_t newval = priorval & (val & 3);
if (newval != priorval) {
if (newval == 0) br = 1;
else if (newval == 0) br = 4;
else if (newval == 0) br = 6;
else br = 7;
ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
if ((ctar & SPI_CTAR_CPHA)) {
ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
} else {
ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
}
}
}
update_ctar(ctar);
}
@@ -947,20 +977,19 @@ public:
if ((val & (1<<DORD)) && (SPI0_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);
if ((val & (1<<CPOL)) && (SPI0_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL);
if ((val & (1<<CPHA)) && (SPI0_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA);
if ((val & 3) == 3) {
if ((val & 3) != 0) {
uint32_t dbr = SPI0_CTAR0 & 15;
uint32_t spr10;
if (dbr <= 1) {
spr10 = 0;
} else if (dbr <= 4) {
ret |= (1<<SPR0);
spr10 |= (1<<SPR0);
} else if (dbr <= 6) {
ret |= (1<<SPR1);
spr10 |= (1<<SPR1);
} else {
ret |= (1<<SPR1)|(1<<SPR0);
spr10 |= (1<<SPR1)|(1<<SPR0);
}
} else if ((val & 3) == 1) {
// TODO: implement - is this ever really needed
} else if ((val & 3) == 2) {
// TODO: implement - is this ever really needed
ret |= spr10 & (val & 3);
}
if (val & (1<<SPE) && (!(SPI0_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE);
if (val & (1<<MSTR) && (SPI0_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR);

Chargement…
Annuler
Enregistrer