Sending unique measured current value was replaced by current accumulator. Now multip...
[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(float 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(float 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         float cur0, cur1, cur2;
90         if (data.adc_m_count){
91                 cur0=data.ch0/data.adc_m_count;
92                 cur1=data.ch1/data.adc_m_count;
93                 cur2=data.ch2/data.adc_m_count;
94         }
95         printf("\npozice=%d\n",(int32_t)data.pozice);
96         printf("hal1=%d, hal2=%d, hal3=%d\n",data.hal1,data.hal2,data.hal3);
97         //printf("en1=%d, en2=%d, en3=%d (Predchozi hodnoty)\n",data.en1,data.en2,data.en3);
98         //printf("shdn1=%d, shdn2=%d, shdn3=%d (P.h.)\n",data.shdn1,data.shdn2,data.shdn3);
99         //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);
100         //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);
101         //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);
102         printf("Pocet namerenych proudu=%u\n",data.adc_m_count);
103         printf("(pwm1)proud1 (ch1)=%d (avg=%4.0f) (%2.2f%%)\n",data.ch1,cur1,diff_p(cur1));
104         printf("(pwm2)proud2 (ch2)=%d (avg=%4.0f)(%2.2f%%)\n",data.ch2,cur2,diff_p(cur2));
105         printf("(pwm3)proud3 (ch0)=%d (avg=%4.0f)(%2.2f%%)\n",data.ch0,cur0,diff_p(cur0));
106         printf("soucet prumeru=%5.0f (%2.2f%%)\n",cur0+cur1+cur2,diff_s(cur0+cur1+cur2));
107 }
108 void prepare_tx(uint8_t * tx){
109
110         /*Data format:
111          * tx[0] - bity 95 downto 88 - bits that are sent first
112          * tx[1] - bity 87 downto 80
113          * tx[2] - bity 79 downto 72
114          * tx[3] - bity 71 downto 64
115          * tx[4] - bity 63 downto 56
116          * tx[5] - bity 55 downto 48
117          * tx[6] - bity 47 downto 40
118          * tx[7] - bity 39 downto 32
119          * tx[8] - bity 31 downto 24
120          * tx[9] - bity 23 downto 16
121          * tx[10] - bity 15 downto 8
122          * tx[11] - bity 7 downto 0
123          *
124          * bit 95 - ADC reset
125          * bit 94 - enable PWM1
126          * bit 93 - enable PWM2
127          * bit 92 - enable PWM3
128          * bit 91 - shutdown1
129          * bit 90 - shutdown2
130          * bit 89 - shutdown3
131          *      .
132          *      .
133          *      .
134          * bits 34 .. 24 - match PWM1
135          * bits 23 .. 13 - match PWM2
136          * bit 11,12 - Unused
137          * bits 10 .. 0  - match PWM3
138          */
139
140
141         uint16_t tmp;
142
143         /* keep the cap*/
144         if (pwm1>2047) pwm1=2047;
145         if (pwm2>2047) pwm2=2047;
146         if (pwm3>2047) pwm3=2047;
147
148         tx[0]=test; /*bit 94 - enable PWM1*/
149
150         /*pwm1*/
151         tx[7]=(tx[7] & 0xF8) | (0x07 & ((uint8_t*)&pwm1)[1]); /*MSB*/
152         tx[8]=((uint8_t*)&pwm1)[0]; /*LSB*/
153
154         /*pwm2*/
155         tmp=pwm2;
156         tmp<<=5;
157         tx[9]=((uint8_t*)&tmp)[1]; /*MSB*/
158         tx[10]=(tx[10] & 0x1F) | (0xE0 & ((uint8_t*)&tmp)[0]); /*LSB*/
159
160         /*pwm3*/
161         tx[10]=(tx[10] & 0xF8) | (0x07 & ((uint8_t*)&pwm3)[1]); /*MSB*/
162         tx[11]=((uint8_t*)&pwm3)[0]; /*LSB*/
163
164
165 }
166 /**
167  * Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
168  */
169 void * pos_monitor(void* param){
170         set_priority(param);            /*set priority*/
171         while(1){
172                 printData(data);
173                 usleep(1000000);        /*1 Hz*/
174         }
175         return (void*)0;
176 }
177
178 /**
179  * Funkce pravidelne vycita data z motoru
180  */
181 void * read_data(void* param){
182         int i;
183         struct rpi_in pocatek;
184         uint8_t tx[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
185         set_priority(param);                            /*set priority*/
186         pocatek = spi_read(tx);
187                 while(1){
188                         prepare_tx(tx);
189                         data = spi_read(tx);
190                         substractOffset(&data,&pocatek);
191                         usleep(1000);                           /*1kHz*/
192                 }
193 }
194
195 /**
196  * \brief Main function.
197  */
198
199 int main(){
200         uint16_t tmp;
201
202         /*nastaveni priorit vlaken*/
203         struct thread_param tsp;
204         tsp.sch_policy = SCHED_FIFO;
205
206         /*nastaveni signalu pro vypnuti pomoci Ctrl+C*/
207         sighnd.sa_handler=&sighnd_fnc;
208         sigaction(SIGINT, &sighnd, NULL );
209
210         clk_init();             /* inicializace gpio hodin */
211         spi_init();             /* iniicializace spi*/
212
213         /*semafor pro detekci zpracovani parametru vlaken*/
214         sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
215
216         /*vlakna*/
217         pthread_t tid;                  /*identifikator vlakna*/
218         pthread_attr_t attr;            /*atributy vlakna*/
219         pthread_attr_init(&attr);       /*inicializuj implicitni atributy*/
220
221
222
223         /*ziskavani dat z motoru*//*vysoka priorita*/
224         tsp.sch_prior = PRIOR_HIGH;
225         pthread_create(&tid, &attr, read_data, (void*)&tsp);
226
227         /*vypisovani lokalni pozice*//*nizka priorita*/
228         tsp.sch_prior = PRIOR_LOW;
229         pthread_create(&tid, &attr, pos_monitor, (void*)&tsp);
230
231
232         /*muzeme zavrit semafor*/
233         sem_destroy(&thd_par_sem);
234
235         while (1){
236                 scanf("%u",&tmp);
237                 printf("volba=%x\n",tmp);
238                 switch (tmp){
239                 case 1:
240                         scanf("%u",&pwm1);
241                         break;
242                 case 2:
243                         scanf("%u",&pwm2);
244                         break;
245                 case 3:
246                         scanf("%u",&pwm3);
247                         break;
248                 case 4:
249                         scanf("%u",&test);
250                         break;
251
252                 default:
253                         break;
254                 }
255
256         }
257         return 0;
258 }