blob: dfc09cbf62265a9fb604aa92a77f21b35cf45fe2 [file] [log] [blame]
Ravago Jonesb83957c2021-12-29 19:57:34 -08001/**
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdio.h>
8
9#include <algorithm>
10#include <cstring>
11
12#include "hardware/dma.h"
13#include "hardware/gpio.h"
14#include "hardware/irq.h"
15#include "hardware/pio.h"
16#include "hardware/pwm.h"
17#include "hardware/spi.h"
18#include "hardware/timer.h"
19#include "pico/binary_info.h"
20#include "pico/bootrom.h"
21#include "pico/double.h"
22#include "pico/stdlib.h"
23#include "quadrature_encoder.pio.h"
24
25// Pinout definitions for the imu
26#define RST_IMU 22
27#define DR_IMU 20
28#define SYNC_IMU 21
29#define DIN_IMU 19
30#define DOUT_IMU 16
31#define SCLK_IMU 18
32#define CS_IMU 17
33
34// Pinout definitions for spi to the pi through the differential drivers
35#define DR_PI 14
36#define MOSI_PI 12
37#define MISO_PI 11
38#define SCK_PI 10
39#define CS_PI 13
40
41// The two drivetrain encoders
42#define ENC1_A 6
43#define ENC1_B 7
44#define ENC2_A 0
45#define ENC2_B 1
46
47// Backup outputs to the roborio
48#define RATE_PWM 2
49#define HEADING_PWM 4
50
51#define PWM_FREQ_HZ 200
52// PWM counts to this before wrapping
53#define PWM_TOP 62499
54
55#define SPI_IMU spi0
56#define SPI_PI spi1
57#define WRITE_BIT 0x8000
58
59// length in half-words of the buffer for communicating with the IMU
60// includes 2 non-data fields
61// the first element is used for recieving zeros while the initial request is
62// made the last element is the checksum
63#define IMU_NUM_ITEMS 17
64
65// length in bytes of the packet to the pi
66#define PI_NUM_ITEMS 42
67
68// number of samples for zeroing the z-gyro axis
69#define YAW_BUF_LEN 5000
70
71#define EXPECTED_PROD_ID 0x4079
72
73// Registers on the ADIS16505
74#define GLOB_CMD 0x68
75#define DIAG_STAT 0x02
76#define FIRM_REV 0x6C
77#define FIRM_DM 0x6E
78#define FIRM_Y 0x70
79#define PROD_ID 0x72
80#define SERIAL_NUM 0x74
81#define FILT_CTRL 0x5C
82#define MSC_CTRL 0x60
83#define DEC_RATE 0x64
84
85// TODO: replace with aos/events/logging/crc32.h
86const uint32_t kCrc32Table[256] = {
87 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
88 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
89 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
90 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
91 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
92 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
93 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
94 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
95 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
96 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
97 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
98 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
99 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
100 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
101 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
102 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
103 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
104 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
105 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
106 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
107 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
108 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
109 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
110 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
111 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
112 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
113 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
114 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
115 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
116 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
117 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
118 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
119 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
120 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
121 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
122 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
123 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
124 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
125 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
126 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
127 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
128 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
129 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
130
131// Buffer to start a burst read and recive 15 items + checksum
132static uint16_t imu_write_buf[IMU_NUM_ITEMS] = {0x6800, 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0};
134// recieves a byte of zeros followed by 15 items + checksum
135static uint16_t imu_data_buffer[IMU_NUM_ITEMS];
136
137static dma_channel_config imu_tx_config;
138static dma_channel_config imu_rx_config;
139static uint imu_dma_tx;
140static uint imu_dma_rx;
141
142// The packet to the pi contains the whole burst read from the IMU (30 bytes)
143// followed by a timestamp, encoder values, and checksum
144// DIAG_STAT, X_GYRO_LOW, X_GYRO_OUT, Y_GYRO_LOW, Y_GYRO_OUT, Z_GYRO_LOW,
145// Z_GYRO_OUT, X_ACCL_LOW, X_ACCL_OUT, Y_ACCL_LOW, Y_ACCL_OUT, Z_ACCL_LOW,
146// Z_ACCL_OUT, TEMP_OUT, DATA_CNTR, TIMESTAMP (32 bit), ENC1_POS, ENC2_POS,
147// CHECKSUM (32-bit)
148
149// the staging buffer gets updated everytime new data is received
150static uint8_t pi_staging_buffer[PI_NUM_ITEMS];
151// the data from the staging buffer is latched into the sending buffer while the
152// pi is reading
153static uint8_t pi_sending_buffer[PI_NUM_ITEMS];
154
155// for now just recieves zeros
156// but is useful because directing the dma to a nullptr messes up the transfer
157// finished interrupt
158static uint8_t pi_recieve_buffer[PI_NUM_ITEMS];
159
160static dma_channel_config pi_tx_config;
161static dma_channel_config pi_rx_config;
162static uint pi_dma_tx;
163static uint pi_dma_rx;
164
165// zeroed yaw from the latest message from the imu
166static double yaw = 0;
167static double yaw_rate = 0;
168
169// TODO: fields for the janky, not encapsulated zeroing function
170static double yaw_rate_offset = 0;
171static bool yaw_zeroed = false;
172
173static int16_t encoder1_count = 0;
174static int16_t encoder2_count = 0;
175
176static uint32_t data_collect_timestamp = 0;
177
178// useful debug counters
179static uint checksum_mismatch_count;
180static uint message_recieved_count;
181static uint message_sent_count;
182// the number of times we had to defer sending new data because another
183// transfer was still in progress
184static uint timing_overrun_count;
185
186// the time it takes from servicing DR_IMU to finishing the transfer to the pi
187static int send_time = 0;
188
189void data_ready();
190void maybe_send_pi_packet();
191
192void gpio_irq_handler(uint gpio, uint32_t events) {
193 if (gpio == DR_IMU && (events & GPIO_IRQ_EDGE_RISE)) {
194 data_ready();
195 }
196}
197
198static inline void cs_select() {
199 gpio_put(CS_IMU, 0); // Active low
200 sleep_us(1);
201}
202
203static inline void cs_deselect() { gpio_put(CS_IMU, 1); }
204
205static uint16_t read_register(uint8_t reg_low) {
206 // For this particular device, we send the device the register we want to read
207 // first, then subsequently read from the device.
208 uint16_t output;
209
210 // The low byte of the register is first in the IMU's memory
211 uint16_t reg = ((uint16_t)reg_low) << 8;
212
213 cs_select();
214 spi_write16_blocking(SPI_IMU, &reg, 1);
215 cs_deselect();
216 sleep_us(20); // wait the stall period
217 cs_select();
218 spi_read16_blocking(SPI_IMU, 0x0000, &output, 1);
219 cs_deselect();
220
221 return output;
222}
223
224static void write_register(uint8_t reg, uint16_t value) {
225 uint16_t low_byte = ((uint16_t)value) & 0xFF;
226 uint16_t high_byte = ((uint16_t)value) >> 8;
227
228 uint16_t command = (((uint16_t)reg) << 8) | low_byte | WRITE_BIT;
229
230 cs_select();
231 spi_write16_blocking(SPI_IMU, &command, 1);
232 cs_deselect();
233
234 sleep_us(20); // wait the stall period
235
236 command = ((((uint16_t)reg) + 1) << 8) | high_byte | WRITE_BIT;
237
238 cs_select();
239 spi_write16_blocking(SPI_IMU, &command, 1);
240 cs_deselect();
241}
242
243static void adis16505_reset() {
244 gpio_put(RST_IMU, 0); // Active low
245 sleep_ms(10);
246 gpio_put(RST_IMU, 1); // Active low
247 sleep_ms(310);
248}
249
250static uint32_t calculate_crc32(uint8_t *data, size_t len) {
251 uint32_t crc = 0xFFFFFFFF;
252 for (size_t i = 0; i < len; i++) {
253 crc = kCrc32Table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8);
254 }
255 return crc;
256}
257
258static bool check_checksum(uint16_t *buf) {
259 uint16_t sum = 0;
260 for (int i = 1; i < IMU_NUM_ITEMS - 1; i++) {
261 uint16_t low = buf[i] & 0xff;
262 uint16_t high = (buf[i] >> 8) & 0xff;
263
264 sum += high + low;
265 }
266
267 uint16_t checksum = buf[IMU_NUM_ITEMS - 1];
268 return sum == checksum;
269}
270
271static void zero_yaw(double yaw) {
272 static double yaw_buffer[YAW_BUF_LEN];
273 static int num_items;
274
275 if (num_items < YAW_BUF_LEN) {
276 yaw_buffer[num_items] = yaw;
277 num_items++;
278 } else if (!yaw_zeroed) {
279 double sum = 0;
280 for (int i = 0; i < YAW_BUF_LEN; i++) {
281 sum += yaw_buffer[i];
282 }
283 yaw_rate_offset = -sum / YAW_BUF_LEN;
284 yaw = 0;
285 printf("offset: %f\n", yaw_rate_offset);
286 yaw_zeroed = true;
287 }
288}
289
290void pack_pi_packet() {
291 // zero the buffer
292 for (int i = 0; i < PI_NUM_ITEMS; i++) {
293 pi_staging_buffer[i] = 0;
294 }
295
296 // skip empty item
297 uint8_t *imu_packet = (uint8_t *)(imu_data_buffer + 1);
298 // skip empty item and checksum and convert to bytes
299 const size_t imu_packet_len = (IMU_NUM_ITEMS - 2) * sizeof(uint16_t);
300
301 memcpy(pi_staging_buffer, imu_packet, imu_packet_len);
302 memcpy(pi_staging_buffer + imu_packet_len, &data_collect_timestamp, 4);
303 memcpy(pi_staging_buffer + imu_packet_len + 4, &encoder1_count, 2);
304 memcpy(pi_staging_buffer + imu_packet_len + 6, &encoder2_count, 2);
305
306 // exclude the part of the buffer that will be the checksum
307 uint32_t crc = calculate_crc32(pi_staging_buffer, PI_NUM_ITEMS - 4);
308 memcpy(pi_staging_buffer + imu_packet_len + 8, &crc, 4);
309
310 static_assert(PI_NUM_ITEMS == imu_packet_len +
311 sizeof(data_collect_timestamp) +
312 sizeof(encoder1_count) +
313 sizeof(encoder2_count) + sizeof(crc),
314 "PI_NUM_ITEMS needs to be able to hold the imu message + the "
315 "timestamp + the encoders + the checksum");
316}
317
318void data_ready() {
319 // save timestamp
320 data_collect_timestamp = time_us_32();
321
322 // read encoders
323 quadrature_encoder_request_count(pio0, 0);
324 quadrature_encoder_request_count(pio0, 1);
325
326 cs_select();
327 dma_channel_configure(imu_dma_tx, &imu_tx_config,
328 &spi_get_hw(SPI_IMU)->dr, // write address
329 &imu_write_buf, // read address
330 IMU_NUM_ITEMS, // element count (each element is of
331 // size transfer_data_size)
332 false); // don't start yet
333 dma_channel_configure(imu_dma_rx, &imu_rx_config,
334 &imu_data_buffer, // write address
335 &spi_get_hw(SPI_IMU)->dr, // read address
336 IMU_NUM_ITEMS, // element count (each element is of
337 // size transfer_data_size)
338 false); // don't start yet
339 dma_start_channel_mask((1u << imu_dma_tx) | (1u << imu_dma_rx));
340
341 encoder1_count = quadrature_encoder_fetch_count(pio0, 0);
342 encoder2_count = quadrature_encoder_fetch_count(pio0, 1);
343}
344
345void imu_read_finished() {
346 cs_deselect();
347
348 // TODO: check status and if necessary set flag to reset in main loop
349
350 message_recieved_count++;
351 bool checksum_passed = check_checksum(imu_data_buffer);
352 if (!checksum_passed) {
353 checksum_mismatch_count++;
354 } else {
355 static const double dt = 0.0005; // seconds
356 int32_t z_gyro_out;
357 memcpy(&z_gyro_out, imu_data_buffer + 6, 4);
358 yaw_rate = (double)z_gyro_out / 655360.0 + yaw_rate_offset; // degrees
359 yaw += yaw_rate * dt;
360
361 // 50% is 0; -2000 deg/sec to 2000 deg/sec
362 uint16_t rate_level =
363 (std::clamp(yaw_rate, -2000.0, 2000.0) / 4000.0 + 0.5) * PWM_TOP;
364 pwm_set_gpio_level(RATE_PWM, rate_level);
365
366 // 0 to 360
367 uint16_t heading_level = (int16_t)(fmod(yaw, 360) / 360.0 * PWM_TOP);
368 pwm_set_gpio_level(HEADING_PWM, heading_level);
369
370 // fill out message and add it to the queue
371 pack_pi_packet();
372 }
373
374 // TODO: this has a sleep in it
375 // stay in sync with the pi by resetting the spi fifos each transfer
376 spi_init(SPI_PI, 2000 * 1000);
377 spi_set_slave(SPI_PI, true);
378 // these settings were the most stable even though the PI is using
379 // polarity 1 and phase 1
380 spi_set_format(SPI_PI, 8, SPI_CPOL_0, SPI_CPHA_1, SPI_MSB_FIRST);
381
382 maybe_send_pi_packet();
383
384 // clear the interrupt
385 dma_hw->ints0 = 1u << imu_dma_rx;
386}
387
388void maybe_send_pi_packet() {
389 // active low; if the pi isn't connected/booted, this will
390 // also look active
391 bool cs_asserted_or_unplugged = !gpio_get(CS_PI);
392
393 if (cs_asserted_or_unplugged) {
394 // the pi is still recieving something else from us
395 timing_overrun_count++;
396 return;
397 }
398
399 gpio_put(DR_PI, 1);
400 memcpy(pi_sending_buffer, pi_staging_buffer, PI_NUM_ITEMS);
401
402 dma_channel_configure(pi_dma_tx, &pi_tx_config,
403 &spi_get_hw(SPI_PI)->dr, // write address
404 &pi_sending_buffer, // read address
405 PI_NUM_ITEMS, // element count (each element is
406 // of size transfer_data_size)
407 false); // don't start yet
408 dma_channel_configure(pi_dma_rx, &pi_rx_config,
409 &pi_recieve_buffer, // write address
410 &spi_get_hw(SPI_PI)->dr, // read address
411 PI_NUM_ITEMS, // element count (each element is of
412 // size transfer_data_size)
413 false); // don't start yet
414
415 // start hardware calculation of the CRC-32; currently calculated in software
416 dma_sniffer_enable(pi_dma_tx, 0x0, true);
417 dma_hw->sniff_data = 0;
418
419 // start both at exactly the same time
420 dma_start_channel_mask((1u << pi_dma_tx) | (1u << pi_dma_rx));
421}
422
423void pi_transfer_finished() {
424 message_sent_count++;
425 gpio_put(DR_PI, 0);
426
427 send_time = time_us_32() - data_collect_timestamp;
428
429 dma_hw->ints1 = 1u << pi_dma_rx;
430}
431
432int main() {
433 stdio_init_all();
434
435 // Use 1MHz with the IMU as that is the limit for burst mode.
436 spi_init(SPI_IMU, 1000 * 1000);
437 spi_set_format(SPI_IMU, 16, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST);
438 gpio_set_function(DOUT_IMU, GPIO_FUNC_SPI);
439 gpio_set_function(SCLK_IMU, GPIO_FUNC_SPI);
440 gpio_set_function(DIN_IMU, GPIO_FUNC_SPI);
441 // Make the SPI pins available to picotool
442 bi_decl(bi_3pins_with_func(DOUT_IMU, DIN_IMU, SCLK_IMU, GPIO_FUNC_SPI));
443
444 // Chip select is active-low, so we'll initialise it to a driven-high state
445 gpio_init(CS_IMU);
446 gpio_set_dir(CS_IMU, GPIO_OUT);
447 gpio_put(CS_IMU, 1);
448 // Make the CS pin available to picotool
449 bi_decl(bi_1pin_with_name(CS_IMU, "IMU CS"));
450
451 // Reset is active-low, so we'll initialise it to a driven-high state
452 gpio_init(RST_IMU);
453 gpio_set_dir(RST_IMU, GPIO_OUT);
454 gpio_put(RST_IMU, 1);
455 // Make the RST pin available to picotool
456 bi_decl(bi_1pin_with_name(RST_IMU, "IMU RESET"));
457
458 imu_dma_tx = dma_claim_unused_channel(true);
459 imu_dma_rx = dma_claim_unused_channel(true);
460
461 // We set the outbound DMA to transfer from a memory buffer to the SPI
462 // transmit FIFO paced by the SPI TX FIFO DREQ The default is for the read
463 // address to increment every element (in this case 2 bytes - DMA_SIZE_16) and
464 // for the write address to remain unchanged.
465
466 imu_tx_config = dma_channel_get_default_config(imu_dma_tx);
467 channel_config_set_transfer_data_size(&imu_tx_config, DMA_SIZE_16);
468 channel_config_set_dreq(&imu_tx_config, spi_get_dreq(SPI_IMU, true));
469 channel_config_set_read_increment(&imu_tx_config, true);
470 channel_config_set_write_increment(&imu_tx_config, false);
471
472 // We set the inbound DMA to transfer from the SPI receive FIFO to a memory
473 // buffer paced by the SPI RX FIFO DREQ We configure the read address to
474 // remain unchanged for each element, but the write address to increment (so
475 // data is written throughout the buffer)
476 imu_rx_config = dma_channel_get_default_config(imu_dma_rx);
477 channel_config_set_transfer_data_size(&imu_rx_config, DMA_SIZE_16);
478 channel_config_set_dreq(&imu_rx_config, spi_get_dreq(SPI_IMU, false));
479 channel_config_set_read_increment(&imu_rx_config, false);
480 channel_config_set_write_increment(&imu_rx_config, true);
481
482 // Tell the DMA to raise IRQ line 0 when the channel finishes a block
483 dma_channel_set_irq0_enabled(imu_dma_rx, true);
484
485 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted
486 irq_set_exclusive_handler(DMA_IRQ_0, imu_read_finished);
487 irq_set_enabled(DMA_IRQ_0, true);
488
489 // Use 2MHz with the PI as that is the maximum speed for the pico
490 gpio_set_function(MISO_PI, GPIO_FUNC_SPI);
491 gpio_set_function(MOSI_PI, GPIO_FUNC_SPI);
492 gpio_set_function(SCK_PI, GPIO_FUNC_SPI);
493 gpio_set_function(CS_PI, GPIO_FUNC_SPI);
494 // Make the SPI pins available to picotool
495 bi_decl(bi_3pins_with_func(DOUT_IMU, DIN_IMU, SCLK_IMU, GPIO_FUNC_SPI));
496
497 gpio_init(DR_PI);
498 gpio_set_dir(DR_PI, GPIO_OUT);
499 gpio_put(DR_PI, 0);
500 // Make the CS pin available to picotool
501 bi_decl(bi_1pin_with_name(DR_PI, "DATA READY PI"));
502
503 pi_dma_tx = dma_claim_unused_channel(true);
504 pi_dma_rx = dma_claim_unused_channel(true);
505
506 // We set the outbound DMA to transfer from a memory buffer to the SPI
507 // transmit FIFO paced by the SPI TX FIFO DREQ The default is for the read
508 // address to increment every element (in this case 2 bytes - DMA_SIZE_16) and
509 // for the write address to remain unchanged.
510
511 pi_tx_config = dma_channel_get_default_config(pi_dma_tx);
512 channel_config_set_transfer_data_size(&pi_tx_config, DMA_SIZE_8);
513 channel_config_set_dreq(&pi_tx_config, spi_get_dreq(SPI_PI, true));
514 channel_config_set_read_increment(&pi_tx_config, true);
515 channel_config_set_write_increment(&pi_tx_config, false);
516
517 // We set the inbound DMA to transfer from the SPI receive FIFO to a memory
518 // buffer paced by the SPI RX FIFO DREQ We configure the read address to
519 // remain unchanged for each element, but the write address to increment (so
520 // data is written throughout the buffer)
521 pi_rx_config = dma_channel_get_default_config(pi_dma_rx);
522 channel_config_set_transfer_data_size(&pi_rx_config, DMA_SIZE_8);
523 channel_config_set_dreq(&pi_rx_config, spi_get_dreq(SPI_PI, false));
524 channel_config_set_read_increment(&pi_rx_config, false);
525 channel_config_set_write_increment(&pi_rx_config, true);
526
527 // Tell the DMA to raise IRQ line 1 when the channel finishes a block
528 dma_channel_set_irq1_enabled(pi_dma_rx, true);
529
530 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted
531 irq_set_exclusive_handler(DMA_IRQ_1, pi_transfer_finished);
532 irq_set_enabled(DMA_IRQ_1, true);
533
534 /* All IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the pico
535 * runtime at startup.
536 *
537 * Handler | Interrupt | Cause of interrupt
538 * --------------------|--------------|---------------------------------------
539 * imu_read_finished | DMA_IRQ_0 | When the dma read from the imu is done
540 * pi_transfer_finished| DMA_IRQ_1 | When the dma read to the pi is
541 * done data_ready | IO_IRQ_BANK0 | On the rising edge of DR_IMU
542 */
543
544 // Tell the GPIOs they are allocated to PWM
545 gpio_set_function(HEADING_PWM, GPIO_FUNC_PWM);
546 gpio_set_function(RATE_PWM, GPIO_FUNC_PWM);
547
548 // Find out which PWM slice is connected to each gpio pin
549 uint heading_slice = pwm_gpio_to_slice_num(HEADING_PWM);
550 uint rate_slice = pwm_gpio_to_slice_num(RATE_PWM);
551
552 /* frequency_pwm = f_sys / ((TOP + 1) * (CSR_PHASE_CORRECT + 1) * (DIV_INT +
553 * DIV_FRAC / 16))
554 *
555 * f_sys = 125 mhz
556 * CSR_PHASE_CORRECT = 0; no phase correct
557 * TARGET_FREQ = 200 hz
558 *
559 * 125 mhz / x = 200 hz * 62500
560 *
561 * TOP = 62499
562 * DIV_INT = 10
563 */
564
565 float divisor = clock_get_hz(clk_sys) / (PWM_TOP + 1) / PWM_FREQ_HZ;
566
567 pwm_config cfg = pwm_get_default_config();
568 pwm_config_set_clkdiv_mode(&cfg, PWM_DIV_FREE_RUNNING);
569 pwm_config_set_clkdiv(&cfg, divisor);
570 pwm_config_set_wrap(&cfg, PWM_TOP);
571
572 pwm_init(heading_slice, &cfg, true);
573 pwm_init(rate_slice, &cfg, true);
574
575 // the two state machine instances use the same program memory from pio0
576 uint offset = pio_add_program(pio0, &quadrature_encoder_program);
577 quadrature_encoder_program_init(pio0, 0, offset, ENC1_A, 0);
578 quadrature_encoder_program_init(pio0, 1, offset, ENC2_A, 0);
579
580 sleep_ms(3 * 1000);
581
582 printf("Hello ADIS16505\n");
583
584 printf(
585 "System clock: %d hz\n"
586 "PWM target frequency: %d hz, PWM clock divisor: "
587 "%f, PWM TOP: %d\n",
588 clock_get_hz(clk_sys), PWM_FREQ_HZ, divisor, PWM_TOP);
589
590 while (true) {
591 adis16505_reset();
592 // See if SPI is working - interrogate the device for its product ID
593 // number, should be 0x4079
594 uint16_t id = read_register(PROD_ID);
595 if (id == EXPECTED_PROD_ID) {
596 printf("Product id: 0x%04x == expected 0x%04x\n", id, EXPECTED_PROD_ID);
597 break;
598 } else {
599 printf("Got 0x%04x for prod id, expected 0x%04x\ntrying again\n", id,
600 EXPECTED_PROD_ID);
601 }
602 }
603
604 uint16_t firmware_revision = read_register(FIRM_REV);
605 uint16_t firmware_day_month = read_register(FIRM_DM);
606 uint16_t firmware_year = read_register(FIRM_Y);
607 uint16_t serial_number = read_register(SERIAL_NUM);
608
609 printf(
610 "Firmware revision: 0x%04x, \nFirmware day month: 0x%04x, \nFirmware "
611 "year: "
612 "0x%04x, \nSerial number: 0x%04x, \n",
613 firmware_revision, firmware_day_month, firmware_year, serial_number);
614
615 // run self test
616 int num_failures = 0;
617 while (true) {
618 write_register(GLOB_CMD, 1u << 2);
619 sleep_ms(24);
620 uint16_t diag_stat = read_register(DIAG_STAT);
621
622 // check the sensor failure bit
623 bool sensor_failure = diag_stat & (1u << 5);
624 printf("Diag stat: 0b%016b, \n", diag_stat);
625
626 if (sensor_failure) {
627 num_failures++;
628 printf("%d failures, trying again\n", num_failures);
629 } else {
630 break;
631 }
632 }
633
634 write_register(FILT_CTRL, 0 /* no filtering */);
635 write_register(
636 MSC_CTRL,
637 (1u << 9) /* enable 32-bit mode for burst reads */ |
638 (0u << 8) /* send gyro and accelerometer data in burst mode */ |
639 (1u << 7) /* enable gyro linear g compensation */ |
640 (1u << 6) /* enable point of percussion alignment */ |
641 (0u << 2) /* internal clock mode */ |
642 (0u << 1) /* sync polarity, doesn't matter */ |
643 (1u << 0) /* data ready is active high */);
644 // Rate of the output will be 2000 / (DEC_RATE + 1) Hz.
645 write_register(DEC_RATE, 0 /* no decimation */);
646
647 sleep_us(200);
648
649 gpio_set_irq_enabled_with_callback(DR_IMU, GPIO_IRQ_EDGE_RISE, true,
650 &gpio_irq_handler);
651
652 while (!yaw_zeroed) {
653 dma_channel_wait_for_finish_blocking(imu_dma_rx);
654 sleep_us(100);
655 zero_yaw(yaw_rate);
656 }
657
658 printf("Press q to enter bootloader\n");
659
660 while (1) {
661 dma_channel_wait_for_finish_blocking(imu_dma_rx);
662 // we want the interrupts to happen before or during the sleep so that we
663 // can get a good picture of what's going on without things moving around
664 sleep_us(100);
665
666 // debug
667 // one printf is faster than many printfs
668 printf(
669 "Z pos is %f encoder: %d %d\n"
670 "Num failed checksums: %d, Total messages recieved: %d,\n"
671 "Num messages to pi: %d, Timing overrun count: %d,\n"
672 "Send time: %d us\n",
673 yaw, encoder1_count, encoder2_count, checksum_mismatch_count,
674 message_recieved_count, message_sent_count, timing_overrun_count,
675 send_time);
676
677 // allow the user to enter the bootloader without removing power or having
678 // to install a reset button
679 char user_input = getchar_timeout_us(0);
680 if (user_input == 'q') {
681 printf("Going down! entering bootloader\n");
682 reset_usb_boot(0, 0);
683 }
684
685 sleep_ms(50);
686 }
687
688 printf("All good\n");
689 dma_channel_unclaim(imu_dma_rx);
690 dma_channel_unclaim(imu_dma_tx);
691 dma_channel_unclaim(pi_dma_rx);
692 dma_channel_unclaim(pi_dma_tx);
693 return 0;
694}