C:/nxpdrv/LPC1700CMSIS/Drivers/source/lpc17xx_spi.c
Go to the documentation of this file.00001 00020 /* Peripheral group ----------------------------------------------------------- */ 00025 /* Includes ------------------------------------------------------------------- */ 00026 #include "lpc17xx_spi.h" 00027 #include "lpc17xx_clkpwr.h" 00028 00029 /* If this source file built with example, the LPC17xx FW library configuration 00030 * file in each example directory ("lpc17xx_libcfg.h") must be included, 00031 * otherwise the default FW library configuration file must be included instead 00032 */ 00033 #ifdef __BUILD_WITH_EXAMPLE__ 00034 #include "lpc17xx_libcfg.h" 00035 #else 00036 #include "lpc17xx_libcfg_default.h" 00037 #endif /* __BUILD_WITH_EXAMPLE__ */ 00038 00039 #ifdef _SPI 00040 00041 /* Private Types -------------------------------------------------------------- */ 00047 typedef struct 00048 { 00049 int32_t dataword; /* Current data word: 0 - 8 bit; 1 - 16 bit */ 00050 uint32_t txrx_setup; /* Transmission setup */ 00051 void (*inthandler)(void); /* Transmission interrupt handler */ 00052 } SPI_CFG_T; 00053 00059 /* Private Variables ---------------------------------------------------------- */ 00060 /* SPI configuration data */ 00061 static SPI_CFG_T spidat; 00062 00063 00064 /* Private Functions ---------------------------------------------------------- */ 00069 /*********************************************************************/ 00074 void SPI_IntHandler(void) 00075 { 00076 SPI_DATA_SETUP_Type *xf_setup; 00077 uint16_t tmp; 00078 00079 xf_setup = (SPI_DATA_SETUP_Type *)spidat.txrx_setup; 00080 00081 /* Dummy read to clear SPI interrupt flag */ 00082 if (LPC_SPI->SPINT & SPI_SPINT_INTFLAG){ 00083 LPC_SPI->SPINT = SPI_SPINT_INTFLAG; 00084 } 00085 00086 // save status 00087 tmp = LPC_SPI->SPSR; 00088 xf_setup->status = tmp; 00089 // Check for error 00090 if (tmp & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){ 00091 xf_setup->status |= SPI_STAT_ERROR; 00092 // Disable Interrupt and call call-back 00093 SPI_IntCmd(LPC_SPI, DISABLE); 00094 if (xf_setup->callback != NULL){ 00095 xf_setup->callback(); 00096 } 00097 return; 00098 } 00099 00100 /* Check SPI complete flag */ 00101 if (tmp & SPI_SPSR_SPIF){ 00102 // Read data from SPI data 00103 tmp = SPI_ReceiveData(LPC_SPI); 00104 if (xf_setup->rx_data != NULL) 00105 { 00106 // if (spidat.dataword == 0){ 00107 // *(uint8_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp; 00108 // } else { 00109 // *(uint16_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp; 00110 // } 00111 if (spidat.dataword == 0){ 00112 *(uint8_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp; 00113 } else { 00114 *(uint16_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp; 00115 } 00116 } 00117 // Increase counter 00118 if (spidat.dataword == 0){ 00119 xf_setup->counter++; 00120 } else { 00121 xf_setup->counter += 2; 00122 } 00123 } 00124 00125 if (xf_setup->counter < xf_setup->length){ 00126 // Write data to buffer 00127 if(xf_setup->tx_data == NULL){ 00128 if (spidat.dataword == 0){ 00129 SPI_SendData(LPC_SPI, 0xFF); 00130 } else { 00131 SPI_SendData(LPC_SPI, 0xFFFF); 00132 } 00133 } else { 00134 // if (spidat.dataword == 0){ 00135 // SPI_SendData(SPI, (*(uint8_t *)(xf_setup->tx_data + xf_setup->counter))); 00136 // } else { 00137 // SPI_SendData(SPI, (*(uint16_t *)(xf_setup->tx_data + xf_setup->counter))); 00138 // } 00139 if (spidat.dataword == 0){ 00140 SPI_SendData(LPC_SPI, (*(uint8_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter))); 00141 } else { 00142 SPI_SendData(LPC_SPI, (*(uint16_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter))); 00143 } 00144 } 00145 } 00146 // No more data to send 00147 else { 00148 xf_setup->status |= SPI_STAT_DONE; 00149 // Disable Interrupt and call call-back 00150 SPI_IntCmd(LPC_SPI, DISABLE); 00151 if (xf_setup->callback != NULL){ 00152 xf_setup->callback(); 00153 } 00154 } 00155 } 00156 00157 00162 /* Public Functions ----------------------------------------------------------- */ 00167 /*********************************************************************/ 00173 void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock) 00174 { 00175 uint32_t spi_pclk; 00176 uint32_t prescale, temp; 00177 00178 CHECK_PARAM(PARAM_SPIx(SPIx)); 00179 00180 if (SPIx == LPC_SPI){ 00181 spi_pclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SPI); 00182 } else { 00183 return; 00184 } 00185 00186 prescale = 8; 00187 // Find closest clock to target clock 00188 while (1){ 00189 temp = target_clock * prescale; 00190 if (temp >= spi_pclk){ 00191 break; 00192 } 00193 prescale += 2; 00194 if(prescale >= 254){ 00195 break; 00196 } 00197 } 00198 00199 // Write to register 00200 SPIx->SPCCR = SPI_SPCCR_COUNTER(prescale); 00201 } 00202 00203 00204 /*********************************************************************/ 00210 void SPI_DeInit(LPC_SPI_TypeDef *SPIx) 00211 { 00212 CHECK_PARAM(PARAM_SPIx(SPIx)); 00213 00214 if (SPIx == LPC_SPI){ 00215 /* Set up clock and power for SPI module */ 00216 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, DISABLE); 00217 } 00218 } 00219 00220 00221 00222 /********************************************************************/ 00231 void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct) 00232 { 00233 uint32_t tmp; 00234 00235 CHECK_PARAM(PARAM_SPIx(SPIx)); 00236 00237 if(SPIx == LPC_SPI){ 00238 /* Set up clock and power for UART module */ 00239 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, ENABLE); 00240 } else { 00241 return; 00242 } 00243 00244 // Configure SPI, interrupt is disable as default 00245 tmp = ((SPI_ConfigStruct->CPHA) | (SPI_ConfigStruct->CPOL) \ 00246 | (SPI_ConfigStruct->DataOrder) | (SPI_ConfigStruct->Databit) \ 00247 | (SPI_ConfigStruct->Mode) | SPI_SPCR_BIT_EN) & SPI_SPCR_BITMASK; 00248 // write back to SPI control register 00249 SPIx->SPCR = tmp; 00250 00251 if (SPI_ConfigStruct->Databit > SPI_DATABIT_8){ 00252 spidat.dataword = 1; 00253 } else { 00254 spidat.dataword = 0; 00255 } 00256 00257 // Set clock rate for SPI peripheral 00258 SPI_SetClock(SPIx, SPI_ConfigStruct->ClockRate); 00259 00260 // If interrupt flag is set, Write '1' to Clear interrupt flag 00261 if (SPIx->SPINT & SPI_SPINT_INTFLAG){ 00262 SPIx->SPINT = SPI_SPINT_INTFLAG; 00263 } 00264 } 00265 00266 00267 00268 /*****************************************************************************/ 00280 void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct) 00281 { 00282 SPI_InitStruct->CPHA = SPI_CPHA_FIRST; 00283 SPI_InitStruct->CPOL = SPI_CPOL_HI; 00284 SPI_InitStruct->ClockRate = 1000000; 00285 SPI_InitStruct->DataOrder = SPI_DATA_MSB_FIRST; 00286 SPI_InitStruct->Databit = SPI_DATABIT_8; 00287 SPI_InitStruct->Mode = SPI_MASTER_MODE; 00288 } 00289 00290 /*********************************************************************/ 00297 void SPI_SendData(LPC_SPI_TypeDef* SPIx, uint16_t Data) 00298 { 00299 CHECK_PARAM(PARAM_SPIx(SPIx)); 00300 00301 SPIx->SPDR = Data & SPI_SPDR_BITMASK; 00302 } 00303 00304 00305 00306 /*********************************************************************/ 00311 uint16_t SPI_ReceiveData(LPC_SPI_TypeDef* SPIx) 00312 { 00313 CHECK_PARAM(PARAM_SPIx(SPIx)); 00314 00315 return ((uint16_t) (SPIx->SPDR & SPI_SPDR_BITMASK)); 00316 } 00317 00318 /*********************************************************************/ 00332 int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, \ 00333 SPI_TRANSFER_Type xfType) 00334 { 00335 uint8_t *rdata8; 00336 uint8_t *wdata8; 00337 uint16_t *rdata16; 00338 uint16_t *wdata16; 00339 uint32_t stat; 00340 uint32_t temp; 00341 00342 //read for empty buffer 00343 temp = SPIx->SPDR; 00344 //dummy to clear status 00345 temp = SPIx->SPSR; 00346 dataCfg->counter = 0; 00347 dataCfg->status = 0; 00348 00349 if (xfType == SPI_TRANSFER_POLLING){ 00350 00351 if (spidat.dataword == 0){ 00352 rdata8 = (uint8_t *)dataCfg->rx_data; 00353 wdata8 = (uint8_t *)dataCfg->tx_data; 00354 } else { 00355 rdata16 = (uint16_t *)dataCfg->rx_data; 00356 wdata16 = (uint16_t *)dataCfg->tx_data; 00357 } 00358 00359 while(dataCfg->counter < dataCfg->length) 00360 { 00361 // Write data to buffer 00362 if(dataCfg->tx_data == NULL){ 00363 if (spidat.dataword == 0){ 00364 SPI_SendData(SPIx, 0xFF); 00365 } else { 00366 SPI_SendData(SPIx, 0xFFFF); 00367 } 00368 } else { 00369 if (spidat.dataword == 0){ 00370 SPI_SendData(SPIx, *wdata8); 00371 wdata8++; 00372 } else { 00373 SPI_SendData(SPIx, *wdata16); 00374 wdata16++; 00375 } 00376 } 00377 // Wait for transfer complete 00378 while (!((stat = SPIx->SPSR) & SPI_SPSR_SPIF)); 00379 // Check for error 00380 if (stat & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){ 00381 // save status 00382 dataCfg->status = stat | SPI_STAT_ERROR; 00383 return (dataCfg->counter); 00384 } 00385 // Read data from SPI dat 00386 temp = (uint32_t) SPI_ReceiveData(SPIx); 00387 00388 // Store data to destination 00389 if (dataCfg->rx_data != NULL) 00390 { 00391 if (spidat.dataword == 0){ 00392 *(rdata8) = (uint8_t) temp; 00393 rdata8++; 00394 } else { 00395 *(rdata16) = (uint16_t) temp; 00396 rdata16++; 00397 } 00398 } 00399 // Increase counter 00400 if (spidat.dataword == 0){ 00401 dataCfg->counter++; 00402 } else { 00403 dataCfg->counter += 2; 00404 } 00405 } 00406 00407 // Return length of actual data transferred 00408 // save status 00409 dataCfg->status = stat | SPI_STAT_DONE; 00410 return (dataCfg->counter); 00411 } 00412 // Interrupt mode 00413 else { 00414 spidat.txrx_setup = (uint32_t)dataCfg; 00415 spidat.inthandler = SPI_IntHandler; 00416 00417 // Check if interrupt flag is already set 00418 if(SPIx->SPINT & SPI_SPINT_INTFLAG){ 00419 SPIx->SPINT = SPI_SPINT_INTFLAG; 00420 } 00421 if (dataCfg->counter < dataCfg->length){ 00422 // Write data to buffer 00423 if(dataCfg->tx_data == NULL){ 00424 if (spidat.dataword == 0){ 00425 SPI_SendData(SPIx, 0xFF); 00426 } else { 00427 SPI_SendData(SPIx, 0xFFFF); 00428 } 00429 } else { 00430 if (spidat.dataword == 0){ 00431 SPI_SendData(SPIx, (*(uint8_t *)dataCfg->tx_data)); 00432 } else { 00433 SPI_SendData(SPIx, (*(uint16_t *)dataCfg->tx_data)); 00434 } 00435 } 00436 SPI_IntCmd(SPIx, ENABLE); 00437 } else { 00438 // Save status 00439 dataCfg->status = SPI_STAT_DONE; 00440 } 00441 return (0); 00442 } 00443 return (0); 00444 } 00445 00446 00447 /********************************************************************/ 00456 void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState) 00457 { 00458 CHECK_PARAM(PARAM_SPIx(SPIx)); 00459 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 00460 00461 if (NewState == ENABLE) 00462 { 00463 SPIx->SPCR |= SPI_SPCR_SPIE; 00464 } 00465 else 00466 { 00467 SPIx->SPCR &= (~SPI_SPCR_SPIE) & SPI_SPCR_BITMASK; 00468 } 00469 } 00470 00471 00472 /********************************************************************/ 00477 IntStatus SPI_GetIntStatus (LPC_SPI_TypeDef *SPIx) 00478 { 00479 CHECK_PARAM(PARAM_SPIx(SPIx)); 00480 00481 return ((SPIx->SPINT & SPI_SPINT_INTFLAG) ? SET : RESET); 00482 } 00483 00484 00485 /********************************************************************/ 00490 void SPI_ClearIntPending(LPC_SPI_TypeDef *SPIx) 00491 { 00492 CHECK_PARAM(PARAM_SPIx(SPIx)); 00493 00494 SPIx->SPINT = SPI_SPINT_INTFLAG; 00495 } 00496 00497 00498 /********************************************************************/ 00510 uint32_t SPI_GetStatus(LPC_SPI_TypeDef* SPIx) 00511 { 00512 CHECK_PARAM(PARAM_SPIx(SPIx)); 00513 00514 return (SPIx->SPSR & SPI_SPSR_BITMASK); 00515 } 00516 00517 00518 00519 /********************************************************************/ 00533 FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus, uint8_t SPIStatus) 00534 { 00535 CHECK_PARAM(PARAM_SPI_STAT(SPIStatus)); 00536 00537 return ((inputSPIStatus & SPIStatus) ? SET : RESET); 00538 } 00539 00545 void SPI_StdIntHandler(void) 00546 { 00547 // Call relevant handler 00548 spidat.inthandler(); 00549 } 00550 00551 00556 #endif /* _SPI */ 00557 00562 /* --------------------------------- End Of File ------------------------------ */
Generated on Mon Feb 8 10:01:38 2010 for LPC1700CMSIS Standard Peripheral Firmware Library by
