--- /dev/null
+/*
+*
+* Author funkci na pohyb motoru: Petr Kovacik <kovacp1@feld.cvut.cz>, (C) 2006
+*
+* Autor funkci na autonomni pohyb: Milan Navratil <navram1@fel.cvut.cz> 2008
+*
+* Popis: main vola funkce autonomni_pohyb() , nebo sleduj_caru(),
+* obe funkce pak volaji funkce na vycteni dat z 10-bitoveho A/D prevodniku
+*
+*/
+#define _USE_EXR_LEVELS 1
+#include <types.h>
+#include <cpu_def.h>
+#include <h8s2638h.h>
+#include <periph/sci_rs232.h>
+#include <system_def.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pxmc.h>
+#include <pxmcbsp.h>
+
+#include <cmd_proc.h>
+#include "cmd_pxmc.h"
+#include "timer3.h"
+#include <stdio.h>
+
+uint16_t read_GP1(void); // deklarace funkce read_GP1
+uint16_t read_GP2(void); // deklarace funkce read_GP2
+uint16_t read_QRD1(void); // deklarace funkce read_QRD1
+uint16_t read_QRD2(void); // deklarace funkce read_QRD2
+uint16_t read_QRD3(void); // deklarace funkce read_QRD3
+
+
+
+cmd_des_t const *cmd_rs232_default[];
+
+/*struktury prikazu cmd*/
+cmd_des_t const cmd_des_help={0, 0,"HELP","prints help for commands",
+ cmd_do_help,{(char*)&cmd_rs232_default}};
+
+cmd_des_t const *cmd_rs232_default[]={
+
+ &cmd_des_help,
+ CMD_DES_CONTINUE_AT(cmd_pxmc_default),
+ NULL
+};
+cmd_des_t const **cmd_bth=cmd_rs232_default; /*cmd prikazy pro bth*/
+cmd_des_t const **cmd_rs232=cmd_rs232_default; /*cmd prikazy pro PC*/
+
+
+/*struktury charakterizujici motor 0*/
+pxmc_state_t mcsX0={
+ pxms_flg:0,
+ pxms_do_inp:0,
+ pxms_do_con:0,
+ pxms_do_out:0,
+ pxms_do_deb:0,
+ pxms_do_gen:0,
+ pxms_ap:0, pxms_as:0,
+ pxms_rp:155l*256,
+ pxms_rs:0, //pxms_subdiv:8,
+ pxms_md:8000l<<8, pxms_ms:5000, pxms_ma:5, // pxms_ma je akcelerace robota byla nastavena na 10
+ pxms_inp_info:(long)TPU_TCNT1,//TPU_TCNT1 /*chanel TPU A,B*/
+ pxms_out_info:(long)PWM_PWBFR1A, /*chanel PWM A,B*/
+ pxms_ene:0, pxms_erc:0,
+ pxms_p:40, pxms_i:0, pxms_d:1, pxms_s1:0, pxms_s2:0,
+ pxms_me:0x1800, //6144
+ pxms_ptirc:40, // 2000 irc per rev, 200/4 steps /
+ pxms_ptper:1,
+ pxms_ptptr1:NULL,
+ pxms_ptptr2:NULL,
+ pxms_cfg:PXMS_CFG_MD2E_m|PXMS_CFG_HLS_m|
+ PXMS_CFG_HPS_m|PXMS_CFG_HDIR_m|0x1
+};
+
+
+/*struktury charakterizujici motor 1*/
+pxmc_state_t mcsX1={
+ pxms_flg:0,
+ pxms_do_inp:0,
+ pxms_do_con:0,
+ pxms_do_out:0,
+ pxms_do_deb:0,
+ pxms_do_gen:0,
+ pxms_ap:0, pxms_as:0,
+ pxms_rp:155l*256,
+ pxms_rs:0, //pxms_subdiv:8,
+ pxms_md:8000l<<8, pxms_ms:5000, pxms_ma:5,
+ pxms_inp_info:(long)TPU_TCNT2, /*chanel TPU C,D*/
+ pxms_out_info:(long)PWM_PWBFR1C, /*chanel PWM C,D*/
+ pxms_ene:0, pxms_erc:0,
+ pxms_p:40, pxms_i:0, pxms_d:1, pxms_s1:0, pxms_s2:0,
+ pxms_me:0x1800, //6144
+ pxms_ptirc:40, // 2000 irc per rev, 200/4 steps /
+ pxms_ptper:1,
+ pxms_ptptr1:NULL,
+ pxms_ptptr2:NULL,
+ pxms_cfg:PXMS_CFG_MD2E_m|PXMS_CFG_HLS_m| //FIXME: nastavit spravne priznaky pro dalsi motorove struktur
+ PXMS_CFG_HPS_m|PXMS_CFG_HDIR_m|0x1
+};
+
+pxmc_state_t *pxmc_main_arr[] = {&mcsX0,&mcsX1};
+
+pxmc_state_list_t pxmc_main_list = {
+ pxml_arr:pxmc_main_arr,
+ pxml_cnt:sizeof(pxmc_main_arr)/sizeof(pxmc_main_arr[0])
+};
+
+
+
+//*******************************************************
+
+void unhandled_exception(void) __attribute__ ((interrupt_handler));
+
+/*Interrupt routines*/
+void unhandled_exception(void)
+{
+};
+//********************************************************
+
+extern cmd_io_t cmd_io_rs232_line;
+
+extern void _print(char *str);
+
+void
+init(void)
+{
+ /********************************************************************************/
+ *DIO_PJDDR=0xff; /*output gate*/
+ *DIO_PEDDR=0xff; /*output gate*/
+ *DIO_PEDR=0x60; /*0x0-LED - light all; 0x6 -ENA,ENB=1, LE33CD=0*/
+ *DIO_PJDR=0x00; //rozsviceni vsech diod na */
+
+
+ /*priority preruseni - SCI > TPU*/
+/* *SYS_SYSCR|=SYSCR_INTM1m; */
+/* *INT_IPRA=0x22; *INT_IPRB=0x22; *INT_IPRC=0x04; */
+/* *INT_IPRD=0x40; *INT_IPRE=0x44; *INT_IPRF=0x55; */
+/* *INT_IPRG=0x55; *INT_IPRH=0x55; *INT_IPRJ=0x06; */
+/* *INT_IPRK=0x67; *INT_IPRM=0x66; */
+
+ /*povoleni vsech preruseni atd...*/
+ cli();
+ excptvec_initfill(unhandled_exception, 0);
+
+ /*nastaveni seriovych linek - Bth, PC*/
+ //sci_rs232_setmode(RS232_BAUD_RAW | 3, 0, 0, 2); // HCI - hardcoded 115200
+ //sci_rs232_setmode(115200, 0, 0, 2); // HCI
+ sci_rs232_setmode(19200, 0, 0, sci_rs232_chan_default); //PC
+ sti();
+
+ _print("Start\n");
+
+ pxmc_initialize();
+
+ if (init_timer3((long long)100/*ms*/*1000*1000) < 0) {
+ /* ERROR */
+ DEB_LED_OFF(0);
+ }
+}
+
+
+// Distance of wheels - d
+#define WHEEL_DIST 74 /* mm */
+#define MAX_R 300 /* mm */
+#define MIN_R (WHEEL_DIST/2) /* mm */
+
+void move(int speed, int r)
+{
+ int sl, sr;
+ int d = WHEEL_DIST;
+
+
+ if (r != 0) {
+ sr = speed + (long long)speed * (d/2) / r;
+ sl = speed - (long long)speed * (d/2) / r;
+ } else {
+ sr = speed;
+ sl = speed + 10; // minus 100 je kompenzace zataceni
+ }
+ pxmc_spd(&mcsX0, +sl, 0);
+ pxmc_spd(&mcsX1, -sr, 0);
+ printf("speed=%5d, r=%5d, sl=%5d, sr=%5d\n", speed, r, sl, sr);
+}
+
+void autonomni_pohyb(void)
+{
+ long int now = get_timer();
+ long int next = now;
+ long int otoc_next = now;
+ long int time_next = now;
+ int speed = 3000;
+ int radius = 100;
+ int stav = 1; // podle priznaku stavu se rozhoduje,zda pojede rovne, nebo zatoci
+ int otoc = 0; // priznak pro otoceni
+ int smer = 1; // smer = 1 robot jede dopredu, smer = -1 robot jede dozadu
+ uint16_t vzdalenost, vzdalenost_zpet, cas=0;
+
+ while (1) {
+
+ long int now = get_timer();
+
+ vzdalenost = read_GP1();
+ vzdalenost_zpet = read_GP2();
+
+ if (now >= time_next){ // podminka vypisu, jednou za vterinu
+ time_next = now + 10;
+ cas++;
+ /*Vypsani vzdalenosti na terminal*/
+ printf("Predni: %d\tZadni: %d\tSpeed: %d\tSmer: %d\tOtoc: %d\n", vzdalenost, vzdalenost_zpet, speed, smer, otoc);
+ } // konec if podminky na vypis za 1s
+
+ if (stav == 1 && now >= next){ // podminka pro jizdu
+ stav = 0;
+ move(-speed,0);
+ otoc++;
+ }
+
+ if (stav == 0 && vzdalenost >= 280 && smer == 1){ // podminka pro zatoceni 260 odpovida (mensi nez 20cm)
+
+ if (rand() % 100 < 70) // 50 % predpoklad pro zatoceni doprava
+ move(-speed,radius); // zatoc rychlosti speed a polomerem radius(doprava)
+ else
+ move(-speed,-radius); // zatoc rychlosti speed a polomerem -radius (doleva)
+ stav = 1;
+
+ next = now + ((rand() % 8)+5); // zataceni po dobu 5 - 12 (nahodne cislo)
+ } // konec if
+
+
+ if (stav == 0 && vzdalenost_zpet >= 280 && smer == -1){ // jizda zpet!!! podminka pro zatoceni 260 odpovida (mensi nez 20cm)
+
+ if (rand() % 100 < 70) // 50 % predpoklad pro zatoceni doprava
+ move(-speed,radius); // zatoc rychlosti speed a radiusem,
+ else
+ move(-speed,-radius);
+ stav = 1;
+
+ next = now + ((rand() % 8)+5); // zataceni po dobu 5 - 12 (nahodne cislo)
+ } //konec if
+
+// NEVIM JAK UDELAT OPRENI SE O PREKAZKU A OTOCENI // osetreni, kdyz se robot opre o prekazku, chceme,aby se rozjel opacnym smerem
+ /*if (vzdalenost <=30 && now >= otoc_next) { // pokud se sensor dotyka prekazky, tak dava hodnotu 110 az 140, kontroluji to 10x 0,1s
+ otoc++;
+ otoc_next = now + 1;
+ }
+
+ 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
+ otoc++;
+ otoc_next = now + 1;
+ }
+
+ if (otoc >= 10){
+ speed = -speed; // zmena smeru
+ otoc = 0;
+ } */
+
+ //zmena_smeru
+ if (otoc >= 6){
+ speed = -speed;
+ otoc = 0;
+ smer = -smer;
+ move(-speed,0); //otoc normalne je pouzit o if cyklus drive, ted si ho jen pujcuji
+ }
+
+ } //konec while
+} //konec funkce
+
+
+void sleduj_caru(void){
+ long int now = get_timer();
+ long int next = now;
+ long int time_next = now;
+ int speed = 2000;
+ int radius = 100;
+ uint16_t leva, stred, prava, cas=0;
+
+ move(2000,0);
+ while(1){
+
+ long int now = get_timer();
+
+ stred = read_QRD3(); // pohled zpredu, cteni senzoru odrazu QRD1114 1-3
+ leva = read_QRD1();
+ prava = read_QRD2();
+
+ if (stred > 1000 && leva < 500 && prava <500 && now >= next){ // rozhodovani
+ move(-speed,0);
+ }
+
+ if (stred < 1000 && leva > 500){
+ move(-speed,radius);
+ next = now + 1;
+ }
+
+ if (stred < 1000 && prava > 500){
+ move(-speed,-radius);
+ next = now + 1;
+ }
+
+ if (now >= time_next){ // podminka vypisu, jednou za vterinu
+ time_next = now + 10;
+ cas++;
+ /*Vypsani vzdalenosti na terminal*/
+ printf("V case %ds\tLeva: %d\tStredni: %d\tPrava: %d\n", cas, leva, stred, prava); // vypisuje hodnoty povrchu po 1s
+ } // konec if podminklz na vypis za 1s
+ } // konec hlavni smycky
+} // konec funkce sleduj_caru()
+
+
+void jezdi_ctverec(void) // funkce jezdeni, zmena podle casovace
+{
+ long int now = get_timer();
+ long int next = now;
+ int speed = 3000;
+ int radius = 100;
+ int stav = 1; // podle priznaku stavu se rozhoduje,zda pojede rovne, nebo zatoci
+ while (1) {
+
+ long int now = get_timer();
+
+ if (stav == 1 && now >= next){ // podminka pro jizdu rovne po dobu 5s
+ stav = 0;
+ move(-speed,0);
+ next = now + 50;
+ }
+
+ if (stav == 0 && now >= next){ // podminka pro zatoceni
+ stav = 1;
+ if (rand() % 100 < 50)
+ move(-speed,radius);
+ else
+ move(-speed,-radius);
+ next = now + 10;
+ }
+
+ }
+}
+
+uint16_t read_QRD1(void) // funkce na vycteni informaci z AD prevodniku z ADDRC kde je nastaven AN6 tedy QRD114-1-leva zpredu
+{
+ *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m; // Zapnuti AD prevodniku
+
+ *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
+
+ uint8_t AN6h, AN6d;
+ 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)
+ int i;
+
+ for(i = 0; i < 5; i++){ // for cyklus na 5 krat probehnuti smicky
+ *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm; // softwarove nastaveni ADF do 0
+ *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm; // spusteni AD prevodu
+
+ while((*AD_ADCSR & ADCSR_ADFm) == 0) { // cekaci smycka dokud neskonci AD prevod
+ ;
+ }
+
+ /*Precteni vysledku AD prevodu z ADDRC*/
+ AN6h = *AD_ADDRCH; // Cteni horniho bytu
+ AN6d = *AD_ADDRCL; // Cteni dolniho bytu
+ AN6 = (AN6d >> 6) | (AN6h << 2); // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
+
+ } // konec for
+ return (AN6); // return pro main_loop, muzu vypnout while(1) a }pro main
+} // konec funkce
+
+
+uint16_t read_QRD2(void) // funkce na vycteni informaci z AD prevodniku z ADDRD kde je nastaven AN7 tedy QRD114-2-prava zpredu
+{
+ *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m; // Zapnuti AD prevodniku
+
+ *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
+
+ uint8_t AN7h, AN7d;
+ 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)
+ int i;
+
+ for(i = 0; i < 5; i++){ // for cyklus na 5 krat probehnuti smicky
+ *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm; // softwarove nastaveni ADF do 0
+ *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm; // spusteni AD prevodu
+
+ while((*AD_ADCSR & ADCSR_ADFm) == 0) { // cekaci smycka dokud neskonci AD prevod
+ ;
+ }
+
+ /*Precteni vysledku AD prevodu z ADDRD*/
+ AN7h = *AD_ADDRDH; //Cteni horniho bytu
+ AN7d = *AD_ADDRDL; //Cteni dolniho bytu
+ AN7 = (AN7d >> 6) | (AN7h << 2); //Posun jednotlivych bitu, abychom dostali 10-bitove cislo
+
+ } //konec for
+ return (AN7); // return pro main_loop, muzu vypnout while(1) a }pro main
+} // konec funkce
+
+
+uint16_t read_QRD3(void) // funkce na vycteni informaci z AD prevodniku z ADDRA kde je nastaven AN8 tedy QRD114-3-prostredni
+{
+ *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m; //Zapnuti AD prevodniku
+
+ *AD_ADCSR = ADCSR_CH3m; // nastaveni analog vstupu AN8 - tedy vystup ze senzoru QRD114-3-prostredni. CH3=1,CH2=0,CH1=0,CH0=0
+
+ uint8_t AN8h, AN8d;
+ 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)
+ int i;
+
+ for(i = 0; i < 5; i++){ // for cyklus na 5 krat probehnuti smicky
+ *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm; // softwarove nastaveni ADF do 0
+ *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm; // spusteni AD prevodu
+
+ while((*AD_ADCSR & ADCSR_ADFm) == 0) { // cekaci smycka dokud neskonci AD prevod
+ ;
+ }
+
+ /*Precteni vysledku AD prevodu z ADDRA*/
+ AN8h = *AD_ADDRAH; // Cteni horniho bytu
+ AN8d = *AD_ADDRAL; // Cteni dolniho bytu
+ AN8 = (AN8d >> 6) | (AN8h << 2); // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
+
+ } // konec for
+ return (AN8); // return pro main_loop, muzu vypnout while(1) a }pro main
+} // konec funkce
+
+
+uint16_t read_GP1(void) // funkce na vycteni informaci z AD prevodniku z ADDRB kde je nastaven AN9 tedy GP2D12 predni
+{ // vraci hodnotu vzdalenosti podle tabulky 4-neco
+ *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m; // Zapnuti AD prevodniku
+
+ *AD_ADCSR = ADCSR_CH3m | ADCSR_CH0m; // nastaveni analog vstupu AN9 - tedy vzstup ze senzoru GP2D12-predni. CH3=1,CH2=0,CH1=0,CH0=1
+
+ uint8_t AN9h, AN9d;
+ 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)
+ int i;
+
+ for (i = 0; i < 5; i++){ // for cyklus na 5 krat probehnuti smicky , aby se ustalily hodnoty ze senzoru a nedavaly nahodnou hodnotu
+ *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm; // softwarove nastaveni ADF do 0
+ *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm; // spusteni AD prevodu
+
+ while((*AD_ADCSR & ADCSR_ADFm) == 0) { // cekaci smycka dokud neskonci AD prevod
+ ;
+ }
+
+ /*Precteni vysledku AD prevodu z ADDRB*/
+ AN9h = *AD_ADDRBH; // Cteni horniho bytu
+ AN9d = *AD_ADDRBL; // Cteni dolniho bytu
+ AN9 = (AN9d >> 6) | (AN9h << 2); // Posun jednotlivych bitu, abychom dostali 10-bitove cislo
+
+ } // konec for
+ return (AN9); // return pro main_loop, muzu vypnout while(1) a }pro main
+} // konec funkce
+
+
+uint16_t read_GP2(void) // funkce na vycteni informaci z AD prevodniku z ADDRC kde je nastaven AN10 tedy GP2D12 zadni
+{
+ *SYS_MSTPCRA = *SYS_MSTPCRA & ~MSTPCRA_MSTPA1m; // Zapnuti AD prevodniku
+ *AD_ADCSR = ADCSR_CH3m | ADCSR_CH1m; // nastaveni analog vstupu AN10 - tedy vstup ze senzoru GP2D12-predni. CH3=1,CH2=0,CH1=1,CH0=0
+
+ uint8_t AN10h, AN10d;
+ 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)
+ int i;
+
+ for(i = 0; i < 5; i++){ // for cyklus na 5 krat probehnuti smicky, aby se ustalily hodnoty ze senzoru a nedavali nahodne hodnoty
+ *AD_ADCSR = *AD_ADCSR & ~ADCSR_ADFm; // softwarove nastaveni ADF do 0
+ *AD_ADCSR = *AD_ADCSR | ADCSR_ADSTm; // spusteni AD prevodu
+
+ while((*AD_ADCSR & ADCSR_ADFm) == 0) { // cekaci smycka dokud neskonci AD prevod
+ ;
+ }
+
+ /*Precteni vysledku AD prevodu z ADDRC*/
+ AN10h = *AD_ADDRCH; // Cteni horniho bytu
+ AN10d = *AD_ADDRCL; // Cteni dolniho bytu
+ AN10 = (AN10d >> 6) | (AN10h << 2); // Posun jednotlivych bitu, abychom dostali 10-bitove cislo*/
+ } //konec for
+ return (AN10);
+}
+
+
+int main()
+{
+ _print("Snowforce for life ! ! !\n");
+ init();
+ /* TODO initialize rand accoring to voltage read from AD6. */
+
+ autonomni_pohyb(); // volani hlavni funkce autonomniho pohybu robota
+ //sleduj_caru(); // volani funkce na sledovani cary
+ for (;;); // nekonecna smycka, pro odchyceni nahodneho skoku zpet do main
+ return 0;
+}