portBASE_TYPE xIOUtilsConfigureZeroCopyTx( Peripheral_Control_t * const pxPeripheralControl ) { portBASE_TYPE xReturn = pdFAIL; Zero_Copy_Tx_State_t *pxZeroCopyState; /* A peripheral is going to use a Zero_Copy_Tx_State_t structure to control transmission. */ vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxTxControl ) ); configASSERT( pxPeripheralControl->pxTxControl ); if( pxPeripheralControl->pxTxControl != NULL ) { /* Create the necessary structure. */ pxZeroCopyState = pvPortMalloc( sizeof( Zero_Copy_Tx_State_t ) ); if( pxZeroCopyState != NULL ) { pxZeroCopyState->xWriteAccessMutex = NULL; /* The structure just created contains a Semaphore handle. Create the mutex type semaphore too. */ pxZeroCopyState->xWriteAccessMutex = xSemaphoreCreateMutex(); pxZeroCopyState->usBufferLength = 0U; if( pxZeroCopyState->xWriteAccessMutex != NULL ) { /* The semaphore was created correctly. Fill in the private data structure. */ pxPeripheralControl->pxTxControl->pvTransferState = ( void * ) pxZeroCopyState; pxPeripheralControl->pxTxControl->ucType = ioctlUSE_ZERO_COPY_TX; xReturn = pdPASS; } else { /* The semaphore was not created successfully, free the Zero_Copy_Tx_State_t structure and just return an error. */ vPortFree( pxZeroCopyState ); pxZeroCopyState = NULL; } } if( pxZeroCopyState == NULL ) { /* The Tx structure, or a member it contains, could not be created, so the Tx control structure (which should point to it) should also be deleted. */ vPortFree( pxPeripheralControl->pxTxControl ); pxPeripheralControl->pxTxControl = NULL; } } return xReturn; }
portBASE_TYPE xIOUtilsConfigureCircularBufferRx( Peripheral_Control_t * const pxPeripheralControl, const portBASE_TYPE xBufferSize ) { portBASE_TYPE xReturn = pdFAIL; Circular_Buffer_Rx_State_t *pxCircularBufferState; /* A peripheral is going to use a Circular_Buffer_Rx_State_t structure to control reception. */ vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxRxControl ) ); configASSERT( pxPeripheralControl->pxRxControl ); if( pxPeripheralControl->pxRxControl != NULL ) { /* Create the necessary structure. */ pxCircularBufferState = pvPortMalloc( sizeof( Circular_Buffer_Rx_State_t ) ); if( pxCircularBufferState != NULL ) { pxCircularBufferState->xNewDataSemaphore = NULL; /* The structure just created contains a Semaphore handle. Create the binary type semaphore too. */ pxCircularBufferState->xNewDataSemaphore = xSemaphoreCreateCounting( portMAX_DELAY, 0 ); if( pxCircularBufferState->xNewDataSemaphore != NULL ) { /* The semaphore was created correctly. Fill in the private data structure. */ pxCircularBufferState->pucBufferStart = pvPortMalloc( xBufferSize ); if( pxCircularBufferState->pucBufferStart != NULL ) { pxCircularBufferState->usBufferLength = ( uint16_t ) xBufferSize; pxCircularBufferState->usErrorState = 0U; pxCircularBufferState->usNextReadIndex = 0U; pxCircularBufferState->usCharCount = 0U; pxCircularBufferState->usNextWriteIndex = 0U; pxPeripheralControl->pxRxControl->pvTransferState = ( void * ) pxCircularBufferState; pxPeripheralControl->pxRxControl->ucType = ioctlUSE_CIRCULAR_BUFFER_RX; pxCircularBufferState->xBlockTime = portMAX_DELAY; xReturn = pdPASS; } else { /* The buffer could not be allocated, so everything allocated thus far will have to be freed again and an error returned. First free the semaphore. */ vSemaphoreDelete( pxCircularBufferState->xNewDataSemaphore ); pxCircularBufferState->xNewDataSemaphore = NULL; } } if( pxCircularBufferState->xNewDataSemaphore == NULL ) { /* The semaphore was not created successfully, or the buffer could not be allocated so the semaphore has been deleted. Free the Circular_Buffer_Rx_State_t structure and just return an error. */ vPortFree( pxCircularBufferState ); pxCircularBufferState = NULL; } } if( pxCircularBufferState == NULL ) { /* The Rx structure, or a member it contains, could not be created, so the Rx control structure (which should point to it) should also be deleted. */ vPortFree( pxPeripheralControl->pxRxControl ); pxPeripheralControl->pxRxControl = NULL; } } return xReturn; }
portBASE_TYPE FreeRTOS_SSP_open( Peripheral_Control_t * const pxPeripheralControl ) { PINSEL_CFG_Type xPinConfig; portBASE_TYPE xReturn = pdFAIL; LPC_SSP_TypeDef * const pxSSP = ( LPC_SSP_TypeDef * const ) diGET_PERIPHERAL_BASE_ADDRESS( pxPeripheralControl ); SSP_DATA_SETUP_Type *pxSSPTransferDefinition; const int8_t cPeripheralNumber = diGET_PERIPHERAL_NUMBER( pxPeripheralControl ); volatile uint16_t usJunkIt; /* Sanity check the peripheral number. */ if( cPeripheralNumber < boardNUM_SSPS ) { /* Polled mode is used by default. Create the structure used to transfer SSP data in polled mode. */ pxSSPTransferDefinition = ( SSP_DATA_SETUP_Type * ) pvPortMalloc( sizeof( SSP_DATA_SETUP_Type ) ); if( pxSSPTransferDefinition != NULL ) { /* Create the transfer control structures in which references to pxSSPTransferDefinition will be stored. */ vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxTxControl ) ); vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxRxControl ) ); if( ( pxPeripheralControl->pxTxControl != NULL ) && ( pxPeripheralControl->pxTxControl != NULL ) ) { pxPeripheralControl->read = FreeRTOS_SSP_read; pxPeripheralControl->write = FreeRTOS_SSP_write; pxPeripheralControl->ioctl = FreeRTOS_SSP_ioctl; pxPeripheralControl->pxTxControl->pvTransferState = pxSSPTransferDefinition; pxPeripheralControl->pxTxControl->ucType = ioctlUSE_POLLED_TX; pxPeripheralControl->pxRxControl->pvTransferState = NULL; pxPeripheralControl->pxRxControl->ucType = ioctlUSE_POLLED_RX; taskENTER_CRITICAL(); { /* Setup the pins for the SSP being used. */ boardCONFIGURE_SSP_PINS( cPeripheralNumber, xPinConfig ); /* Set up the default SSP configuration. */ SSP_ConfigStructInit( &( xSSPConfigurations[ cPeripheralNumber ] ) ); SSP_Init( pxSSP, &( xSSPConfigurations[ cPeripheralNumber ] ) ); SSP_Cmd( pxSSP, ENABLE ); /* Clear data in Rx Fifo. */ while( ( pxSSP->SR & SSP_SR_RNE ) != 0 ) { usJunkIt = pxSSP->DR; } } taskEXIT_CRITICAL(); xReturn = pdPASS; } else { /* Could not create one of other transfer control structure, so free the created LPC_SSP_TypeDef typedef structures and any transfer control structures that were created before exiting. */ if( pxPeripheralControl->pxTxControl != NULL ) { vPortFree( pxPeripheralControl->pxTxControl ); pxPeripheralControl->pxTxControl = NULL; } if( pxPeripheralControl->pxRxControl != NULL ) { vPortFree( pxPeripheralControl->pxRxControl ); pxPeripheralControl->pxRxControl = NULL; } vPortFree( pxSSPTransferDefinition ); } } } return xReturn; }
portBASE_TYPE FreeRTOS_I2C_open( Peripheral_Control_t * const pxPeripheralControl ) { PINSEL_CFG_Type xPinConfig; LPC_I2C_TypeDef * const pxI2C = ( LPC_I2C_TypeDef * const ) diGET_PERIPHERAL_BASE_ADDRESS( pxPeripheralControl ); portBASE_TYPE xReturn = pdFAIL; const uint8_t cPeripheralNumber = diGET_PERIPHERAL_NUMBER( pxPeripheralControl ); I2C_M_SETUP_Type *pxI2CTxTransferDefinition = NULL, *pxI2CRxTransferDefinition = NULL; /* Sanity check the peripheral number. */ if( cPeripheralNumber < boardNUM_I2CS ) { /* Polled mode is used by default. This can be changed using an ioctl() call. Create the structures used to transfer I2C data in polled mode. */ pxI2CTxTransferDefinition = ( I2C_M_SETUP_Type * ) pvPortMalloc( sizeof( I2C_M_SETUP_Type ) ); pxI2CRxTransferDefinition = ( I2C_M_SETUP_Type * ) pvPortMalloc( sizeof( I2C_M_SETUP_Type ) ); if( ( pxI2CTxTransferDefinition != NULL ) && ( pxI2CRxTransferDefinition != NULL ) ) { /* Create the transfer control structures in which references to pxI2CNxTransferDefinitions will be stored. */ vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxTxControl ) ); vIOUtilsCreateTransferControlStructure( &( pxPeripheralControl->pxRxControl ) ); if( ( pxPeripheralControl->pxTxControl != NULL ) && ( pxPeripheralControl->pxRxControl != NULL ) ) { pxPeripheralControl->read = FreeRTOS_I2C_read; pxPeripheralControl->write = FreeRTOS_I2C_write; pxPeripheralControl->ioctl = FreeRTOS_I2C_ioctl; pxPeripheralControl->pxTxControl->pvTransferState = pxI2CTxTransferDefinition; pxPeripheralControl->pxTxControl->ucType = ioctlUSE_POLLED_TX; pxPeripheralControl->pxRxControl->pvTransferState = pxI2CRxTransferDefinition; pxPeripheralControl->pxRxControl->ucType = ioctlUSE_POLLED_RX; taskENTER_CRITICAL(); { /* Setup the pins for the I2C being used. */ boardCONFIGURE_I2C_PINS( cPeripheralNumber, xPinConfig ); /* Set up the default I2C configuration. */ I2C_Init( pxI2C, boardDEFAULT_I2C_SPEED ); I2C_Cmd( pxI2C, ENABLE ); } taskEXIT_CRITICAL(); xReturn = pdPASS; } } if( xReturn != pdPASS ) { /* The open operation could not complete because something could not be created. Delete anything that was created. */ if( pxI2CTxTransferDefinition != NULL ) { vPortFree( pxI2CTxTransferDefinition ); } if( pxI2CRxTransferDefinition != NULL ) { vPortFree( pxI2CRxTransferDefinition ); } if( pxPeripheralControl->pxTxControl != NULL ) { vPortFree( pxPeripheralControl->pxTxControl ); pxPeripheralControl->pxTxControl = NULL; } if( pxPeripheralControl->pxRxControl != NULL ) { vPortFree( pxPeripheralControl->pxRxControl ); pxPeripheralControl->pxRxControl = NULL; } } } /* Just to prevent compiler warnings when FreeRTIOSIOConfig.h is configured such that the variable is not used. */ ( void ) pxRxTransferControlStructs; return xReturn; }