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