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;
33  
34 /*
35 * Konfigurace USART2
36 */
37  
38 static const SerialConfig USART2_config =
39 {
40 /*Speed*/
41 9600,
42 /*Initialization value for the CR1 register.*/
43 0,
44 /*Initialization value for the CR2 register.*/
45 USART_CR2_STOP1_BITS | USART_CR2_LINEN,
46 /*Initialization value for the CR3 register.*/
47  
48 };
2950 poskozby 49  
2943 poskozby 50 /*
51 * GPT2 callback.
52 */
53 static void gpt2cb(GPTDriver *gptp)
54 {
55 (void)gptp;
56 palTogglePad(GPIOB, GPIOB_LED4);
57 /* Wakes up the thread.*/
58 chSysLockFromIsr();
59 if (tp_odpal != NULL) {
2950 poskozby 60 tp_odpal->p_u.rdymsg = (msg_t)50; /* Znaci, ze se vlakno probouzi kvuli preruseni od GPT*/
2943 poskozby 61 chSchReadyI(tp_odpal);
62 tp_odpal = NULL;
63 }
64 chSysUnlockFromIsr();
65 }
66  
67 /*
68 *Konfigurace casovace 2
69 */
70 static const GPTConfig gpt2cfg =
71 {
72 1000, /*1000Hz f*/
73 gpt2cb /*callback fce*/
74 };
75  
76  
77 /*
78 * Vlakno pro ovladani odpalovaci sekvence
79 */
2945 poskozby 80 static WORKING_AREA(waThread_odpal, 128);
81 static msg_t Thread_odpal(void *arg) {
82 uint8_t stav = 0; // rika, ve ktere fazi je odpalovani
83 uint8_t odpal_povolen = 0;
2950 poskozby 84 uint8_t msg_zrusen[] = "Odpal zrusen uzivatelem.\r\n";
85 uint8_t odpal_pomocna = 0;
2943 poskozby 86 (void)arg;
87 chRegSetThreadName("Odpal_vlakno");
2950 poskozby 88  
89  
2943 poskozby 90 while (TRUE)
91 {
2945 poskozby 92 msg_t msg;
2943 poskozby 93  
94 /* Waiting for the IRQ to happen.*/
95 chSysLock();
96 tp_odpal = chThdSelf();
97 chSchGoSleepS(THD_STATE_SUSPENDED);
2945 poskozby 98 msg = chThdSelf()->p_u.rdymsg; /* Retrieving the message, optional.*/
2943 poskozby 99 chSysUnlock();
100 /* Perform processing here.*/
2945 poskozby 101 if(msg == 1)
2943 poskozby 102 {
2950 poskozby 103 odpal_povolen = 1;
104 odpal_pomocna++;
2943 poskozby 105 }
2950 poskozby 106 else if (msg == 2) //Pokud se ma odpal zrusit v prubehu
107 {
108 odpal_povolen = 0;
109 odpal_pomocna = 0;
110 stav = 0;
111 sdWrite(&SD1, msg_zrusen, sizeof(msg_zrusen)/sizeof(uint8_t));
112 }
113 else if (msg == 50 && odpal_povolen == 1) // preruseni od GPT
114 {
115 odpal_pomocna = 1;
116 }
117 if (odpal_povolen == 1 && odpal_pomocna <= 1)
118 {
119 odpal_pomocna = 2; // aby nepretelkla tato promenna
2945 poskozby 120 switch (stav)
121 {
122 case 0:
2950 poskozby 123 sdWrite(&SD1,"0\r\n",3);
2945 poskozby 124 gptStartOneShot(&GPTD2,1000);
125 break;
126 case 1:
2950 poskozby 127 sdWrite(&SD1,"1\r\n",3);
2945 poskozby 128 gptStartOneShot(&GPTD2,1500);
129 break;
130 case 2:
2950 poskozby 131 sdWrite(&SD1,"2\r\n",3);
2945 poskozby 132 gptStartOneShot(&GPTD2,2000);
133 break;
134 case 3:
2950 poskozby 135 sdWrite(&SD1,"3\r\n",3);
2945 poskozby 136 gptStartOneShot(&GPTD2,3000);
137 break;
138 case 4:
2950 poskozby 139 sdWrite(&SD1,"4\r\n",3);
2945 poskozby 140 gptStartOneShot(&GPTD2,5000);
141 break;
142 default:
2950 poskozby 143 sdWrite(&SD1,"konec\r\n",7); //posledni krok
2945 poskozby 144 odpal_povolen = 0;
2950 poskozby 145 odpal_pomocna = 0;
2945 poskozby 146 stav = 0;
147 break;
148 }
149 stav++;
150 }
2950 poskozby 151 }
2943 poskozby 152 }
153  
154  
155 /*
156 * Vlakno pro obsluhu GPS prijimace
157 */
158 static WORKING_AREA(waThread_GPS, 768);
159 static msg_t Thread_GPS(void *arg) {
160 /*
161 * Nacita se jen nekolik NMEA zprav, aby se neplytvalo pameti na ulozeni kompletniho
162 * setu s tím rizikem, ze se nekdy nenacte aktualni informace o poloze.
163 */
164 uint8_t inBuffer[GPS_BUFFER];
165 char *zacatek_retezce;
166 char *konec_retezce;
167 uint8_t pocet_znaku;
168 uint8_t NMEA_zprava[100];
169  
170 (void)arg;
2950 poskozby 171 chRegSetThreadName("GPS_NMEA");
2943 poskozby 172  
173 while (TRUE) {
174 chThdSleepMilliseconds(1000); //neni potreba data vycitat rychleji
175 sdRead(&SD2,inBuffer,GPS_BUFFER);
176  
177 /*
178 *Nejprve se vycte cast NMEA dat, pote se vyhleda retezec GPGGA zpravy, ta se vyparsuje a pomoci fce
179 *dekoduj_zpravu_GPS, ktera vyparsuje data o poloze a jine, a ulozi je do struktury GPGGA_informace.
180 */
181  
182 if ((zacatek_retezce = strstr((char *)inBuffer,"$GPGGA")) != NULL)
183 {
184 if ((konec_retezce = strstr(zacatek_retezce,"*")) != NULL)
185 {
186 pocet_znaku = (konec_retezce-zacatek_retezce)/sizeof(char);
187 if (pocet_znaku > 100)
188 {
189 pocet_znaku = 100;
190 }
191 strncpy((char *)NMEA_zprava,zacatek_retezce,pocet_znaku);
192 dekoduj_zpravu_GPS(&NMEA_zprava[0],pocet_znaku);
193 sdWrite(&SD2,"Latitude: ",sizeof("Latitude: ")/sizeof(char));
194 sdWrite(&SD2,GPGGA_informace.Latitude,sizeof(GPGGA_informace.Latitude)/sizeof(uint8_t));
195 sdWrite(&SD2,"\r\n",2);
196 sdWrite(&SD2,"Longitude: ",sizeof("Longitude: ")/sizeof(char));
197 sdWrite(&SD2,GPGGA_informace.Longitude,sizeof(GPGGA_informace.Longitude)/sizeof(uint8_t));
198 sdWrite(&SD2,"\r\n",2);
199 sdWrite(&SD2,"Altitude: ",sizeof("Altitude: ")/sizeof(char));
200 sdWrite(&SD2,GPGGA_informace.Altitude,sizeof(GPGGA_informace.Altitude)/sizeof(uint8_t));
201 sdWrite(&SD2,"\r\n",2);
202 sdWrite(&SD2,"Status: ",sizeof("Status: ")/sizeof(char));
203 sdWrite(&SD2,&GPGGA_informace.Status_GPS,sizeof(GPGGA_informace.Status_GPS)/sizeof(uint8_t));
204 sdWrite(&SD2,"\r\n",2);
205 sdWrite(&SD2,NMEA_zprava,pocet_znaku);
206 sdWrite(&SD2,"\r\n",2);
207 }
208 else
209 {
210 sdWrite(&SD2,"\r\n",2);
2950 poskozby 211 sdWrite(&SD2,"Nenalezen ukoncovaci znak NMEA zpravy *\r\n",sizeof("Nenalezen ukoncovaci znak NMEA zpravy *\r\n")/sizeof(char));
2943 poskozby 212 sdWrite(&SD2,inBuffer,GPS_BUFFER);
213 }
214 }
215 else
2950 poskozby 216 sdWrite(&SD2,"Nenalezen zacatek GPGGA zpravy\r\n",sizeof("Nenalezen zacatek GPGGA zpravy\r\n")/sizeof(char));
2943 poskozby 217  
218 }
219 }
220  
221 void dekodujPrikaz(char *prikaz)
222 {
2945 poskozby 223 if(strcmp(prikaz,"odpal") == 0)
2943 poskozby 224 {
2945 poskozby 225 /* Wakes up the thread.*/
226 chSysLockFromIsr();
227 if (tp_odpal != NULL) {
228 tp_odpal->p_u.rdymsg = (msg_t)1; /* odpal povolen*/
229 chSchReadyI(tp_odpal);
230 tp_odpal = NULL;
231 }
232 chSysUnlockFromIsr();
2943 poskozby 233 palTogglePad(GPIOB, GPIOB_LED4);
234 }
2950 poskozby 235 else if (strcmp(prikaz,"zrus") == 0)
2943 poskozby 236 {
2950 poskozby 237 /* Wakes up the thread.*/
238 chSysLockFromIsr();
239 if (tp_odpal != NULL) {
240 tp_odpal->p_u.rdymsg = (msg_t)2; /* zakazano pokracovat v odpalovaci sekvenci*/
241 chSchReadyI(tp_odpal);
242 tp_odpal = NULL;
243 }
244 chSysUnlockFromIsr();
2943 poskozby 245 }
246 else
247 {
248 uint8_t zp_neplatny[] = "Neplatny prikaz, spravny format *<prikaz>\n\r";
249 sdWrite(&SD1,zp_neplatny,sizeof(zp_neplatny)/sizeof(uint8_t));
250 palTogglePad(GPIOB, GPIOB_LED3);
251 }
252 }
253  
254 /*
255 * Application entry point.
256 */
257 int main(void) {
2950 poskozby 258  
2943 poskozby 259 uint8_t znaky[20];
260 char prikaz[MAX_DELKA_PRIKAZU + 1];
2946 poskozby 261 uint8_t pocet_znaku = 0;
2943 poskozby 262  
263 /*
264 * System initializations.
265 * - HAL initialization, this also initializes the configured device drivers
266 * and performs the board-specific initializations.
267 * - Kernel initialization, the main() function becomes a thread and the
268 * RTOS is active.
269 */
270 halInit();
271 chSysInit();
272  
2950 poskozby 273 /*
2943 poskozby 274 * Activates the serial driver 1 using the driver default configuration.
275 * PA9 and PA10 are routed to USART1.
2950 poskozby 276 * Komunikace s uzivatelem
2943 poskozby 277 */
278 sdStart(&SD1, NULL);
2945 poskozby 279 palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7)); //TX
280 palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7)); //RX
2943 poskozby 281  
282 /*
2950 poskozby 283 * Activates the serial driver 2 using the driver default configuration.
284 * PA2 and PA3 are routed to USART2.
285 *GPS
2943 poskozby 286 */
2950 poskozby 287 sdStart(&SD2, &USART2_config);
288 palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)); //TX
289 palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)); //RX
290  
2943 poskozby 291 /*
2950 poskozby 292 * LED na vyvojove desce
2943 poskozby 293 */
294 palSetPadMode(GPIOB, GPIOB_LED4, PAL_MODE_OUTPUT_PUSHPULL);
295 palSetPadMode(GPIOB, GPIOB_LED3, PAL_MODE_OUTPUT_PUSHPULL);
2950 poskozby 296  
2943 poskozby 297 /*
2950 poskozby 298 * Porty pro vypousteci sekvenci
299 */
300 palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
301 palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
302 palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL);
303 palSetPadMode(GPIOB, 13, PAL_MODE_OUTPUT_PUSHPULL);
304 /*
305 * Aktivuje timer2 a prejde tak do aktivniho stavu
306 */
307 gptStart(&GPTD2,&gpt2cfg);
2943 poskozby 308  
2950 poskozby 309  
2943 poskozby 310 /*
311 * Vytvori vlakno pro prijem dat z GPS modulu
312 */
313 chThdCreateStatic(waThread_GPS, sizeof(waThread_GPS), NORMALPRIO, Thread_GPS, NULL);
2950 poskozby 314  
2943 poskozby 315 /*
316 * Vytvori vlakno pro odpalovaci sekvenci
317 */
2950 poskozby 318 chThdCreateStatic (waThread_odpal, sizeof(waThread_odpal), NORMALPRIO, Thread_odpal, NULL);
319  
2943 poskozby 320 /*
321 * Normal main() thread activity, in this demo it does nothing except
322 * sleeping in a loop and check the button state, when the button is
323 * pressed the test procedure is launched with output on the serial
324 * driver 1.
325 */
326 while (TRUE) {
327 sdRead(&SD1,znaky,1);
2950 poskozby 328 /*Kdyz uzivatel stiskne enter -> dekoduj a vykonej prikaz, nebo pokud je prikaz delsi, nez by mel byt,
329 *prestane ukladat a upozorni uzivatele
330 */
331 if (znaky[0] == '\r' || pocet_znaku >= MAX_DELKA_PRIKAZU)
2943 poskozby 332 {
2946 poskozby 333 pocet_znaku = 0;
2943 poskozby 334 dekodujPrikaz(prikaz);
335 prikaz[0] = 0;
336 }
337 /*Uklada prikaz*/
2950 poskozby 338 else
2943 poskozby 339 {
2946 poskozby 340 prikaz[pocet_znaku + 1] = 0;
341 prikaz[pocet_znaku++] = znaky[0];
2943 poskozby 342 }
343 }
344 }