Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
spi_slave_hs_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 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 
29 #include "spi_slave_hs_arch.h"
30 #include "mcu_periph/spi.h"
31 
32 #include BOARD_CONFIG
33 #include "std.h"
34 #include "mcu.h"
35 #include "led.h"
36 #include "LPC21xx.h"
37 #include "ssp_hw.h"
38 #include "pprz_debug.h"
39 #include "armVIC.h"
40 
42 
43 /* High Speed SPI Slave Circular Buffer */
48 
49 /* Prototypes */
50 static void SSP_ISR(void) __attribute__((naked));
51 
52 /* SSPCR0 settings */
53 #define SSP_DDS 0x07 << 0 /* data size : 8 bits */
54 //#define SSP_DDS 0x0F << 0 /* data size : 16 bits */
55 #define SSP_FRF 0x00 << 4 /* frame format : SPI */
56 #define SSP_CPOL 0x00 << 6 /* clock polarity : data captured on first clock transition */
57 #define SSP_CPHA 0x00 << 7 /* clock phase : SCK idles low */
58 #define SSP_SCR 0x00 << 8 /* serial clock rate : divide by 1 */
59 
60 #define SSPCR0_VAL (SSP_DDS | SSP_FRF | SSP_CPOL | SSP_CPHA | SSP_SCR )
61 
62 /* SSPCR1 settings */
63 #define SSP_LBM 0x00 << 0 /* loopback mode : disabled */
64 #define SSP_SSE 0x00 << 1 /* SSP enable : enable later when init ready */
65 #define SSP_MS 0x01 << 2 /* master slave mode : slave */
66 #define SSP_SOD 0x00 << 3 /* slave output disable : don't care when master */
67 
68 #define SSPCR1_VAL (SSP_LBM | SSP_SSE | SSP_MS | SSP_SOD )
69 
70 /* SSPCPSR settings
71  * min value as master: 2
72  * min value as slave: 12
73  */
74 #if (PCLK == 15000000)
75 #define CPSDVSR 12
76 #else
77 
78 #if (PCLK == 30000000)
79 #define CPSDVSR 24
80 #else
81 
82 #if (PCLK == 60000000)
83 #define CPSDVSR 28
84 #else
85 
86 #error unknown PCLK frequency
87 #endif
88 #endif
89 #endif
90 
91 #define SSP_PINSEL1_SCK (2<<2)
92 #define SSP_PINSEL1_MISO (2<<4)
93 #define SSP_PINSEL1_MOSI (2<<6)
94 #define SSP_PINSEL1_SSEL (2<<8)
95 
96 
97 #define SSP_Write(X) SSPDR=(X)
98 #define SSP_Read() SSPDR
99 #define SSP_Status() SSPSR
100 
102 #ifndef SPI1_VIC_SLOT
103 #define SPI1_VIC_SLOT 7
104 #endif
105 
106 
107 // Functions for the generic device API
108 static int spi_slave_hs_check_free_space(struct spi_slave_hs *p __attribute__((unused)), long *fd __attribute__((unused)), uint16_t len __attribute__((unused)))
109 {
110  return true;
111 }
112 
113 static void spi_slave_hs_transmit(struct spi_slave_hs *p __attribute__((unused)), long fd __attribute__((unused)), uint8_t byte)
114 {
116  if (temp != spi_slave_hs_tx_extract_idx) /* there is room left */
117  {
120  }
121 }
122 
123 static void spi_slave_hs_transmit_buffer(struct spi_slave_hs *p __attribute__((unused)), long fd, uint8_t *data, uint16_t len)
124 {
125  int i;
126  for (i = 0; i < len; i++) {
127  spi_slave_hs_transmit(p, fd, data[i]);
128  }
129 }
130 
131 static void spi_slave_hs_send(struct spi_slave_hs *p __attribute__((unused)), long fd __attribute__((unused))) { }
132 
133 static int spi_slave_hs_char_available(struct spi_slave_hs *p __attribute__((unused)))
134 {
136 }
137 
138 static uint8_t spi_slave_hs_getch(struct spi_slave_hs *p __attribute__((unused)))
139 {
142  return ret;
143 }
144 
146 {
147 
148  /* setup pins for SSP (SCK, MISO, MOSI) */
150 
151  /* setup SSP */
152  // Control Registers
153  SSPCR0 = SSPCR0_VAL;
154  SSPCR1 = SSPCR1_VAL;
155  // Clock Prescale Registers
156  SSPCPSR = CPSDVSR;
157 
158  /* initialize interrupt vector */
159  VICIntSelect &= ~VIC_BIT(VIC_SPI1); /* SPI1 selected as IRQ */
160  VICIntEnable = VIC_BIT(VIC_SPI1); /* enable it */
162  _VIC_ADDR(SPI1_VIC_SLOT) = (uint32_t)SSP_ISR; /* address of the ISR */
163 
164 
165  // Enable SPI Slave
166  SetBit(SSPCR1, SSE);
167 
168  // Enable Receive interrupt
169  SetBit(SSPIMSC, RXIM);
170 
171  // Configure generic device
172  spi_slave_hs.device.periph = (void *)(&spi_slave_hs);
173  spi_slave_hs.device.check_free_space = (check_free_space_t) spi_slave_hs_check_free_space;
174  spi_slave_hs.device.put_byte = (put_byte_t) spi_slave_hs_transmit;
175  spi_slave_hs.device.put_buffer = (put_buffer_t) spi_slave_hs_transmit_buffer;
176  spi_slave_hs.device.send_message = (send_message_t) spi_slave_hs_send;
177  spi_slave_hs.device.char_available = (char_available_t) spi_slave_hs_char_available;
178  spi_slave_hs.device.get_byte = (get_byte_t) spi_slave_hs_getch;
179 
180 }
181 
182 /*
183  * SSP Status:
184  *
185  * ROVR Read Overrun
186  * WCOL Write Collision (send new byte during a transfer in progress
187  * ABRT SSEL inactive before end of transfer
188  *
189  *
190  */
191 
192 
193 static void SSP_ISR(void)
194 {
195  ISR_ENTRY();
196 
197  //LED_TOGGLE(3);
198 
199  // If any TX bytes are pending
203  SSP_Write(ret);
204  } else {
205  SSP_Write(0x00);
206  }
207 
208 
209  //do
210  {
211  uint16_t temp;
212 
213  // calc next insert index & store character
216 
217  // check for more room in queue
218  if (temp != spi_slave_hs_rx_extract_idx) {
219  spi_slave_hs_rx_insert_idx = temp; // update insert index
220  }
221 
222  // else overrun
223  }
224  // while FIFO not empty
225  //while (SSPSR & RNE);
226 
227  /*
228  // loop until not more interrupt sources
229  while (((iid = U0IIR) & UIIR_NO_INT) == 0)
230  while (U0LSR & ULSR_THRE)
231  {
232  // check if more data to send
233  if (uart0_tx_insert_idx != uart0_tx_extract_idx)
234  {
235  U0THR = uart0_tx_buffer[uart0_tx_extract_idx];
236  uart0_tx_extract_idx++;
237  uart0_tx_extract_idx %= UART0_TX_BUFFER_SIZE;
238  }
239  else
240  {
241  // no
242  uart0_tx_running = 0; // clear running flag
243  break;
244  }
245  }
246 
247  */
248  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
249  ISR_EXIT();
250 }
251 
#define VICIntSelect
Definition: LPC21xx.h:430
#define SPI1_VIC_SLOT
default initial settings
unsigned short uint16_t
Definition: types.h:16
#define SSPCPSR
Definition: LPC21xx.h:226
#define _VIC_CNTL(idx)
Definition: armVIC.h:19
#define SSPCR0_VAL
uint8_t spi_slave_hs_rx_buffer[SPI_SLAVE_HS_RX_BUFFER_SIZE]
#define RXIM
Definition: LPC21xx.h:273
static void spi_slave_hs_transmit(struct spi_slave_hs *p, long fd, uint8_t byte)
#define SSPCR1_VAL
void spi_slave_hs_init(void)
#define SSP_PINSEL1_SSEL
#define SSPCR0
Definition: LPC21xx.h:222
uint16_t spi_slave_hs_rx_extract_idx
#define _VIC_ADDR(idx)
Definition: armVIC.h:20
static int spi_slave_hs_char_available(struct spi_slave_hs *p)
Architecture independent SPI (Serial Peripheral Interface) API.
#define SSP_PINSEL1_SCK
#define SSP_Write(X)
static void spi_slave_hs_send(struct spi_slave_hs *p, long fd)
#define SPI_SLAVE_HS_TX_BUFFER_SIZE
#define VICVectAddr
Definition: LPC21xx.h:436
unsigned long uint32_t
Definition: types.h:18
static void SSP_ISR(void)
static int spi_slave_hs_check_free_space(struct spi_slave_hs *p, long *fd, uint16_t len)
uint8_t spi_slave_hs_tx_extract_idx
static void spi_slave_hs_transmit_buffer(struct spi_slave_hs *p, long fd, uint8_t *data, uint16_t len)
#define VIC_BIT(chan)
Definition: lpcVIC.h:105
uint8_t spi_slave_hs_tx_insert_idx
Arch independent mcu ( Micro Controller Unit ) utilities.
#define SPI_SLAVE_HS_RX_BUFFER_SIZE
struct link_device device
Generic device interface.
unsigned char uint8_t
Definition: types.h:14
static uint8_t spi_slave_hs_getch(struct spi_slave_hs *p)
uint8_t spi_slave_hs_tx_buffer[SPI_SLAVE_HS_TX_BUFFER_SIZE]
#define ISR_EXIT()
Definition: armVIC.h:61
#define byte
int fd
Definition: serial.c:26
#define VICIntEnable
Definition: LPC21xx.h:431
#define PINSEL1
Definition: LPC21xx.h:348
#define SSP_PINSEL1_MOSI
#define VIC_SPI1
Definition: lpcVIC.h:81
arch independent LED (Light Emitting Diodes) API
static float p[2][2]
Highspeed SPI Slave Interface.
#define SSP_PINSEL1_MISO
#define SSPCR1
Definition: LPC21xx.h:223
#define SSE
Definition: LPC21xx.h:266
#define SSP_Read()
uint16_t spi_slave_hs_rx_insert_idx
#define SSPIMSC
Definition: LPC21xx.h:227
#define ISR_ENTRY()
Definition: armVIC.h:40
#define VIC_ENABLE
Definition: lpcVIC.h:102