RT-AICHIP-sample
ssp.c
[詳解]
1 /*****************************************************************************
2  * ssp.c: SSP C file for NXP LPC13xx Family Microprocessors
3  *
4  * Copyright(C) 2008, NXP Semiconductor
5  * All rights reserved.
6  *
7  * History
8  * 2008.07.20 ver 1.00 Preliminary version, first Release
9  *
10 *****************************************************************************/
11 #include "LPC13xx.h" /* LPC13xx Peripheral Registers */
12 #include "ssp.h"
13 
14 /* statistics of all the interrupts */
18 
19 /*****************************************************************************
20 ** Function name: SSP_IRQHandler
21 **
22 ** Descriptions: SSP port is used for SPI communication.
23 ** SSP interrupt handler
24 ** The algorithm is, if RXFIFO is at least half full,
25 ** start receive until it's empty; if TXFIFO is at least
26 ** half empty, start transmit until it's full.
27 ** This will maximize the use of both FIFOs and performance.
28 **
29 ** parameters: None
30 ** Returned value: None
31 **
32 *****************************************************************************/
33 void SSP_IRQHandler(void)
34 {
35  uint32_t regValue;
36 
37  regValue = LPC_SSP->MIS;
38  if ( regValue & SSPMIS_RORMIS ) /* Receive overrun interrupt */
39  {
41  LPC_SSP->ICR = SSPICR_RORIC; /* clear interrupt */
42  }
43  if ( regValue & SSPMIS_RTMIS ) /* Receive timeout interrupt */
44  {
46  LPC_SSP->ICR = SSPICR_RTIC; /* clear interrupt */
47  }
48 
49  /* please be aware that, in main and ISR, CurrentRxIndex and CurrentTxIndex
50  are shared as global variables. It may create some race condition that main
51  and ISR manipulate these variables at the same time. SSPSR_BSY checking (polling)
52  in both main and ISR could prevent this kind of race condition */
53  if ( regValue & SSPMIS_RXMIS ) /* Rx at least half full */
54  {
55  interruptRxStat++; /* receive until it's empty */
56  }
57  return;
58 }
59 
60 /*****************************************************************************
61 ** Function name: SSPInit
62 **
63 ** Descriptions: SSP port initialization routine
64 **
65 ** parameters: None
66 ** Returned value: None
67 **
68 *****************************************************************************/
69 void SSPInit( void )
70 {
71  uint8_t i, Dummy=Dummy;
72 
73  LPC_SYSCON->PRESETCTRL |= (0x1<<0);
74  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
75  LPC_SYSCON->SSPCLKDIV = 0x0f; /* Divided by 2 */
76  LPC_IOCON->PIO0_8 &= ~0x07; /* SSP I/O config */
77  LPC_IOCON->PIO0_8 |= 0x01; /* SSP MISO */
78  LPC_IOCON->PIO0_9 &= ~0x07;
79  LPC_IOCON->PIO0_9 |= 0x01; /* SSP MOSI */
80  #ifdef __JTAG_DISABLED
81  LPC_IOCON->SCKLOC = 0x00;
82  LPC_IOCON->JTAG_TCK_PIO0_10 &= ~0x07;
83  LPC_IOCON->JTAG_TCK_PIO0_10 |= 0x02; /* SSP CLK */
84  #endif
85 
86  #if 0
87  /* On HummingBird 1(HB1), SSP CLK can be routed to different pins,
88  other than JTAG TCK, it's either P2.11 func. 1 or P0.6 func. 2. */
89  LPC_IOCON->SCKLOC = 0x01;
90  LPC_IOCON->PIO2_11 = 0x01;/* P2.11 function 1 is SSP clock, need to combined
91  with IOCONSCKLOC register setting */
92  #else
93  LPC_IOCON->SCKLOC = 0x02;
94  LPC_IOCON->PIO0_6 = 0x02; /* P0.6 function 2 is SSP clock, need to combined
95  with IOCONSCKLOC register setting */
96  #endif
97 
98  #if USE_CS
99  LPC_IOCON->PIO0_2 &= ~0x07;
100  LPC_IOCON->PIO0_2 |= 0x01; /* SSP SSEL */
101  #else
102  LPC_IOCON->PIO0_2 &= ~0x07; /* SSP SSEL is a GPIO pin */
103  /* port0, bit 2 is set to GPIO output and high */
104  LPC_GPIO0->DIR |= (0x1<<2); //Data Direction(1 output , 0 input)
105  LPC_GPIO0->DATA |= (0x1<<2);
106 
107  #endif
108 
109  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
110  LPC_SSP->CR0 = 0x0707;
111  //CPOL 6bit
112  //LPC_SSP->CR0 |= (0x1<<6);
113  //CPHA 7bit
114  //LPC_SSP->CR0 &= ~(0x1<<7);
115 
116 
117  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
118  LPC_SSP->CPSR = 0x2;
119 
120  for ( i = 0; i < FIFOSIZE; i++ )
121  {
122  Dummy = LPC_SSP->DR; /* clear the RxFIFO */
123  }
124 
125  /* Enable the SSP Interrupt */
126  NVIC_EnableIRQ(SSP_IRQn);
127 
128  /* Device select as master, SSP Enabled */
129  #if LOOPBACK_MODE
130  LPC_SSP->CR1 = SSPCR1_LBM | SSPCR1_SSE;
131  #else
132  #if SSP_SLAVE
133  /* Slave mode */
134  if ( LPC_SSP->CR1 & SSPCR1_SSE )
135  {
136  /* The slave bit can't be set until SSE bit is zero. */
137  LPC_SSP->CR1 &= ~SSPCR1_SSE;
138  }
139  LPC_SSP->CR1 = SSPCR1_MS; /* Enable slave bit first */
140  LPC_SSP->CR1 |= SSPCR1_SSE; /* Enable SSP */
141  #else
142  /* Master mode */
143  LPC_SSP->CR1 = SSPCR1_SSE;
144  #endif
145  #endif
146  /* Set SSPINMS registers to enable interrupts */
147  /* enable all error related interrupts */
148  LPC_SSP->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
149  return;
150 }
151 
152 /*****************************************************************************
153 ** Function name: SSPSend
154 **
155 ** Descriptions: Send a block of data to the SSP port, the
156 ** first parameter is the buffer pointer, the 2nd
157 ** parameter is the block length.
158 **
159 ** parameters: buffer pointer, and the block length
160 ** Returned value: None
161 **
162 *****************************************************************************/
163 void SSPSend( uint8_t *buf, uint32_t Length )
164 {
165  uint32_t i;
166  uint8_t Dummy = Dummy;
167 
168  for ( i = 0; i < Length; i++ )
169  {
170  /* Move on only if NOT busy and TX FIFO not full. */
171  while ( (LPC_SSP->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
172  LPC_SSP->DR = *buf;
173  buf++;
174 #if !LOOPBACK_MODE
175  while ( (LPC_SSP->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE );
176  /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
177  on MISO. Otherwise, when SSP0Receive() is called, previous data byte
178  is left in the FIFO. */
179  Dummy = LPC_SSP->DR;
180 #else
181  /* Wait until the Busy bit is cleared. */
182  while ( LPC_SSP->SR & SSPSR_BSY );
183 #endif
184  }
185  return;
186 }
187 
188 /*****************************************************************************
189 ** Function name: SSPReceive
190 ** Descriptions: the module will receive a block of data from
191 ** the SSP, the 2nd parameter is the block
192 ** length.
193 ** parameters: buffer pointer, and block length
194 ** Returned value: None
195 **
196 *****************************************************************************/
197 void SSPReceive( uint8_t *buf, uint32_t Length )
198 {
199  uint32_t i;
200 
201  for ( i = 0; i < Length; i++ )
202  {
203  /* As long as Receive FIFO is not empty, I can always receive. */
204  /* If it's a loopback test, clock is shared for both TX and RX,
205  no need to write dummy byte to get clock to get the data */
206  /* if it's a peer-to-peer communication, SSPDR needs to be written
207  before a read can take place. */
208 #if !LOOPBACK_MODE
209 #if SSP_SLAVE
210  while ( !(LPC_SSP->SR & SSPSR_RNE) );
211 #else
212  LPC_SSP->DR = 0xFF;
213  /* Wait until the Busy bit is cleared */
214  while ( (LPC_SSP->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE );
215 #endif
216 #else
217  while ( !(LPC_SSP->SR & SSPSR_RNE) );
218 #endif
219  *buf = LPC_SSP->DR;
220  buf++;
221 
222  }
223  return;
224 }
225 
226 
227 #ifdef debug
228 void readWhoAmI()
229 {
230  uint8_t send_data[2];
231  uint8_t receive_data[10];
232  send_data[0] = 0x8f;
233  send_data[1] = 0x8f;
234 
235  receive_data[0] = 0;
236 
237  LPC_GPIO0->DATA &= ~(0x1<<2);
238 
239  SSPSend( &send_data[0], 1 );
240  SSPReceive( &receive_data[0], 2 );
241 
242  LPC_GPIO0->DATA |= (0x1<<2);
243 
244  myPrintfUSB("whoAmI %d %d %d \n",receive_data[0],receive_data[1],receive_data[2] );
245 }
246 #endif
247 
248 /******************************************************************************
249 ** End Of File
250 ******************************************************************************/
#define SSPCR1_LBM
Definition: ssp.h:59
void SSPSend(uint8_t *buf, uint32_t Length)
Definition: ssp.c:163
#define SSPSR_RNE
Definition: ssp.h:47
#define SSPICR_RORIC
Definition: ssp.h:83
#define SSPICR_RTIC
Definition: ssp.h:84
#define SSPIMSC_RTIM
Definition: ssp.h:66
volatile uint32_t interruptRxTimeoutStat
Definition: ssp.c:17
#define SSPCR1_SSE
Definition: ssp.h:60
void SSPReceive(uint8_t *buf, uint32_t Length)
Definition: ssp.c:197
volatile uint32_t interruptOverRunStat
Definition: ssp.c:16
#define SSPSR_TNF
Definition: ssp.h:46
unsigned char uint8_t
Definition: type.h:27
#define FIFOSIZE
Definition: ssp.h:36
#define SSPIMSC_RORIM
Definition: ssp.h:65
#define SSPMIS_RTMIS
Definition: ssp.h:78
void SSP_IRQHandler(void)
Definition: ssp.c:33
#define SSPMIS_RXMIS
Definition: ssp.h:79
volatile uint32_t interruptRxStat
Definition: ssp.c:15
#define SSPMIS_RORMIS
Definition: ssp.h:77
#define SSPCR1_MS
Definition: ssp.h:61
#define SSPSR_BSY
Definition: ssp.h:49
int myPrintfUSB(const char *fmt,...)
Definition: debug.c:23
void SSPInit(void)
Definition: ssp.c:69
unsigned int uint32_t
Definition: type.h:29