Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
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 #error "SPI0 is currently not implemented in the mcu_periph/spi HAL for the LPC!"
386 
387 // void spi0_ISR(void) __attribute__((naked));
388 //
389 // void spi0_ISR(void) {
390 // ISR_ENTRY();
391 // VICVectAddr = 0x00000000;
392 // ISR_EXIT();
393 // }
394 
396 
397 void spi0_arch_init(void) {
398 
399  spi0.reg_addr = SPI0;
400  spi0_vic_slot = VIC_SPI0;
401  spi0.init_struct = (void*)(&spi0_vic_slot);
402 
403  // TODO set spi0 and interrupt vector
404 }
405 
406 #endif
407 
408 
409 #if USE_SPI1
410 
411 /* SSPCR0 settings */
412 #define MASTER_SSP_DSS 0x07 << 0
413 #define MASTER_SSP_FRF 0x00 << 4
414 #define MASTER_SSP_CPOL 0x00 << 6
415 #define MASTER_SSP_CPHA 0x00 << 7
416 #define MASTER_SSP_SCR 0x0F << 8
417 
418 /* SSPCR1 settings */
419 #define MASTER_SSP_LBM 0x00 << 0
420 #define MASTER_SSP_SSE 0x00 << 1
421 #define MASTER_SSP_MS 0x00 << 2
422 #define MASTER_SSP_SOD 0x00 << 3
423 
424 
428 #ifndef SSPCPSR_VAL
429 #define SSPCPSR_VAL 0x02 /* clock prescale */
430 #endif
431 
432 void spi1_ISR(void) __attribute__((naked));
433 
434 void spi1_ISR(void) {
435  ISR_ENTRY();
436 
437  SpiAutomaton(&spi1);
438 
439  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
440  ISR_EXIT();
441 }
442 
444 
445 void spi1_arch_init(void) {
446 
447  spi1.reg_addr = SPI1;
448  spi1_vic_slot = VIC_SPI1;
449  spi1.init_struct = (void*)(&spi1_vic_slot);
450 
451  /* setup pins for SSP (SCK, MISO, MOSI) */
453 
454  /* setup SSP */
457  SSPCPSR = SSPCPSR_VAL; /* Prescaler */
458 
459  /* initialize interrupt vector */
460  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
461  VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
463  _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)spi1_ISR; /* address of the ISR */
464 
465 }
466 
467 #endif
468 
469 
470 bool_t spi_submit(struct spi_periph* p, struct spi_transaction* t) {
471  //unsigned cpsr;
472 
473  uint8_t idx;
474  idx = p->trans_insert_idx + 1;
475  if (idx >= SPI_TRANSACTION_QUEUE_LEN) idx = 0;
476  if (idx == p->trans_extract_idx) {
477  t->status = SPITransFailed;
478  return FALSE; /* queue full */
479  }
480  t->status = SPITransPending;
481 
482  // Disable interrupts
483  //uint8_t* vic = (uint8_t*)(p->init_struct);
484  //cpsr = disableIRQ(); // disable global interrupts
485  //VICIntEnClear = VIC_BIT(*vic);
486  //restoreIRQ(cpsr); // restore global interrupts
487  disableIRQ();
488 
489  p->trans[p->trans_insert_idx] = t;
490  p->trans_insert_idx = idx;
491  /* if peripheral is idle and not locked, start the transaction */
492  if (p->status == SPIIdle && !p->suspend) {
493  SpiStart(p,p->trans[p->trans_extract_idx]);
494  }
495 
496  //cpsr = disableIRQ(); // disable global interrupts
497  //VICIntEnable = VIC_BIT(*vic);
498  //restoreIRQ(cpsr); // restore global interrupts
499  enableIRQ();
500  return TRUE;
501 }
502 
503 
504 void spi_init_slaves(void) {
505 #if USE_SPI_SLAVE0
506  /* setup slave0_select pin
507  * slave0_select is output
508  */
512 #endif
513 
514 #if USE_SPI_SLAVE1
515  /* setup slave1_select pin
516  * slave1_select is output
517  */
521 #endif
522 
523 #if USE_SPI_SLAVE2
524 #error SPI_SLAVE2 is not implemented yet, sorry
525 #endif
526 }
527 
529  SpiSlaveSelect(slave);
530 }
531 
533  SpiSlaveUnselect(slave);
534 }
535 
536 bool_t spi_lock(struct spi_periph* p, uint8_t slave) {
537  uint8_t* vic = (uint8_t*)(p->init_struct);
538  VICIntEnClear = VIC_BIT(*vic);
539  if (slave < 254 && p->suspend == 0) {
540  p->suspend = slave + 1; // 0 is reserved for unlock state
541  VICIntEnable = VIC_BIT(*vic);
542  return TRUE;
543  }
544  VICIntEnable = VIC_BIT(*vic);
545  return FALSE;
546 }
547 
548 bool_t spi_resume(struct spi_periph* p, uint8_t slave) {
549  uint8_t* vic = (uint8_t*)(p->init_struct);
550  VICIntEnClear = VIC_BIT(*vic);
551  if (p->suspend == slave + 1) {
552  // restart fifo
553  p->suspend = 0;
554  if (p->trans_extract_idx != p->trans_insert_idx && p->status == SPIIdle) {
555  SpiStart(p,p->trans[p->trans_extract_idx]);
556  }
557  VICIntEnable = VIC_BIT(*vic);
558  return TRUE;
559  }
560  VICIntEnable = VIC_BIT(*vic);
561  return FALSE;
562 }
563 
564 #endif /* SPI_MASTER */
565 
566 
567 /*
568  *
569  * SPI Slave code
570  *
571  * FIXME it is probably not working at all right now
572  *
573  */
574 #if SPI_SLAVE
575 
576 /* set SSP input clock, PCLK / CPSDVSR = 468.75kHz */
577 
578 #if (PCLK == 15000000)
579 #define CPSDVSR 32
580 #else
581 
582 #if (PCLK == 30000000)
583 #define CPSDVSR 64
584 #else
585 
586 #if (PCLK == 60000000)
587 #define CPSDVSR 128
588 #else
589 
590 #error unknown PCLK frequency
591 #endif
592 #endif
593 #endif
594 
595 #if USE_SPI0_SLAVE
596 #error SPI0 in slave mode is not implemented yet, sorry
597 #endif
598 
599 #if USE_SPI1_SLAVE
600 
601 /* SSPCR0 settings */
602 #define SLAVE_SSP_DSS 0x07 << 0 /* data size : 8 bits */
603 #define SLAVE_SSP_FRF 0x00 << 4 /* frame format : SPI */
604 #define SLAVE_SSP_CPOL 0x00 << 6 /* clock polarity : idle low */
605 #define SLAVE_SSP_CPHA 0x01 << 7 /* clock phase : 1 */
606 #define SLAVE_SSP_SCR 0x0F << 8 /* serial clock rate : 29.3kHz, SSP input clock / 16 */
607 
608 /* SSPCR1 settings */
609 #define SLAVE_SSP_LBM 0x00 << 0 /* loopback mode : disabled */
610 #define SLAVE_SSP_SSE 0x00 << 1 /* SSP enable : disabled */
611 #define SLAVE_SSP_MS 0x01 << 2 /* master slave mode : slave */
612 #define SLAVE_SSP_SOD 0x00 << 3 /* slave output disable : disabled */
613 
614 void spi1_slave_ISR(void) __attribute__((naked));
615 
616 void spi1_slave_ISR(void) {
617  ISR_ENTRY();
618 
620 
621  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
622  ISR_EXIT();
623 }
624 
625 void spi1_slave_arch_init(void) {
626 
627  spi1.reg_addr = SPI1;
628 
629  /* setup pins for SSP (SCK, MISO, MOSI, SS) */
631 
632  /* setup SSP */
633  SSPCR0 = SLAVE_SSP_DSS | SLAVE_SSP_FRF | SLAVE_SSP_CPOL | SLAVE_SSP_CPHA | SLAVE_SSP_SCR;
634  SSPCR1 = SLAVE_SSP_LBM | SLAVE_SSP_MS | SLAVE_SSP_SOD;
635  SSPCPSR = CPSDVSR; /* Prescaler, UM10120_1.pdf page 167 */
636 
637  /* initialize interrupt vector */
638  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
639  VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
641  _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)spi1_slave_ISR; /* address of the ISR */
642 
643 }
644 
645 #endif
646 
648 bool_t spi_slave_register(struct spi_periph* p, struct spi_transaction* t) {
649 
650  if (p->trans_insert_idx >= 1) {
651  t->status = SPITransFailed;
652  return FALSE;
653  }
654  t->status = SPITransPending;
655  p->status = SPIIdle;
656  p->trans[p->trans_insert_idx] = t; // No need to disable interrupts, only one transaction
657  p->trans_insert_idx = 1;
658 
659  // handle spi options (CPOL, CPHA, data size,...)
660  if (t->cpol == SPICpolIdleHigh) SpiSetCPOL(p);
661  else SpiClearCPOL(p);
662 
663  if (t->cpha == SPICphaEdge2) SpiSetCPHA(p);
664  else SpiClearCPHA(p);
665 
666  SpiSetDataSize(p, t->dss);
667 
668  return TRUE;
669 }
670 
671 bool_t spi_slave_wait(struct spi_periph* p) {
672  if (p->trans_insert_idx == 0) {
673  // no transaction registered
674  return FALSE;
675  }
676  // Start waiting
678  return TRUE;
679 }
680 
681 #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:443
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:127
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:536
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:445
bool_t spi_slave_wait(struct spi_periph *p)
Initialized and wait for the next transaction.
Definition: spi_arch.c:671
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:413
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
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: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:177
#define RTMIS
Definition: LPC21xx.h:285
#define SSPCPSR_VAL
Clock prescaler.
Definition: spi_arch.c:429
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:178
#define TXMIS
Definition: LPC21xx.h:287
#define MASTER_SSP_SCR
serial clock rate : divide by 16
Definition: spi_arch.c:416
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 MASTER_SSP_CPOL
clock polarity : SCK idles low
Definition: spi_arch.c:414
#define FALSE
Definition: imu_chimu.h:141
#define SPI_SLAVE0
Definition: spi.h:186
enum SPITransactionStatus status
Definition: spi.h:156
#define MASTER_SSP_CPHA
clock phase : data captured on first clock transition
Definition: spi_arch.c:415
Architecture independent SPI (Serial Peripheral Interface) API.
enum SPIStatus status
internal state of the peripheral
Definition: spi.h:174
#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
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:532
bool_t spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit a spi transaction.
Definition: spi_arch.c:470
#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_SLAVE0_PIN
Definition: apogee_0.99.h:71
#define SPI_SELECT_SLAVE1_PINSEL_BIT
Definition: booz_1.0.h:128
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:434
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:421
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:170
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
SPI peripheral structure.
Definition: spi.h:168
volatile uint8_t suspend
control for stop/resume of the fifo
Definition: spi.h:181
#define MASTER_SSP_LBM
loopback mode : disabled
Definition: spi_arch.c:419
#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:648
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:126
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:422
#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:548
uint8_t trans_extract_idx
Definition: spi.h:172
#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:395
#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
SPI transaction queue length.
Definition: spi.h:163
#define SSE
Definition: LPC21xx.h:266
#define SPI_SELECT_SLAVE1_IOSET
Definition: spi_arch.c:54
#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:504
#define RTIC
Definition: LPC21xx.h:291
#define MASTER_SSP_DSS
data size : 8 bits
Definition: spi_arch.c:412
void spi_slave_select(uint8_t slave)
Select a slave.
Definition: spi_arch.c:528
#define SPI_SELECT_SLAVE0_PINSEL_VAL
Definition: booz_1.0.h:123
uint8_t trans_insert_idx
Definition: spi.h:171
#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:397
#define CPHA
Definition: LPC21xx.h:246
#define ISR_ENTRY()
Definition: armVIC.h:40
process_rx_dma_interrupt & spi1
receive transferred over DMA
Definition: spi_arch.c:961
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:129