]> rtime.felk.cvut.cz Git - fpga/rpi-motor-control.git/blob - pmsm-control/test_sw/main_pmsm.c
f0fc982529cb410ebf8fc4aafd3e8425a8d6803a
[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         .main_commutator=zero_commutator,       /* komutace vypnuta */
65         .main_controller=zero_controller        /* rizeni vypnuto */
66 };
67
68
69 /**
70  * \brief Initilizes GPCLK.
71  */
72 int clk_init()
73 {
74         initialise(); /*namapovani gpio*/
75         initClock(PLLD_500_MHZ, 10, 0);
76         gpioSetMode(4, FSEL_ALT0);
77         return 0;
78 }
79
80 /**
81  * \brief Signal handler pro Ctrl+C
82  */
83 void appl_stop(){
84         uint8_t tx[16];
85         sem_wait(&rps.thd_par_sem);
86
87         memset(tx,0,16*sizeof(int));
88         rps.pwm1=0;
89         rps.pwm2=0;
90         rps.pwm3=0;
91         spi_read(&rps);
92
93         spi_disable();
94         termClock(0);
95         freeLogs(&rps);
96         /*muzeme zavrit semafor*/
97         sem_destroy(&rps.thd_par_sem);
98         printf("\nprogram bezpecne ukoncen\n");
99 }
100
101 /**
102  * Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
103  */
104 void * pos_monitor(void* param){
105         while(1){
106                 printData(&rps);
107                 usleep(1000000);        /*1 Hz*/
108         }
109         return (void*)0;
110 }
111
112 /*
113  * \brief
114  * Feedback loop.
115  * TODO: replace bunch of 'IFs' with Object-like pattern
116  */
117 void * control_loop(void* param){
118         int i;
119         struct rpi_in pocatek;
120         struct rpi_state poc={
121                 .spi_dat=&pocatek,
122                 .test=0,
123                 .pwm1=0, .pwm1=0, .pwm3=0
124         };
125         struct timespec t;
126         int interval = 1000000; /* 1ms ~ 1kHz*/
127         char first=1;
128         uint16_t last_index;                            /*we have index up-to date*/
129         spi_read(&poc);         /*pocatecni informace*/
130         clock_gettime(CLOCK_MONOTONIC ,&t);
131         /* start after one second */
132         t.tv_sec++;
133                 while(1){
134                         /* wait until next shot */
135                         clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
136                         sem_wait(&rps.thd_par_sem);             /*---take semaphore---*/
137
138                         /*old positions*/
139                         rps.old_pos[rps.tf_count%OLD_POS_NUM]=rps.spi_dat->pozice;
140                         spi_read(&rps);                         /*exchange data*/
141                         rps.tf_count++;
142                         substractOffset(&data,poc.spi_dat);     /*subtract initiate postion */
143                         compSpeed(&rps);                        /*spocita rychlost*/
144
145                         if (!rps.index_ok){
146                                 if (first){
147                                         last_index=data.index_position;
148                                         first=0;
149                                 }else if (last_index!=data.index_position){
150                                         setIndexOK(&rps);
151                                         comIndDist(&rps);       /*vypocet vzdalenosti indexu*/
152                                 }
153                         }else{ /*index je v poradku*/
154                                 comIndDist(&rps);               /*vypocet vzdalenosti indexu*/
155                         }
156
157                         /* pocitame sirku plneni podle potreb rizeni*/
158                         rps.main_controller(&rps);
159
160                         /* sirku plneni prepocteme na jednotlive pwm */
161                         rps.main_commutator(&rps);
162
163                         /*zalogujeme hodnoty*/
164                         if (rps.doLogs && !(rps.tf_count%LOG_PERIOD)){
165                                 makeLog(&rps);
166                         }
167
168                         sem_post(&rps.thd_par_sem);             /*--post semaphore---*/
169
170                         /* calculate next shot */
171                         t.tv_nsec += interval;
172
173                         while (t.tv_nsec >= NSEC_PER_SEC) {
174                                 t.tv_nsec -= NSEC_PER_SEC;
175                                 t.tv_sec++;
176                         }
177
178                 }
179 }
180
181 /**
182  * \brief Main function.
183  */
184 int main(){
185         pthread_t base_thread_id;
186         clk_init();             /* inicializace gpio hodin */
187         spi_init();             /* iniicializace spi*/
188
189         /*semafor pro detekci zpracovani parametru vlaken*/
190         sem_init(&rps.thd_par_sem,THREAD_SHARED,INIT_VALUE);
191         setup_environment();
192
193         base_thread_id=pthread_self();
194
195         /*main control loop*/
196         create_rt_task(&base_thread_id,PRIOR_HIGH,control_loop,NULL);
197
198         /*monitor of current state*/
199         create_rt_task(&base_thread_id,PRIOR_LOW,pos_monitor,NULL);
200
201         /*wait for commands*/
202         poll_cmd(&rps);
203
204         return 0;
205 }