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.
7 (C) 2015 by Martin Prudek prudemar@fel.cvut.cz
8 (C) 2015 by Pavel Pisa pisa@cmp.felk.cvut.cz
18 #include <sys/ioctl.h>
19 #include <linux/types.h>
20 #include <linux/spi/spidev.h>
22 #include "pxmc_spimc.h"
24 #define SPIMC_INDEX_BITS 12
25 #define SPIMC_INDEX_MASK ((1 << SPIMC_INDEX_BITS) - 1)
27 static uint8_t spimc_mode = 0;
28 static uint8_t spimc_bits = 8;
29 static uint32_t spimc_speed = 500000;
30 static uint16_t spimc_delay = 0;
32 static void pabort(const char *s)
38 int spimc_transfer(spimc_state_t *spimcst)
40 uint8_t *tx = spimcst->tx_buf;
41 uint8_t *rx = spimcst->rx_buf;
43 uint32_t pwm1, pwm2, pwm3;
47 memset(tx, 0, SPIMC_TRANSFER_SIZE);
48 memset(rx, 0, SPIMC_TRANSFER_SIZE);
51 * rx[0] - bity 127 downto 120 the first income bit..127
52 * rx[1] - bity 119 downto 112
53 * rx[2] - bity 111 downto 104
54 * rx[3] - bity 103 downto 96
55 * tx[4] - bity 95 downto 88
56 * tx[5] - bity 87 downto 80
57 * tx[6] - bity 79 downto 72
58 * tx[7] - bity 71 downto 64
59 * tx[8] - bity 63 downto 56
60 * tx[9] - bity 55 downto 48
61 * tx[10] - bity 47 downto 40
62 * tx[11] - bity 39 downto 32
63 * tx[12] - bity 31 downto 24
64 * tx[13] - bity 23 downto 16
65 * tx[14] - bity 15 downto 8
66 * tx[15] - bity 7 downto 0
69 * bit 126 - enable PWM1
70 * bit 125 - enable PWM2
71 * bit 124 - enable PWM3
76 * bits 47 .. 32 - match PWM1
77 * bits 31 .. 16 - match PWM2
78 * bits 15 .. 0 - match PWM3
81 pwm1 = spimcst->pwm[0];
82 pwm2 = spimcst->pwm[1];
83 pwm3 = spimcst->pwm[2];
86 if (pwm1 & SPIMC_PWM_ENABLE)
88 if (pwm1 & SPIMC_PWM_SHUTDOWN)
90 if (pwm2 & SPIMC_PWM_ENABLE)
92 if (pwm2 & SPIMC_PWM_SHUTDOWN)
94 if (pwm3 & SPIMC_PWM_ENABLE)
96 if (pwm3 & SPIMC_PWM_SHUTDOWN)
99 pwm1 &= SPIMC_PWM_VALUE_m;
100 pwm2 &= SPIMC_PWM_VALUE_m;
101 pwm3 &= SPIMC_PWM_VALUE_m;
104 if (pwm1 > 2047) pwm1 = 2047;
105 if (pwm2 > 2047) pwm2 = 2047;
106 if (pwm3 > 2047) pwm3 = 2047;
109 tx[10] = pwm1 >> 8; /*MSB*/
110 tx[11] = pwm1 & 0xff; /*LSB*/
113 tx[12] = pwm2 >> 8; /*MSB*/
114 tx[13] = pwm2 & 0xff; /*LSB*/
117 tx[14] = pwm3 >> 8; /*MSB*/
118 tx[15] = pwm3 & 0xff; /*LSB*/
120 struct spi_ioc_transfer tr = {
121 .tx_buf = (uintptr_t)tx,
122 .rx_buf = (uintptr_t)rx,
123 .len = SPIMC_TRANSFER_SIZE,
124 .delay_usecs = spimc_delay,
125 .speed_hz = spimc_speed,
126 .bits_per_word = spimc_bits,
129 ret = ioctl(spimcst->spi_fd, SPI_IOC_MESSAGE(1), &tr);
134 * rx[0] - bity 127 downto 120 the first income bit..127
135 * rx[1] - bity 119 downto 112
136 * rx[2] - bity 111 downto 104
137 * rx[3] - bity 103 downto 96
138 * rx[4] - bity 95 downto 88
139 * rx[5] - bity 87 downto 80
140 * rx[6] - bity 79 downto 72
141 * rx[7] - bity 71 downto 64
142 * rx[8] - bity 63 downto 56
143 * rx[9] - bity 55 downto 48
144 * rx[10] - bity 47 downto 40
145 * rx[11] - bity 39 downto 32
146 * rx[12] - bity 31 downto 24
147 * rx[13] - bity 23 downto 16
148 * rx[14] - bity 15 downto 8
149 * rx[15] - bity 7 downto 0 the last income bit..0
152 /* position from IRC counter */
153 spimcst->act_pos = ((uint32_t)rx[0] << 24) |
154 ((uint32_t)rx[1] << 16) |
155 ((uint32_t)rx[2] << 8) |
156 ((uint32_t)rx[3] << 0);
163 spimcst->hal_sensors = ((0x80 & rx[4]) >> 7) |
164 ((0x40 & rx[4]) >> 5) |
165 ((0x20 & rx[4]) >> 3);
169 * 92..88 in rx[4] last 5 bits (from left)
170 * 87..81 in rx[5] first 7 bits (from left)
177 if ((idx ^ spimcst->index_pos) & SPIMC_INDEX_MASK) {
178 idxdiff = (idx - spimcst->act_pos +
179 (1 << (SPIMC_INDEX_BITS - 1))) & SPIMC_INDEX_MASK;
180 idxdiff -= 1 << (SPIMC_INDEX_BITS - 1);
181 idx = spimcst->act_pos + idxdiff;
182 spimcst->index_pos = idx;
183 spimcst->index_occur += 1;
186 /* current measurments count
189 * bits 79..72 in rx[6]
192 spimcst->curadc_sqn = 0x01 & rx[5];
193 spimcst->curadc_sqn <<= 8;
194 spimcst->curadc_sqn |= rx[6];
198 * ch2 - bits 71 downto 48
199 * 71..64 in rx[7] - all byte
200 * 63..56 in rx[8] - all byte
201 * 55..48 in rx[9] - all byte
202 * ch0 - bits 47 downto 24
203 * 47..40 in rx[10] - all byte
204 * 39..32 in rx[11] - all byte
205 * 31..24 in rx[12] - all byte
206 * ch1 - bits 23 downto 0
207 * 23..16 in rx[13] - all byte
208 * 15..8 in rx[14] - all byte
209 * 7..0 in rx[15] - all byte
212 spimcst->curadc_cumsum[2] = rx[7];
213 spimcst->curadc_cumsum[2] <<= 8;
214 spimcst->curadc_cumsum[2] |= rx[8];
215 spimcst->curadc_cumsum[2] <<= 8;
216 spimcst->curadc_cumsum[2] |= rx[9];
218 spimcst->curadc_cumsum[0] = rx[10];
219 spimcst->curadc_cumsum[0] <<= 8;
220 spimcst->curadc_cumsum[0] |= rx[11];
221 spimcst->curadc_cumsum[0] <<= 8;
222 spimcst->curadc_cumsum[0] |=rx [12];
224 spimcst->curadc_cumsum[1] = rx[13];
225 spimcst->curadc_cumsum[1] <<= 8;
226 spimcst->curadc_cumsum[1] |= rx[14];
227 spimcst->curadc_cumsum[1] <<= 8;
228 spimcst->curadc_cumsum[1] |= rx[15];
233 int spimc_init(spimc_state_t *spimcst)
238 spimcst->spi_fd = -1;
240 fd = open(spimcst->spi_dev, O_RDWR);
242 pabort("can't open device");
244 printf("device open\n");
248 ret = ioctl(fd, SPI_IOC_WR_MODE, &spimc_mode);
250 pabort("can't set spi mode");
252 ret = ioctl(fd, SPI_IOC_RD_MODE, &spimc_mode);
254 pabort("can't get spi mode");
259 ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spimc_bits);
261 pabort("can't set bits per word");
263 ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spimc_bits);
265 pabort("can't get bits per word");
270 ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &spimc_speed);
272 pabort("can't set max speed hz");
274 ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &spimc_speed);
276 pabort("can't get max speed hz");
278 printf("spi spimc_mode: %d\n", spimc_mode);
279 printf("bits per word: %d\n", spimc_bits);
280 printf("delay: %d\n", spimc_delay);
281 printf("max spimc_speed: %d Hz (%d KHz)\n", spimc_speed, spimc_speed/1000);
283 spimcst->spi_fd = fd;
285 spimcst->curadc_use_diff_to_last_fl = 0;