/* --------------------------------------------------------------------------- * spi1.c - v1.0 (c) 2006 Micro-key bv * --------------------------------------------------------------------------- * Micro-key bv * Industrieweg 28, 9804 TG Noordhorn * Postbus 92, 9800 AA Zuidhorn * The Netherlands * Tel: +31 594 503020 * Fax: +31 594 505825 * Email: support@microkey.nl * Web: www.microkey.nl * --------------------------------------------------------------------------- * Description: spi1 driver. * --------------------------------------------------------------------------- * Version(s): 1.0, 27-10-2006, Jos Pasop. * Creation. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * System include files. * --------------------------------------------------------------------------- */ #include "types.h" #include "lpc23xx.h" #include "irq.h" #include "ssp0.h" #include "ssp0ISR.h" /* FreeRTOS includes */ #include "FreeRTOS.h" #include "Task.h" #include "queue.h" #include "semphr.h" /* --------------------------------------------------------------------------- * Application include files. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local constant and macro definitions. * --------------------------------------------------------------------------- */ #define SSP0_DISPATCH_QUEUE_SIZE 64 #define SSP_CR0 SSP0CR0 #define SSP_CR1 SSP0CR1 #define SSP_CPSR SSP0CPSR #define SSP_SR SSP0SR #define SSP_DR SSP0DR #define SSP_IMSC SSP0IMSC /* Functions. */ #define SPI_RXIM_ENABLE SSP1IMSC |= SSPIMSC_RXIM #define SPI_RXIM_DISABLE SSP1IMSC &= ~SSPIMSC_RXIM #define SPI_TXIM_ENABLE SSP1IMSC |= SSPIMSC_TXIM #define SPI_TXIM_DISABLE SSP1IMSC &= ~SSPIMSC_TXIM /* --------------------------------------------------------------------------- * Global variable definitions. * --------------------------------------------------------------------------- */ xQueueHandle ssp0DispatchedIsrQueue; xSemaphoreHandle ssp0BusMutex; /* --------------------------------------------------------------------------- * Local variable definitions. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local function declarations. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * ssp1Init -- SPI1 controller init. * * This function initialises the SPI1 controller. * SPI1 is configured as master for the A/D converters (ADS8344). * The SPI clock is used to clock the conversion. * Each conversion takes 24 clk pulses. For a 50kHz throughput the SPI clock * should be set at 24 * 50kHz = 1,2 MHz. * * Global variables: -- * --------------------------------------------------------------------------- */ void ssp0Init ( void ) { // Create queue and task for ISR-dispatching ssp0DispatchedIsrQueue = xQueueCreate( SSP0_DISPATCH_QUEUE_SIZE, sizeof(UINT8)); ssp0BusMutex = xSemaphoreCreateMutex(); /* enable clock to SSP0 for security reason. By default, it's enabled already */ PCONP |= (1 << 10); /* Configure PIN connect block */ /* port 1 bits 7, 8, 9, 6 are SSP port SCK0, MISO0, MOSI0 */ /* set SSEL to GPIO pin that you will have the totoal freedom to set/reset the SPI chip-select pin */ //PINSEL3 &= ~0x000FC000; // Clear de pin selection for SSP1 PINSEL3 |= 0x0003C300; /* Control register 0. * DSS = 16 bit tranfer * FRF = SPI * CPOL = 0 * CPHA = 0 * SCR = 0 */ SSP_CR0 = SSPCR0_DSS_8 | SSPCR0_SPO_L | SSPCR0_SPH_N; /* Control register 1. * LBM = 0 * SSE = 0 * MS = 0 (master) * SOD = 0 */ SSP_CR1 = 0x0; /* SSP Clock Prescale register. */ SSP_CPSR = 10; /* 12 MHz / 10 = 1,2 Mhz (ADC highest speed) */ // Enable SSP0 interrupt install_irq( VIC_CHAN_NUM_SSP0, (void *)ssp0ISR, HIGHEST_PRIORITY); SSP_IMSC = (SSPIMSC_RORIM) | (SSPIMSC_RTIM) | (SSPIMSC_RXIM); } /* --------------------------------------------------------------------------- * ssp1Enable -- SPI1 enable. * * This function enables the SSP controller * * Global variables: -- * --------------------------------------------------------------------------- */ void ssp0Enable ( void ) { SSP_CR1 |= SSPCR1_SSE; } /* --------------------------------------------------------------------------- * ssp1Disable -- SPI1 disable. * * This function disables the SSP controller * * Global variables: -- * --------------------------------------------------------------------------- */ void ssp0Disable ( void ) { SSP_CR1 &= ~SSPCR1_SSE; } void ssp0TakeBus(void) { xSemaphoreTake( ssp0BusMutex, portMAX_DELAY ); } void ssp0ReleaseBus(void) { xSemaphoreGive( ssp0BusMutex ); } /* --------------------------------------------------------------------------- * ssp1Write -- SPI1 write bit. * * This function sends bit data through the SPI bus. * If the SPI bus is disabled ERROR is returned. Otherwise OK. * * Global variables: -- * --------------------------------------------------------------------------- */ RESULT ssp0Write ( UINT8 data ) { if ((SSP_CR1 & SSPCR1_SSE) == 0) { return ERROR; /* SPI controller is disabled */ } while ((SSP_SR & SSPSR_TNF) == 0); /* wait if transmit FIFO is full */ SSP_DR = data; /* write data */ return OK; } /* --------------------------------------------------------------------------- * ssp1Read -- SPI1 read. * * This function reads 16 bit data from the SPI bus. * If no data is available ERROR is returned. Otherwise OK. * * Global variables: -- * --------------------------------------------------------------------------- */ RESULT ssp0Read ( UINT8 * pData ) { UINT16 dispatchItem; if (xQueueReceive(ssp0DispatchedIsrQueue, &dispatchItem, 200)) { *pData = (UINT8)dispatchItem; } return OK; } void ssp0WriteBuffer( UINT8 *buffer, UINT16 length ) { UINT16 i; for ( i = 0; i < length; i++ ) { /* as long as TNF bit is set (TxFIFO is not full), I can always transmit */ while ( !(SSP_SR & SSPSR_TNF) ); SSP_DR = *buffer; buffer++; /* Wait until the Busy bit is cleared */ while ( SSP_SR & SSPSR_BSY ); } return; } void ssp0ReadBuffer( UINT8 *buffer, UINT16 length ) { UINT16 i; UINT8 dispatchItem; for ( i = 0; i < length; i++ ) { if (xQueueReceive(ssp0DispatchedIsrQueue, &dispatchItem, 200)) { *buffer = dispatchItem; buffer++; } } return; } void ssp0Loopback( BOOLEAN enable ) { if (enable == TRUE) { SSP_CR1 |= SSPCR1_LBM; } else { SSP_CR1 &= ~SSPCR1_LBM; } }