]> rtime.felk.cvut.cz Git - fpga/rpi-motor-control-pxmc.git/blob - src/app/rpi-pmsm-test1/rpi_spi.c
084c361454fd9d16584da403fbdf89e09b93b23a
[fpga/rpi-motor-control-pxmc.git] / src / app / rpi-pmsm-test1 / rpi_spi.c
1 /*
2   Communication with Raspberry Pi equipped by 3-phase
3   motor driver and RPI-MI-1 FPGA board designed
4   by Petr Porazil for PiKRON company.
5   The VHDL design by Martin Prudek.
6
7   (C) 2015 by Martin Prudek prudemar@fel.cvut.cz
8   (C) 2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
9  */
10
11 #include <stdint.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <getopt.h>
17 #include <fcntl.h>
18 #include <sys/ioctl.h>
19 #include <linux/types.h>
20 #include <linux/spi/spidev.h>
21
22 #include "pxmc_spimc.h"
23
24 static uint8_t spimc_mode = 0;
25 static uint8_t spimc_bits = 8;
26 static uint32_t spimc_speed = 500000;
27 static uint16_t spimc_delay = 0;
28
29 static void pabort(const char *s)
30 {
31         perror(s);
32         abort();
33 }
34
35 int spimc_transfer(spimc_state_t *spimcst)
36 {
37         uint8_t *tx = spimcst->tx_buf;
38         uint8_t *rx = spimcst->rx_buf;
39         int ret;
40         uint32_t pwm1, pwm2, pwm3;
41
42         memset(tx, 0, SPIMC_TRANSFER_SIZE);
43         memset(rx, 0, SPIMC_TRANSFER_SIZE);
44
45         /*Data format:
46          * rx[0] - bity 127 downto 120 the first income bit..127
47          * rx[1] - bity 119 downto 112
48          * rx[2] - bity 111 downto 104
49          * rx[3] - bity 103 downto 96
50          * tx[4] - bity 95 downto 88
51          * tx[5] - bity 87 downto 80
52          * tx[6] - bity 79 downto 72
53          * tx[7] - bity 71 downto 64
54          * tx[8] - bity 63 downto 56
55          * tx[9] - bity 55 downto 48
56          * tx[10] - bity 47 downto 40
57          * tx[11] - bity 39 downto 32
58          * tx[12] - bity 31 downto 24
59          * tx[13] - bity 23 downto 16
60          * tx[14] - bity 15 downto 8
61          * tx[15] - bity 7 downto 0
62          *
63          * bit 127 - ADC reset
64          * bit 126 - enable PWM1
65          * bit 125 - enable PWM2
66          * bit 124 - enable PWM3
67          * bit 123 - shutdown1
68          * bit 122 - shutdown2
69          * bit 121 - shutdown3
70          *      .
71          * bits 47 .. 32 - match PWM1
72          * bits 31 .. 16 - match PWM2
73          * bits 15 .. 0  - match PWM3
74          */
75
76         pwm1 = spimcst->pwm[0];
77         pwm2 = spimcst->pwm[1];
78         pwm3 = spimcst->pwm[2];
79
80         tx[0] = 0;
81         if (pwm1 & SPIMC_PWM_ENABLE)
82           tx[0] |= 1 << 6;
83         if (pwm1 & SPIMC_PWM_SHUTDOWN)
84           tx[0] |= 1 << 3;
85         if (pwm2 & SPIMC_PWM_ENABLE)
86           tx[0] |= 1 << 5;
87         if (pwm2 & SPIMC_PWM_SHUTDOWN)
88           tx[0] |= 1 << 2;
89         if (pwm3 & SPIMC_PWM_ENABLE)
90           tx[0] |= 1 << 4;
91         if (pwm3 & SPIMC_PWM_SHUTDOWN)
92           tx[0] |= 1 << 1;
93
94         pwm1 &= SPIMC_PWM_VALUE_m;
95         pwm2 &= SPIMC_PWM_VALUE_m;
96         pwm3 &= SPIMC_PWM_VALUE_m;
97
98         /* keep the cap*/
99         if (pwm1 > 2047) pwm1 = 2047;
100         if (pwm2 > 2047) pwm2 = 2047;
101         if (pwm3 > 2047) pwm3 = 2047;
102
103         /*pwm1*/
104         tx[10] = pwm1 >> 8;   /*MSB*/
105         tx[11] = pwm1 & 0xff; /*LSB*/
106
107         /*pwm2*/
108         tx[12] = pwm2 >> 8;   /*MSB*/
109         tx[13] = pwm2 & 0xff; /*LSB*/
110
111         /*pwm3*/
112         tx[14] = pwm3 >> 8;   /*MSB*/
113         tx[15] = pwm3 & 0xff; /*LSB*/
114
115         struct spi_ioc_transfer tr = {
116                 .tx_buf = (uintptr_t)tx,
117                 .rx_buf = (uintptr_t)rx,
118                 .len = SPIMC_TRANSFER_SIZE,
119                 .delay_usecs = spimc_delay,
120                 .speed_hz = spimc_speed,
121                 .bits_per_word = spimc_bits,
122         };
123
124         ret = ioctl(spimcst->spi_fd, SPI_IOC_MESSAGE(1), &tr);
125         if (ret < 1)
126                 return -1;
127
128         /*prichozi data:
129          * rx[0] - bity 127 downto 120 the first income bit..127
130          * rx[1] - bity 119 downto 112
131          * rx[2] - bity 111 downto 104
132          * rx[3] - bity 103 downto 96
133          * rx[4] - bity 95 downto 88
134          * rx[5] - bity 87 downto 80
135          * rx[6] - bity 79 downto 72
136          * rx[7] - bity 71 downto 64
137          * rx[8] - bity 63 downto 56
138          * rx[9] - bity 55 downto 48
139          * rx[10] - bity 47 downto 40
140          * rx[11] - bity 39 downto 32
141          * rx[12] - bity 31 downto 24
142          * rx[13] - bity 23 downto 16
143          * rx[14] - bity 15 downto 8
144          * rx[15] - bity 7 downto 0     the last income bit..0
145          */
146
147         /* position from IRC counter */
148         spimcst->act_pos = ((uint32_t)rx[0] << 24) |
149                            ((uint32_t)rx[1] << 16) |
150                            ((uint32_t)rx[2] << 8) |
151                            ((uint32_t)rx[3] << 0);
152
153         /*halove sondy
154          * hal1 - bit95
155          * hal2 - bit94
156          * hal3 - bit93
157          */
158         spimcst->hal_sensors = ((0x80 & rx[4]) >> 7) |
159                                ((0x40 & rx[4]) >> 5) |
160                                ((0x20 & rx[4]) >> 3);
161
162         /* index position
163          * bits 92 downto 81
164          *      92..88 in rx[4] last 5 bits (from left)
165          *      87..81 in rx[5] first 7 bits (from left)
166          */
167         spimcst->index_pos = 0x1F & rx[4];
168         spimcst->index_pos <<= 8;
169         spimcst->index_pos |= 0xFE & rx[5];
170         spimcst->index_pos >>= 1;
171
172         /* current measurments count
173          * bits 80 downto 72
174          * bit 80 in rx[5]
175          * bits 79..72 in rx[6]
176          */
177
178         spimcst->curadc_sqn = 0x01 & rx[5];
179         spimcst->curadc_sqn <<= 8;
180         spimcst->curadc_sqn |= rx[6];
181
182
183         /** currents
184          * ch2 - bits 71 downto 48
185          *      71..64 in rx[7] - all byte
186          *      63..56 in rx[8] - all byte
187          *      55..48 in rx[9] - all byte
188          * ch0 - bits 47 downto 24
189          *      47..40 in rx[10] - all byte
190          *      39..32 in rx[11] - all byte
191          *      31..24 in rx[12] - all byte
192          * ch1 - bits 23 downto 0
193          *      23..16 in rx[13] - all byte
194          *      15..8 in rx[14] - all byte
195          *      7..0 in rx[15] - all byte
196          */
197
198         spimcst->curadc_cumsum[2] = rx[7];
199         spimcst->curadc_cumsum[2] <<= 8;
200         spimcst->curadc_cumsum[2] |= rx[8];
201         spimcst->curadc_cumsum[2] <<= 8;
202         spimcst->curadc_cumsum[2] |= rx[9];
203
204         spimcst->curadc_cumsum[0] = rx[10];
205         spimcst->curadc_cumsum[0] <<= 8;
206         spimcst->curadc_cumsum[0] |= rx[11];
207         spimcst->curadc_cumsum[0] <<= 8;
208         spimcst->curadc_cumsum[0] |=rx [12];
209
210         spimcst->curadc_cumsum[1] = rx[13];
211         spimcst->curadc_cumsum[1] <<= 8;
212         spimcst->curadc_cumsum[1] |= rx[14];
213         spimcst->curadc_cumsum[1] <<= 8;
214         spimcst->curadc_cumsum[1] |= rx[15];
215
216         return 0;
217 }
218
219 int spimc_init(spimc_state_t *spimcst)
220 {
221         int ret = 0;
222         int fd;
223
224         spimcst->spi_fd = -1;
225
226         fd = open(spimcst->spi_dev, O_RDWR);
227         if (fd < 0) {
228                 pabort("can't open device");
229         }
230         printf("device open\n");
231         /*
232          * spi spimc_mode
233          */
234         ret = ioctl(fd, SPI_IOC_WR_MODE, &spimc_mode);
235         if (ret == -1)
236                 pabort("can't set spi mode");
237
238         ret = ioctl(fd, SPI_IOC_RD_MODE, &spimc_mode);
239         if (ret == -1)
240                 pabort("can't get spi mode");
241
242         /*
243          * bits per word
244          */
245         ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spimc_bits);
246         if (ret == -1)
247                 pabort("can't set bits per word");
248
249         ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spimc_bits);
250         if (ret == -1)
251                 pabort("can't get bits per word");
252
253         /*
254          * max spimc_speed hz
255          */
256         ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &spimc_speed);
257         if (ret == -1)
258                 pabort("can't set max speed hz");
259
260         ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &spimc_speed);
261         if (ret == -1)
262                 pabort("can't get max speed hz");
263
264         printf("spi spimc_mode: %d\n", spimc_mode);
265         printf("bits per word: %d\n", spimc_bits);
266         printf("delay: %d\n", spimc_delay);
267         printf("max spimc_speed: %d Hz (%d KHz)\n", spimc_speed, spimc_speed/1000);
268
269         spimcst->spi_fd = fd;
270
271         return ret;
272 }