dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fpga_drv.c
Go to the documentation of this file.
1 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  * for more details.
24  *
25  * You should have received a copy of the GNU General Public License along
26  * with this program; if not, see <http://www.gnu.org/licenses/>
27  *
28  * Additional note on redistribution: The copyright and license notices above
29  * must be maintained in each individual source file that is a derivative work
30  * of this source file; otherwise redistribution is prohibited.
31  */
32 
33 #include <pios.h>
34 
35 #if defined(PIOS_INCLUDE_RE1_FPGA)
36 
37 #include "fpga_drv.h"
38 #include "stm32f4xx_rcc.h"
39 #include "pios_spi_priv.h"
40 #include "pios_ws2811.h"
41 
84 enum pios_re1fpga_register {
85  RE1FPGA_REG_HWREV = 0x00,
86  RE1FPGA_REG_CFG = 0x01,
87  RE1FPGA_REG_CTL = 0x02,
88  RE1FPGA_REG_BLACK = 0x03,
89  RE1FPGA_REG_WHITE = 0x04,
90  RE1FPGA_REG_THR = 0x05,
91  RE1FPGA_REG_XCFG = 0x06,
92  RE1FPGA_REG_XCFG2 = 0x07,
93  RE1FPGA_REG_IRCFG = 0x08,
94  RE1FPGA_REG_IRDATA = 0x09,
95  RE1FPGA_REG_LED = 0x0F,
96 };
97 
98 struct re1_shadow_reg {
99  uint8_t reg_hwrev;
100  uint8_t reg_cfg;
101  uint8_t reg_ctl;
102  uint8_t reg_black;
103  uint8_t reg_white;
104  uint8_t reg_thr;
105  uint8_t reg_xcfg;
106  uint8_t reg_xcfg2;
107  uint8_t reg_ircfg;
108 };
109 
110 
111 enum pios_re1fpga_dev_magic {
112  PIOS_RE1FPGA_DEV_MAGIC = 0xbadfed42,
113 };
114 
115 struct re1fpga_dev {
116  pios_spi_t spi_id;
117  uint32_t slave_num;
118  const struct pios_re1fpga_cfg *cfg;
119  struct re1_shadow_reg shadow_reg;
120  enum pios_re1fpga_dev_magic magic;
121 };
122 
123 #define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
124 
126 static struct re1fpga_dev *dev;
127 
128 static int32_t PIOS_RE1FPGA_WriteReg(uint8_t reg, uint8_t data, uint8_t mask);
129 static int32_t PIOS_RE1FPGA_WriteRegDirect(enum pios_re1fpga_register reg, uint8_t data);
130 static uint8_t PIOS_RE1FPGA_ReadReg(uint8_t reg);
131 static void update_shadow_regs();
132 int32_t PIOS_RE1FPGA_SetLEDs(const uint8_t * led_data, uint16_t n_leds);
133 int32_t PIOS_RE1FPGA_SetIRData(const uint8_t * ir_data, uint8_t n_bytes);
134 
135 
139 static struct re1fpga_dev *PIOS_RE1FPGA_alloc(const struct pios_re1fpga_cfg *cfg)
140 {
141  struct re1fpga_dev *re1fpga_dev;
142 
143  re1fpga_dev = (struct re1fpga_dev *)PIOS_malloc(sizeof(*re1fpga_dev));
144  if (!re1fpga_dev)
145  return NULL;
146 
147  re1fpga_dev->magic = PIOS_RE1FPGA_DEV_MAGIC;
148 
149  return re1fpga_dev;
150 }
151 
152 volatile uint8_t test;
157 int32_t PIOS_RE1FPGA_Init(pios_spi_t spi_id, uint32_t slave_num,
158  const struct pios_re1fpga_cfg *cfg, bool load_config)
159 {
160  dev = PIOS_RE1FPGA_alloc(cfg);
161  if (dev == NULL)
162  return -1;
163 
164  dev->spi_id = spi_id;
165  dev->slave_num = slave_num;
166  dev->cfg = cfg;
167 
168  if (load_config) {
169  /* Configure the CDONE and CRESETB pins */
170  GPIO_Init(dev->cfg->cdone_pin.gpio, (GPIO_InitTypeDef *) & (dev->cfg->cdone_pin.init));
171  GPIO_Init(dev->cfg->cresetb_pin.gpio, (GPIO_InitTypeDef *) & (dev->cfg->cresetb_pin.init));
172 
173  // CRESETB low for 1ms
174  GPIO_ResetBits(dev->cfg->cresetb_pin.gpio, dev->cfg->cresetb_pin.init.GPIO_Pin);
176  GPIO_SetBits(dev->cfg->cresetb_pin.gpio, dev->cfg->cresetb_pin.init.GPIO_Pin);
177 
178  for (int i=0; i<100; i++) {
179  if (GPIO_ReadInputDataBit(dev->cfg->cdone_pin.gpio, dev->cfg->cdone_pin.init.GPIO_Pin))
180  break;
182  }
183 
184  if (!GPIO_ReadInputDataBit(dev->cfg->cdone_pin.gpio, dev->cfg->cdone_pin.init.GPIO_Pin))
185  return -2;
186  }
187 
188  /* Configure 16MHz clock output to FPGA */
189  GPIO_Init(dev->cfg->mco_pin.gpio, (GPIO_InitTypeDef *) & (dev->cfg->mco_pin.init));
190  GPIO_PinAFConfig(dev->cfg->mco_pin.gpio,
191  __builtin_ctz(dev->cfg->mco_pin.init.GPIO_Pin),
192  GPIO_AF_MCO);
193  RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1);
194  RCC_MCO1Cmd(ENABLE);
195 
196  /* Configure reset pin */
197  GPIO_Init(dev->cfg->rst_pin.gpio, (GPIO_InitTypeDef *) & (dev->cfg->rst_pin.init));
198  GPIO_ResetBits(dev->cfg->rst_pin.gpio, dev->cfg->rst_pin.init.GPIO_Pin);
199 
200  // Give the PLL some time to stabilize
201  PIOS_DELAY_WaitmS(10);
202 
203  // Reset the FPGA (pull rst low and then high again)
204  GPIO_SetBits(dev->cfg->rst_pin.gpio, dev->cfg->rst_pin.init.GPIO_Pin);
205  PIOS_DELAY_WaitmS(10);
206  GPIO_ResetBits(dev->cfg->rst_pin.gpio, dev->cfg->rst_pin.init.GPIO_Pin);
208 
209  // Initialize registers
210  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_CFG, 0x00);
211  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_CTL, 0x00);
212  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_BLACK, 35);
213  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_BLACK, 110);
214  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_THR, 120);
215  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_XCFG, 0x08);
216  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_XCFG2, 0x10);
217  PIOS_RE1FPGA_WriteRegDirect(RE1FPGA_REG_IRCFG, 0x00);
218 
219  // Read all registers into shadow regsiters
220  update_shadow_regs();
221 
222  return 0;
223 }
224 
229 static int32_t PIOS_RE1FPGA_Validate(struct re1fpga_dev *dev)
230 {
231  if (dev == NULL)
232  return -1;
233  if (dev->magic != PIOS_RE1FPGA_DEV_MAGIC)
234  return -2;
235  if (dev->spi_id == 0)
236  return -3;
237  return 0;
238 }
239 
244 static int32_t PIOS_RE1FPGA_ClaimBus()
245 {
246  if (PIOS_RE1FPGA_Validate(dev) != 0)
247  return -1;
248 
249  if (PIOS_SPI_ClaimBus(dev->spi_id) != 0)
250  return -2;
251 
252  PIOS_SPI_RC_PinSet(dev->spi_id, dev->slave_num, 0);
253 
254  return 0;
255 }
256 
261 static int32_t PIOS_RE1FPGA_ReleaseBus()
262 {
263  if (PIOS_RE1FPGA_Validate(dev) != 0)
264  return -1;
265 
266  PIOS_SPI_RC_PinSet(dev->spi_id, dev->slave_num, 1);
267 
268  PIOS_SPI_ReleaseBus(dev->spi_id);
269 
270  return 0;
271 }
272 
279 static int32_t PIOS_RE1FPGA_WriteReg(enum pios_re1fpga_register reg, uint8_t data, uint8_t mask)
280 {
281  uint8_t* cur_reg;
282 
283  if (PIOS_RE1FPGA_Validate(dev) != 0)
284  return -1;
285 
286  switch (reg) {
287  case RE1FPGA_REG_HWREV:
288  return -2;
289  case RE1FPGA_REG_CFG:
290  cur_reg = &dev->shadow_reg.reg_cfg;
291  break;
292  case RE1FPGA_REG_CTL:
293  cur_reg = &dev->shadow_reg.reg_ctl;
294  break;
295  case RE1FPGA_REG_BLACK:
296  cur_reg = &dev->shadow_reg.reg_black;
297  break;
298  case RE1FPGA_REG_WHITE:
299  cur_reg = &dev->shadow_reg.reg_white;
300  break;
301  case RE1FPGA_REG_THR:
302  cur_reg = &dev->shadow_reg.reg_thr;
303  break;
304  case RE1FPGA_REG_XCFG:
305  cur_reg = &dev->shadow_reg.reg_xcfg;
306  break;
307  case RE1FPGA_REG_XCFG2:
308  cur_reg = &dev->shadow_reg.reg_xcfg2;
309  break;
310  case RE1FPGA_REG_IRCFG:
311  cur_reg = &dev->shadow_reg.reg_ircfg;
312  break;
313 
314  default:
315  case RE1FPGA_REG_LED:
316  return -2;
317  }
318 
319  uint8_t new_data = (*cur_reg & ~mask) | (data & mask);
320 
321 
322  if (new_data == *cur_reg) {
323  return 0;
324  }
325 
326  *cur_reg = new_data;
327 
328  return PIOS_RE1FPGA_WriteRegDirect(reg, new_data);
329 }
330 
331 static int32_t PIOS_RE1FPGA_WriteRegDirect(enum pios_re1fpga_register reg, uint8_t data)
332 {
333 
334  if (PIOS_RE1FPGA_Validate(dev) != 0)
335  return -1;
336 
337  if (PIOS_RE1FPGA_ClaimBus() != 0)
338  return -3;
339 
340  PIOS_SPI_TransferByte(dev->spi_id, 0x7f & reg);
341  PIOS_SPI_TransferByte(dev->spi_id, data);
342 
343  PIOS_RE1FPGA_ReleaseBus();
344 
345  return 0;
346 }
347 
353 static uint8_t PIOS_RE1FPGA_ReadReg(enum pios_re1fpga_register reg)
354 {
355  uint8_t data;
356 
357  PIOS_RE1FPGA_ClaimBus();
358 
359  PIOS_SPI_TransferByte(dev->spi_id, 0x80 | reg); // request byte
360  data = PIOS_SPI_TransferByte(dev->spi_id, 0); // receive response
361 
362  PIOS_RE1FPGA_ReleaseBus();
363 
364  return data;
365 }
366 
367 
371 static void update_shadow_regs(void)
372 {
373  dev->shadow_reg.reg_hwrev = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_HWREV);
374  dev->shadow_reg.reg_cfg = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_CFG);
375  dev->shadow_reg.reg_ctl = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_CTL);
376  dev->shadow_reg.reg_black = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_BLACK);
377  dev->shadow_reg.reg_white = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_WHITE);
378  dev->shadow_reg.reg_thr = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_THR);
379  dev->shadow_reg.reg_xcfg = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_XCFG);
380  dev->shadow_reg.reg_xcfg2 = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_XCFG2);
381  dev->shadow_reg.reg_ircfg = PIOS_RE1FPGA_ReadReg(RE1FPGA_REG_IRCFG);
382 }
383 
388 {
389  return dev->shadow_reg.reg_hwrev;
390 }
391 
396 {
397  uint8_t value = 0;
398 
399  switch (ir_protocol) {
401  value = 0;
402  break;
405  /* They use the same basic protocol */
406  value = 0x01;
407  break;
408  }
409 
410  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_IRCFG, value, 0x0F);
411 }
412 
416 int32_t PIOS_RE1FPGA_SetIRData(const uint8_t * ir_data, uint8_t n_bytes)
417 {
418  if (n_bytes > 16)
419  return - 1;
420 
421  if (PIOS_RE1FPGA_ClaimBus() != 0)
422  return -2;
423 
424 
425  PIOS_SPI_TransferByte(dev->spi_id, 0x7f & RE1FPGA_REG_IRDATA);
426  PIOS_SPI_TransferBlock(dev->spi_id, ir_data, NULL, n_bytes);
427 
428  PIOS_RE1FPGA_ReleaseBus();
429 
430  return 0;
431 }
432 
436 int32_t PIOS_RE1FPGA_SerialRxInvert(bool invert)
437 {
438  uint8_t data;
439  if (invert) {
440  data = 0x01;
441  }
442  else {
443  data = 0x00;
444  }
445  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CFG, data, 0x01);
446 }
447 
451 int32_t PIOS_RE1FPGA_MPTxPinMode(bool bidrectional, bool invert)
452 {
453  uint8_t data = 0;
454 
455  data |= bidrectional << 1;
456  data |= invert << 2;
457 
458  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CFG, data, 0x06);
459 }
460 
464 int32_t PIOS_RE1FPGA_MPTxPinPullUpDown(bool enable, bool pullup)
465 {
466  uint8_t data = 0;
467 
468  data |= enable << 3;
469  data |= pullup << 4;
470 
471  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CFG, data, 0x18);
472 }
473 
478 {
479  uint8_t data;
480  if (type == PIOS_RE1FPGA_BUZZER_DC) {
481  data = 0;
482  }
483  else {
484  data = 255;
485  }
486  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CFG, data, 0x40);
487 }
488 
489 
493 int32_t PIOS_RE1FPGA_Buzzer(bool enable)
494 {
495  uint8_t data = enable;
496 
497  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CTL, data, 0x01);
498 }
499 
504 {
505  uint8_t value;
506 
507  if (led_colors == PIOS_RE1FPGA_STATUS_BLUE_CUSTOM_GREEN)
508  value = 0;
509  else
510  value = 255;
511 
512  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_CFG, value, 0x20);
513 }
514 
518 void PIOS_RE1FPGA_SetBwLevels(uint8_t black, uint8_t white)
519 {
520  PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_BLACK, black, 0xFF);
521  PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_WHITE, white, 0xFF);
522 }
523 
527 int32_t PIOS_RE1FPGA_SetSyncThreshold(uint8_t threshold)
528 {
529  return PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_THR, threshold, 0xFF);
530 }
531 
535 void PIOS_RE1FPGA_SetXOffset(int8_t x_offset)
536 {
537  //x_offset += 5;
538  if (x_offset >= 7)
539  x_offset = 7;
540  if (x_offset < -8)
541  x_offset = -8;
542 
543  uint8_t value = 8 + x_offset;
544  PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_XCFG, value, 0x0F);
545 }
546 
550 void PIOS_RE1FPGA_SetXScale(uint8_t x_scale)
551 {
552  x_scale = (x_scale & 0x0F) << 4;
553  PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_XCFG, x_scale, 0xF0);
554 }
555 
559 void PIOS_RE1FPGA_Set3DConfig(enum pios_video_3d_mode mode, uint8_t x_shift_right)
560 {
561  uint8_t cfg;
562  uint8_t enabled = (mode == PIOS_VIDEO_3D_SBS3D);
563 
564  cfg = (enabled << 6) | (x_shift_right & 0x3F);
565  PIOS_RE1FPGA_WriteReg(RE1FPGA_REG_XCFG2, cfg, 0xFF);
566 }
567 
568 // **********************************************************************************
569 // PIOS WS2811 support functions
570 
571 struct ws2811_pixel_data_s {
572  uint8_t g;
573  uint8_t r;
574  uint8_t b;
575 };
576 
577 struct ws2811_dev_s {
578 #define WS2811_MAGIC 0x31313832 /* '2811' */
579  uint32_t magic;
580  uint16_t max_leds;
581  uint16_t max_idx;
582  struct ws2811_pixel_data_s pixel_data[0];
583 };
584 
585 int PIOS_WS2811_init(ws2811_dev_t *dev_out, const struct pios_ws2811_cfg *cfg,
586  int max_leds)
587 {
588  PIOS_Assert(max_leds > 0);
589  PIOS_Assert(max_leds <= 1024);
590 
591  ws2811_dev_t dev = PIOS_malloc(sizeof(*dev) +
592  sizeof(struct ws2811_pixel_data_s) * max_leds);
593 
594  if (!dev) {
595  return -1;
596  }
597 
598  dev->magic = WS2811_MAGIC;
599  dev->max_leds = max_leds;
600  dev-> max_idx = 0;
601 
602  PIOS_WS2811_set_all(dev, 0, 0, 0);
603 
604  *dev_out = dev;
605 
606  return 0;
607 }
608 
609 void PIOS_WS2811_set(ws2811_dev_t ws2811_dev, int idx, uint8_t r, uint8_t g,
610  uint8_t b)
611 {
612  PIOS_Assert(ws2811_dev->magic == WS2811_MAGIC);
613 
614  if (idx >= ws2811_dev->max_leds) {
615  return;
616  }
617 
618  if (idx > ws2811_dev->max_idx) {
619  ws2811_dev->max_idx = idx;
620  }
621 
622  ws2811_dev->pixel_data[idx] = (struct ws2811_pixel_data_s)
623  { .r = r, .g = g, .b = b };
624 }
625 
626 void PIOS_WS2811_set_all(ws2811_dev_t ws2811_dev, uint8_t r, uint8_t g,
627  uint8_t b)
628 {
629  PIOS_Assert(ws2811_dev->magic == WS2811_MAGIC);
630 
631  for (int i = 0; i < ws2811_dev->max_leds; i++) {
632  PIOS_WS2811_set(ws2811_dev, i, r, g, b);
633  }
634 }
635 
637 {
638  uint16_t n_leds;
639  PIOS_Assert(ws2811_dev->magic == WS2811_MAGIC);
640 
641  if (PIOS_RE1FPGA_ClaimBus() != 0)
642  return;
643 
644  n_leds = MIN(ws2811_dev->max_idx + 1, 1024);
645 
646  PIOS_SPI_TransferByte(dev->spi_id, 0x7f & RE1FPGA_REG_LED);
647  PIOS_SPI_TransferBlock(dev->spi_id, (uint8_t*)ws2811_dev->pixel_data, NULL,
648  sizeof(struct ws2811_pixel_data_s) * n_leds);
649 
650  PIOS_RE1FPGA_ReleaseBus();
651 }
652 
654 {
655  PIOS_Assert(ws2811_dev->magic == WS2811_MAGIC);
656 
657  uint16_t n_leds = MIN(ws2811_dev->max_idx + 1, 1024);
658 
659  return n_leds;
660 }
661 
662 #endif /* defined(PIOS_INCLUDE_RE1_FPGA) */
663 
void PIOS_RE1FPGA_SetBwLevels(uint8_t black, uint8_t white)
int32_t PIOS_RE1FPGA_Init(pios_spi_t spi_id, uint32_t slave_num, const struct pios_re1fpga_cfg *cfg, bool load_config)
int PIOS_WS2811_get_num_leds(ws2811_dev_t dev)
Find out how many LEDs are configured on an interface.
Definition: pios_ws2811.c:227
int32_t PIOS_RE1FPGA_SetBuzzerType(enum pios_re1fpga_buzzer_types type)
Main PiOS header to include all the compiled in PiOS options.
SPI private definitions.
int32_t PIOS_SPI_RC_PinSet(pios_spi_t spi_dev, uint32_t slave_id, bool pin_value)
uint32_t magic
Definition: pios_ws2811.c:53
pios_re1fpga_buzzer_types
Definition: fpga_drv.h:56
int32_t PIOS_SPI_ClaimBus(pios_spi_t spi_dev)
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
pios_video_3d_mode
Definition: pios_video.h:45
int32_t PIOS_RE1FPGA_Buzzer(bool enable)
int PIOS_WS2811_init(ws2811_dev_t *dev_out, const struct pios_ws2811_cfg *cfg, int max_leds)
Allocate and initialise WS2811 device.
Definition: pios_ws2811.c:64
uint8_t data[XFER_BYTES_PER_PACKET]
Definition: bl_messages.h:129
void PIOS_RE1FPGA_SetXOffset(int8_t x_offset)
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
void PIOS_RE1FPGA_SetXScale(uint8_t x_scale)
int32_t PIOS_RE1FPGA_MPTxPinMode(bool bidrectional, bool invert)
void PIOS_WS2811_set_all(ws2811_dev_t dev, uint8_t r, uint8_t g, uint8_t b)
Sets all LEDs to a color value.
Definition: pios_ws2811.c:219
int32_t PIOS_RE1FPGA_SetSyncThreshold(uint8_t threshold)
uint8_t PIOS_SPI_TransferByte(pios_spi_t spi_dev, uint8_t b)
int32_t PIOS_RE1FPGA_SetNotificationLedColor(enum pios_re1fpga_led_colors led_colors)
int32_t PIOS_SPI_TransferBlock(pios_spi_t spi_dev, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len)
uint8_t i
Definition: msp_messages.h:97
uint8_t PIOS_RE1FPGA_GetHWRevision()
enum channel_mode mode
Definition: pios_servo.c:58
uint16_t value
Definition: storm32bgc.c:155
int32_t PIOS_RE1FPGA_SetIRProtocol(enum pios_re1fpga_ir_protocols ir_protocol)
uint32_t magic
int32_t PIOS_RE1FPGA_MPTxPinPullUpDown(bool enable, bool pullup)
uint8_t type
void PIOS_WS2811_set(ws2811_dev_t dev, int idx, uint8_t r, uint8_t g, uint8_t b)
Set a given LED to a color value.
Definition: pios_ws2811.c:176
#define MIN(a, b)
Definition: misc_math.h:41
void PIOS_WS2811_trigger_update(ws2811_dev_t dev)
Trigger an update of the LED strand.
Definition: pios_ws2811.c:197
pios_re1fpga_ir_protocols
Definition: fpga_drv.h:50
pios_re1fpga_led_colors
Definition: fpga_drv.h:45
int32_t PIOS_SPI_ReleaseBus(pios_spi_t spi_dev)
int32_t PIOS_RE1FPGA_SerialRxInvert(bool invert)
void PIOS_RE1FPGA_Set3DConfig(enum pios_video_3d_mode mode, uint8_t x_shift_right)
int32_t PIOS_RE1FPGA_SetIRData(const uint8_t *ir_data, uint8_t n_bytes)
#define PIOS_Assert(test)
Definition: pios_debug.h:52
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
Definition: pios_delay.c:140