Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
spi_arch.c
Go to the documentation of this file.
1 /* $Id$
2  *
3  * Copyright (C) 2003-2005 Pascal Brisset, Antoine Drouin
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  */
23 
28 #include "mcu_periph/spi.h"
29 
30 #include "std.h"
31 #include "LPC21xx.h"
32 #include "armVIC.h"
33 
36 
37 /* SSP (SPI1) pins (UM10120_1.pdf page 76)
38  P0.17 SCK PINSEL1 2 << 2
39  P0.18 MISO PINSEL1 2 << 4
40  P0.19 MOSI PINSEL1 2 << 6
41  P0.20 SS PINSEL1 2 << 8
42 */
43 #define PINSEL1_SCK (2 << 2)
44 #define PINSEL1_MISO (2 << 4)
45 #define PINSEL1_MOSI (2 << 6)
46 #define PINSEL1_SSEL (2 << 8)
47 
48 #ifdef SPI_SLAVE
49 void SPI1_ISR(void) __attribute__((naked));
50 
51 /* set SSP input clock, PCLK / CPSDVSR = 468.75kHz */
52 
53 #if (PCLK == 15000000)
54 #define CPSDVSR 32
55 #else
56 
57 #if (PCLK == 30000000)
58 #define CPSDVSR 64
59 #else
60 
61 #if (PCLK == 60000000)
62 #define CPSDVSR 128
63 #else
64 
65 #error unknown PCLK frequency
66 #endif
67 #endif
68 #endif
69 
70 /* SSPCR0 settings */
71 #define SSP_DSS 0x07 << 0 /* data size : 8 bits */
72 #define SSP_FRF 0x00 << 4 /* frame format : SPI */
73 #define SSP_CPOL 0x00 << 6 /* clock polarity : idle low */
74 #define SSP_CPHA 0x01 << 7 /* clock phase : 1 */
75 #define SSP_SCR 0x0F << 8 /* serial clock rate : 29.3kHz, SSP input clock / 16 */
76 
77 /* SSPCR1 settings */
78 #define SSP_LBM 0x00 << 0 /* loopback mode : disabled */
79 #define SSP_SSE 0x00 << 1 /* SSP enable : disabled */
80 #define SSP_MS 0x01 << 2 /* master slave mode : slave */
81 #define SSP_SOD 0x00 << 3 /* slave output disable : disabled */
82 
83 void spi_init( void ) {
84  /* setup pins for SSP (SCK, MISO, MOSI, SS) */
86 
87  /* setup SSP */
90  SSPCPSR = CPSDVSR; /* Prescaler, UM10120_1.pdf page 167 */
91 
92  /* initialize interrupt vector */
93  VICIntSelect &= ~VIC_BIT(VIC_SPI1); // SPI1 selected as IRQ
94  VICIntEnable = VIC_BIT(VIC_SPI1); // SPI1 interrupt enabled
96  VICVectAddr7 = (uint32_t)SPI1_ISR; // address of the ISR
97 
98  /* enable SPI */
99  // SpiEnable();
100 }
101 
102 void SPI1_ISR(void) {
103  ISR_ENTRY();
104 
105  if (bit_is_set(SSPMIS, TXMIS)) { /* Tx half empty */
106  SpiTransmit();
107  SpiReceive();
108  SpiEnableRti();
109  }
110 
111  if ( bit_is_set(SSPMIS, RTMIS)) { /* Rx timeout */
112  SpiReceive();
113  SpiClearRti(); /* clear interrupt */
114  SpiDisableRti();
115  SpiDisable();
117  }
118 
119  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
120  ISR_EXIT();
121 }
122 
123 #endif /* SPI_SLAVE */
124 
125 
126 /*
127  *
128  * SPI Master code
129  *
130  *
131  */
132 
133 #ifdef SPI_MASTER
134 
135 #include "led.h" /* FIXME remove that */
136 
137 /* interrupt handler */
138 void SPI1_ISR(void) __attribute__((naked));
139 
140 /* SSPCR0 settings */
141 #define SSP_DSS 0x07 << 0 /* data size : 8 bits */
142 #define SSP_FRF 0x00 << 4 /* frame format : SPI */
143 #define SSP_CPOL 0x00 << 6 /* clock polarity : SCK idles low */
144 #define SSP_CPHA 0x01 << 7 /* clock phase : data captured on second clock transition */
145 #define SSP_SCR 0x00 << 8 /* serial clock rate */
146 
147 /* SSPCR1 settings */
148 #define SSP_LBM 0x00 << 0 /* loopback mode : disabled */
149 #define SSP_SSE 0x00 << 1 /* SSP enable : disabled */
150 #define SSP_MS 0x00 << 2 /* master slave mode : master */
151 #define SSP_SOD 0x00 << 3 /* slave output disable : don't care when master */
152 
153 #ifndef SSPCPSR_VAL
154 #define SSPCPSR_VAL 0x20
155 #endif
156 
157 void spi_init( void ) {
158  /* setup pins for SSP (SCK, MISO, MOSI) */
160 
161 #if defined USE_SPI_SLAVE0
162  /* setup slave0_select pin */
163  SPI_SELECT_SLAVE0_IODIR |= 1 << SPI_SELECT_SLAVE0_PIN; /* slave0_select is output */
164  SpiUnselectSlave0(); /* slave0 is unselected */
165 #endif
166 
167 #if defined USE_SPI_SLAVE1
168  /* setup slave1_select pin */
169  PINSEL2 &= ~(_BV(3)); /* P1.25-16 are used as GPIO */
170  SPI_SELECT_SLAVE1_IODIR |= 1 << SPI_SELECT_SLAVE1_PIN; /* slave1_select is output */
171  SpiUnselectSlave1(); /* slave1 is unselected */
172 #endif
173 
174  /* setup SSP */
177  SSPCPSR = SSPCPSR_VAL; /* Prescaler */
178 
179  /* initialize interrupt vector */
180  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
181  VICIntEnable = VIC_BIT(VIC_SPI1); /* SPI1 interrupt enabled */
183  VICVectAddr7 = (uint32_t)SPI1_ISR; /* address of the ISR */
184 }
185 
186 void SPI1_ISR(void) {
187  ISR_ENTRY();
188 
189  if (bit_is_set(SSPMIS, TXMIS)) { /* Tx fifo is half empty */
190  SpiTransmit();
191  SpiReceive();
192  SpiEnableRti();
193  }
194 
195  if (bit_is_set(SSPMIS, RTMIS)) { /* Rx fifo is not empty and no receive took place in the last 32 bits period */
196 #if !SPI_NO_UNSELECT_SLAVE
197  SpiUnselectCurrentSlave();
198 #endif
199  SpiReceive();
200  SpiDisableRti();
201  SpiClearRti(); /* clear interrupt */
202  SpiDisable();
204  }
205 
206  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
207  ISR_EXIT();
208 }
209 
210 #endif
#define VICIntSelect
Definition: LPC21xx.h:398
bool_t spi_message_received
Definition: sim_baro.c:8
#define SSP_CPOL
Definition: ADS8344.c:70
#define SSP_FRF
Definition: ADS8344.c:69
#define SpiDisableRti()
Definition: spi_arch.h:80
#define SpiTransmit()
Definition: spi_arch.h:45
#define SSPCPSR
Definition: LPC21xx.h:226
#define PINSEL1_MISO
Definition: spi_arch.c:44
#define SSPMIS
Definition: LPC21xx.h:229
#define RTMIS
Definition: LPC21xx.h:253
#define TXMIS
Definition: LPC21xx.h:255
#define SSP_LBM
Definition: ADS8344.c:75
#define SSPCR0
Definition: LPC21xx.h:222
#define SpiClearRti()
Definition: spi_arch.h:84
#define SSP_MS
Definition: ADS8344.c:77
arch independent SPI (Serial Peripheral Interface) API
void spi_init(void)
Definition: spi_arch.c:3
#define SSP_SCR
Definition: ADS8344.c:72
static void SPI1_ISR(void)
Definition: ADS8344.c:81
#define VICVectAddr
Definition: LPC21xx.h:404
unsigned long uint32_t
Definition: types.h:18
#define PINSEL1_SSEL
Definition: spi_arch.c:46
#define VIC_BIT(chan)
Definition: lpcVIC.h:105
#define TRUE
Definition: imu_chimu.h:144
#define SSPCPSR_VAL
#define SSP_CPHA
Definition: ADS8344.c:71
#define PINSEL1_SCK
Definition: spi_arch.c:43
unsigned char uint8_t
Definition: types.h:14
#define SpiDisable()
Definition: spi_arch.h:72
#define ISR_EXIT()
Definition: armVIC.h:61
#define SSP_SOD
Definition: ADS8344.c:78
#define PINSEL2
Definition: LPC21xx.h:317
#define SpiReceive()
Definition: spi_arch.h:55
#define VICIntEnable
Definition: LPC21xx.h:399
#define PINSEL1
Definition: LPC21xx.h:316
#define VICVectAddr7
Definition: LPC21xx.h:413
#define SpiEnableRti()
Definition: spi_arch.h:76
#define VIC_SPI1
Definition: lpcVIC.h:81
arch independent LED (Light Emitting Diodes) API
volatile uint8_t spi_tx_idx
handling of arm7 SPI hardware for now only SPI1 ( aka SSP )
Definition: spi_arch.c:34
volatile uint8_t spi_rx_idx
Definition: spi_arch.c:35
#define SSPCR1
Definition: LPC21xx.h:223
#define PINSEL1_MOSI
Definition: spi_arch.c:45
#define SPI_SELECT_SLAVE0_PIN
Definition: logom_2.6.h:182
__attribute__((always_inline))
Definition: i2c_arch.c:35
#define ISR_ENTRY()
Definition: armVIC.h:40
#define VIC_ENABLE
Definition: lpcVIC.h:102
#define VICVectCntl7
Definition: LPC21xx.h:429
#define SSP_DSS
Definition: ADS8344.c:68