aboutsummaryrefslogtreecommitdiffstats
path: root/src/testapp1/main.c
blob: 117551a5ee1a7d9bbcd5718fbfad7b3e2bec2df9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <stdio.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "delay.h"
#include "morse.h"

/* Definitions for pins */
#define PORTB_PTT (1 << 0)
#define PORTB_SYNCn (1 << 2)
#define PORTB_LED (1 << 4)

/* Specify ID here */
static const uint8_t renard_id = 0;

static const uint8_t num_renards_cycle = 4;
// colon (:) represents ERROR
static const char letters[] = "eish:";
static const char unique_letter = letters[renard_id];

volatile uint8_t reset_time;
volatile uint8_t systick;        /* Timer (100Hz increment) */
volatile uint8_t seconds;
volatile uint16_t minutes;

/*---------------------------------------------------------*/
/* 100Hz timer interrupt generated by OC2                  */
/*---------------------------------------------------------*/
ISR(TIMER1_COMPA_vect)
{
    systick++;
    if (systick == 10) {
        systick = 0;
        seconds += 1;
    }

    if (seconds == 60) {
        seconds = 0;
        minutes++;
    }

    if (reset_time) {
        reset_time = 0;
        seconds = 0;
        minutes = 0;
    }
}

static int inittimer(void)
{
    /* Start 100Hz system timer (TC2.OC) */
    TCCR0B |= (1 << WGM02); // Configure timer for CTC mode
    TIMSK  |= (1 << OCIE1A); // enable overflow interrupt
    OCR1A = (uint8_t)(F_CPU / 64 / 1000 / 100 - 1); // Set CTC compare value to 10ms
    TCCR0B |= ((1 << CS10) | (1 << CS11)); // Start timer at Fcpu/64

    // Enable interrupts
    sei();

    return 0;
}

#define PTT_LOGIC_LOW 0

#if PTT_LOGIC_LOW
void dah(void)
{
    PORTB = PORTB_LED; // LED is non-inverted logic
    delay_ms(3*DIT_DURATION);

    PORTB = PORTB_PTT; // PTT is inverted logic
    delay_ms(DIT_DURATION);
}

void dit(void)
{
    PORTB = PORTB_LED; // LED is non-inverted logic
    delay_ms(DIT_DURATION);

    PORTB = PORTB_PTT; // PTT is inverted logic
    delay_ms(DIT_DURATION);
}
#else
void dah(void)
{
    PORTB = PORTB_PTT | PORTB_LED;
    delay_ms(3*DIT_DURATION);

    PORTB = 0;
    delay_ms(DIT_DURATION);
}

void dit(void)
{
    PORTB = PORTB_PTT | PORTB_LED;
    delay_ms(DIT_DURATION);

    PORTB = 0;
    delay_ms(DIT_DURATION);
}
#endif

int main(void)
{
    systick = 0;
    seconds = 0;
    minutes = 0;
    reset_time = 0;

    /* Enable PTT output on PB0 */
#if PTT_LOGIC_LOW
    PORTB = PORTB_PTT;
#endif
    /* LED is never inverted */
    DDRB  = PORTB_PTT | PORTB_LED;

    /* initialise timer interrupt */
    inittimer();

    static char *morse_string = "MO ";
    morse_string[2] = unique_letter;

    const int permanent = (unique_letter == ':');

    delay_ms(12*DIT_DURATION);
    morse("HB9HI");
    delay_ms(12*DIT_DURATION);

    while (1) {
        if ((PINB & PORTB_SYNCn) == 0) {
            reset_time = 1;
        }

        if (permanent) {
            morse(morse_string);
            delay_ms(6*DIT_DURATION);
        }
        else if (minutes >= 10) { // see README.md
            /* renard id 0: start at (k * num_renards_cycle) * 60, end at (k * num_renards_cycle) * 60 + 55 */
            const int in_timeslot = (minutes % num_renards_cycle) == renard_id;

            if (in_timeslot && seconds < 55) {
                morse(morse_string);
                delay_ms(6*DIT_DURATION);
            }
            else {
                delay_ms(DIT_DURATION);
            }
        }
        else {
            /* renard id 0: start every 30s, with an additional 2s offset depending on renard_id */
            const uint32_t second_offset = seconds % 30;

            if (second_offset == 2 * renard_id) {
                morse_char(unique_letter);
                delay_ms(1000); // avoid retrigger in same second
            }
        }
    }

    return 0;
}