spiTouINS.c
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright 2014-2019 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include <asf.h>
14 #include "spiTouINS.h"
15 #include "board_opt.h"
16 #include "drivers/d_dma.h"
17 #include "../../../hw-libs/misc/rtos.h"
18 
19 #define SPI_INS_BAUDRATE 10000000UL
20 
21 // SPI Channel
22 #define SPI_INS_BASE SPI0
23 #define SPI_INS_CHIP_SEL 2
24 #define SPI_spiTouINS_Handler SPI0_Handler
25 #define SPI_IRQn SPI0_IRQn
26 #define SPI_XDMAC_TX_CH_NUM 1
27 #define SPI_XDMAC_RX_CH_NUM 2
28 
29 // Clock polarity & phase. Set to mode 3.
30 #define SPI_INS_CLK_POLARITY 1
31 #define SPI_INS_CLK_PHASE 0
32 
33 // Delay before SPCK.
34 #define SPI_DLYBS 0x10
35 
36 // Delay between consecutive transfers.
37 #define SPI_DLYBCT 0x03
38 
39 #define TX_BUFFER_SIZE 512
40 #define RX_BUFFER_SIZE 2048 //Needs to be a power of 2 (2^x)
41 #define RX_INT_BUFFER_SIZE 1024 //Needs to be a power of 2 (2^x)
42 
43 #define READ_SIZE 100
44 #define READ_ADDITIONAL_SIZE 20
45 
46 COMPILER_ALIGNED(32) static volatile uint8_t TxBuf[TX_BUFFER_SIZE];
47 COMPILER_ALIGNED(32) static volatile uint8_t TxBlank[READ_SIZE];
48 COMPILER_ALIGNED(32) static volatile uint8_t RxBuf[RX_BUFFER_SIZE];
49 COMPILER_ALIGNED(32) static volatile uint8_t RxBufInternal[RX_INT_BUFFER_SIZE];
50 static volatile uint32_t rxfptr = 0, rxbptr = 0, rxintptr = 0;
51 static volatile uint8_t *txfptr = TxBuf;
52 
53 //Pointers for the lld_view0 array
54 volatile uint32_t lld_fptr;
55 volatile uint32_t lld_bptr;
56 
57 // DMA linked list descriptor used for reload
58 #define DMA_LLD_COUNT 32 //Must be 2^x in size
59 #define DMA_LLD_MASK (DMA_LLD_COUNT - 1)
60 COMPILER_WORD_ALIGNED volatile lld_view0 lld[DMA_LLD_COUNT];
61 COMPILER_WORD_ALIGNED volatile lld_view0 rx_lld;
62 
63 static void sendMoreData(int len);
64 
65 //Task stuff
66 #define TASK_SPI_TO_UINS_STACK_SIZE (512/sizeof(portSTACK_TYPE))
67 #define TASK_SPI_TO_UINS_PRIORITY (configMAX_PRIORITIES - 2) // We want this to be the highest priority - Only timer task higher
68 #define TASK_SPI_TO_UINS_PERIOD_MS 1
69 static TaskHandle_t xHandlingTask;
70 
71 void XDMAC_spiTouINS_Handler(void)
72 {
74  {
75  //Check to see if DMA is finished (as indicated by channel becoming disabled)
76  if ((XDMAC->XDMAC_GS & (XDMAC_GS_ST0 << DMA_CH_SPI_INS_TX)) == 0)
77  {
78  if(lld_bptr != lld_fptr) //Not equal means there is data ready to send
79  {
80  //Setup TX DMA
83 
84  //Move pointer
85  lld_bptr = (lld_bptr + 1) & DMA_LLD_MASK;
86 
87  //Enable - We don't need to clean cache as DMA data is already flushed to main memory
88  XDMAC->XDMAC_GE = (XDMAC_GE_EN0 << DMA_CH_SPI_INS_TX);
89  }
90  else
91  {
92  //We are done with the list
94 
95  //See if we need to receive more or lower CS line
97  {
98  //Keep receiving
100  }
101  else
102  {
104  }
105  }
106 
107  //Notify task to process data
108  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
109  xTaskNotifyFromISR(g_rtos.task[EVB_TASK_SPI_UINS_COM].handle, 1, eSetBits, &xHigherPriorityTaskWoken);
110  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
111  }
112  }
113 }
114 
116 {
117  static volatile bool inDataPacket = false;
118 
119  uint32_t spi_statusReg;
120 
121 // PIOC->PIO_SODR = 1U << 20;
122 
123  if((SPI_INS_BASE->SPI_IMR & SPI_IMR_TDRE) && (SPI_INS_BASE->SPI_SR & SPI_SR_TXEMPTY))
124  {
125  //Turn off interrupt as we are either done or sending more data
127 
128  if(inDataPacket || ioport_get_pin_level(INS_DATA_RDY_PIN_IDX))
129  {
130  //Keep receiving
132  }
133  else
134  {
135  //Deactivate CS line
137 
138  //Enable Data Ready interrupt
141  }
142  }
143 
144 // PIOC->PIO_CODR = 1U << 20;
145 }
146 
147 static void PIO_DataReady_Handler(uint32_t id, uint32_t mask)
148 {
149  //Clear interrupt by reading status
151 
152  if (INS_DATA_RDY_PIN_ID == id && (INS_DATA_RDY_PIN_MASK & mask))
153  {
155 
156  //Start transmission
157  sendMoreData(READ_SIZE);
158  }
159 }
160 
161 static void spiTouINS_task(void *pvParameters)
162 {
163  UNUSED(pvParameters);
164  static volatile bool inDataPacket = false;
165 
166  while(1)
167  {
168 // PIOC->PIO_CODR = 1U << 20;
169 
170  //Wait to be notified by interrupt
171  xTaskNotifyWait( pdFALSE, 0xFFFFFFFFUL, 0, pdMS_TO_TICKS(1000));
172 
173 // PIOC->PIO_SODR = 1U << 20;
174 
175  //Check and process any data in the internal buffer into the external buffer.
176 
177  //Flush FIFO, content of the FIFO is written to memory
179 
180  //Find how much data we have
181  uint32_t bytesReady;
182  uint32_t curDmaAddr = (uint32_t)XDMAC->XDMAC_CHID[DMA_CH_SPI_INS_RX].XDMAC_CDA - (uint32_t)RxBufInternal;
183  if (curDmaAddr < rxintptr)
184  bytesReady = RX_INT_BUFFER_SIZE - rxintptr + curDmaAddr;
185  else
186  bytesReady = curDmaAddr - rxintptr;
187 
188  for(uint32_t i=0; i<bytesReady; i++)
189  {
190  if(inDataPacket)
191  {
192  //Store data in buffer
193  RxBuf[rxfptr] = RxBufInternal[rxintptr];
194 
195  //Check to see if it is the end of packet
196  if(0xFE == RxBufInternal[rxintptr])
197  {
198  inDataPacket = false;
199  }
200 
201  //Move to next location
202  rxfptr = (rxfptr + 1) & (RX_BUFFER_SIZE - 1);
203  }
204  else
205  {
206  //Watch for start of packet
207  if(0xFF == RxBufInternal[rxintptr])
208  {
209  inDataPacket = true;
210 
211  //Store data in buffer
212  RxBuf[rxfptr] = RxBufInternal[rxintptr];
213  rxfptr = (rxfptr + 1) & (RX_BUFFER_SIZE - 1);
214  }
215  }
216 
217  //Move internal buffer pointer
218  rxintptr = (rxintptr + 1) & (RX_INT_BUFFER_SIZE - 1);
219  }
220  }
221 }
222 
223 //The optimizer seems to allow the use of the lld array before it is completely configured. No optimization prevents that from happening.
224 __attribute__((optimize("O0")))
225 void spiTouINS_init(void)
226 {
227 //Setup SPI Port
231 
235 
237 
241 
244 
246 
250 
251 //DMA for incoming
252  xdmac_channel_config_t cfg = {0};
253  cfg.mbr_sa = (uint32_t)&(SPI_INS_BASE->SPI_RDR);
254  cfg.mbr_da = (uint32_t)RxBufInternal;
267 
268  // Configure linked list descriptor (only uses one)
269  rx_lld.mbr_ta = (uint32_t)RxBufInternal;
270  rx_lld.mbr_nda = (uint32_t)&rx_lld; // point to self
271  rx_lld.mbr_ubc =
276 
277  // Set initial descriptor control
282  xdmac_channel_set_descriptor_addr(XDMAC, DMA_CH_SPI_INS_RX, (uint32_t)&rx_lld, 0); //Updates CNDA register
283 
284  rxintptr = 0;
285  SCB_CLEAN_DCACHE_BY_ADDR_32BYTE_ALIGNED(&rx_lld, sizeof(rx_lld));
286  XDMAC->XDMAC_GE = (XDMAC_GE_EN0 << DMA_CH_SPI_INS_RX);
287 
288 //Configure task for processing incoming data
290 
291 //DMA for outgoing
292  cfg.mbr_sa = (uint32_t)TxBuf;
293  cfg.mbr_da = (uint32_t)&(SPI_INS_BASE->SPI_TDR);
305  cfg.mbr_ubc = 0;
307 
308  //Setup pointers to lld array
309  lld_fptr = 0;
310  lld_bptr = 0;
311 
312  //Setup interrupts for DMA for UART mode (gets multiple setups as this routine is called for multiple USARTs)
314  NVIC_SetPriority(XDMAC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); //Must not be higher than RTOS allows
316 
317 //Setup data ready pin
320 
321  //Enable Data Ready interrupt
322  pio_handler_set_priority(INS_DATA_RDY_PIN_PIO, (IRQn_Type) INS_DATA_RDY_PIN_ID, 3);
325 
326  //Haven't figured out why, but the first packet out is garbage so send one now
327  //Maybe it has something to do with the mode we are in, because before we send the data/clock lines are not in their default states
329 }
330 
331 //This routine is called by interrupts to read data out of the uINS
332 //Don't use outside this module.
333 static void sendMoreData(int len)
334 {
337 
338  //Check for sending overflow
339  if(((lld_fptr + 1) & DMA_LLD_MASK) == lld_bptr )
340  return; //This isn't great
341 
342  // Setup DMA to transfer some more data
343  lld[lld_fptr].mbr_ta = (uint32_t)TxBlank;
344  lld[lld_fptr].mbr_ubc = XDMAC_UBC_UBLEN(len);
345 
346  // Move to next lld
347  lld_fptr = (lld_fptr + 1) & DMA_LLD_MASK;
348 
349  //Block interrupt handler from running and causing a double configure
351 
352  //Enable DMA if it isn't running
353  if((XDMAC->XDMAC_GS & (XDMAC_GS_ST0 << DMA_CH_SPI_INS_TX)) == 0)
354  {
355  if(lld_bptr != lld_fptr)
356  {
357  //Activate CS line
359 
360  //Setup TX DMA
361  xdmac_channel_set_source_addr(XDMAC, DMA_CH_SPI_INS_TX, lld[lld_bptr].mbr_ta);
363 
364  //Move pointer
365  lld_bptr = (lld_bptr + 1) & DMA_LLD_MASK;
366 
367  // Enable DMA interrupt
371 
372  //Enable - cache should have already been cleaned
373  XDMAC->XDMAC_GE = (XDMAC_GE_EN0 << DMA_CH_SPI_INS_TX);
374  }
375  }
376 
378 }
379 
380 static uint32_t getTxFree(void)
381 {
382  if ((XDMAC->XDMAC_GS & (XDMAC_GS_ST0 << DMA_CH_SPI_INS_TX)) == 0)
383  return TX_BUFFER_SIZE;
384 
385  uint8_t* curDmaAddr = XDMAC->XDMAC_CHID[DMA_CH_SPI_INS_TX].XDMAC_CDA;
386 
387  if (txfptr < curDmaAddr)
388  return (int)(curDmaAddr - txfptr);
389  else
390  return TX_BUFFER_SIZE - (int)(txfptr - curDmaAddr);
391 }
392 
393 int spiTouINS_serWrite(const unsigned char *buf, int size)
394 {
395  if (size <= 0) return 0;
396  if (g_rtos.task[EVB_TASK_SPI_UINS_COM].handle == 0) return 0; //Block executing if we have not been configured
397 
398  //Disable interrupt so we don't get double writes
401 
402  // Bytes free in DMA buffer
403  int dmaFreeBytes = getTxFree();
404 
406 
407  // Limit size
408  if (size > dmaFreeBytes || ((lld_fptr + 1) & DMA_LLD_MASK) == lld_bptr )
409  return 0;
410 
412  // Copy into DMA buffer
413  // Bytes before end of DMA buffer
414  int bytesToEnd = (TxBuf + TX_BUFFER_SIZE) - txfptr;
415 
416  // Add data to ring buffer
417  if (size <= bytesToEnd)
418  {
419  // Don't need to wrap
420  // Copy data into DMA buffer
421  MEMCPY_DCACHE_CLEAN(txfptr, buf, size);
422 
423  // Setup DMA
424  lld[lld_fptr].mbr_ta = (uint32_t)txfptr;
425  lld[lld_fptr].mbr_ubc = XDMAC_UBC_UBLEN(size);
426 
427  // Increment buffer pointer
428  txfptr += size;
429 
430  // Move to next lld
431  lld_fptr = (lld_fptr + 1) & DMA_LLD_MASK;
432  }
433  else // Need to wrap
434  {
435  // Bytes to write at buffer start
436  int bytesWrapped = size - bytesToEnd;
437  uint32_t bufptr = lld_fptr;
438  int count = 1;
439 
440  //Write out data needed to fill the end of the buffer
441  if (bytesToEnd)
442  {
443  // Not already at buffer end. Fill buffer to end.
444  // Copy data into DMA buffer & update transfer size
445  MEMCPY_DCACHE_CLEAN(txfptr, buf, bytesToEnd);
446 
447  // Setup DMA for end
448  lld[bufptr].mbr_ta = (uint32_t)txfptr;
449  lld[bufptr].mbr_ubc = XDMAC_UBC_UBLEN(bytesToEnd);
450 
451  // Move to next lld
452  bufptr = (bufptr + 1) & DMA_LLD_MASK;
453  count++;
454  }
455 
456  // Copy data into DMA buffer start & update pointer
457  MEMCPY_DCACHE_CLEAN(TxBuf, buf + bytesToEnd, bytesWrapped);
458 
459  // Setup DMA for beginning
460  lld[bufptr].mbr_ta = (uint32_t)TxBuf;
461  lld[bufptr].mbr_ubc = XDMAC_UBC_UBLEN(bytesWrapped);
462 
463  // Increment buffer pointer
464  txfptr = TxBuf + bytesWrapped;
465 
466  // Move to next lld
467  lld_fptr = (lld_fptr + count) & DMA_LLD_MASK;
468  }
469 
471  // Transfer out of DMA buffer
472 
473  //Block interrupt handler from running and causing a double configure
475 
476  //Enable DMA if it isn't running
477  if((XDMAC->XDMAC_GS & (XDMAC_GS_ST0 << DMA_CH_SPI_INS_TX)) == 0)
478  {
479  if(lld_bptr != lld_fptr)
480  {
481  //Activate CS line
483 
484  //Setup TX DMA
485  xdmac_channel_set_source_addr(XDMAC, DMA_CH_SPI_INS_TX, lld[lld_bptr].mbr_ta);
487 
488  //Move pointer
489  lld_bptr = (lld_bptr + 1) & DMA_LLD_MASK;
490 
491  // Enable DMA interrupt
495 
496  //Enable - cache should have already been cleaned
497  XDMAC->XDMAC_GE = (XDMAC_GE_EN0 << DMA_CH_SPI_INS_TX);
498  }
499  }
500 
502 
504 
505  return size;
506 }
507 
509 {
510  int dataAvail = rxfptr - rxbptr;
511  if(dataAvail < 0)
512  return RX_BUFFER_SIZE + dataAvail;
513  else
514  return dataAvail;
515 }
516 
517 int spiTouINS_serRead(unsigned char *buf, int size)
518 {
519  if(rxfptr == rxbptr) //No data available.
520  return 0;
521 
522  int dataAvail = rxfptr - rxbptr;
523 
524  if(dataAvail < 0) //Take care of buffer wrap
525  {
526  // Limit to bytes available
527  size = Min(size, RX_BUFFER_SIZE + dataAvail);
528  int bytesToEnd = RX_BUFFER_SIZE - rxbptr;
529 
530  // Copy data
531  if(size <= bytesToEnd)
532  {
533  memcpy(buf, (const uint8_t*)&RxBuf[rxbptr], size);
534  }
535  else
536  {
537  memcpy(buf, (const uint8_t*)&RxBuf[rxbptr], bytesToEnd);
538  memcpy(&buf[bytesToEnd], (const uint8_t*)RxBuf, size - bytesToEnd);
539  }
540  }
541  else
542  {
543  // Limit to bytes available
544  size = Min(size, dataAvail);
545 
546  // Copy data
547  memcpy(buf, (const uint8_t*)&RxBuf[rxbptr], size);
548  }
549 
550  // Move pointer
551  rxbptr = (rxbptr + size) & (RX_BUFFER_SIZE - 1);
552 
553  return size;
554 }
555 
556 
557 
558 void test_spiTouINS(void)
559 {
560 #if 0
561  vTaskDelay(1000);
562  udi_cdc_write_buf("Testing\r\n", 9);
563 
564  //Clear uINS buffer
565  {
566  #define SIZE 500
567  uint8_t buf[SIZE];
568  buf[0] = 0xFF;
569  buf[1] = 0xFE;
570  for(int i=2; i<SIZE; i++)
571  buf[i] = 0;
572  spiTouINS_serWrite(buf, SIZE);
573  vTaskDelay(1000);
574  spiTouINS_serRead(buf, SIZE);
575  }
576 
577  int packet_count = 0;
578  int failure = 0;
579  int seed = 0;
580 
581  uint32_t total = 0;
582  int seconds = 0;
583 
584  while(1)
585  {
586  #define BUF_SIZE 100
587  uint8_t tx_buf[BUF_SIZE];
588  uint8_t rx_buf[BUF_SIZE];
589  char str[BUF_SIZE];
590  int tx_len, rx_len, len;
591 
592  //Make packet
593  tx_buf[0] = 0xFF; //Start
594  rx_buf[0] = 0;
595  len = 60 + rand() % 30;
596  for(tx_len = 1; tx_len < len; tx_len++)
597  {
598  tx_buf[tx_len] = tx_len + seed;
599  rx_buf[tx_len] = 0;
600  }
601  tx_buf[tx_len] = 0xFE; //End
602  rx_buf[tx_len++] = 0;
603  if(++seed >= 100)
604  seed = 0;
605  total += tx_len;
606 
607  //Send data
608  spiTouINS_serWrite(tx_buf, tx_len);
609 
610  //Wait for TX/RX (with timeout)
611  volatile uint32_t j=20000;
612  while(spiTouINS_dataReady() < tx_len)
613  {
614  if(--j == 0)
615  break;
616  }
617 
618  //Read data
619  rx_len = spiTouINS_serRead(rx_buf, BUF_SIZE);
620 
621  if(tx_len != rx_len)
622  {
623  len = sprintf(str, "len %d %d %d\r\n", tx_len, rx_len, packet_count);
624  udi_cdc_write_buf(str, len);
625  }
626 
627  bool issue = false;
628  for(int i=0;i<tx_len;i++)
629  {
630  if(rx_buf[i] != tx_buf[i])
631  {
632  len = sprintf(str, "byte %d %d ", tx_buf[i], rx_buf[i]);
633  udi_cdc_write_buf(str, len);
634  issue = true;
635  }
636  }
637  if(issue)
638  {
639  udi_cdc_write_buf("\r\n", 2);
640  failure++;
641  }
642 
643  ++packet_count;
644  /* if(packet_count % 1000 == 0)
645  {
646  len = sprintf(str, "Packets %d %d\r\n", packet_count, failure);
647  udi_cdc_write_buf(str, len);
648  }
649  */
650  if((RTC->RTC_SR & RTC_SR_SEC) == RTC_SR_SEC)
651  {
652  RTC->RTC_SCCR = RTC_SCCR_SECCLR;
653 
654  if(++seconds >= 10)
655  {
656  len = sprintf(str, "Packets %d, failures %d, rate %.01f kB/s (each direction)\r\n", packet_count, failure, (float)(total / seconds) / 1000.0);
657  udi_cdc_write_buf(str, len);
658 
659  total = 0;
660  seconds = 0;
661  }
662 
663  }
664  }
665 #endif
666 
667 #if 0
668  while(1)
669  {
670  #define BUF_SIZE 256
671  uint8_t buf[BUF_SIZE];
672  int len;
673 
674  //USB -> SPI
675  while(udi_cdc_is_rx_ready())
676  {
677  len = udi_cdc_read_no_polling(buf, BUF_SIZE);
678  spiTouINS_serWrite(buf, len);
679  }
680 
681  //SPI -> USB
682  while((len = spiTouINS_serRead(buf, BUF_SIZE)) > 0)
683  {
685  {
686  udi_cdc_write_buf(buf, len);
687  }
688  }
689 
690  vTaskDelay(1);
691  }
692 #endif
693 
694 }
static void PIO_DataReady_Handler(uint32_t id, uint32_t mask)
Definition: spiTouINS.c:147
static void spi_set_master_mode(Spi *p_spi)
Set SPI to Master mode.
#define INS_DATA_RDY_PIN_ID
Definition: user_board.h:106
void spi_set_clock_phase(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_phase)
Set Data Capture Phase.
Definition: spi.c:307
#define XDMAC_CC_DSYNC_MEM2PER
(XDMAC_CC) Memory to Peripheral transfer
static void spi_enable(Spi *p_spi)
Enable SPI.
#define MEMCPY_DCACHE_CLEAN(dst, src, size)
Definition: d_dma.h:26
#define pdMS_TO_TICKS(xTimeInMs)
Definition: projdefs.h:42
#define UNUSED(v)
Marking v as a unused parameter or value.
Definition: compiler.h:86
static void xdmac_channel_set_descriptor_control(Xdmac *xdmac, uint32_t channel_num, uint32_t config)
Set next descriptor&#39;s configuration for the relevant channel of given XDMA.
#define SPI_INS_CLK_PHASE
Definition: spiTouINS.c:31
static void ioport_set_pin_level(ioport_pin_t pin, bool level)
Set an IOPORT pin to a specified logical value.
Definition: ioport.h:275
#define SPI_XDMAC_RX_CH_NUM
Definition: spiTouINS.c:27
#define XDMAC_CC_TYPE_PER_TRAN
(XDMAC_CC) Synchronized mode (Peripheral to Memory or Memory to Peripheral Transfer).
bool udi_cdc_is_tx_ready(void)
This function checks if a new character sent is possible The type int is used to support scanf redire...
Definition: udi_cdc.c:1045
#define taskEXIT_CRITICAL()
Definition: task.h:194
__attribute__((optimize("O0")))
Definition: spiTouINS.c:224
#define sprintf
Definition: test_suite.cpp:72
static void sendMoreData(int len)
Definition: spiTouINS.c:333
#define SCB_CLEAN_DCACHE_BY_ADDR_32BYTE_ALIGNED(addr, size)
#define XDMAC_CC_SAM_FIXED_AM
(XDMAC_CC) The address remains unchanged.
#define XDMAC_CNDC_NDVIEW_NDV0
(XDMAC_CNDC) Next Descriptor View 0
#define XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED
(XDMAC_CNDC) Destination parameters are updated when the descriptor is retrieved. ...
int16_t spi_set_baudrate_div(Spi *p_spi, uint32_t ul_pcs_ch, uint8_t uc_baudrate_divider)
Set Serial Clock Baud Rate divider value (SCBR).
Definition: spi.c:385
evb_rtos_info_t g_rtos
Definition: globals.c:27
#define PIO_IT_HIGH_LEVEL
#define Min(a, b)
Takes the minimal value of a and b.
Definition: compiler.h:786
#define XDMAC
(XDMAC ) Base Address
Definition: same70j19.h:520
static void spi_enable_interrupt(Spi *p_spi, uint32_t ul_sources)
Enable SPI interrupts.
#define DMA_LLD_MASK
static void xdmac_channel_software_flush_request(Xdmac *xdmac, uint32_t channel_num)
Set software flush request on the relevant channel.
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
Set Interrupt Priority.
Definition: core_cm7.h:1766
#define SPI_DLYBS
Definition: spiTouINS.c:34
static void xdmac_channel_set_descriptor_addr(Xdmac *xdmac, uint32_t channel_num, uint32_t desc_addr, uint8_t ndaif)
Set next descriptor&#39;s address & interface for the relevant channel of given XDMA. ...
rtos_task_t task[UINS_RTOS_NUM_TASKS]
Definition: data_sets.h:3457
#define NULL
Definition: nm_bsp.h:52
#define SPI_INS_CHIP_SEL
Definition: spiTouINS.c:23
void spi_set_bits_per_transfer(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_bits)
Set number of bits per transfer.
Definition: spi.c:345
#define spi_get_pcs(chip_sel_id)
Generate Peripheral Chip Select Value from Chip Select ID.
#define XDMAC_UBC_NDE_FETCH_EN
void spi_set_clock_polarity(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_polarity)
Set clock default state.
Definition: spi.c:290
#define XDMAC_CC_MEMSET_NORMAL_MODE
(XDMAC_CC) Memset is not activated
static void spi_disable_interrupt(Spi *p_spi, uint32_t ul_sources)
Disable SPI interrupts.
#define SPI_spiTouINS_Handler
Definition: spiTouINS.c:24
#define XDMAC_UBC_UBLEN(value)
static uint32_t xdmac_channel_get_interrupt_status(Xdmac *xdmac, uint32_t channel_num)
Get interrupt status for the relevant channel of given XDMA.
#define xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken)
Definition: task.h:1858
#define SPI_IMR_TDRE
(SPI_IMR) SPI Transmit Data Register Empty Interrupt Mask
#define XDMAC_CC_DAM_FIXED_AM
(XDMAC_CC) The address remains unchanged.
#define TASK_SPI_TO_UINS_PRIORITY
uint32_t handle
Definition: data_sets.h:3441
static bool ioport_get_pin_level(ioport_pin_t pin)
Get current value of an IOPORT pin, which has been configured as an input.
Definition: ioport.h:301
static void xdmac_channel_set_source_addr(Xdmac *xdmac, uint32_t channel_num, uint32_t src_addr)
Set source address for the relevant channel of given XDMA.
iram_size_t udi_cdc_write_buf(const void *buf, iram_size_t size)
Writes a RAM buffer on CDC line.
Definition: udi_cdc.c:1146
static uint32_t xdmac_channel_get_interrupt_mask(Xdmac *xdmac, uint32_t channel_num)
Get interrupt mask for the relevant channel of given XDMA.
#define XDMAC_CIE_BIE
(XDMAC_CIE) End of Block Interrupt Enable Bit
#define SPI_IRQn
Definition: spiTouINS.c:25
#define XDMAC_CC_DAM_INCREMENTED_AM
(XDMAC_CC) The addressing mode is incremented (the increment size is set to the data size)...
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
Disable External Interrupt.
Definition: core_cm7.h:1696
#define XDMAC_CC_SIF_AHB_IF1
(XDMAC_CC) The data is read through the system bus interface 1
static void spi_reset(Spi *p_spi)
Reset SPI and set it to Slave mode.
static void spiTouINS_task(void *pvParameters)
Definition: spiTouINS.c:161
void test_spiTouINS(void)
Definition: spiTouINS.c:558
#define XDMAC_CNDC_NDE_DSCR_FETCH_EN
(XDMAC_CNDC) Descriptor fetch is enabled
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
#define INS_DATA_RDY_PIN_IDX
Definition: user_board.h:104
#define TASK_SPI_TO_UINS_PERIOD_MS
static uint32_t sysclk_get_peripheral_hz(void)
Retrieves the current rate in Hz of the peripheral clocks.
int spiTouINS_serWrite(const unsigned char *buf, int size)
Definition: spiTouINS.c:393
#define TX_BUFFER_SIZE
Definition: spiTouINS.c:39
static void xdmac_channel_set_microblock_control(Xdmac *xdmac, uint32_t channel_num, uint32_t ublen)
Set microblock length for the relevant channel of given XDMA.
#define RX_BUFFER_SIZE
Definition: spiTouINS.c:40
#define TASK_SPI_TO_UINS_STACK_SIZE
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
Definition: core_cm7.h:1683
void spi_enable_clock(Spi *p_spi)
Enable SPI clock.
Definition: spi.c:60
bool udi_cdc_is_rx_ready(void)
This function checks if a character has been received on the CDC line.
Definition: udi_cdc.c:857
iram_size_t udi_cdc_read_no_polling(void *buf, iram_size_t size)
Non polling reads of a up to &#39;size&#39; data from CDC line.
Definition: udi_cdc.c:996
#define SPI_INS_BASE
Definition: spiTouINS.c:22
#define READ_ADDITIONAL_SIZE
Definition: spiTouINS.c:44
Definition: task.h:85
#define INS_DATA_RDY_PIN_PIO
Definition: user_board.h:107
void XDMAC_spiTouINS_Handler(void)
void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask)
Enable the given interrupt source. The PIO must be configured as an NVIC interrupt source as well...
Definition: pio.c:578
static void xdmac_channel_disable_interrupt(Xdmac *xdmac, uint32_t channel_num, uint32_t mask)
Disable interrupt with mask on the relevant channel of given XDMA.
static void xdmac_enable_interrupt(Xdmac *xdmac, uint32_t channel_num)
Enables XDMAC global interrupt.
void spiTouINS_init(void)
#define portYIELD_FROM_ISR(x)
Definition: portmacro.h:94
void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask)
Disable a given interrupt source, with no added side effects.
Definition: pio.c:589
#define SPI_CSR_BITS_8_BIT
(SPI_CSR[4]) 8 bits for transfer
#define XDMAC_UBC_NDEN_UPDATED
#define SPI_INS_BAUDRATE
Definition: spiTouINS.c:19
static void xdmac_channel_enable_interrupt(Xdmac *xdmac, uint32_t channel_num, uint32_t mask)
Enable interrupt with mask on the relevant channel of given XDMA.
#define SPI_INS_CS_PIN
Definition: user_board.h:99
long BaseType_t
Definition: portmacro.h:57
void xdmac_configure_transfer(Xdmac *xdmac, uint32_t channel_num, xdmac_channel_config_t *cfg)
Configure DMA for a transfer.
Definition: xdmac.c:46
#define XDMAC_CC_DIF_AHB_IF1
(XDMAC_CC) The data is written though the system bus interface 1
bool g_usb_cdc_open
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
Clear Pending Interrupt.
Definition: core_cm7.h:1736
void * TaskHandle_t
Definition: task.h:62
#define XDMAC_CC_CSIZE_CHK_1
(XDMAC_CC) 1 data transferred
static uint32_t getTxFree(void)
Definition: spiTouINS.c:380
static void spi_disable_mode_fault_detect(Spi *p_spi)
Disable Mode Fault Detection.
void spi_set_peripheral_chip_select_value(Spi *p_spi, uint32_t ul_value)
Set Peripheral Chip Select (PCS) value.
Definition: spi.c:193
#define XDMAC_CC_DSYNC_PER2MEM
(XDMAC_CC) Peripheral to Memory transfer
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
uint32_t pio_get_interrupt_status(const Pio *p_pio)
Read and clear PIO interrupt status.
Definition: pio.c:601
Structure for storing parameters for DMA view0 that can be performed by the DMA Master transfer...
static void spi_write_single(Spi *p_spi, uint8_t data)
Write one byte to an SPI device.
#define pdFALSE
Definition: projdefs.h:45
#define SPI_XDMAC_TX_CH_NUM
Definition: spiTouINS.c:26
#define taskENTER_CRITICAL()
Definition: task.h:179
void pio_handler_set_priority(Pio *p_pio, IRQn_Type ul_irqn, uint32_t ul_priority)
Initialize PIO interrupt management logic.
Definition: pio_handler.c:274
enum IRQn IRQn_Type
#define RX_INT_BUFFER_SIZE
Definition: spiTouINS.c:41
#define XDMAC_CIS_BIS
(XDMAC_CIS) End of Block Interrupt Status Bit
#define SPI_DLYBCT
Definition: spiTouINS.c:37
void spi_set_transfer_delay(Spi *p_spi, uint32_t ul_pcs_ch, uint8_t uc_dlybs, uint8_t uc_dlybct)
Configure timing for SPI transfer.
Definition: spi.c:405
#define RTC_SCCR_SECCLR
(RTC_SCCR) Second Clear
#define XDMAC_CC_SAM_INCREMENTED_AM
(XDMAC_CC) The addressing mode is incremented (the increment size is set to the data size)...
int spiTouINS_dataReady(void)
Definition: spiTouINS.c:508
void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION
COMPILER_ALIGNED(32)
Definition: spiTouINS.c:46
#define PIO_DEBOUNCE
Autogenerated API include file for the Atmel Software Framework (ASF)
static void spi_disable(Spi *p_spi)
Disable SPI.
#define RTC_SR_SEC
(RTC_SR) Second Event
#define XDMAC_GS_ST0
(XDMAC_GS) XDMAC Channel 0 Status Bit
int spiTouINS_serRead(unsigned char *buf, int size)
Definition: spiTouINS.c:517
#define SPI_INS_CLK_POLARITY
Definition: spiTouINS.c:30
#define XDMAC_GE_EN0
(XDMAC_GE) XDMAC Channel 0 Enable Bit
#define SPI_SR_TXEMPTY
(SPI_SR) Transmission Registers Empty (cleared by writing SPI_TDR)
#define XDMAC_UBC_NVIEW_NDV0
#define XDMAC_CC_MBSIZE_SINGLE
(XDMAC_CC) The memory burst size is set to one.
#define RTC
(RTC ) Base Address
Definition: same70j19.h:536
#define INS_DATA_RDY_PIN_MASK
Definition: user_board.h:105
#define DMA_LLD_COUNT
int createTask(int index, pdTASK_CODE pxTaskCode, const char *const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, portTickType xTimeIncrement)
Definition: rtos.c:30
#define XDMAC_CC_DWIDTH_BYTE
(XDMAC_CC) The data size is set to 8 bits
#define SPI_IER_TDRE
(SPI_IER) SPI Transmit Data Register Empty Interrupt Enable
#define BUF_SIZE
static void spi_set_lastxfer(Spi *p_spi)
Issue a LASTXFER command. The next transfer is the last transfer and after that CS is de-asserted...
uint32_t pio_handler_set(Pio *p_pio, uint32_t ul_id, uint32_t ul_mask, uint32_t ul_attr, void(*p_handler)(uint32_t, uint32_t))
Set an interrupt handler for the provided pins. The provided handler will be called with the triggeri...
Definition: pio_handler.c:132
#define READ_SIZE
Definition: spiTouINS.c:43


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:58