📄 main.c
字号:
last_x = 0;
correction = 0;
toggle = 9 * (pulsesPerBit >> 3);
while ( TIMSK & (1<<TOIE2) ) { //wait until done
z = TCNT0 - last_z;
if (z >= toggle) {
icr = ICR1;
capt = icr - last_capture;
x = capt >> 3; //(y/8)
if ((debug_mode & 1) == 0) { //decode
if (capt < 2*halfDataRate) { //if the half bit period is not so long
x += correction; //apply correction
correction = 0;
if (bit_pos == 0) { //resolve the bit for each captured pair
if (pulsesPerBit == 8) { //high data rate
if (last_x + x > 77) { //one more pulse is measured, save it to next bit period
correction = 4;
x -= correction;
}
// store_pulse( last_x + x );
y = 0;
if ( (last_x <= 0x27) && (x <= 0x27) ) y = 1;
yvld = 0;
if ((last_x >= 0x28) && (last_x <= 0x2A) && (x == 0x25)) yvld = 1;
// store_pulse(last_x);
// store_pulse(x);
store_bit( y, yvld );
} else { //low data rate
if ((uint16_t)last_x + x > 0x130) { //one more pulse is measured, save it to next bit period
correction = 4;
x -= correction;
}
y = 0;
if ( (last_x <= 0xA0) && (x <= 0xA0) ) y = 1;
yvld = 0;
if ((last_x >= 0xA1) && (last_x <= 0x2A) && (x == 0x25)) yvld = 1;
// store_pulse(last_x);
// store_pulse(x);
store_bit( y, yvld );
}
}
} else { //quite good pause? => error
store_bit(0, 1); //
}
} else { //raw data capture
if (capt < 2*halfDataRate) {
x += correction; //apply the correction
correction = 0;
//raw capture
store_pulse(z); //z
if (bit_pos == 0) { //resolve the correctuib for each captured pair
if (pulsesPerBit == 8) { //high data rate
if (last_x + x > 77) { //one more pulse is measured, save it to next bit period
correction = 4;
x -= correction;
}
} else { //low data rate
}
}
store_pulse(x); //y
} else { //quite good pause? => error
store_pulse(0xFF); //
store_pulse(capt);
store_pulse(capt>>8);
}
//#ifdef DEBUG
// PORTC = PINC ^ (1<<DBG_TRANS);
//#endif
}
bit_pos ^= 1;
toggle = (bit_pos | 8) * (pulsesPerBit >> 3);
if (correction != 0) toggle--;
last_z += z;
last_x = x;
last_capture = icr;
}
}
//there is no information about EOF
//data validity check is left on CRC
sof = 2;
#if 0
//#ifdef DEBUG
UDR = capture_cnt;
while (!(UCSRA & (1<<UDRE)))
{};
UDR = dbg_cnt;
while (!(UCSRA & (1<<UDRE)))
{};
UDR = x;
while (!(UCSRA & (1<<UDRE)))
{};
UDR = TCNT0;
while (!(UCSRA & (1<<UDRE)))
{};
UDR = last_z;
while (!(UCSRA & (1<<UDRE)))
{};
#endif
}
// ==================================================================
// Down Link setup function
// Requires: maxCaptureTimeLow and maxCaptureTimeHi
// (located here instead of level2 because of register variables)
void Capture(uint8_t style) {
uint8_t last_cnt;
TCCR0 = 0; //disable Counter0
TCCR1B = 0; //disable Counter1
pulsesPerBit2 = 2 * pulsesPerBit;
pulsesPerBit3 = 3 * pulsesPerBit;
if (!bufferClean) ClearCaptureBuffers();
bufferClean = 0;
previous_delay = 0;
captured_bit_count = 0; //reset some values
capture_cnt = 0;
bit_pos = 1;
sof = 0;
last_valid = 0;
last_capture = TCNT1;
old_capture = TCNT1;
currentMaxTimeHi = ~maxCaptureTimeHi; //set hi byte of maximum capture timer2 timeout
TCNT2 = ~maxCaptureTimeLow; //set low byte timer2 timeout
TCNT0 = 0; //clear timer0
TIFR = TIFR | (1<<ICF1) | (1<<TOV1) | (1<<OCF2) | (1<<TOV2); //clear pending interrupts
sbi( TIMSK, TOIE2 ); //enable timer2 overflow for both
if (style != 5) {
if((decode_number & 1) == 0) {
sbi( TIMSK, TICIE1 ); //enable timer1 capture for ASK only
}
TCCR0 = (1<<CS02)|(1<<CS01); //external clock source, falling edge
TCCR1B = (1<<ICNC1)|(1<<CS10); //noise canceler, clk_io clock, falling edge
TCCR2 = (1<<CS21)|(1<<CS20); //run! at clk/32
} else {
TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11); //noise canceler, clk/8 clock, start with rising edge
TCCR2 = (1<<CS22); //run! at clk/64
}
#if 0
//#ifdef DEBUG
PORTD = PIND ^ (1<<DBG_FORWARD);
#endif
if (style == 5) {
EM4006_polling();
}
else if((decode_number & 1) == 0) {
while ( TIMSK & (1<<TOIE2) ) //wait until done for ASK
{}
} else {
dual_subcarrier_polling(); //do polling until done for FSK
}
TCCR0 = 0; //stop all
TCCR1B = 0;
TCCR2 = 0;
TIMSK = TIMSK & (0xFF ^ ((1<<TICIE1) | (1<<TOIE2))); //disable timer1 capture, timer2 overflow
TIFR = TIFR | (1<<ICF1) | (1<<TOV1) | (1<<OCF2) | (1<<TOV2); //clear pending interrupts
//#if 0
#ifdef DEBUG
PORTD = PIND ^ (1<<DBG_FORWARD);
#endif
last_cnt = TCNT0;
if (debug_mode != 1) {
while (captured_bit_count != 0) //flush captured bits
store_bit(0,1);
} else {
if ((decode_number & 1) == 0) //store number of pulses of last chunk for ASK
store_pulse(last_cnt);
else //flush captured pulses for FSK
store_pulse((uint8_t)(last_cnt - last_z));
}
if((style != 5) && (decode_number & 1) == 0) { //ASK EOF resolution
if ((sof == 1) && (last_cnt >= (3*pulsesPerBit-TOLERANCE)) && (last_cnt <= (3*pulsesPerBit+TOLERANCE))) //kludge for very long delays
sof = 2;
}
}
// ==================================================================
// Wait
void Wait(uint16_t period) {
period = -period;
TCCR2 = 0; //disable Counter2
TCNT2 = period; //set timer with initial time
TIFR = TIFR | (1<<OCF2) | (1<<TOV2); //clear pending interrupts
currentMaxTimeHi = period >> 8;
sbi(TIMSK, TOIE2); //enable overflow
TCCR2 = (1<<CS21)|(1<<CS20); //run! at clk/32
while ( TIMSK & (1<<TOIE2) ) //wait until done
{}
TCCR2 = 0; //stop
#if 0
//#ifdef DEBUG
cbi(PORTC, DBG_TRANS);
sbi(PORTC, DBG_TRANS);
cbi(PORTC, DBG_TRANS);
#endif
}
// ==================================================================
// ==================================================================
// INTERRUPT ROUTINES
// ==================================================================
SIGNAL (SIG_OVERFLOW2)
{
if (currentMaxTimeHi++ == 0xFF) { //hi datarate
TIMSK = 0; //finished, disable all
}
}
// ==================================================================
// ==================================================================
// EM4006 capture routine
void EM4006_polling(void) {
uint16_t capt;
uint16_t icr;
uint8_t x;
uint8_t y;
uint8_t bit;
uint8_t last_bit;
uint8_t dataRate;
dataRate = EM4006_bitRate >> EM4006_scale; //compute the scaled datarate
last_bit = TCCR1B & (1 << ICES1);
while ( TIMSK & (1<<TOIE2) ) { //wait until done
if ( bit_is_set( TIFR, ICF1 ) != 0 ) {
sbi ( TIFR, ICF1 ); //clear capture flag
icr = ICR1;
bit = TCCR1B ^ (1<<ICES1); //invert capture edge
TCCR1B = bit;
bit = bit & (1<<ICES1);
capt = icr - last_capture;
capt >>= EM4006_scale; //working for higher bitrates only
// ............................................................
if (debug_mode != 1) { //normal/decode debug mode
if (capt >= 3 * dataRate) { // long pulse is rejected here
last_bit = 1;
store_bit ( 0, 1); // store bad bit
store_bit ( 1, 0); // store expected start bit
} else
if (capt < dataRate >> 1) { // too short pulse is rejected here
last_bit = 0;
store_bit ( 0, 1); // store bad bit
} else {
y = 0;
x = capt - (dataRate >> 2); // dynamic resolution (dependent on datarate)
// from now on, 8bit operations are enough
if (x >= dataRate) { // when longer than that, try to subtract once more
x -= dataRate;
y++;
if (x >= (dataRate >> 1)) { // when longer than that, try to subtract once more
y++;
}
}
if (y==2) { // only combination "101"
store_bit(0, 0);
store_bit(1, 0);
last_bit = 1;
} else if (!y) { // the same bit as previously
store_bit(last_bit, 0);
} else if (last_bit) { // y==1, last_bit=1
store_bit(0, 0);
last_bit = 0;
} else { // y==1, last_bit=0
store_bit(0, 0);
store_bit(1, 0);
last_bit = 1;
}
}
}
else
if (debug_mode == 1) { //raw data capture
if (bit == last_bit) {
store_pulse(0xFE); //subsampling
} else {
if (capt <= 256) {
//raw capture
store_pulse(bit); //phase
store_pulse(capt); //length
} else { //quite good pause? => error
store_pulse(0xFF); //
store_pulse(capt);
store_pulse(capt>>8);
}
}
last_bit = bit;
}
#ifdef DEBUG
PORTC = PINC ^ (1<<DBG_TRANS);
#endif
last_capture = icr;
}
}
//there is no information about EOF
//data validity check is left on CRC
sof = 2;
}
// ==================================================================
// ==================================================================
// ==================================================================
int main(void)
{
SetLEDOn();
watchdog_reset = bit_is_set(MCUCSR, WDRF); //capture watchdog resets
avr_ini(); // initialization
main_receiver();
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -