#include #include #include #include #include "uartdrv.h" #define START_GAP_MIN 1500 #define ONE_WIDTH_MIN 170 #define ONE_WIDTH_MAX 250 #define ZERO_WIDTH_MIN 70 #define ZERO_WIDTH_MAX 140 typedef struct receivedData_s { uint8_t minuteDigit0; uint8_t minuteDigit1; uint8_t minuteOneCnt; uint8_t hourDigit0; uint8_t hourDigit1; uint8_t hourOneCnt; uint8_t dayDigit0; uint8_t dayDigit1; uint8_t weekdayDigit0; uint8_t monthDigit0; uint8_t monthDigit1; uint8_t yearDigit0; uint8_t yearDigit1; uint8_t dateOneCnt; } receivedData_t; typedef struct clock_s { uint8_t hour; uint8_t minute; uint8_t second; uint8_t day; uint8_t weekday; uint8_t month; uint8_t year; } clock_t; receivedData_t rd; volatile clock_t clock; volatile uint8_t tick; volatile uint16_t captValue = 0; volatile uint16_t gapValue = 0; ISR(TIMER2_OVF_vect) { clock.second++; if (clock.second >= 60) { clock.second = 0; clock.minute++; } if (clock.minute >= 60) { clock.minute = 0; clock.hour++; } if (clock.hour >= 24) { clock.hour = 0; } } ISR(INT0_vect) { uint16_t tmpCnt = TCNT1; gapValue = tmpCnt - captValue; TCNT1 = 0; } ISR(INT1_vect) { captValue = TCNT1; tick = 1; } int main() { uartdrvInit(); clock.hour = 0; clock.minute = 0; clock.second = 0; TCCR2 = 0b00000101; ASSR |= (1 << AS2); TIMSK |= (1 << TOIE2) | (1 << TICIE1); TCCR1A = 0; TCCR1B = (1 << CS12) | (1 << CS10); PIND &= ~(1 << PD2); PIND &= ~(1 << PD3); PORTD |= (1 << PD2) | (1 << PD3); MCUCR |= (1 << ISC11) | (1 << ISC10) | (1 << ISC01); GICR |= (1 << INT0) | (1 << INT1); sei(); printf("Hello world!\n"); uint8_t valid = 0; uint8_t bit = 0; uint8_t state = 0; while (1) { if (tick != 0) { tick = 0; uint16_t pulse = (((uint32_t) captValue) * 1000) / 15625; uint16_t gap = (((uint32_t) gapValue) * 1000) / 15625; if (gap > START_GAP_MIN) { valid = 1; state = 0; clock.second = 0; } if (pulse > ZERO_WIDTH_MIN && pulse < ZERO_WIDTH_MAX) { bit = 0; } else if (pulse > ONE_WIDTH_MIN && pulse < ONE_WIDTH_MAX) { bit = 1; } else { valid = 0; } if (valid > 0) { switch (state) { case 0: if (bit != 0) valid = 0; break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; case 10: break; case 11: break; case 12: break; case 13: break; case 14: break; case 15: break; case 16: break; case 17: break; case 18: break; case 19: break; case 20: if (bit != 1) valid = 0; break; case 21: rd.minuteOneCnt = 0; rd.minuteDigit0 = 0; rd.minuteDigit0 |= bit; if (bit == 1) rd.minuteOneCnt++; break; case 22: rd.minuteDigit0 |= (bit << 1); if (bit == 1) rd.minuteOneCnt++; break; case 23: rd.minuteDigit0 |= (bit << 2); if (bit == 1) rd.minuteOneCnt++; break; case 24: rd.minuteDigit0 |= (bit << 3); if (bit == 1) rd.minuteOneCnt++; break; case 25: rd.minuteDigit1 = 0; rd.minuteDigit1 |= bit; if (bit == 1) rd.minuteOneCnt++; break; case 26: rd.minuteDigit1 |= (bit << 1); if (bit == 1) rd.minuteOneCnt++; break; case 27: rd.minuteDigit1 |= (bit << 2); if (bit == 1) rd.minuteOneCnt++; break; case 28: rd.minuteOneCnt += bit; if (rd.minuteOneCnt % 2 != 0) { printf("MINUTE INVALID\n"); valid = 0; } else { printf("MINUTE %u %u\n", rd.minuteDigit0, rd.minuteDigit1); } break; case 29: rd.hourOneCnt = 0; rd.hourDigit0 = 0; rd.hourDigit0 |= bit; if (bit == 1) rd.hourOneCnt++; break; case 30: rd.hourDigit0 |= (bit << 1); if (bit == 1) rd.hourOneCnt++; break; case 31: rd.hourDigit0 |= (bit << 2); if (bit == 1) rd.hourOneCnt++; break; case 32: rd.hourDigit0 |= (bit << 3); if (bit == 1) rd.hourOneCnt++; break; case 33: rd.hourDigit1 = 0; rd.hourDigit1 |= bit; if (bit == 1) rd.hourOneCnt++; break; case 34: rd.hourDigit1 |= (bit << 1); if (bit == 1) rd.hourOneCnt++; break; case 35: rd.hourOneCnt += bit; if (rd.hourOneCnt % 2 != 0) { printf("HOUR INVALID\n"); valid = 0; } else { printf("HOUR %u %u\n", rd.hourDigit0, rd.hourDigit1); } break; case 36: rd.dateOneCnt = 0; rd.dayDigit0 = 0; rd.dayDigit0 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 37: rd.dayDigit0 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 38: rd.dayDigit0 |= (bit << 2); if (bit == 1) rd.dateOneCnt++; break; case 39: rd.dayDigit0 |= (bit << 3); if (bit == 1) rd.dateOneCnt++; break; case 40: rd.dayDigit1 = 0; rd.dayDigit1 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 41: rd.dayDigit1 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 42: rd.weekdayDigit0 = 0; rd.weekdayDigit0 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 43: rd.weekdayDigit0 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 44: rd.weekdayDigit0 |= (bit << 2); if (bit == 1) rd.dateOneCnt++; break; case 45: rd.monthDigit0 = 0; rd.monthDigit0 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 46: rd.monthDigit0 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 47: rd.monthDigit0 |= (bit << 2); if (bit == 1) rd.dateOneCnt++; break; case 48: rd.monthDigit0 |= (bit << 3); if (bit == 1) rd.dateOneCnt++; break; case 49: rd.monthDigit1 = 0; rd.monthDigit1 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 50: rd.yearDigit0 = 0; rd.yearDigit0 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 51: rd.yearDigit0 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 52: rd.yearDigit0 |= (bit << 2); if (bit == 1) rd.dateOneCnt++; break; case 53: rd.yearDigit0 |= (bit << 3); if (bit == 1) rd.dateOneCnt++; break; case 54: rd.yearDigit1 = 0; rd.yearDigit1 |= bit; if (bit == 1) rd.dateOneCnt++; break; case 55: rd.yearDigit1 |= (bit << 1); if (bit == 1) rd.dateOneCnt++; break; case 56: rd.yearDigit1 |= (bit << 2); if (bit == 1) rd.dateOneCnt++; break; case 57: rd.yearDigit1 |= (bit << 3); if (bit == 1) rd.dateOneCnt++; break; case 58: rd.dateOneCnt += bit; if (rd.dateOneCnt % 2 != 0) { printf("DATE INVALID\n"); valid = 0; } else { printf("DAY %u %u\n", rd.dayDigit0, rd.dayDigit1); printf("WEEKDAY %u\n", rd.weekdayDigit0); printf("MONTH %u %u\n", rd.monthDigit0, rd.monthDigit1); printf("YEAR %u %u\n", rd.yearDigit0, rd.yearDigit1); clock.minute = rd.minuteDigit0 + rd.minuteDigit1 * 10; clock.hour = rd.hourDigit0 + rd.hourDigit1 * 10; clock.day = rd.dayDigit0 + rd.dayDigit1 * 10; clock.weekday = rd.weekdayDigit0; clock.month = rd.monthDigit0 + rd.monthDigit1 * 10; clock.year = rd.yearDigit0 + rd.yearDigit1 * 10; valid = 2; } break; case 59: break; default: valid = 0; break; } printf("VALID %02d:%02d:%02d %02u.%02u.%02u %u %u %u %u %u %u \n", clock.hour, clock.minute, clock.second, clock.day, clock.month, clock.year, clock.weekday, valid, state, bit, pulse, gap); state++; } else { printf("INVALID %02d:%02d:%02d %02u.%02u.%02u %u %u %u %u \n", clock.hour, clock.minute, clock.second, clock.day, clock.month, clock.year, clock.weekday, bit, pulse, gap); } } } }