Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
spi_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2012 The Paparazzi Team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
33 #include "mcu_periph/spi.h"
34 
35 #include "std.h"
36 #include "LPC21xx.h"
37 #include "armVIC.h"
38 #include BOARD_CONFIG
39 
43 #define SPI_SELECT_SLAVE_IO__(port, reg) IO ## port ## reg
45 #define SPI_SELECT_SLAVE_IO_(port, reg) SPI_SELECT_SLAVE_IO__(port, reg)
46 
47 #define SPI_SELECT_SLAVE0_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, DIR)
48 #define SPI_SELECT_SLAVE0_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, CLR)
49 #define SPI_SELECT_SLAVE0_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, SET)
50 
51 #define SPI_SELECT_SLAVE1_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, DIR)
52 #define SPI_SELECT_SLAVE1_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, CLR)
53 #define SPI_SELECT_SLAVE1_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, SET)
54 
55 __attribute__((always_inline)) static inline void SpiSlaveSelect(uint8_t slave)
56 {
57  switch (slave) {
58 #if USE_SPI_SLAVE0
59  case SPI_SLAVE0:
61  break;
62 #endif
63 #if USE_SPI_SLAVE1
64  case SPI_SLAVE1:
66  break;
67 #endif
68  default:
69  break;
70  }
71 }
72 
73 __attribute__((always_inline)) static inline void SpiSlaveUnselect(uint8_t slave)
74 {
75  switch (slave) {
76 #if USE_SPI_SLAVE0
77  case SPI_SLAVE0:
79  break;
80 #endif
81 #if USE_SPI_SLAVE1
82  case SPI_SLAVE1:
84  break;
85 #endif
86  default:
87  break;
88  }
89 }
91 
95 __attribute__((always_inline)) static inline void SpiSetCPOL(struct spi_periph *p)
97 {
98  SetBit(((sspRegs_t *)(p->reg_addr))->cr0, CPOL);
99 }
100 
101 __attribute__((always_inline)) static inline void SpiClearCPOL(struct spi_periph *p)
102 {
103  ClearBit(((sspRegs_t *)(p->reg_addr))->cr0, CPOL);
104 }
105 
106 __attribute__((always_inline)) static inline void SpiSetCPHA(struct spi_periph *p)
107 {
108  SetBit(((sspRegs_t *)(p->reg_addr))->cr0, CPHA);
109 }
110 
111 __attribute__((always_inline)) static inline void SpiClearCPHA(struct spi_periph *p)
112 {
113  ClearBit(((sspRegs_t *)(p->reg_addr))->cr0, CPHA);
114 }
116 
117 
123 __attribute__((always_inline)) static inline void SpiSetDataSize(struct spi_periph *p, enum SPIDataSizeSelect dss)
124 {
125  switch (dss) {
126  default:
127  case SPIDss8bit:
128  ((sspRegs_t *)(p->reg_addr))->cr0 = (((sspRegs_t *)(p->reg_addr))->cr0 & ~(0xF << DSS)) | (DSS_VAL8 << DSS);
129  break;
130  case SPIDss16bit:
131  ((sspRegs_t *)(p->reg_addr))->cr0 = (((sspRegs_t *)(p->reg_addr))->cr0 & ~(0xF << DSS)) | (DSS_VAL16 << DSS);
132  break;
133  }
134 }
135 
136 
140 __attribute__((always_inline)) static inline void SpiEnable(struct spi_periph *p)
142 {
143  SetBit(((sspRegs_t *)(p->reg_addr))->cr1, SSE);
144 }
145 
146 __attribute__((always_inline)) static inline void SpiDisable(struct spi_periph *p)
147 {
148  ClearBit(((sspRegs_t *)(p->reg_addr))->cr1, SSE);
149 }
150 
151 __attribute__((always_inline)) static inline void SpiEnableRti(struct spi_periph *p)
152 {
153  SetBit(((sspRegs_t *)(p->reg_addr))->imsc, RTIM);
154 }
155 
156 __attribute__((always_inline)) static inline void SpiDisableRti(struct spi_periph *p)
157 {
158  ClearBit(((sspRegs_t *)(p->reg_addr))->imsc, RTIM);
159 }
160 
161 __attribute__((always_inline)) static inline void SpiClearRti(struct spi_periph *p)
162 {
163  SetBit(((sspRegs_t *)(p->reg_addr))->icr, RTIC);
164 }
165 
166 __attribute__((always_inline)) static inline void SpiEnableTxi(struct spi_periph *p)
167 {
168  SetBit(((sspRegs_t *)(p->reg_addr))->imsc, TXIM);
169 }
170 
171 __attribute__((always_inline)) static inline void SpiDisableTxi(struct spi_periph *p)
172 {
173  ClearBit(((sspRegs_t *)(p->reg_addr))->imsc, TXIM);
174 }
175 
176 __attribute__((always_inline)) static inline void SpiEnableRxi(struct spi_periph *p)
177 {
178  SetBit(((sspRegs_t *)(p->reg_addr))->imsc, RXIM);
179 }
180 
181 __attribute__((always_inline)) static inline void SpiDisableRxi(struct spi_periph *p)
182 {
183  ClearBit(((sspRegs_t *)(p->reg_addr))->imsc, RXIM);
184 }
185 
186 __attribute__((always_inline)) static inline void SpiSend(struct spi_periph *p, uint16_t c)
187 {
188  ((sspRegs_t *)(p->reg_addr))->dr = c;
189 }
190 
191 __attribute__((always_inline)) static inline void SpiRead(struct spi_periph *p, uint16_t *c)
192 {
193  *c = ((sspRegs_t *)(p->reg_addr))->dr;
194 }
195 
196 
197 __attribute__((always_inline)) static inline void SpiTransmit(struct spi_periph *p, struct spi_transaction *t)
198 {
199  // when all byte are sent, continue until tx_idx reach input_length
200  // needed when input_length is bigger than output_length
201  uint16_t max_idx = Max(t->output_length, t->input_length);
202  while (p->tx_idx_buf < max_idx && bit_is_set(((sspRegs_t *)(p->reg_addr))->sr, TNF)) {
203  if (p->tx_idx_buf < t->output_length) {
204  if (t->dss == SPIDss8bit) {
205  SpiSend(p, t->output_buf[p->tx_idx_buf]);
206  } else if (t->dss == SPIDss16bit) {
207  uint16_t tmp1 = t->output_buf[2 * p->tx_idx_buf]; // LSB
208  uint16_t tmp2 = t->output_buf[2 * p->tx_idx_buf + 1] << 8; // MSB
209  SpiSend(p, tmp1 | tmp2);
210  }
211  } else {
212  SpiSend(p, 0);
213  }
214  p->tx_idx_buf++;
215  }
216  if (p->tx_idx_buf == max_idx) {
217  SpiDisableTxi(p);
218  }
219 }
220 
221 __attribute__((always_inline)) static inline void SpiReceive(struct spi_periph *p, struct spi_transaction *t)
222 {
223  while (bit_is_set(((sspRegs_t *)(p->reg_addr))->sr, RNE)) {
224  if (p->rx_idx_buf < t->input_length) {
225  uint16_t r;
226  SpiRead(p, &r);
227  if (t->dss == SPIDss8bit) {
228  t->input_buf[p->rx_idx_buf] = (uint8_t)r;
229  } else if (t->dss == SPIDss16bit) {
230  t->input_buf[2 * p->rx_idx_buf] = (uint8_t)r;
231  t->input_buf[2 * p->rx_idx_buf + 1] = (uint8_t)(r >> 8);
232  }
233  p->rx_idx_buf++;
234  } else {
235  uint16_t foo;
236  SpiRead(p, &foo);
237  }
238  }
239 }
240 
241 __attribute__((always_inline)) static inline void SpiInitBuf(struct spi_periph *p, struct spi_transaction *t)
242 {
243  p->rx_idx_buf = 0;
244  p->tx_idx_buf = 0;
245  SpiTransmit(p, t); // fill fifo
246 }
247 
248 
249 __attribute__((always_inline)) static inline void SpiStart(struct spi_periph *p, struct spi_transaction *t)
250 {
251  p->status = SPIRunning;
252  t->status = SPITransRunning;
253 
254  // handle spi options (CPOL, CPHA, data size,...)
255  if (t->cpol == SPICpolIdleHigh) { SpiSetCPOL(p); }
256  else { SpiClearCPOL(p); }
257 
258  if (t->cpha == SPICphaEdge2) { SpiSetCPHA(p); }
259  else { SpiClearCPHA(p); }
260 
261  SpiSetDataSize(p, t->dss);
262 
263  // handle slave select
264  if (t->select == SPISelectUnselect || t->select == SPISelect) {
265  SpiSlaveSelect(t->slave_idx);
266  }
267 
268  // callback function before transaction
269  if (t->before_cb != 0) { t->before_cb(t); }
270 
271  // start spi transaction
272  SpiEnable(p);
273  SpiInitBuf(p, t);
274  SpiEnableTxi(p); // enable tx fifo half empty interrupt
275  SpiEnableRti(p); // enable rx timeout interrupt
276 }
277 
278 __attribute__((always_inline)) static inline void SpiEndOfTransaction(struct spi_periph *p, struct spi_transaction *t)
279 {
280  // callback function after transaction
281  if (t->after_cb != 0) { t->after_cb(t); }
282 
283  // handle slave unselect
284  if (t->select == SPISelectUnselect || t->select == SPIUnselect) {
285  SpiSlaveUnselect(t->slave_idx);
286  }
287 
288  SpiDisable(p);
289  // end transaction with success
290  t->status = SPITransSuccess;
291 
292  // handle transaction fifo here
293  p->trans_extract_idx++;
294  if (p->trans_extract_idx >= SPI_TRANSACTION_QUEUE_LEN) {
295  p->trans_extract_idx = 0;
296  }
297  // if no more transaction to process or locked, stop here, else start next transaction
298  if (p->trans_extract_idx == p->trans_insert_idx || p->suspend) {
299  p->status = SPIIdle;
300  } else {
301  SpiStart(p, p->trans[p->trans_extract_idx]);
302  }
303 
304 }
305 
306 __attribute__((always_inline)) static inline void SpiAutomaton(struct spi_periph *p)
307 {
308  struct spi_transaction *trans = p->trans[p->trans_extract_idx];
309 
310  /* Tx fifo is half empty */
311  if (bit_is_set(((sspRegs_t *)(p->reg_addr))->mis, TXMIS)) {
312  SpiTransmit(p, trans);
313  SpiReceive(p, trans);
314  // tx_idx can be greater than output_length (when input_length > output_length)
315  if (p->tx_idx_buf >= trans->output_length && p->rx_idx_buf == trans->input_length) {
316  if (bit_is_set(((sspRegs_t *)(p->reg_addr))->sr, BSY)) {
317  SpiEnableTxi(p); // FIXME in case Rti is not called
318  } else {
319  SpiDisableRti(p);
320  SpiClearRti(p); /* clear interrupt */
321  SpiEndOfTransaction(p, trans);
322  }
323  }
324  }
325 
326  /* Rx fifo is not empty and no receive took place in the last 32 bits period */
327  if (bit_is_set(((sspRegs_t *)(p->reg_addr))->mis, RTMIS)) {
328  SpiReceive(p, trans);
329  SpiDisableRti(p);
330  SpiClearRti(p); /* clear interrupt */
331  SpiEndOfTransaction(p, trans);
332  }
333 }
334 
335 __attribute__((always_inline)) static inline void SpiSlaveStart(struct spi_periph *p, struct spi_transaction *t)
336 {
337  p->status = SPIRunning;
338  t->status = SPITransRunning;
339 
340  // callback function before transaction
341  if (t->before_cb != 0) { t->before_cb(t); }
342 
343  // start spi transaction
344  SpiEnable(p);
345  SpiInitBuf(p, t);
346  SpiEnableTxi(p); // enable tx fifo half empty interrupt
347  //SpiEnableRti(p); // enable rx timeout interrupt
348 }
349 
350 __attribute__((always_inline)) static inline void SpiSlaveAutomaton(struct spi_periph *p)
351 {
352  struct spi_transaction *trans = p->trans[p->trans_extract_idx];
353 
354  /* Tx fifo is half empty */
355  if (bit_is_set(((sspRegs_t *)(p->reg_addr))->mis, TXMIS)) {
356  SpiTransmit(p, trans);
357  SpiReceive(p, trans);
358  SpiEnableRti(p);
359  }
360 
361  /* Rx fifo is not empty and no receive took place in the last 32 bits period */
362  if (bit_is_set(((sspRegs_t *)(p->reg_addr))->mis, RTMIS)) {
363  SpiReceive(p, trans);
364  SpiClearRti(p); /* clear interrupt */
365  SpiDisableRti(p);
366 
367  // callback function after transaction
368  if (trans->after_cb != 0) { trans->after_cb(trans); }
369 
370  SpiDisable(p);
371  // end transaction with success
372  trans->status = SPITransSuccess;
373  p->status = SPIIdle;
374  }
375 
376 }
378 
379 /* SSP (SPI1) pins (UM10120_1.pdf page 76)
380  P0.17 SCK PINSEL1 2 << 2
381  P0.18 MISO PINSEL1 2 << 4
382  P0.19 MOSI PINSEL1 2 << 6
383  P0.20 SS PINSEL1 2 << 8
384 */
385 #define SSP_PINSEL1_SCK (2 << 2)
386 #define SSP_PINSEL1_MISO (2 << 4)
387 #define SSP_PINSEL1_MOSI (2 << 6)
388 #define SSP_PINSEL1_SSEL (2 << 8)
389 
391 #ifndef SPI1_VIC_SLOT
392 #define SPI1_VIC_SLOT 7
393 #endif
394 
395 /*
396  *
397  * SPI Master code
398  *
399  *
400  */
401 
402 #if SPI_MASTER
403 
404 #if USE_SPI0
405 #error "SPI0 is currently not implemented in the mcu_periph/spi HAL for the LPC!"
406 
407 // void spi0_ISR(void) __attribute__((naked));
408 //
409 // void spi0_ISR(void) {
410 // ISR_ENTRY();
411 // VICVectAddr = 0x00000000;
412 // ISR_EXIT();
413 // }
414 
416 
417 void spi0_arch_init(void)
418 {
419 
420  spi0.reg_addr = SPI0;
421  spi0_vic_slot = VIC_SPI0;
422  spi0.init_struct = (void *)(&spi0_vic_slot);
423 
424  // TODO set spi0 and interrupt vector
425 }
426 
427 #endif
428 
429 
430 #if USE_SPI1
431 
432 /* SSPCR0 settings */
433 #define MASTER_SSP_DSS 0x07 << 0
434 #define MASTER_SSP_FRF 0x00 << 4
435 #define MASTER_SSP_CPOL 0x00 << 6
436 #define MASTER_SSP_CPHA 0x00 << 7
437 #define MASTER_SSP_SCR 0x0F << 8
438 
439 /* SSPCR1 settings */
440 #define MASTER_SSP_LBM 0x00 << 0
441 #define MASTER_SSP_SSE 0x00 << 1
442 #define MASTER_SSP_MS 0x00 << 2
443 #define MASTER_SSP_SOD 0x00 << 3
444 
445 
449 #ifndef SSPCPSR_VAL
450 #define SSPCPSR_VAL 0x02 /* clock prescale */
451 #endif
452 
453 void spi1_ISR(void) __attribute__((naked));
454 
455 void spi1_ISR(void)
456 {
457  ISR_ENTRY();
458 
459  SpiAutomaton(&spi1);
460 
461  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
462  ISR_EXIT();
463 }
464 
466 
467 void spi1_arch_init(void)
468 {
469 
470  spi1.reg_addr = SPI1;
471  spi1_vic_slot = VIC_SPI1;
472  spi1.init_struct = (void *)(&spi1_vic_slot);
473 
474  /* setup pins for SSP (SCK, MISO, MOSI) */
476 
477  /* setup SSP */
480  SSPCPSR = SSPCPSR_VAL; /* Prescaler */
481 
482  /* initialize interrupt vector */
483  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
484  VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
486  _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)spi1_ISR; /* address of the ISR */
487 
488 }
489 
490 #endif
491 
492 
493 bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
494 {
495  //unsigned cpsr;
496 
497  uint8_t idx;
498  idx = p->trans_insert_idx + 1;
499  if (idx >= SPI_TRANSACTION_QUEUE_LEN) { idx = 0; }
500  if (idx == p->trans_extract_idx) {
501  t->status = SPITransFailed;
502  return false; /* queue full */
503  }
504  t->status = SPITransPending;
505 
506  // Disable interrupts
507  //uint8_t* vic = (uint8_t*)(p->init_struct);
508  //cpsr = disableIRQ(); // disable global interrupts
509  //VICIntEnClear = VIC_BIT(*vic);
510  //restoreIRQ(cpsr); // restore global interrupts
511  disableIRQ();
512 
513  p->trans[p->trans_insert_idx] = t;
514  p->trans_insert_idx = idx;
515  /* if peripheral is idle and not locked, start the transaction */
516  if (p->status == SPIIdle && !p->suspend) {
517  SpiStart(p, p->trans[p->trans_extract_idx]);
518  }
519 
520  //cpsr = disableIRQ(); // disable global interrupts
521  //VICIntEnable = VIC_BIT(*vic);
522  //restoreIRQ(cpsr); // restore global interrupts
523  enableIRQ();
524  return true;
525 }
526 
527 
528 void spi_init_slaves(void)
529 {
530 #if USE_SPI_SLAVE0
531  /* setup slave0_select pin
532  * slave0_select is output
533  */
537 #endif
538 
539 #if USE_SPI_SLAVE1
540  /* setup slave1_select pin
541  * slave1_select is output
542  */
546 #endif
547 
548 #if USE_SPI_SLAVE2
549 #error SPI_SLAVE2 is not implemented yet, sorry
550 #endif
551 }
552 
554 {
555  SpiSlaveSelect(slave);
556 }
557 
559 {
560  SpiSlaveUnselect(slave);
561 }
562 
563 bool spi_lock(struct spi_periph *p, uint8_t slave)
564 {
565  uint8_t *vic = (uint8_t *)(p->init_struct);
566  VICIntEnClear = VIC_BIT(*vic);
567  if (slave < 254 && p->suspend == 0) {
568  p->suspend = slave + 1; // 0 is reserved for unlock state
569  VICIntEnable = VIC_BIT(*vic);
570  return true;
571  }
572  VICIntEnable = VIC_BIT(*vic);
573  return false;
574 }
575 
576 bool spi_resume(struct spi_periph *p, uint8_t slave)
577 {
578  uint8_t *vic = (uint8_t *)(p->init_struct);
579  VICIntEnClear = VIC_BIT(*vic);
580  if (p->suspend == slave + 1) {
581  // restart fifo
582  p->suspend = 0;
583  if (p->trans_extract_idx != p->trans_insert_idx && p->status == SPIIdle) {
584  SpiStart(p, p->trans[p->trans_extract_idx]);
585  }
586  VICIntEnable = VIC_BIT(*vic);
587  return true;
588  }
589  VICIntEnable = VIC_BIT(*vic);
590  return false;
591 }
592 
593 #endif /* SPI_MASTER */
594 
595 
596 /*
597  *
598  * SPI Slave code
599  *
600  * FIXME it is probably not working at all right now
601  *
602  */
603 #if SPI_SLAVE
604 
605 /* set SSP input clock, PCLK / CPSDVSR = 468.75kHz */
606 
607 #if (PCLK == 15000000)
608 #define CPSDVSR 32
609 #else
610 
611 #if (PCLK == 30000000)
612 #define CPSDVSR 64
613 #else
614 
615 #if (PCLK == 60000000)
616 #define CPSDVSR 128
617 #else
618 
619 #error unknown PCLK frequency
620 #endif
621 #endif
622 #endif
623 
624 #if USE_SPI0_SLAVE
625 #error SPI0 in slave mode is not implemented yet, sorry
626 #endif
627 
628 #if USE_SPI1_SLAVE
629 
630 /* SSPCR0 settings */
631 #define SLAVE_SSP_DSS 0x07 << 0 /* data size : 8 bits */
632 #define SLAVE_SSP_FRF 0x00 << 4 /* frame format : SPI */
633 #define SLAVE_SSP_CPOL 0x00 << 6 /* clock polarity : idle low */
634 #define SLAVE_SSP_CPHA 0x01 << 7 /* clock phase : 1 */
635 #define SLAVE_SSP_SCR 0x0F << 8 /* serial clock rate : 29.3kHz, SSP input clock / 16 */
636 
637 /* SSPCR1 settings */
638 #define SLAVE_SSP_LBM 0x00 << 0 /* loopback mode : disabled */
639 #define SLAVE_SSP_SSE 0x00 << 1 /* SSP enable : disabled */
640 #define SLAVE_SSP_MS 0x01 << 2 /* master slave mode : slave */
641 #define SLAVE_SSP_SOD 0x00 << 3 /* slave output disable : disabled */
642 
643 void spi1_slave_ISR(void) __attribute__((naked));
644 
645 void spi1_slave_ISR(void)
646 {
647  ISR_ENTRY();
648 
650 
651  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
652  ISR_EXIT();
653 }
654 
655 void spi1_slave_arch_init(void)
656 {
657 
658  spi1.reg_addr = SPI1;
659 
660  /* setup pins for SSP (SCK, MISO, MOSI, SS) */
662 
663  /* setup SSP */
664  SSPCR0 = SLAVE_SSP_DSS | SLAVE_SSP_FRF | SLAVE_SSP_CPOL | SLAVE_SSP_CPHA | SLAVE_SSP_SCR;
665  SSPCR1 = SLAVE_SSP_LBM | SLAVE_SSP_MS | SLAVE_SSP_SOD;
666  SSPCPSR = CPSDVSR; /* Prescaler, UM10120_1.pdf page 167 */
667 
668  /* initialize interrupt vector */
669  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
670  VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
672  _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)spi1_slave_ISR; /* address of the ISR */
673 
674 }
675 
676 #endif
677 
680 {
681 
682  if (p->trans_insert_idx >= 1) {
683  t->status = SPITransFailed;
684  return false;
685  }
686  t->status = SPITransPending;
687  p->status = SPIIdle;
688  p->trans[p->trans_insert_idx] = t; // No need to disable interrupts, only one transaction
689  p->trans_insert_idx = 1;
690 
691  // handle spi options (CPOL, CPHA, data size,...)
692  if (t->cpol == SPICpolIdleHigh) { SpiSetCPOL(p); }
693  else { SpiClearCPOL(p); }
694 
695  if (t->cpha == SPICphaEdge2) { SpiSetCPHA(p); }
696  else { SpiClearCPHA(p); }
697 
698  SpiSetDataSize(p, t->dss);
699 
700  return true;
701 }
702 
703 bool spi_slave_wait(struct spi_periph *p)
704 {
705  if (p->trans_insert_idx == 0) {
706  // no transaction registered
707  return false;
708  }
709  // Start waiting
711  return true;
712 }
713 
714 #endif /* SPI_SLAVE */
#define VICIntSelect
Definition: LPC21xx.h:430
unsigned short uint16_t
Definition: types.h:16
#define SSP_PINSEL1_MOSI
Definition: spi_arch.c:387
static void SpiDisable(struct spi_periph *p)
Definition: spi_arch.c:146
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
bool spi_slave_register(struct spi_periph *p, struct spi_transaction *t)
Register one (and only one) transaction to use spi as slave.
Definition: spi_arch.c:679
uint8_t spi1_vic_slot
Definition: spi_arch.c:465
#define TXIM
Definition: LPC21xx.h:274
static uint32_t idx
static void SpiInitBuf(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:241
#define SPI_SELECT_SLAVE1_PINSEL
Definition: booz_1.0.h:127
static void SpiRead(struct spi_periph *p, uint16_t *c)
Definition: spi_arch.c:191
uint16_t output_length
number of data words to write
Definition: spi.h:146
SPIDataSizeSelect
SPI data word size of transfer.
Definition: spi.h:83
static void SpiDisableRxi(struct spi_periph *p)
Definition: spi_arch.c:181
slave is selected before transaction but not unselected
Definition: spi.h:58
void * reg_addr
Definition: spi.h:177
static void SpiAutomaton(struct spi_periph *p)
Definition: spi_arch.c:306
void spi1_arch_init(void)
Architecture dependent SPI1 initialization.
Definition: spi_arch.c:352
slave is not selected but unselected after transaction
Definition: spi.h:59
static void SpiClearCPHA(struct spi_periph *p)
Definition: spi_arch.c:111
#define MASTER_SSP_FRF
frame format : SPI
Definition: spi_arch.c:434
CPHA = 1.
Definition: spi.h:69
#define SPI_SLAVE1
Definition: spi.h:187
static void SpiStart(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:249
static void SpiClearRti(struct spi_periph *p)
Definition: spi_arch.c:161
#define CPOL
Definition: LPC21xx.h:245
#define SSPCPSR
Definition: LPC21xx.h:226
#define _VIC_CNTL(idx)
Definition: armVIC.h:19
static void SpiSetCPHA(struct spi_periph *p)
Definition: spi_arch.c:106
static void SpiSlaveSelect(uint8_t slave)
Definition: spi_arch.c:55
static void SpiSetDataSize(struct spi_periph *p, enum SPIDataSizeSelect dss)
Set the SPI data size to 8 or 16bit.
Definition: spi_arch.c:123
#define RXIM
Definition: LPC21xx.h:273
SPI transaction structure.
Definition: spi.h:142
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:458
#define RTMIS
Definition: LPC21xx.h:285
#define SSPCPSR_VAL
Clock prescaler.
Definition: spi_arch.c:450
static void SpiReceive(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:221
CPOL = 1.
Definition: spi.h:78
#define TXMIS
Definition: LPC21xx.h:287
#define MASTER_SSP_SCR
serial clock rate : divide by 16
Definition: spi_arch.c:437
static void SpiEnableTxi(struct spi_periph *p)
Definition: spi_arch.c:166
static void SpiClearCPOL(struct spi_periph *p)
Definition: spi_arch.c:101
void * init_struct
Definition: spi.h:178
#define SSPCR0
Definition: LPC21xx.h:222
volatile uint8_t suspend
control for stop/resume of the fifo
Definition: spi.h:181
static void SpiTransmit(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:197
#define SPI_SELECT_SLAVE0_IODIR
Definition: spi_arch.c:47
static void SpiEnableRti(struct spi_periph *p)
Definition: spi_arch.c:151
#define _VIC_ADDR(idx)
Definition: armVIC.h:20
#define MASTER_SSP_CPOL
clock polarity : SCK idles low
Definition: spi_arch.c:435
#define SPI_SLAVE0
Definition: spi.h:186
#define MASTER_SSP_CPHA
clock phase : data captured on first clock transition
Definition: spi_arch.c:436
Architecture independent SPI (Serial Peripheral Interface) API.
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
#define SPI_SELECT_SLAVE0_PINSEL_BIT
Definition: booz_1.0.h:122
#define VIC_SPI0
Definition: lpcVIC.h:80
#define DSS
Definition: LPC21xx.h:243
bool spi_lock(struct spi_periph *p, uint8_t slave)
spi_lock() function
Definition: spi_arch.c:576
SPI peripheral structure.
Definition: spi.h:168
Definition: spi.h:84
#define SPI_SELECT_SLAVE0_PIN
Definition: board.h:989
#define SSP_PINSEL1_SSEL
Definition: spi_arch.c:388
unsigned enableIRQ(void)
Definition: armVIC.c:51
void spi_slave_unselect(uint8_t slave)
spi_slave_unselect() function
Definition: spi_arch.c:533
#define SPI_SELECT_SLAVE1_IOCLR
Definition: spi_arch.c:52
static void SpiEnable(struct spi_periph *p)
Definition: spi_arch.c:141
struct spi_periph spi0
Definition: spi.c:35
#define SPI_SELECT_SLAVE1_PINSEL_BIT
Definition: booz_1.0.h:128
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155
#define VICVectAddr
Definition: LPC21xx.h:436
unsigned long uint32_t
Definition: types.h:18
void spi1_ISR(void)
Definition: spi_arch.c:455
static void SpiSetCPOL(struct spi_periph *p)
Definition: spi_arch.c:96
bool spi_slave_wait(struct spi_periph *p)
Initialized and wait for the next transaction.
Definition: spi_arch.c:703
#define SPI_SELECT_SLAVE1_PIN
Definition: board.h:992
#define SPI_SELECT_SLAVE0_IOSET
Definition: spi_arch.c:49
#define MASTER_SSP_MS
master slave mode : master
Definition: spi_arch.c:442
uint16_t foo
Definition: main_demo5.c:59
#define RTIM
Definition: LPC21xx.h:272
static void SpiSlaveUnselect(uint8_t slave)
Definition: spi_arch.c:73
#define Max(x, y)
Definition: main_fbw.c:53
uint16_t input_length
number of data words to read
Definition: spi.h:145
#define VIC_BIT(chan)
Definition: lpcVIC.h:105
enum SPIStatus status
internal state of the peripheral
Definition: spi.h:174
static void SpiEnableRxi(struct spi_periph *p)
Definition: spi_arch.c:176
#define RNE
Definition: LPC21xx.h:279
static void SpiEndOfTransaction(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:278
#define MASTER_SSP_LBM
loopback mode : disabled
Definition: spi_arch.c:440
#define VICIntEnClear
Definition: LPC21xx.h:432
unsigned char uint8_t
Definition: types.h:14
unsigned disableIRQ(void)
Definition: armVIC.c:33
#define ISR_EXIT()
Definition: armVIC.h:61
Definition: spi.h:101
#define SSP_PINSEL1_SCK
Definition: spi_arch.c:385
bool spi_resume(struct spi_periph *p, uint8_t slave)
spi_resume() function
Definition: spi_arch.c:590
slave is selected before transaction and unselected after
Definition: spi.h:57
#define SPI_SELECT_SLAVE0_PINSEL
Definition: booz_1.0.h:121
#define VICIntEnable
Definition: LPC21xx.h:431
#define MASTER_SSP_SOD
slave output disable : don't care when master
Definition: spi_arch.c:443
#define SPI_SELECT_SLAVE0_IOCLR
Definition: spi_arch.c:48
#define PINSEL1
Definition: LPC21xx.h:348
uint8_t trans_extract_idx
Definition: spi.h:172
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
#define VIC_SPI1
Definition: lpcVIC.h:81
static void SpiSend(struct spi_periph *p, uint16_t c)
Definition: spi_arch.c:186
static float p[2][2]
#define SPI1_VIC_SLOT
default initial settings
Definition: spi_arch.c:392
#define SPI1
Definition: LPC21xx.h:210
static void SpiSlaveStart(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:335
static void SpiDisableRti(struct spi_periph *p)
Definition: spi_arch.c:156
#define DSS_VAL16
Definition: LPC21xx.h:262
uint8_t spi0_vic_slot
Definition: spi_arch.c:415
#define SPI_SELECT_SLAVE1_IODIR
Definition: spi_arch.c:51
#define TNF
Definition: LPC21xx.h:278
#define SSPCR1
Definition: LPC21xx.h:223
#define DSS_VAL8
Definition: LPC21xx.h:254
#define SPI_TRANSACTION_QUEUE_LEN
SPI transaction queue length.
Definition: spi.h:163
#define SSE
Definition: LPC21xx.h:266
#define SPI_SELECT_SLAVE1_IOSET
Definition: spi_arch.c:53
#define SPI0
Definition: LPC21xx.h:195
#define SSP_PINSEL1_MISO
Definition: spi_arch.c:386
void spi_init_slaves(void)
spi_init_slaves() function
Definition: spi_arch.c:604
#define RTIC
Definition: LPC21xx.h:291
#define MASTER_SSP_DSS
data size : 8 bits
Definition: spi_arch.c:433
void spi_slave_select(uint8_t slave)
spi_slave_select() function
Definition: spi_arch.c:491
#define SPI_SELECT_SLAVE0_PINSEL_VAL
Definition: booz_1.0.h:123
#define BSY
Definition: LPC21xx.h:281
static void SpiDisableTxi(struct spi_periph *p)
Definition: spi_arch.c:171
void spi0_arch_init(void)
Architecture dependent SPI0 initialization.
Definition: spi_arch.c:136
#define CPHA
Definition: LPC21xx.h:246
#define ISR_ENTRY()
Definition: armVIC.h:40
struct spi_transaction * trans[SPI_TRANSACTION_QUEUE_LEN]
circular buffer holding transactions
Definition: spi.h:170
process_rx_dma_interrupt & spi1
receive transferred over DMA
Definition: spi_arch.c:967
static void SpiSlaveAutomaton(struct spi_periph *p)
Definition: spi_arch.c:350
#define VIC_ENABLE
Definition: lpcVIC.h:102
enum SPITransactionStatus status
Definition: spi.h:156
uint8_t trans_insert_idx
Definition: spi.h:171
#define SPI_SELECT_SLAVE1_PINSEL_VAL
Definition: booz_1.0.h:129