main/task_dcf.c

changeset 2
053649608c09
parent 1
86b275481021
child 3
849ca14d4a2f
equal deleted inserted replaced
1:86b275481021 2:053649608c09
11 11
12 12
13 SemaphoreHandle_t xSemaphoreDCF = NULL; ///< Semaphore DCF task. 13 SemaphoreHandle_t xSemaphoreDCF = NULL; ///< Semaphore DCF task.
14 EventGroupHandle_t xEventGroupDCF; ///< Events DCF task. 14 EventGroupHandle_t xEventGroupDCF; ///< Events DCF task.
15 DCF_State *dcf_state = NULL; ///< Public state for other tasks. 15 DCF_State *dcf_state = NULL; ///< Public state for other tasks.
16 esp_timer_handle_t timerHandle; ///< Timer handler
17 int impulseCount = 0; ///< 100 mSec transmit slices.
18 int8_t impulseArray[61]; ///< Pulses, 0 = no pulse, 1=100ms, 2=200ms
19 int actualSecond = 0; ///< Current second to transmit.
20 time_t dcf_now; ///< Current time to send.
21 struct tm dcf_tm; ///< Local broken down time.
22 ///
23 extern bool System_TimeOk;
24
16 25
17 #define LED1 CONFIG_LED1_PIN 26 #define LED1 CONFIG_LED1_PIN
18 #define LED2 CONFIG_LED2_PIN 27 #define LED2 CONFIG_LED2_PIN
19 28
20 29
31 40
32 41
33 42
34 void request_DCF(bool run) 43 void request_DCF(bool run)
35 { 44 {
45 ESP_LOGI(TAG, "request_DCF(%s)", run ? "start":"stop");
46
47 if (run)
48 xEventGroupSetBits(xEventGroupDCF, TASK_DCF_REQUEST_START);
49 else
50 xEventGroupSetBits(xEventGroupDCF, TASK_DCF_REQUEST_STOP);
51 }
52
53
54 int bin2bcd(int data)
55 {
56 int msb, lsb;
57
58 if (data < 10)
59 return data;
60 msb = (data / 10) << 4;
61 lsb = data % 10;
62 return msb + lsb;
63 }
64
65
66 static void DCFout(void* arg);
67 void DCFout(void* arg)
68 {
69 int i, tmp, parity;
70
71 switch (impulseCount++) {
72 case 0: if (actualSecond == 0) {
73 time(&dcf_now);
74 dcf_now += 60;
75 }
76 if (impulseArray[actualSecond] != 0) {
77 gpio_set_level(CONFIG_LED1_PIN, 1);
78 }
79 break;
80 case 1: if (impulseArray[actualSecond] == 1) {
81 gpio_set_level(CONFIG_LED1_PIN, 0);
82 }
83 break;
84 case 2: gpio_set_level(CONFIG_LED1_PIN, 0);
85 break;
86 case 9: impulseCount = 0;
87 /*
88 * To spread the CPU load, we set all bits during the first seconds
89 * because we don't use these bits.
90 */
91 switch (actualSecond) {
92 case 0: /* the first 20 bits of each minute at a logical zero value */
93 for (i = 0; i < 20; i++)
94 impulseArray[i] = 1;
95 break;
96 case 1: localtime_r(&dcf_now, &dcf_tm);
97 char strftime_buf[64];
98 strftime(strftime_buf, sizeof(strftime_buf), "%c", &dcf_tm);
99 ESP_LOGI(TAG, "The current date/time to send is: %s", strftime_buf);
100 break;
101 case 2: /* DST bits */
102 if (dcf_tm.tm_isdst == 0) {
103 impulseArray[17] = 1;
104 impulseArray[18] = 2;
105 } else {
106 impulseArray[17] = 2;
107 impulseArray[18] = 1;
108 }
109 /* bit 20 must be 1 to indicate active time */
110 impulseArray[20] = 2;
111 break;
112 case 3: int minute = bin2bcd(dcf_tm.tm_min);
113 parity = 0;
114 for (i = 21; i < 28; i++) {
115 tmp = minute & 1;
116 impulseArray[i] = tmp + 1;
117 parity += tmp;
118 minute >>= 1;
119 }
120 impulseArray[28] = (parity & 1) ? 2:1;
121 ESP_LOGI(TAG, "minute %d%d%d%d%d%d%d %d", impulseArray[21], impulseArray[22], impulseArray[23],
122 impulseArray[24], impulseArray[25], impulseArray[26], impulseArray[27], impulseArray[28]);
123 break;
124
125
126 }
127 if (actualSecond < 59) /* Can include leap second */
128 actualSecond++;
129 break;
130 }
131
132 if (actualSecond >= 59) {
133 time_t now = time(NULL);
134 localtime_r(&now, &dcf_tm);
135 if (dcf_tm.tm_sec == 0) {
136 actualSecond = impulseCount = 0;
137 }
138 }
36 } 139 }
37 140
38 141
39 142
40 void task_DCF(void *pvParameters) 143 void task_DCF(void *pvParameters)
49 gpio_reset_pin(LED1); 152 gpio_reset_pin(LED1);
50 gpio_reset_pin(LED2); 153 gpio_reset_pin(LED2);
51 gpio_set_direction(LED1, GPIO_MODE_OUTPUT); 154 gpio_set_direction(LED1, GPIO_MODE_OUTPUT);
52 gpio_set_direction(LED2, GPIO_MODE_OUTPUT); 155 gpio_set_direction(LED2, GPIO_MODE_OUTPUT);
53 156
157 esp_timer_create_args_t timerDCF = {
158 .callback = &DCFout,
159 .name = "DCF timer"
160 };
161 esp_timer_create(&timerDCF, &timerHandle);
162
163 for (int i = 0; i < 59; i++)
164 impulseArray[i] = 1;
165 impulseArray[59] = impulseArray[60] = 0;
166
54 xEventGroupClearBits(xEventGroupDCF, TASK_DCF_RUN); 167 xEventGroupClearBits(xEventGroupDCF, TASK_DCF_RUN);
55 EventBits_t uxBits; 168 EventBits_t uxBits;
56 169
57 for (;;) { 170 for (;;) {
58 uxBits = xEventGroupWaitBits(xEventGroupDCF, TASK_DCF_REQUEST_START | TASK_DCF_REQUEST_STOP, pdFALSE, pdFALSE, portMAX_DELAY ); 171 uxBits = xEventGroupWaitBits(xEventGroupDCF, TASK_DCF_REQUEST_START | TASK_DCF_REQUEST_STOP, pdFALSE, pdFALSE, portMAX_DELAY );
59 172
60 if (uxBits & TASK_DCF_REQUEST_START) { 173 if (uxBits & TASK_DCF_REQUEST_START) {
61 if (dcf_state->DCF_running) { 174 if (dcf_state->DCF_running) {
62 /* Already running */ 175 /* Already running */
63 xEventGroupClearBits(xEventGroupDCF, TASK_DCF_REQUEST_START); 176 } else {
177 actualSecond = 0;
178 impulseCount = 0;
179 esp_timer_start_periodic(timerHandle, 100000);
180 dcf_state->DCF_running = true;
64 } 181 }
182 xEventGroupClearBits(xEventGroupDCF, TASK_DCF_REQUEST_START);
65 183
66 } else if (uxBits & TASK_DCF_REQUEST_STOP) { 184 } else if (uxBits & TASK_DCF_REQUEST_STOP) {
67 185 esp_timer_stop(timerHandle);
68 } 186 }
69 } /* for(;;) */ 187 } /* for(;;) */
70 } 188 }
71 189
72 190

mercurial