Added testing SW in folder test_sw.
[fpga/rpi-motor-control.git] / pmsm-control / test_sw / main_pmsm.c
1 /**
2  * \file main_pmsm.c
3  * \author Martin Prudek
4  * \brief Mainfile pro pmsm control.
5  */
6
7 #ifndef NULL
8 #define NULL (void*) 0
9 #endif /*NULL*/
10
11
12 #include <stdlib.h>     /*exit*/
13 #include <signal.h>     /*signal handler Ctrl+C*/
14 #include <stdio.h>      /*printf*/
15 #include <sched.h>      /*sheduler*/
16 #include <unistd.h>     /*usleep*/
17 #include <pthread.h>    /*threads*/
18
19 #include "rpin.h"       /*gpclk*/
20 #include "rp_spi.h"     /*spi*/
21 #include "misc.h"       /*structure for priorities*/
22
23
24 #define PRUM_PROUD      2061
25 #define PRUM_SOUC       6183
26
27 #define PRIOR_KERN      50
28 #define PRIOR_HIGH      49
29 #define PRIOR_LOW       20
30
31 #define THREAD_SHARED   0
32 #define INIT_VALUE      0       /*init value for semaphor*/
33
34 struct sigaction sighnd; /*struktura pro signal handler*/
35 struct rpi_in data;
36
37 uint8_t test;
38 uint16_t pwm1, pwm2, pwm3;
39
40
41 /**
42  * \brief Initilizes GPCLK.
43  */
44 int clk_init()
45 {
46         initialise(); /*namapovani gpio*/
47         initClock(PLLD_500_MHZ, 10, 0);
48         gpioSetMode(4, FSEL_ALT0);
49         return 0;
50 }
51 /*
52  * \brief Terminates GPCLK.
53  */
54
55 inline void clk_disable(){
56         termClock(0);
57 }
58
59 /**
60  * \brief Signal handler pro Ctrl+C
61  */
62 void sighnd_fnc(){
63         spi_disable();
64         clk_disable();
65         printf("\nprogram bezpecne ukoncen\n");
66         exit(0);
67 }
68
69 void substractOffset(struct rpi_in* data, struct rpi_in* offset){
70         data->pozice-=offset->pozice;
71         return;
72 }
73 /*
74  * pocita procentualni odchylku od prumerneho proudu
75  */
76 float diff_p(int16_t value){
77         return ((float)value-PRUM_PROUD)*100/PRUM_PROUD;
78 }
79 /*
80  * pocita procentualni odchylku od prumerneho souctu proudu
81  */
82 float diff_s(int16_t value){
83         return ((float)value-PRUM_SOUC)*100/PRUM_SOUC;
84 }
85 /*
86  * tiskne potrebna data
87  */
88 void printData(struct rpi_in data){
89         printf("\npozice=%d\n",(int32_t)data.pozice);
90         printf("hal1=%d, hal2=%d, hal3=%d\n",data.hal1,data.hal2,data.hal3);
91         printf("en1=%d, en2=%d, en3=%d (Predchozi hodnoty)\n",data.en1,data.en2,data.en3);
92         printf("shdn1=%d, shdn2=%d, shdn3=%d (P.h.)\n",data.shdn1,data.shdn2,data.shdn3);
93         printf("PWM1(10d5)b54=%d %d %d %d %d %d=b49(P.h.)\n",data.b54,data.b53,data.b52,data.b51,data.b50,data.b49);
94         printf("PWM2(10d4)b48=%d %d %d %d %d %d %d=b42(P.h.)\n",data.b48,data.b47,data.b46,data.b45,data.b44,data.b43,data.b42);
95         printf("PWM3(10d5)b41=%d %d %d %d %d %d=b36(P.h.)\n",data.b41,data.b40,data.b39,data.b38,data.b37,data.b36);
96         printf("(pwm1)proud1 (ch1)=%d (%2.2f%%) %x\n",data.ch1,diff_p(data.ch1),(uint16_t)data.ch1);
97         printf("(pwm2)proud2 (ch2)=%d (%2.2f%%) %x\n",data.ch2,diff_p(data.ch2),(uint16_t)data.ch2);
98         printf("(pwm3)proud3 (ch0)=%d (%2.2f%%) %x\n",data.ch0,diff_p(data.ch0),(uint16_t)data.ch0);
99         printf("soucet proudu=%d (%2.2f%%)\n",data.ch0+data.ch1+data.ch2,diff_s(data.ch0+data.ch1+data.ch2));
100 }
101 void prepare_tx(uint8_t * tx){
102
103         /*Data format:
104          * tx[0] - bity 95 downto 88 - bits that are sent first
105          * tx[1] - bity 87 downto 80
106          * tx[2] - bity 79 downto 72
107          * tx[3] - bity 71 downto 64
108          * tx[4] - bity 63 downto 56
109          * tx[5] - bity 55 downto 48
110          * tx[6] - bity 47 downto 40
111          * tx[7] - bity 39 downto 32
112          * tx[8] - bity 31 downto 24
113          * tx[9] - bity 23 downto 16
114          * tx[10] - bity 15 downto 8
115          * tx[11] - bity 7 downto 0
116          *
117          * bit 95 - ADC reset
118          * bit 94 - enable PWM1
119          * bit 93 - enable PWM2
120          * bit 92 - enable PWM3
121          * bit 91 - shutdown1
122          * bit 90 - shutdown2
123          * bit 89 - shutdown3
124          *      .
125          *      .
126          *      .
127          * bits 34 .. 24 - match PWM1
128          * bits 23 .. 13 - match PWM2
129          * bit 11,12 - Unused
130          * bits 10 .. 0  - match PWM3
131          */
132
133
134         uint16_t tmp;
135
136         /* keep the cap*/
137         if (pwm1>2047) pwm1=2047;
138         if (pwm2>2047) pwm2=2047;
139         if (pwm3>2047) pwm3=2047;
140
141         tx[0]=test; /*bit 94 - enable PWM1*/
142
143         /*pwm1*/
144         tx[7]=(tx[7] & 0xF8) | (0x07 & ((uint8_t*)&pwm1)[1]); /*MSB*/
145         tx[8]=((uint8_t*)&pwm1)[0]; /*LSB*/
146
147         /*pwm2*/
148         tmp=pwm2;
149         tmp<<=5;
150         tx[9]=((uint8_t*)&tmp)[1]; /*MSB*/
151         tx[10]=(tx[10] & 0x1F) | (0xE0 & ((uint8_t*)&tmp)[0]); /*LSB*/
152
153         /*pwm3*/
154         tx[10]=(tx[10] & 0xF8) | (0x07 & ((uint8_t*)&pwm3)[1]); /*MSB*/
155         tx[11]=((uint8_t*)&pwm3)[0]; /*LSB*/
156
157
158 }
159 /**
160  * Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
161  */
162 void * pos_monitor(void* param){
163         set_priority(param);            /*set priority*/
164         while(1){
165                 printData(data);
166                 usleep(1000000);        /*1 Hz*/
167         }
168         return (void*)0;
169 }
170
171 /**
172  * Funkce pravidelne vycita data z motoru
173  */
174 void * read_data(void* param){
175         int i;
176         struct rpi_in pocatek;
177         uint8_t tx[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
178         set_priority(param);                            /*set priority*/
179         pocatek = spi_read(tx);
180                 while(1){
181                         prepare_tx(tx);
182                         data = spi_read(tx);
183                         substractOffset(&data,&pocatek);
184                         usleep(1000);                           /*1kHz*/
185                 }
186 }
187
188 /**
189  * \brief Main function.
190  */
191
192 int main(){
193         uint16_t tmp;
194
195         /*nastaveni priorit vlaken*/
196         struct thread_param tsp;
197         tsp.sch_policy = SCHED_FIFO;
198
199         /*nastaveni signalu pro vypnuti pomoci Ctrl+C*/
200         sighnd.sa_handler=&sighnd_fnc;
201         sigaction(SIGINT, &sighnd, NULL );
202
203         clk_init();             /* inicializace gpio hodin */
204         spi_init();             /* iniicializace spi*/
205
206         /*semafor pro detekci zpracovani parametru vlaken*/
207         sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
208
209         /*vlakna*/
210         pthread_t tid;                  /*identifikator vlakna*/
211         pthread_attr_t attr;            /*atributy vlakna*/
212         pthread_attr_init(&attr);       /*inicializuj implicitni atributy*/
213
214
215
216         /*ziskavani dat z motoru*//*vysoka priorita*/
217         tsp.sch_prior = PRIOR_HIGH;
218         pthread_create(&tid, &attr, read_data, (void*)&tsp);
219
220         /*vypisovani lokalni pozice*//*nizka priorita*/
221         tsp.sch_prior = PRIOR_LOW;
222         pthread_create(&tid, &attr, pos_monitor, (void*)&tsp);
223
224
225         /*muzeme zavrit semafor*/
226         sem_destroy(&thd_par_sem);
227
228         while (1){
229                 scanf("%u",&tmp);
230                 printf("volba=%x\n",tmp);
231                 switch (tmp){
232                 case 1:
233                         scanf("%u",&pwm1);
234                         break;
235                 case 2:
236                         scanf("%u",&pwm2);
237                         break;
238                 case 3:
239                         scanf("%u",&pwm3);
240                         break;
241                 case 4:
242                         scanf("%u",&test);
243                         break;
244
245                 default:
246                         break;
247                 }
248
249         }
250         return 0;
251 }