/* --------------------------------------------------------------------------- * ssp1.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: ssp1 driver. * --------------------------------------------------------------------------- * Version(s): 1.0, 27-10-2006, Jos Pasop. * Creation. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * System include files. * --------------------------------------------------------------------------- */ #include "types.h" #include "lpc23xx.h" #include "irq.h" #include "ssp1.h" #include "ssp1ISR.h" /* FreeRTOS includes */ #include "FreeRTOS.h" #include "Task.h" #include "queue.h" #include "semphr.h" /* --------------------------------------------------------------------------- * Application include files. * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local constant and macro definitions. * --------------------------------------------------------------------------- */ #define SSP1_DISPATCH_QUEUE_SIZE 150 #define SSP_CR0 SSP1CR0 #define SSP_CR1 SSP1CR1 #define SSP_CPSR SSP1CPSR #define SSP_SR SSP1SR #define SSP_DR SSP1DR #define SSP_IMSC SSP1IMSC /* 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 ssp1DispatchedIsrQueue; xSemaphoreHandle ssp1BusMutex; /* --------------------------------------------------------------------------- * 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 ssp1Init ( void ) { // Create queue and task for ISR-dispatching ssp1DispatchedIsrQueue = xQueueCreate( SSP1_DISPATCH_QUEUE_SIZE, sizeof(UINT8)); ssp1BusMutex = xSemaphoreCreateMutex(); /* enable clock to SSP1 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 SCK1, MISO1, MOSI1 */ /* set SSEL to GPIO pin that you will have the totoal freedom to set/reset the SPI chip-select pin */ PINSEL0 &= ~0x000FC000; // Clear de pin selection for SSP1 PINSEL0 |= 0x000A8000; /* 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 = 4; /* 12 MHz / 4 EEPROM max 5 MHz */ // Enable SSP1 interrupt install_irq( VIC_CHAN_NUM_SSP1, (void *)ssp1ISR, HIGHEST_PRIORITY ); SSP_IMSC = (SSPIMSC_RORIM) | (SSPIMSC_RTIM) | (SSPIMSC_RXIM); } /* --------------------------------------------------------------------------- * ssp1Enable -- SPI1 enable. * * This function enables the SSP controller * * Global variables: -- * --------------------------------------------------------------------------- */ void ssp1Enable ( void ) { SSP_CR1 |= SSPCR1_SSE; } /* --------------------------------------------------------------------------- * ssp1Disable -- SPI1 disable. * * This function disables the SSP controller * * Global variables: -- * --------------------------------------------------------------------------- */ void ssp1Disable ( void ) { SSP_CR1 &= ~SSPCR1_SSE; } void ssp1TakeBus(void) { xSemaphoreTake( ssp1BusMutex, portMAX_DELAY ); } void ssp1ReleaseBus(void) { xSemaphoreGive( ssp1BusMutex ); } /* --------------------------------------------------------------------------- * 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 ssp1Write ( 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; } //BOOLEAN //ssp1TransmitBufferFull //( //) /* --------------------------------------------------------------------------- * 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 ssp1Read ( UINT8 * pData ) { UINT16 dispatchItem; if (xQueueReceive(ssp1DispatchedIsrQueue, &dispatchItem, 200)) { *pData = (UINT8)dispatchItem; return OK; } else { return ERROR; } } void ssp1WriteBuffer( 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 `(Busy if 1)*/ while ( (SSP_SR & SSPSR_BSY) ); } return; } void ssp1ReadBuffer( UINT8 *buffer, UINT16 length ) { UINT16 i; UINT8 dispatchItem; for ( i = 0; i < length; i++ ) { if (xQueueReceive(ssp1DispatchedIsrQueue, &dispatchItem, 200)) { *buffer = dispatchItem; buffer++; } } return; } void ssp1Loopback( BOOLEAN enable ) { if (enable == TRUE) { SSP_CR1 |= SSPCR1_LBM; } else { SSP_CR1 &= ~SSPCR1_LBM; } }