]> rtime.felk.cvut.cz Git - fpga/rpi-motor-control.git/blob - pmsm-control/test_sw/main_pmsm.c
2eb92627ea55c8174b4e7661b201c86c2e0f71cc
[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 #include <time.h>       /*nanosleep*/
19 #include <string.h>
20
21 #include "rpin.h"       /*gpclk*/
22 #include "rp_spi.h"     /*spi*/
23 #include "misc.h"       /*structure for priorities*/
24 #include "pmsm_state.h"
25 #include "cmd_proc.h"
26 #include "controllers.h"
27 #include "commutators.h"
28 #include "comp.h"
29 #include "logs.h"
30
31 #define PRIOR_KERN      50
32 #define PRIOR_HIGH      49
33 #define PRIOR_LOW       20
34
35 #define THREAD_SHARED   0
36 #define INIT_VALUE      1       /*init value for semaphor*/
37
38
39 #define NSEC_PER_SEC    (1000000000) /* The number of nsecs per sec. */
40
41
42 struct rpi_in data;
43 struct rpi_state rps={
44         //.MAX_DUTY=170,
45         .spi_dat=&data,
46         .test=0,
47         .pwm1=0,.pwm2=0, .pwm3=0,
48         .pwm1=0, .t_pwm2=0, .t_pwm3=0,
49         .commutate=0,
50         .duty=0,                        /* duty cycle of pwm */
51         .index_dist=0,          /* distance to index position */
52         .index_ok=0,
53         .tf_count=0,            /*number of transfer*/
54         .desired_pos=0,         /* desired position */
55         .pos_reg_ena=0,
56         .desired_spd=0,
57         .spd_reg_ena=0,
58         .old_pos={0},
59         .spd_err_sum=0,
60         .log_col_count=0,       /* pocet radku zaznamu */
61         .log_col=0,
62         .doLogs=0,
63         .alpha_offset=960
64 };
65
66
67 /**
68  * \brief Initilizes GPCLK.
69  */
70 int clk_init()
71 {
72         initialise(); /*namapovani gpio*/
73         initClock(PLLD_500_MHZ, 10, 0);
74         gpioSetMode(4, FSEL_ALT0);
75         return 0;
76 }
77
78 /**
79  * \brief Signal handler pro Ctrl+C
80  */
81 void appl_stop(){
82         uint8_t tx[16];
83         sem_wait(&rps.thd_par_sem);
84
85         memset(tx,0,16*sizeof(int));
86         rps.pwm1=0;
87         rps.pwm2=0;
88         rps.pwm3=0;
89         spi_read(&rps);
90
91         spi_disable();
92         termClock(0);
93         freeLogs(&rps);
94         /*muzeme zavrit semafor*/
95         sem_destroy(&rps.thd_par_sem);
96         printf("\nprogram bezpecne ukoncen\n");
97 }
98
99 /**
100  * Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
101  */
102 void * pos_monitor(void* param){
103         while(1){
104                 printData(&rps);
105                 usleep(1000000);        /*1 Hz*/
106         }
107         return (void*)0;
108 }
109
110 /*
111  * \brief
112  * Feedback loop.
113  * TODO: replace bunch of 'IFs' with Object-like pattern
114  */
115 void * read_data(void* param){
116         int i;
117         struct rpi_in pocatek;
118         struct rpi_state poc={
119                 .spi_dat=&pocatek,
120                 .test=0,
121                 .pwm1=0, .pwm1=0, .pwm3=0
122         };
123         struct timespec t;
124         int interval = 1000000; /* 1ms ~ 1kHz*/
125         char first=1;
126         uint16_t last_index;                            /*we have index up-to date*/
127         spi_read(&poc);         /*pocatecni informace*/
128         clock_gettime(CLOCK_MONOTONIC ,&t);
129         /* start after one second */
130         t.tv_sec++;
131                 while(1){
132                         /* wait until next shot */
133                         clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
134                         sem_wait(&rps.thd_par_sem);             /*---take semaphore---*/
135
136                         /*old positions*/
137                         rps.old_pos[rps.tf_count%OLD_POS_NUM]=rps.spi_dat->pozice;
138                         spi_read(&rps);         /*exchange data*/
139                         /*subtract initiate postion */
140                         rps.tf_count++;
141                         substractOffset(&data,poc.spi_dat);
142                         compSpeed(&rps);                        /*spocita rychlost*/
143
144                         if (!rps.index_ok){
145                                 if (first){
146                                         last_index=data.index_position;
147                                         first=0;
148                                 }else if (last_index!=data.index_position){
149                                         rps.index_ok=1;
150                                         comIndDist(&rps);       /*vypocet vzdalenosti indexu*/
151                                 }
152                         }else{ /*index je v poradku*/
153                                 comIndDist(&rps);               /*vypocet vzdalenosti indexu*/
154                         }
155
156                         /* pocitame sirku plneni podle potreb rizeni*/
157                         if (rps.pos_reg_ena){           /*pozicni rizeni*/
158                                 pos_pid(&rps);
159                         }else if(rps.spd_reg_ena){      /*rizeni na rychlost*/
160                                 spd_pid(&rps);
161                         }
162
163                         /* sirka plneni prepoctena na jednotlive pwm */
164                         if (rps.index_ok && rps.commutate){
165                                 /*simple_ind_dist_commutator(rps.duty);*/
166                                 /*sin_commutator(rps.duty);*/
167                                 inv_trans_comm(&rps);
168                                 inv_trans_comm_2(&rps);
169                         }else if(!rps.index_ok && rps.commutate){
170                                 simple_hall_commutator(&rps);
171                         }
172
173                         /*zalogujeme hodnoty*/
174                         if (rps.doLogs && !(rps.tf_count%LOG_PERIOD)){
175                                 makeLog(&rps);
176                         }
177
178                         sem_post(&rps.thd_par_sem);             /*--post semaphore---*/
179
180                         /* calculate next shot */
181                         t.tv_nsec += interval;
182
183                         while (t.tv_nsec >= NSEC_PER_SEC) {
184                                 t.tv_nsec -= NSEC_PER_SEC;
185                                 t.tv_sec++;
186                         }
187
188                 }
189 }
190
191 /**
192  * \brief Main function.
193  */
194 int main(){
195         pthread_t base_thread_id;
196         clk_init();             /* inicializace gpio hodin */
197         spi_init();             /* iniicializace spi*/
198
199         /*semafor pro detekci zpracovani parametru vlaken*/
200         sem_init(&rps.thd_par_sem,THREAD_SHARED,INIT_VALUE);
201         setup_environment();
202
203         base_thread_id=pthread_self();
204
205         /*main control loop*/
206         create_rt_task(&base_thread_id,PRIOR_HIGH,read_data,NULL);
207
208         /*monitor of current state*/
209         create_rt_task(&base_thread_id,PRIOR_LOW,pos_monitor,NULL);
210
211         /*wait for commands*/
212         poll_cmd(&rps);
213
214         return 0;
215 }