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 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;
29 static void pabort(const char *s)
35 int spimc_transfer(spimc_state_t *spimcst)
37 uint8_t *tx = spimcst->tx_buf;
38 uint8_t *rx = spimcst->rx_buf;
40 uint32_t pwm1, pwm2, pwm3;
42 memset(tx, 0, SPIMC_TRANSFER_SIZE);
43 memset(rx, 0, SPIMC_TRANSFER_SIZE);
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
64 * bit 126 - enable PWM1
65 * bit 125 - enable PWM2
66 * bit 124 - enable PWM3
71 * bits 47 .. 32 - match PWM1
72 * bits 31 .. 16 - match PWM2
73 * bits 15 .. 0 - match PWM3
76 pwm1 = spimcst->pwm[0];
77 pwm2 = spimcst->pwm[1];
78 pwm3 = spimcst->pwm[2];
81 if (pwm1 & SPIMC_PWM_ENABLE)
83 if (pwm1 & SPIMC_PWM_SHUTDOWN)
85 if (pwm2 & SPIMC_PWM_ENABLE)
87 if (pwm2 & SPIMC_PWM_SHUTDOWN)
89 if (pwm3 & SPIMC_PWM_ENABLE)
91 if (pwm3 & SPIMC_PWM_SHUTDOWN)
94 pwm1 &= SPIMC_PWM_VALUE_m;
95 pwm2 &= SPIMC_PWM_VALUE_m;
96 pwm3 &= SPIMC_PWM_VALUE_m;
99 if (pwm1 > 2047) pwm1 = 2047;
100 if (pwm2 > 2047) pwm2 = 2047;
101 if (pwm3 > 2047) pwm3 = 2047;
104 tx[10] = pwm1 >> 8; /*MSB*/
105 tx[11] = pwm1 & 0xff; /*LSB*/
108 tx[12] = pwm2 >> 8; /*MSB*/
109 tx[13] = pwm2 & 0xff; /*LSB*/
112 tx[14] = pwm3 >> 8; /*MSB*/
113 tx[15] = pwm3 & 0xff; /*LSB*/
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,
124 ret = ioctl(spimcst->spi_fd, SPI_IOC_MESSAGE(1), &tr);
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
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);
158 spimcst->hal_sensors = ((0x80 & rx[4]) >> 7) |
159 ((0x40 & rx[4]) >> 5) |
160 ((0x20 & rx[4]) >> 3);
164 * 92..88 in rx[4] last 5 bits (from left)
165 * 87..81 in rx[5] first 7 bits (from left)
167 spimcst->index_pos = 0x1F & rx[4];
168 spimcst->index_pos <<= 8;
169 spimcst->index_pos |= 0xFE & rx[5];
170 spimcst->index_pos >>= 1;
172 /* current measurments count
175 * bits 79..72 in rx[6]
178 spimcst->curadc_sqn = 0x01 & rx[5];
179 spimcst->curadc_sqn <<= 8;
180 spimcst->curadc_sqn |= rx[6];
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
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];
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];
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];
219 int spimc_init(spimc_state_t *spimcst)
224 spimcst->spi_fd = -1;
226 fd = open(spimcst->spi_dev, O_RDWR);
228 pabort("can't open device");
230 printf("device open\n");
234 ret = ioctl(fd, SPI_IOC_WR_MODE, &spimc_mode);
236 pabort("can't set spi mode");
238 ret = ioctl(fd, SPI_IOC_RD_MODE, &spimc_mode);
240 pabort("can't get spi mode");
245 ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spimc_bits);
247 pabort("can't set bits per word");
249 ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spimc_bits);
251 pabort("can't get bits per word");
256 ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &spimc_speed);
258 pabort("can't set max speed hz");
260 ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &spimc_speed);
262 pabort("can't get max speed hz");
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);
269 spimcst->spi_fd = fd;