Rev Author Line No. Line
2943 poskozby 1 /*
2 ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3  
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7  
8 http://www.apache.org/licenses/LICENSE-2.0
9  
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16  
17 #include "ch.h"
18 #include "hal.h"
19 #include "test.h"
20 #include "serial.h"
21 #include "gpt.h"
22 #include <string.h>
23 #include "keil/GPS_dekoduj.h"
24  
25 /*MAX delka prikazu, ktery uzivatel muze zadat*/
26 #define MAX_DELKA_PRIKAZU 10
27  
28 /*Velikost GPS bufferu*/
29 #define GPS_BUFFER 500
30  
31 extern NMEA_GPGGA GPGGA_informace;
32 Thread *tp_odpal = NULL;
2952 poskozby 33 uint8_t uvitaci_zprava[] = "\r\n\r\n* * * * * * * * * * * * * * * * * * * * * * * * * *\r\nVita vas Automaticky Vypoustec Meteobalonu 1.1\r\nZapojeni vyvodu:\r\n\tGPIOB10 - ventil\r\n\tGPIOB11 - lis\r\n\tGPIOB12 - zataveni balonu\r\n\tGPIOB13 - otevreni krytu\r\nPrikazy:\r\n\t<odpal> zahajeni sekvence vypousteni\n\r\t<zrus> zruseni vypousteni\n\r\t<help> napoveda\r\n* * * * * * * * * * * * * * * * * * * * * * * * * *\r\n\r\n";
2943 poskozby 34  
35 /*
36 * Konfigurace USART2
37 */
38  
39 static const SerialConfig USART2_config =
40 {
41 /*Speed*/
42 9600,
43 /*Initialization value for the CR1 register.*/
44 0,
45 /*Initialization value for the CR2 register.*/
46 USART_CR2_STOP1_BITS | USART_CR2_LINEN,
47 /*Initialization value for the CR3 register.*/
48  
49 };
2950 poskozby 50  
2943 poskozby 51 /*
52 * GPT2 callback.
53 */
54 static void gpt2cb(GPTDriver *gptp)
55 {
56 (void)gptp;
57 palTogglePad(GPIOB, GPIOB_LED4);
58 /* Wakes up the thread.*/
59 chSysLockFromIsr();
60 if (tp_odpal != NULL) {
2950 poskozby 61 tp_odpal->p_u.rdymsg = (msg_t)50; /* Znaci, ze se vlakno probouzi kvuli preruseni od GPT*/
2943 poskozby 62 chSchReadyI(tp_odpal);
63 tp_odpal = NULL;
64 }
65 chSysUnlockFromIsr();
66 }
67  
68 /*
69 *Konfigurace casovace 2
70 */
71 static const GPTConfig gpt2cfg =
72 {
73 1000, /*1000Hz f*/
74 gpt2cb /*callback fce*/
75 };
76  
77  
78 /*
79 * Vlakno pro ovladani odpalovaci sekvence
80 */
2945 poskozby 81 static WORKING_AREA(waThread_odpal, 128);
82 static msg_t Thread_odpal(void *arg) {
83 uint8_t stav = 0; // rika, ve ktere fazi je odpalovani
84 uint8_t odpal_povolen = 0;
2950 poskozby 85 uint8_t msg_zrusen[] = "Odpal zrusen uzivatelem.\r\n";
86 uint8_t odpal_pomocna = 0;
2943 poskozby 87 (void)arg;
88 chRegSetThreadName("Odpal_vlakno");
2950 poskozby 89  
90  
2943 poskozby 91 while (TRUE)
92 {
2945 poskozby 93 msg_t msg;
2943 poskozby 94  
95 /* Waiting for the IRQ to happen.*/
96 chSysLock();
97 tp_odpal = chThdSelf();
98 chSchGoSleepS(THD_STATE_SUSPENDED);
2945 poskozby 99 msg = chThdSelf()->p_u.rdymsg; /* Retrieving the message, optional.*/
2943 poskozby 100 chSysUnlock();
101 /* Perform processing here.*/
2945 poskozby 102 if(msg == 1)
2943 poskozby 103 {
2950 poskozby 104 odpal_povolen = 1;
105 odpal_pomocna++;
2943 poskozby 106 }
2950 poskozby 107 else if (msg == 2) //Pokud se ma odpal zrusit v prubehu
108 {
2952 poskozby 109 /*
110 * Pro jistotu se vypnou vsechny vystupy pri zruseni odpalu
111 */
112 palClearPad(GPIOB, GPIOB_PIN10);
113 palClearPad(GPIOB, GPIOB_PIN11);
114 palClearPad(GPIOB, GPIOB_PIN12);
115 palClearPad(GPIOB, GPIOB_PIN13);
116  
2950 poskozby 117 odpal_povolen = 0;
118 odpal_pomocna = 0;
119 stav = 0;
120 sdWrite(&SD1, msg_zrusen, sizeof(msg_zrusen)/sizeof(uint8_t));
121 }
122 else if (msg == 50 && odpal_povolen == 1) // preruseni od GPT
123 {
124 odpal_pomocna = 1;
125 }
126 if (odpal_povolen == 1 && odpal_pomocna <= 1)
127 {
128 odpal_pomocna = 2; // aby nepretelkla tato promenna
2945 poskozby 129 switch (stav)
130 {
131 case 0:
2952 poskozby 132 sdWrite(&SD1,"Vypousteni zahajeno!\r\n",sizeof("Vypousteni zahajeno!\r\n")/sizeof(char));
133 sdWrite(&SD1,"(1/4)\tVentil otevren -> nafukovani balonu\r\n",sizeof("1/4)\tVentil otevren -> nafukovani balonu\r\n")/sizeof(char));
134 palSetPad(GPIOB, GPIOB_PIN10);
135 gptStartOneShot(&GPTD2,10000);
2945 poskozby 136 break;
137 case 1:
2952 poskozby 138 palClearPad(GPIOB, GPIOB_PIN10);
139 palSetPad(GPIOB, GPIOB_PIN11);
140 sdWrite(&SD1,"(2/4)\tPrepalovani lisu...\r\n",sizeof("(2/4)\tPrepalovani lisu...\r\n")/sizeof(char));
141 gptStartOneShot(&GPTD2,5000);
2945 poskozby 142 break;
143 case 2:
2952 poskozby 144 palClearPad(GPIOB, GPIOB_PIN11);
145 palSetPad(GPIOB, GPIOB_PIN12);
146 sdWrite(&SD1,"(3/4)\tZatavovani balonu...\r\n",sizeof("(3/4)\tZatavovani balonu...\r\n")/sizeof(char));
147 gptStartOneShot(&GPTD2,5000);
2945 poskozby 148 break;
2952 poskozby 149 case 3:
150 palClearPad(GPIOB, GPIOB_PIN12);
151 palSetPad(GPIOB, GPIOB_PIN13);
152 sdWrite(&SD1,"(4/4)\tOtevirani vika...\r\n",sizeof("(4/4)\tOtevirani vika...\r\n")/sizeof(char));
2945 poskozby 153 gptStartOneShot(&GPTD2,3000);
154 break;
155 case 4:
2952 poskozby 156 palClearPad(GPIOB, GPIOB_PIN13);
157 sdWrite(&SD1,"Vypousteni ukonceno!\r\n",sizeof("Vypousteni ukonceno!\r\n")/sizeof(char));
158 odpal_povolen = 0;
159 odpal_pomocna = 0;
160 stav = 0;
2945 poskozby 161 break;
162 default:
163 break;
164 }
165 stav++;
166 }
2950 poskozby 167 }
2943 poskozby 168 }
169  
170  
171 /*
172 * Vlakno pro obsluhu GPS prijimace
173 */
174 static WORKING_AREA(waThread_GPS, 768);
175 static msg_t Thread_GPS(void *arg) {
176 /*
177 * Nacita se jen nekolik NMEA zprav, aby se neplytvalo pameti na ulozeni kompletniho
178 * setu s tím rizikem, ze se nekdy nenacte aktualni informace o poloze.
179 */
180 uint8_t inBuffer[GPS_BUFFER];
181 char *zacatek_retezce;
182 char *konec_retezce;
183 uint8_t pocet_znaku;
184 uint8_t NMEA_zprava[100];
185  
186 (void)arg;
2950 poskozby 187 chRegSetThreadName("GPS_NMEA");
2943 poskozby 188  
189 while (TRUE) {
190 chThdSleepMilliseconds(1000); //neni potreba data vycitat rychleji
191 sdRead(&SD2,inBuffer,GPS_BUFFER);
192  
193 /*
194 *Nejprve se vycte cast NMEA dat, pote se vyhleda retezec GPGGA zpravy, ta se vyparsuje a pomoci fce
195 *dekoduj_zpravu_GPS, ktera vyparsuje data o poloze a jine, a ulozi je do struktury GPGGA_informace.
196 */
197  
198 if ((zacatek_retezce = strstr((char *)inBuffer,"$GPGGA")) != NULL)
199 {
200 if ((konec_retezce = strstr(zacatek_retezce,"*")) != NULL)
201 {
202 pocet_znaku = (konec_retezce-zacatek_retezce)/sizeof(char);
203 if (pocet_znaku > 100)
204 {
205 pocet_znaku = 100;
206 }
207 strncpy((char *)NMEA_zprava,zacatek_retezce,pocet_znaku);
208 dekoduj_zpravu_GPS(&NMEA_zprava[0],pocet_znaku);
209 sdWrite(&SD2,"Latitude: ",sizeof("Latitude: ")/sizeof(char));
210 sdWrite(&SD2,GPGGA_informace.Latitude,sizeof(GPGGA_informace.Latitude)/sizeof(uint8_t));
211 sdWrite(&SD2,"\r\n",2);
212 sdWrite(&SD2,"Longitude: ",sizeof("Longitude: ")/sizeof(char));
213 sdWrite(&SD2,GPGGA_informace.Longitude,sizeof(GPGGA_informace.Longitude)/sizeof(uint8_t));
214 sdWrite(&SD2,"\r\n",2);
215 sdWrite(&SD2,"Altitude: ",sizeof("Altitude: ")/sizeof(char));
216 sdWrite(&SD2,GPGGA_informace.Altitude,sizeof(GPGGA_informace.Altitude)/sizeof(uint8_t));
217 sdWrite(&SD2,"\r\n",2);
218 sdWrite(&SD2,"Status: ",sizeof("Status: ")/sizeof(char));
219 sdWrite(&SD2,&GPGGA_informace.Status_GPS,sizeof(GPGGA_informace.Status_GPS)/sizeof(uint8_t));
220 sdWrite(&SD2,"\r\n",2);
221 sdWrite(&SD2,NMEA_zprava,pocet_znaku);
222 sdWrite(&SD2,"\r\n",2);
223 }
224 else
225 {
226 sdWrite(&SD2,"\r\n",2);
2950 poskozby 227 sdWrite(&SD2,"Nenalezen ukoncovaci znak NMEA zpravy *\r\n",sizeof("Nenalezen ukoncovaci znak NMEA zpravy *\r\n")/sizeof(char));
2943 poskozby 228 sdWrite(&SD2,inBuffer,GPS_BUFFER);
229 }
230 }
231 else
2950 poskozby 232 sdWrite(&SD2,"Nenalezen zacatek GPGGA zpravy\r\n",sizeof("Nenalezen zacatek GPGGA zpravy\r\n")/sizeof(char));
2943 poskozby 233  
234 }
235 }
236  
237 void dekodujPrikaz(char *prikaz)
238 {
2945 poskozby 239 if(strcmp(prikaz,"odpal") == 0)
2943 poskozby 240 {
2945 poskozby 241 /* Wakes up the thread.*/
242 chSysLockFromIsr();
243 if (tp_odpal != NULL) {
244 tp_odpal->p_u.rdymsg = (msg_t)1; /* odpal povolen*/
245 chSchReadyI(tp_odpal);
246 tp_odpal = NULL;
247 }
248 chSysUnlockFromIsr();
2943 poskozby 249 palTogglePad(GPIOB, GPIOB_LED4);
250 }
2950 poskozby 251 else if (strcmp(prikaz,"zrus") == 0)
2943 poskozby 252 {
2950 poskozby 253 /* Wakes up the thread.*/
254 chSysLockFromIsr();
255 if (tp_odpal != NULL) {
256 tp_odpal->p_u.rdymsg = (msg_t)2; /* zakazano pokracovat v odpalovaci sekvenci*/
257 chSchReadyI(tp_odpal);
258 tp_odpal = NULL;
259 }
260 chSysUnlockFromIsr();
2943 poskozby 261 }
2952 poskozby 262 else if (strcmp(prikaz,"help") == 0)
263 {
264 sdWrite(&SD1, uvitaci_zprava, sizeof(uvitaci_zprava)/sizeof(uint8_t));
265 }
2943 poskozby 266 else
267 {
2952 poskozby 268 uint8_t zp_neplatny[] = "Neplatny prikaz, napiste <odpal> pro zahajeni sekvence\n\r ci <zrus> pro zruseni vypousteni\n\r";
2943 poskozby 269 sdWrite(&SD1,zp_neplatny,sizeof(zp_neplatny)/sizeof(uint8_t));
270 palTogglePad(GPIOB, GPIOB_LED3);
271 }
272 }
273  
274 /*
275 * Application entry point.
276 */
277 int main(void) {
2950 poskozby 278  
2943 poskozby 279 uint8_t znaky[20];
280 char prikaz[MAX_DELKA_PRIKAZU + 1];
2946 poskozby 281 uint8_t pocet_znaku = 0;
2943 poskozby 282  
283 /*
284 * System initializations.
285 * - HAL initialization, this also initializes the configured device drivers
286 * and performs the board-specific initializations.
287 * - Kernel initialization, the main() function becomes a thread and the
288 * RTOS is active.
289 */
290 halInit();
291 chSysInit();
292  
2950 poskozby 293 /*
2943 poskozby 294 * Activates the serial driver 1 using the driver default configuration.
295 * PA9 and PA10 are routed to USART1.
2950 poskozby 296 * Komunikace s uzivatelem
2943 poskozby 297 */
298 sdStart(&SD1, NULL);
2945 poskozby 299 palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7)); //TX
300 palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7)); //RX
2943 poskozby 301  
302 /*
2950 poskozby 303 * Activates the serial driver 2 using the driver default configuration.
304 * PA2 and PA3 are routed to USART2.
305 *GPS
2943 poskozby 306 */
2950 poskozby 307 sdStart(&SD2, &USART2_config);
308 palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)); //TX
309 palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)); //RX
310  
2943 poskozby 311 /*
2950 poskozby 312 * LED na vyvojove desce
2943 poskozby 313 */
314 palSetPadMode(GPIOB, GPIOB_LED4, PAL_MODE_OUTPUT_PUSHPULL);
315 palSetPadMode(GPIOB, GPIOB_LED3, PAL_MODE_OUTPUT_PUSHPULL);
2950 poskozby 316  
2943 poskozby 317 /*
2950 poskozby 318 * Porty pro vypousteci sekvenci
319 */
320 palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
321 palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
322 palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL);
323 palSetPadMode(GPIOB, 13, PAL_MODE_OUTPUT_PUSHPULL);
324 /*
325 * Aktivuje timer2 a prejde tak do aktivniho stavu
326 */
327 gptStart(&GPTD2,&gpt2cfg);
2943 poskozby 328  
2950 poskozby 329  
2943 poskozby 330 /*
331 * Vytvori vlakno pro prijem dat z GPS modulu
332 */
333 chThdCreateStatic(waThread_GPS, sizeof(waThread_GPS), NORMALPRIO, Thread_GPS, NULL);
2950 poskozby 334  
2943 poskozby 335 /*
336 * Vytvori vlakno pro odpalovaci sekvenci
337 */
2950 poskozby 338 chThdCreateStatic (waThread_odpal, sizeof(waThread_odpal), NORMALPRIO, Thread_odpal, NULL);
339  
2952 poskozby 340 sdWrite(&SD1, uvitaci_zprava, sizeof(uvitaci_zprava)/sizeof(uint8_t));
2943 poskozby 341 /*
342 * Normal main() thread activity, in this demo it does nothing except
343 * sleeping in a loop and check the button state, when the button is
344 * pressed the test procedure is launched with output on the serial
345 * driver 1.
346 */
347 while (TRUE) {
348 sdRead(&SD1,znaky,1);
2950 poskozby 349 /*Kdyz uzivatel stiskne enter -> dekoduj a vykonej prikaz, nebo pokud je prikaz delsi, nez by mel byt,
350 *prestane ukladat a upozorni uzivatele
351 */
352 if (znaky[0] == '\r' || pocet_znaku >= MAX_DELKA_PRIKAZU)
2943 poskozby 353 {
2946 poskozby 354 pocet_znaku = 0;
2943 poskozby 355 dekodujPrikaz(prikaz);
356 prikaz[0] = 0;
357 }
358 /*Uklada prikaz*/
2950 poskozby 359 else
2943 poskozby 360 {
2946 poskozby 361 prikaz[pocet_znaku + 1] = 0;
362 prikaz[pocet_znaku++] = znaky[0];
2943 poskozby 363 }
364 }
365 }