Reworked DAC ISR

This commit is contained in:
Mark Qvist 2014-04-04 08:24:22 +02:00
parent ee9b5ec307
commit d35f134128
3 changed files with 85 additions and 119 deletions

View File

@ -209,145 +209,111 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
// Signal modulation and DAC // // Signal modulation and DAC //
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
static void afsk_txStart(Afsk *af)
{
if (!af->sending)
{
af->phaseInc = MARK_INC;
af->phaseAcc = 0;
af->bitstuffCount = 0;
af->sending = true;
af->preambleLength = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000);
AFSK_DAC_IRQ_START(af->dacPin);
}
ATOMIC(af->tailLength = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN * BITRATE, 8000));
}
#define BIT_STUFF_LEN 5 #define BIT_STUFF_LEN 5
#define SWITCH_TONE(inc) (((inc) == MARK_INC) ? SPACE_INC : MARK_INC) #define SWITCH_TONE(inc) (((inc) == MARK_INC) ? SPACE_INC : MARK_INC)
/** static void afsk_txStart(Afsk *afsk) {
* DAC ISR callback. if (!afsk->sending) {
* This function has to be called by the DAC ISR when a sample of the configured afsk->phaseInc = MARK_INC;
* channel has been converted out. afsk->phaseAcc = 0;
*/ afsk->bitstuffCount = 0;
uint8_t afsk_dac_isr(Afsk *af) afsk->sending = true;
{ afsk->preambleLength = DIV_ROUND(CONFIG_AFSK_PREAMBLE_LEN * BITRATE, 8000);
AFSK_STROBE_ON(); AFSK_DAC_IRQ_START(afsk->dacPin);
}
ATOMIC(afsk->tailLength = DIV_ROUND(CONFIG_AFSK_TRAILER_LEN * BITRATE, 8000));
}
/* Check if we are at a start of a sample cycle */ // This is the DAC ISR, called at sampling ratewhenever the DAC IRQ is on.
if (af->sampleIndex == 0) // It modulates the data to be transmitted and returns a value directly
{ // for output on the DAC
if (af->txBit == 0) uint8_t afsk_dac_isr(Afsk *afsk) {
{ // Check whether we are at the beginning of a sample
/* We have just finished transimitting a char, get a new one. */ if (afsk->sampleIndex == 0) {
if (fifo_isempty(&af->txFifo) && af->tailLength == 0) if (afsk->txBit == 0) {
{ // If TX FIFO is empty and tail-length has decremented to 0
AFSK_DAC_IRQ_STOP(af->dacPin); // we are done, stop the IRQ and reset
af->sending = false; if (fifo_isempty(&afsk->txFifo) && afsk->tailLength == 0) {
AFSK_STROBE_OFF(); AFSK_DAC_IRQ_STOP(afsk->dacPin);
afsk->sending = false;
return 0; return 0;
} } else {
else // Reset the bitstuff counter if we have just sent
{ // a bitstuffed byte
/* if (!afsk->bitStuff) afsk->bitstuffCount = 0;
* If we have just finished sending an unstuffed byte, // Reset bitstuff indicator to true
* reset bitstuff counter. afsk->bitStuff = true;
*/
if (!af->bitStuff)
af->bitstuffCount = 0;
af->bitStuff = true; // Check if we are in preamble or tail
if (afsk->preambleLength == 0) {
/* if (fifo_isempty(&afsk->txFifo)) {
* Handle preamble and trailer afsk->tailLength--;
*/ afsk->currentOutputByte = HDLC_FLAG;
if (af->preambleLength == 0) } else {
{ // If preamble is already transmitted and TX
if (fifo_isempty(&af->txFifo)) // buffer is not empty, we should get a byte
{ // for transmission
af->tailLength--; afsk->currentOutputByte = fifo_pop(&afsk->txFifo);
af->currentOutputByte = HDLC_FLAG;
} }
else } else {
af->currentOutputByte = fifo_pop(&af->txFifo); afsk->preambleLength--;
} afsk->currentOutputByte = HDLC_FLAG;
else
{
af->preambleLength--;
af->currentOutputByte = HDLC_FLAG;
} }
/* Handle char escape */ // Handle escape sequences
if (af->currentOutputByte == AX25_ESC) if (afsk->currentOutputByte == AX25_ESC) {
{ if (fifo_isempty(&afsk->txFifo)) {
if (fifo_isempty(&af->txFifo)) AFSK_DAC_IRQ_STOP(afsk->dacPin);
{ afsk->sending = false;
AFSK_DAC_IRQ_STOP(af->dacPin);
af->sending = false;
AFSK_STROBE_OFF();
return 0; return 0;
} else {
afsk->currentOutputByte = fifo_pop(&afsk->txFifo);
} }
else } else if (afsk->currentOutputByte == HDLC_FLAG || afsk->currentOutputByte == HDLC_RESET) {
af->currentOutputByte = fifo_pop(&af->txFifo); afsk->bitStuff = false;
} }
else if (af->currentOutputByte == HDLC_FLAG || af->currentOutputByte == HDLC_RESET)
/* If these chars are not escaped disable bit stuffing */
af->bitStuff = false;
} }
/* Start with LSB mask */ // Start with LSB mask
af->txBit = 0x01; afsk->txBit = 0x01;
} }
/* check for bit stuffing */ // Check for bit stuffing
if (af->bitStuff && af->bitstuffCount >= BIT_STUFF_LEN) if (afsk->bitStuff && afsk->bitstuffCount >= BIT_STUFF_LEN) {
{ afsk->bitstuffCount = 0;
/* If there are more than 5 ones in a row insert a 0 */ afsk->phaseInc = SWITCH_TONE(afsk->phaseInc);
af->bitstuffCount = 0; } else {
/* switch tone */ // We are using NRZI so if we want to transmit a 1
af->phaseInc = SWITCH_TONE(af->phaseInc); // the modulated signal will stay the same. For a 0
} // we make the signal transition
else if (afsk->currentOutputByte & afsk->txBit) {
{ // We don't do anything, aka stay on the same
/* // tone as before. We have sent one 1, so we
* NRZI: if we want to transmit a 1 the modulated frequency will stay // increment the bitstuff counter.
* unchanged; with a 0, there will be a change in the tone. afsk->bitstuffCount++;
*/ } else {
if (af->currentOutputByte & af->txBit) // We switch the tone, and reset the bitstuff
{ // counter, since we have now transmitted a
/* // zero
* Transmit a 1: afsk->bitstuffCount = 0;
* - Stay on the previous tone afsk->phaseInc = SWITCH_TONE(afsk->phaseInc);
* - Increase bit stuff counter
*/
af->bitstuffCount++;
}
else
{
/*
* Transmit a 0:
* - Reset bit stuff counter
* - Switch tone
*/
af->bitstuffCount = 0;
af->phaseInc = SWITCH_TONE(af->phaseInc);
} }
/* Go to the next bit */ // Move on to the next bit
af->txBit <<= 1; afsk->txBit <<= 1;
} }
af->sampleIndex = DAC_SAMPLESPERBIT;
afsk->sampleIndex = DAC_SAMPLESPERBIT;
} }
/* Get new sample and put it out on the DAC */ // Retrieve af new sample index and DAC it
af->phaseAcc += af->phaseInc; afsk->phaseAcc += afsk->phaseInc;
af->phaseAcc %= SIN_LEN; afsk->phaseAcc %= SIN_LEN;
afsk->sampleIndex--;
af->sampleIndex--; return sinSample(afsk->phaseAcc);
AFSK_STROBE_OFF();
return sinSample(af->phaseAcc);
} }
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// File operation overwrites for read/write // // File operation overwrites for read/write //
////////////////////////////////////////////////////// //////////////////////////////////////////////////////

View File

@ -30,7 +30,7 @@ static void message_callback(struct AX25Msg *msg)
kfile_printf(&ser.fd, "DATA: %.*s\r\n", msg->len, msg->info); kfile_printf(&ser.fd, "DATA: %.*s\r\n", msg->len, msg->info);
} }
////////////////////////////////////////////// ///////////////////////////////////////////////
static void init(void) static void init(void)

View File

@ -1,2 +1,2 @@
#define VERS_BUILD 108 #define VERS_BUILD 113
#define VERS_HOST "vixen" #define VERS_HOST "vixen"