]> rtime.felk.cvut.cz Git - mirosot.git/blob - navratil_ad/navratil_ad.c
Disabled prinfs to have smaller application and shorter load times
[mirosot.git] / navratil_ad / navratil_ad.c
1 /*
2 *
3 * Author funkci na pohyb motoru:    Petr Kovacik <kovacp1@feld.cvut.cz>, (C) 2006
4
5 * Autor funkci na autonomni pohyb:  Milan Navratil <navram1@fel.cvut.cz> 2008
6 *
7 * Popis: main vola funkce autonomni_pohyb() , nebo sleduj_caru(),
8 * obe funkce pak volaji funkce na vycteni dat z 10-bitoveho A/D prevodniku
9 *
10 */
11 #define _USE_EXR_LEVELS 1
12 #include <types.h>
13 #include <cpu_def.h>
14 #include <h8s2638h.h>
15 #include <periph/sci_rs232.h>
16 #include <system_def.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <pxmc.h>
21 #include <pxmcbsp.h>
22
23 #include <cmd_proc.h>
24 #include "cmd_pxmc.h"
25 #include "timer3.h"
26 #include <stdio.h>
27
28 uint16_t read_GP1(void);                        // deklarace funkce read_GP1
29 uint16_t read_GP2(void);                        // deklarace funkce read_GP2
30 uint16_t read_QRD1(void);                       // deklarace funkce read_QRD1
31 uint16_t read_QRD2(void);                       // deklarace funkce read_QRD2
32 uint16_t read_QRD3(void);                       // deklarace funkce read_QRD3
33
34
35
36 cmd_des_t const *cmd_rs232_default[];
37
38 /*struktury prikazu cmd*/
39 cmd_des_t const cmd_des_help={0, 0,"HELP","prints help for commands",
40                         cmd_do_help,{(char*)&cmd_rs232_default}};
41                         
42 cmd_des_t const *cmd_rs232_default[]={
43
44   &cmd_des_help,
45   CMD_DES_CONTINUE_AT(cmd_pxmc_default),
46   NULL
47 };
48 cmd_des_t const **cmd_bth=cmd_rs232_default;       /*cmd prikazy pro bth*/
49 cmd_des_t const **cmd_rs232=cmd_rs232_default;     /*cmd prikazy pro PC*/
50
51
52 /*struktury charakterizujici motor 0*/
53 pxmc_state_t mcsX0={
54   pxms_flg:0,
55   pxms_do_inp:0,
56   pxms_do_con:0,
57   pxms_do_out:0,
58   pxms_do_deb:0,
59   pxms_do_gen:0,
60   pxms_ap:0, pxms_as:0,
61   pxms_rp:155l*256,
62   pxms_rs:0, //pxms_subdiv:8,
63   pxms_md:8000l<<8, pxms_ms:5000, pxms_ma:5,            // pxms_ma je akcelerace robota byla nastavena na 10
64   pxms_inp_info:(long)TPU_TCNT1,//TPU_TCNT1                     /*chanel TPU A,B*/
65   pxms_out_info:(long)PWM_PWBFR1A,                      /*chanel PWM A,B*/
66   pxms_ene:0, pxms_erc:0,
67   pxms_p:40, pxms_i:0, pxms_d:1, pxms_s1:0, pxms_s2:0,
68   pxms_me:0x1800, //6144
69   pxms_ptirc:40, // 2000 irc per rev, 200/4 steps /
70   pxms_ptper:1,
71   pxms_ptptr1:NULL,
72   pxms_ptptr2:NULL,
73   pxms_cfg:PXMS_CFG_MD2E_m|PXMS_CFG_HLS_m|
74       PXMS_CFG_HPS_m|PXMS_CFG_HDIR_m|0x1
75 };
76
77
78 /*struktury charakterizujici motor 1*/
79 pxmc_state_t mcsX1={
80   pxms_flg:0,
81   pxms_do_inp:0,
82   pxms_do_con:0,
83   pxms_do_out:0,
84   pxms_do_deb:0,
85   pxms_do_gen:0,
86   pxms_ap:0, pxms_as:0,
87   pxms_rp:155l*256,
88   pxms_rs:0, //pxms_subdiv:8,
89   pxms_md:8000l<<8, pxms_ms:5000, pxms_ma:5,
90   pxms_inp_info:(long)TPU_TCNT2,                        /*chanel TPU C,D*/
91   pxms_out_info:(long)PWM_PWBFR1C,                      /*chanel PWM C,D*/
92   pxms_ene:0, pxms_erc:0,
93   pxms_p:40, pxms_i:0, pxms_d:1, pxms_s1:0, pxms_s2:0,
94   pxms_me:0x1800, //6144
95   pxms_ptirc:40, // 2000 irc per rev, 200/4 steps /
96   pxms_ptper:1,
97   pxms_ptptr1:NULL,
98   pxms_ptptr2:NULL,
99   pxms_cfg:PXMS_CFG_MD2E_m|PXMS_CFG_HLS_m|      //FIXME: nastavit spravne priznaky pro dalsi motorove struktur
100       PXMS_CFG_HPS_m|PXMS_CFG_HDIR_m|0x1
101 };
102
103 pxmc_state_t *pxmc_main_arr[] = {&mcsX0,&mcsX1};
104
105 pxmc_state_list_t pxmc_main_list = {
106   pxml_arr:pxmc_main_arr,
107   pxml_cnt:sizeof(pxmc_main_arr)/sizeof(pxmc_main_arr[0])
108 };
109
110
111
112 //*******************************************************
113
114 void  unhandled_exception(void) __attribute__ ((interrupt_handler));
115
116 /*Interrupt routines*/
117 void  unhandled_exception(void)
118 {
119 };
120 //********************************************************
121
122 extern cmd_io_t cmd_io_rs232_line;
123
124 extern void _print(char *str);
125
126 void
127 init(void)
128 {
129   /********************************************************************************/
130   *DIO_PJDDR=0xff;      /*output gate*/
131   *DIO_PEDDR=0xff;      /*output gate*/
132   *DIO_PEDR=0x60;       /*0x0-LED - light all; 0x6 -ENA,ENB=1, LE33CD=0*/
133   *DIO_PJDR=0x00;       //rozsviceni vsech diod na */
134   
135
136   /*priority preruseni - SCI > TPU*/
137 /*   *SYS_SYSCR|=SYSCR_INTM1m; */
138 /*   *INT_IPRA=0x22; *INT_IPRB=0x22; *INT_IPRC=0x04;  */
139 /*   *INT_IPRD=0x40; *INT_IPRE=0x44; *INT_IPRF=0x55; */
140 /*   *INT_IPRG=0x55; *INT_IPRH=0x55; *INT_IPRJ=0x06; */
141 /*   *INT_IPRK=0x67; *INT_IPRM=0x66; */
142
143   /*povoleni vsech preruseni atd...*/
144   cli();
145   excptvec_initfill(unhandled_exception, 0);
146
147   /*nastaveni seriovych linek - Bth, PC*/
148   //sci_rs232_setmode(RS232_BAUD_RAW | 3, 0, 0, 2);     // HCI - hardcoded 115200
149   //sci_rs232_setmode(115200, 0, 0, 2); // HCI
150   sci_rs232_setmode(19200, 0, 0, sci_rs232_chan_default); //PC
151   sti();
152
153   _print("Start\n");
154
155   pxmc_initialize();
156
157   if (init_timer3((long long)100/*ms*/*1000*1000) < 0) {
158     /* ERROR */
159     DEB_LED_OFF(0);
160   }
161 }
162
163
164 // Distance of wheels - d
165 #define WHEEL_DIST 74 /* mm */
166 #define MAX_R 300 /* mm */
167 #define MIN_R (WHEEL_DIST/2) /* mm */
168
169 void move(int speed, int r)
170 {
171   int sl, sr;
172   int d = WHEEL_DIST;
173
174
175   if (r != 0) {
176     sr = speed + (long long)speed * (d/2) / r;
177     sl = speed - (long long)speed * (d/2) / r;
178   } else {
179     sr = speed;
180     sl = speed + 10;            // minus 100 je kompenzace zataceni
181   }
182   pxmc_spd(&mcsX0, +sl, 0);
183   pxmc_spd(&mcsX1, -sr, 0);
184   //printf("speed=%5d, r=%5d, sl=%5d, sr=%5d\n", speed, r, sl, sr);
185 }
186
187 void autonomni_pohyb(void)
188 {
189   long int now = get_timer();
190   long int next = now;
191   long int otoc_next = now;
192   long int time_next = now;
193   int speed = 3000;
194   int radius = 100;
195   int stav = 1;                                                 // podle priznaku stavu se rozhoduje,zda pojede rovne, nebo zatoci
196   int otoc = 0;                                                 // priznak pro otoceni
197   int smer = 1;                                                 // smer = 1 robot jede dopredu, smer = -1 robot jede dozadu
198   uint16_t vzdalenost, vzdalenost_zpet, cas=0;
199
200   while (1) {
201     
202     long int now = get_timer();
203     
204     vzdalenost = read_GP1();
205     vzdalenost_zpet = read_GP2();
206     
207     if (now >= time_next){                                      // podminka vypisu, jednou za vterinu
208       time_next = now + 10;
209       cas++;
210       /*Vypsani vzdalenosti na terminal*/
211       //printf("Predni: %d\tZadni: %d\tSpeed: %d\tSmer: %d\tOtoc: %d\n", vzdalenost, vzdalenost_zpet, speed, smer, otoc);       
212     }                                                           // konec if podminky na vypis za 1s 
213
214     if (stav == 1 && now >= next){                              // podminka pro jizdu 
215       stav = 0;
216       move(-speed,0);
217       otoc++;
218     }
219
220     if (stav == 0 && vzdalenost >= 280 && smer == 1){           // podminka pro zatoceni 260 odpovida (mensi nez 20cm)
221
222       if (rand() % 100 < 70)                                    // 50 % predpoklad pro zatoceni doprava
223         move(-speed,radius);                                    // zatoc rychlosti speed a polomerem radius(doprava) 
224       else
225         move(-speed,-radius);                                   // zatoc rychlosti speed a polomerem -radius (doleva)
226       stav = 1;                                                 
227       
228       next = now + ((rand() % 8)+5);                            // zataceni po dobu 5 - 12 (nahodne cislo)
229     }                                                           // konec if
230
231
232     if (stav == 0 && vzdalenost_zpet >= 280 && smer == -1){                     // jizda zpet!!! podminka pro zatoceni 260 odpovida (mensi nez 20cm)
233
234       if (rand() % 100 < 70)                                    // 50 % predpoklad pro zatoceni doprava
235         move(-speed,radius);                                    // zatoc rychlosti speed a radiusem, 
236       else
237         move(-speed,-radius);
238       stav = 1;                                                 
239       
240       next = now + ((rand() % 8)+5);                            // zataceni po dobu 5 - 12 (nahodne cislo)
241     }                                                           //konec if
242
243 // NEVIM JAK UDELAT OPRENI SE O PREKAZKU A OTOCENI              // osetreni, kdyz se robot opre o prekazku, chceme,aby se rozjel opacnym smerem
244     /*if (vzdalenost <=30 && now >= otoc_next)  {               // pokud se sensor dotyka prekazky, tak dava hodnotu 110 az 140, kontroluji to 10x 0,1s
245       otoc++;
246       otoc_next = now + 1;  
247     }
248
249     if (vzdalenost_zpet >= 110 && vzdalenost_zpet <=140 && now >= otoc_next)  { // pokud se sensor dotyka prekazky, tak dava hodnotu 110 az 140, kontroluji to 10x 0,1s
250       otoc++;
251       otoc_next = now + 1;  
252     }
253
254     if (otoc >= 10){
255       speed = -speed;                                           // zmena smeru
256       otoc = 0;
257     } */ 
258
259     //zmena_smeru
260     if (otoc >= 6){
261       speed = -speed;
262       otoc = 0; 
263       smer = -smer;
264       move(-speed,0);                                                   //otoc normalne je pouzit o if cyklus drive, ted si ho jen pujcuji
265     }
266
267   }                                                             //konec while
268 }                                                               //konec funkce
269
270
271 void sleduj_caru(void){
272   long int now = get_timer();
273   long int next = now;
274   long int time_next = now;
275   int speed = 2000;
276   int radius = 100;
277   uint16_t leva, stred, prava, cas=0;
278   
279   move(2000,0);
280   while(1){
281
282     long int now = get_timer();
283
284     stred = read_QRD3();                                        // pohled zpredu, cteni senzoru odrazu QRD1114 1-3
285     leva = read_QRD1();
286     prava = read_QRD2();
287     
288     if (stred > 1000 && leva < 500 && prava <500 && now >= next){ // rozhodovani 
289       move(-speed,0);
290     }
291
292     if (stred < 1000 && leva > 500){
293       move(-speed,radius);
294       next = now + 1;
295     }
296
297     if (stred < 1000 && prava > 500){
298       move(-speed,-radius);
299       next = now + 1;
300     }    
301
302     if (now >= time_next){                                      // podminka vypisu, jednou za vterinu
303       time_next = now + 10;
304       cas++;
305       /*Vypsani vzdalenosti na terminal*/
306       //printf("V case %ds\tLeva: %d\tStredni: %d\tPrava: %d\n", cas, leva, stred, prava);      // vypisuje hodnoty povrchu po 1s
307     }                                                           // konec if podminklz na vypis za 1s 
308   }                                                             // konec hlavni smycky
309 }                                                               // konec funkce sleduj_caru()
310
311
312 void jezdi_ctverec(void)                                        // funkce jezdeni, zmena podle casovace
313 {
314   long int now = get_timer();
315   long int next = now;
316   int speed = 3000;
317   int radius = 100;
318   int stav = 1;                                                 // podle priznaku stavu se rozhoduje,zda pojede rovne, nebo zatoci
319   while (1) {
320     
321     long int now = get_timer();
322     
323       if (stav == 1 && now >= next){                            // podminka pro jizdu rovne po dobu 5s
324       stav = 0;
325       move(-speed,0);
326       next = now + 50;
327     }
328
329     if (stav == 0 && now >= next){                              // podminka pro zatoceni
330       stav = 1;                                                 
331       if (rand() % 100 < 50)
332       move(-speed,radius);
333       else
334       move(-speed,-radius);
335       next = now + 10;
336     }
337
338   }
339 }
340
341 uint16_t read_QRD1(void)                                        // funkce na vycteni informaci z AD prevodniku z ADDRC kde je nastaven AN6 tedy QRD114-1-leva zpredu
342 {
343   *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m;               // Zapnuti AD prevodniku 
344
345   *AD_ADCSR = ADCSR_CH2m | ADCSR_CH1m;                          // nastaveni analog vstupu AN8 - tedy vystup ze senzoru QRD114-3-prostredni. CH3=0,CH2=1,CH1=1,CH0=0 
346
347   uint8_t AN6h, AN6d;
348   uint16_t AN6;                                                 // AN6h je horni byte AD prevodu, AN6d je dolni byte. Jsou cteny z ADDRC (viz tabulka 4-2 [navratil], AN6 je cele 10-bitove cislo)
349   int i;
350
351   for(i = 0; i < 5; i++){                                       // for cyklus na 5 krat probehnuti smicky 
352     *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm;                        // softwarove nastaveni ADF do 0
353     *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm;                        // spusteni AD prevodu 
354             
355     while((*AD_ADCSR & ADCSR_ADFm) == 0) {                      // cekaci smycka dokud neskonci AD prevod
356       ;
357     }
358
359     /*Precteni vysledku AD prevodu z ADDRC*/
360     AN6h = *AD_ADDRCH;                                          // Cteni horniho bytu
361     AN6d = *AD_ADDRCL;                                          // Cteni dolniho bytu
362     AN6 = (AN6d >> 6) | (AN6h << 2);                            // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
363
364    }                                                            // konec for                                
365    return (AN6);                                                // return pro main_loop, muzu vypnout while(1) a }pro main 
366 }                                                               // konec funkce
367
368
369 uint16_t read_QRD2(void)                                        // funkce na vycteni informaci z AD prevodniku z ADDRD kde je nastaven AN7 tedy QRD114-2-prava zpredu
370 {
371   *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m;               // Zapnuti AD prevodniku 
372   
373   *AD_ADCSR = ADCSR_CH2m | ADCSR_CH1m | ADCSR_CH0m;             // nastaveni analog vstupu AN8 - tedy vystup ze senzoru QRD114-3-prostredni. CH3=0,CH2=1,CH1=1,CH0=1 
374   
375   uint8_t AN7h, AN7d;
376   uint16_t AN7;                                                 // AN7h je horni byte AD prevodu, AN7d je dolni byte. Jsou cteny z ADDRD (viz tabulka 4-2 [navratil], AN7 je cele 10-bitove cislo)
377   int i;
378
379   for(i = 0; i < 5; i++){                                       // for cyklus na 5 krat probehnuti smicky 
380     *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm;                        // softwarove nastaveni ADF do 0
381     *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm;                        // spusteni AD prevodu 
382             
383     while((*AD_ADCSR & ADCSR_ADFm) == 0) {                      // cekaci smycka dokud neskonci AD prevod
384       ;
385     }
386
387     /*Precteni vysledku AD prevodu z ADDRD*/
388     AN7h = *AD_ADDRDH;                                          //Cteni horniho bytu
389     AN7d = *AD_ADDRDL;                                          //Cteni dolniho bytu
390     AN7 = (AN7d >> 6) | (AN7h << 2);                            //Posun jednotlivych bitu, abychom dostali 10-bitove cislo
391
392    }                                                            //konec for                       
393    return (AN7);                                                // return pro main_loop, muzu vypnout while(1) a }pro main 
394 }                                                               // konec funkce
395
396
397 uint16_t read_QRD3(void)                                        // funkce na vycteni informaci z AD prevodniku z ADDRA kde je nastaven AN8 tedy QRD114-3-prostredni
398 {
399   *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m;               //Zapnuti AD prevodniku 
400   
401   *AD_ADCSR = ADCSR_CH3m;                                       // nastaveni analog vstupu AN8 - tedy vystup ze senzoru QRD114-3-prostredni. CH3=1,CH2=0,CH1=0,CH0=0 
402
403   uint8_t AN8h, AN8d;
404   uint16_t AN8;                                                 //AN8h je horni byte AD prevodu, AN8d je dolni byte. Jsou cteny z ADDRA (viz tabulka 4-2 [navratil], AN8 je cele 10-bitove cislo)
405   int i;
406
407   for(i = 0; i < 5; i++){                                       // for cyklus na 5 krat probehnuti smicky 
408     *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm;                        // softwarove nastaveni ADF do 0
409     *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm;                        // spusteni AD prevodu 
410             
411     while((*AD_ADCSR & ADCSR_ADFm) == 0) {                      // cekaci smycka dokud neskonci AD prevod
412       ;
413     }
414
415     /*Precteni vysledku AD prevodu z ADDRA*/
416     AN8h = *AD_ADDRAH;                                          // Cteni horniho bytu  
417     AN8d = *AD_ADDRAL;                                          // Cteni dolniho bytu
418     AN8 = (AN8d >> 6) | (AN8h << 2);                            // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
419
420    }                                                            // konec for                                
421    return (AN8);                                                // return pro main_loop, muzu vypnout while(1) a }pro main 
422 }                                                               // konec funkce
423
424
425 uint16_t read_GP1(void)                                         // funkce na vycteni informaci z AD prevodniku z ADDRB kde je nastaven AN9 tedy GP2D12 predni
426 {                                                               // vraci hodnotu vzdalenosti podle tabulky 4-neco
427   *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m;               // Zapnuti AD prevodniku
428
429    *AD_ADCSR = ADCSR_CH3m | ADCSR_CH0m;                         // nastaveni analog vstupu AN9 - tedy vzstup ze senzoru GP2D12-predni. CH3=1,CH2=0,CH1=0,CH0=1 
430
431   uint8_t AN9h, AN9d;
432   uint16_t AN9;                                                 // AN9h je horni byte AD prevodu, AN9d je dolni byte. Jsou cteny z ADDRB (viz tabulka 4-2 [navratil], AN9 je cele 10-bitove cislo)
433   int i;
434
435   for (i = 0; i < 5; i++){                                      // for cyklus na 5 krat probehnuti smicky , aby se ustalily hodnoty ze senzoru a nedavaly nahodnou hodnotu
436     *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm;                        // softwarove nastaveni ADF do 0
437     *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm;                        // spusteni AD prevodu 
438             
439     while((*AD_ADCSR & ADCSR_ADFm) == 0) {                      // cekaci smycka dokud neskonci AD prevod
440       ;
441     }
442
443     /*Precteni vysledku AD prevodu z ADDRB*/
444     AN9h = *AD_ADDRBH;                                          // Cteni horniho bytu
445     AN9d = *AD_ADDRBL;                                          // Cteni dolniho bytu
446     AN9 = (AN9d >> 6) | (AN9h << 2);                            // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
447
448    }                                                            // konec for                               
449    return (AN9);                                                // return pro main_loop, muzu vypnout while(1) a }pro main 
450 }                                                               // konec funkce
451
452
453 uint16_t read_GP2(void)                                         // funkce na vycteni informaci z AD prevodniku z ADDRC kde je nastaven AN10 tedy GP2D12 zadni
454 {
455   *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m;               // Zapnuti AD prevodniku 
456   *AD_ADCSR = ADCSR_CH3m | ADCSR_CH1m;                          // nastaveni analog vstupu AN10 - tedy vstup ze senzoru GP2D12-predni. CH3=1,CH2=0,CH1=1,CH0=0 
457
458   uint8_t AN10h, AN10d;
459   uint16_t AN10;                                                //AN10h je horni byte AD prevodu, AN10d je dolni byte. Jsou cteny z ADDRC (viz tabulka 4-2 [navratil], AN10 je cele 10-bitove cislo)
460   int i;
461
462    for(i = 0; i < 5; i++){                                      // for cyklus na 5 krat probehnuti smicky, aby se ustalily hodnoty ze senzoru a nedavali nahodne hodnoty 
463     *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm;                        // softwarove nastaveni ADF do 0
464     *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm;                        // spusteni AD prevodu 
465             
466     while((*AD_ADCSR & ADCSR_ADFm) == 0) {                      // cekaci smycka dokud neskonci AD prevod
467       ;
468     }
469
470     /*Precteni vysledku AD prevodu z ADDRC*/
471     AN10h = *AD_ADDRCH;                                         // Cteni horniho bytu
472     AN10d = *AD_ADDRCL;                                         // Cteni dolniho bytu
473     AN10 = (AN10d >> 6) | (AN10h << 2);                         // Posun jednotlivych bitu, abychom dostali 10-bitove cislo*/
474    }                                                             //konec for                                
475    return (AN10);
476 }
477
478
479 int main()
480 {
481   _print("Snowforce for life ! ! !\n"); 
482   init();
483   /* TODO initialize rand accoring to voltage read from AD6. */
484
485   autonomni_pohyb();                                            // volani hlavni funkce autonomniho pohybu robota
486   //sleduj_caru();                                              // volani funkce na sledovani cary
487   for (;;);                                                     // nekonecna smycka, pro odchyceni nahodneho skoku zpet do main
488   return 0;
489 }