ISF  2.2 rev 5
Intelligent Sensing Framework for Kinetis with Processor Expert
isf_uart_adapter.c
Go to the documentation of this file.
1 /*!
2 ********************************************************************************
3 * File:isf_uart_adapter.c
4 *
5 * Copyright (c) 2015, Freescale Semiconductor, Inc.
6 *
7 *******************************************************************************/
8 /*!
9 * @file isf_uart_adapter.c
10 * @brief \b isf_uart_adapter.c implements uart protocol adapter.
11 */
12 #include "isf.h"
13 #include "isf_uart_adapter.h"
14 #include "isf_uart_types.h"
15 #include "isf_devmsg.h"
16 #include "isf_util.h"
17 #include "isf_protocol_adapter.h"
18 
19 
20 
21 #define ISF_LOCK_DEFAULT (0)
22 
23 static isf_status_t bus_lock(busHandle_t *apBusHandle, isf_duration_t aTimeout, uint8 type);
24 static isf_status_t bus_unlock(busHandle_t *apBusHandle, uint8 type);
25 
26 const uart_UserDefinedVars_t * g_uartUserDefinedVars[UART_INSTANCE_COUNT];
29 extern mutex_t uart_lock[];
30 extern mutex_t uart_rdlock[];
31 
32 /*******************************************************************************
33  * Functions
34  ******************************************************************************/
35 /***********************************************************************
36  *
37  * Function Name : uart_adapter_init
38  * Description : This function Initialize the uart driver.
39  * It initialize the bus handle, reset all the registers and configure the control register for interrupt.
40  * This also initialize the lock functionality.
41  *
42  ***************************************************************************/
44 {
45  if( gSys_NumUartBuses <= aBusId){
46  return COMM_ERROR_NOEXIST ;
47  }
48  OSA_EnterCritical(kCriticalDisableInt);
49 
50  uart_busHandle_t *pBusHandle = &uart_busHandle[aBusId];
51  //uart_busHandle_t *pBusHandle = (uart_busHandle_t*)OSA_MemAllocZero(sizeof(uart_busHandle_t));
52  apBusHandle->nLock = ISF_LOCK_DEFAULT;
53  apBusHandle->pLock = &uart_lock[aBusId];
54  //apBusHandle->pLock = OSA_MemAllocZero(sizeof(mutex_t));
55  apBusHandle->nRdLock = ISF_LOCK_DEFAULT;
56  apBusHandle->pRdLock = &uart_rdlock[aBusId];
57  //apBusHandle->pRdLock = OSA_MemAllocZero(sizeof(mutex_t));
58  pBusHandle->uartHandle.instance = aBusId;
59  if(pBusHandle->busState == COMM_STATE_NO_INIT){
60  OSA_MutexCreate(apBusHandle->pLock);
61  OSA_MutexCreate(apBusHandle->pRdLock);
62  pBusHandle->busState = COMM_STATE_INIT;
63  }
64 
65  apBusHandle->pHandle = pBusHandle;
66  OSA_ExitCritical(kCriticalDisableInt);
67  return ISF_SUCCESS;
68 }
69 /***********************************************************************
70  *
71  * Function Name : uart_adapter_configure
72  * Description : This function configure the of the baudrate and timeout.
73  *
74  ***************************************************************************/
75 isf_status_t uart_adapter_configure(busHandle_t *apBusHandle, uart_user_config_t* apBusConfig)
76 {
78  if((apBusHandle == NULL) || (apBusConfig == NULL)){
79  return COMM_ERROR_NULL_PTR;
80  }
81 
82  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
83  if(pBusHandle->busState != COMM_STATE_INIT && pBusHandle->busState != COMM_STATE_STOPPED){
84  return COMM_ERROR_STOP;
85  }
86 
87  UART_Type* base = g_uartBase[pBusHandle->uartHandle.instance];
88  uart_BusConfig_t* pBusConfig = (uart_BusConfig_t*)&pBusHandle->busConfig;
89  bus_lock(apBusHandle, pBusConfig->timeout, UART_LOCK_COMMON);
90  bus_lock(apBusHandle, pBusConfig->timeout, UART_LOCK_READ);
91 
92  // Copy the user specific configuration to bushandle.
93  pBusConfig->config.baudRate = apBusConfig->baudRate;
94  pBusConfig->config.parityMode = apBusConfig->parityMode;
95  pBusConfig->config.stopBitCount = apBusConfig->stopBitCount;
96  pBusConfig->config.bitCountPerChar = apBusConfig->bitCountPerChar;
97  pBusHandle->busConfig.timeout = g_uartUserDefinedVars[pBusHandle->uartHandle.instance]->timeout;
98 
99  //release the both lock.
100  bus_unlock(apBusHandle, UART_LOCK_COMMON);
101  bus_unlock(apBusHandle, UART_LOCK_READ);
102  return ret;
103 }
104 /***********************************************************************
105  *
106  * Function Name : uart_adapter_get_state
107  * Description : This function provides the current state of the bus for a given UART bus.
108  *
109  ***************************************************************************/
111 {
112  if(apBusHandle == NULL){
113  return COMM_ERROR_NULL_PTR;
114  }
115  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
116  return pBusHandle->busState;
117 }
118 /***********************************************************************
119  *
120  * Function Name : uart_adapter_get_config
121  * Description : This function provides the current configuration for a given UART bus.
122  *
123  ***************************************************************************/
124 isf_status_t uart_adapter_get_config(busHandle_t *apBusHandle, void* apBusConfig)
125 {
126  //verify the passed the parameter
127  if((apBusHandle == NULL) || (apBusConfig == NULL)){
128  return COMM_ERROR_NULL_PTR;
129  }
130  *((uart_BusConfig_t*)apBusConfig) = ((uart_busHandle_t *)apBusHandle->pHandle)->busConfig;
131  return ISF_SUCCESS;
132 }
133 /***********************************************************************
134  *
135  * Function Name : uart_adapter_acquire_lock
136  * Description : This function provides explicit lock functionality for
137  * the multiple transactions.
138  * Note: It is important to explicit release by calling uart_adapter_release_lock
139  * once the multi-transaction is done.
140  *
141  ***************************************************************************/
143 {
144  if(apBusHandle == NULL){
145  return COMM_ERROR_NULL_PTR;
146  }
148  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
149  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
150  return ret;
151 }
152 /***********************************************************************
153  *
154  * Function Name : uart_adapter_release_lock
155  * Description : This function provides explicit release lock functionality for
156  * the multiple transactions.
157  *
158  ***************************************************************************/
160 {
161  if(apBusHandle == NULL){
162  return COMM_ERROR_NULL_PTR;
163  }
165  ret = bus_unlock(apBusHandle, UART_LOCK_COMMON);
166  return ret;
167 }
168 /***********************************************************************
169  *
170  * Function Name : uart_adapter_start
171  * Description : This function implements the start functionality of bus.
172  * Once the bus started the bus is ready to use.
173  *
174  ***************************************************************************/
176 {
177  if(apBusHandle == NULL){
178  return COMM_ERROR_NULL_PTR;
179  }
180  isf_status_t ret;
181  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
182 
183  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
184  // Enable the transmitter and receiver.
185  UART_Type* base = g_uartBase[pBusHandle->uartHandle.instance];
186  UART_HAL_EnableTransmitter (base);
187  UART_HAL_EnableReceiver (base);
188  // State settings for the bus.
189  pBusHandle->busState = COMM_STATE_OK;
190  bus_unlock(apBusHandle, UART_LOCK_COMMON);
191  return ret;
192 }
193 /***********************************************************************
194  *
195  * Function Name : uart_adapter_stop
196  * Description : This function implements the stop functionality of bus.
197  * Once the bus stopped the bus is not ready for further use. It is necessary to start the bus again.
198  *
199  ***************************************************************************/
201 {
202  if(apBusHandle == NULL){
203  return COMM_ERROR_NULL_PTR;
204  }
205  isf_status_t ret;
206  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
207  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
208  // Disable the transmitter and receiver.
209  UART_Type* base = g_uartBase[pBusHandle->uartHandle.instance];
210  UART_HAL_DisableTransmitter (base);
211  UART_HAL_DisableReceiver (base);
212  // State settings for the bus.
213  pBusHandle->busState = COMM_STATE_STOPPED;
214  bus_unlock(apBusHandle, UART_LOCK_COMMON);
215  return ret;
216 }
217 /***********************************************************************
218  *
219  * Function Name : uart_adapter_get_endpoint
220  * Description : This function uses to establish a communication endpoint
221  * between the devices for a given UART bus. A bus can have multiple device connected virtually.
222  * Each will be having separate a communication endpoint through which the master can talk the device.
223  *
224  ***************************************************************************/
225 isf_status_t uart_adapter_get_endpoint(busHandle_t *apBusHandle, void *apDevice, void** apEndpointHandle)
226 {
227  isf_status_t ret;
228  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
229  if((apBusHandle == NULL) || (apEndpointHandle == NULL)){
230  return COMM_ERROR_NULL_PTR;
231  }
232  // Cannot open if the bus is not started.
233  if(pBusHandle->busState != COMM_STATE_OK){
234  return COMM_ERROR_STOP;
235  }
236  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
237  if(ret != ISF_SUCCESS){
238  return ret;
239  }
240  uart_Endpoint_t *pEndpoint = OSA_MemAllocZero(sizeof(uart_Endpoint_t));
241  pEndpoint->pBusHandle = apBusHandle;
242  *apEndpointHandle = pEndpoint;
243  bus_unlock(apBusHandle, UART_LOCK_COMMON);
244  return ret;
245 }
246 /***********************************************************************
247  *
248  * Function Name : uart_adapter_release_endpoint
249  * Description : Its designed to release the communication endpoint.
250  * At this point there is nothing to implement.
251  *
252  ***************************************************************************/
254 {
255  if(apEndpoint == NULL){
256  return COMM_ERROR_NULL_PTR;
257  }
258  OSA_MemFree(apEndpoint);
259  return ISF_SUCCESS;
260 }
261 /***********************************************************************
262  *
263  * Function Name : uart_adapter_write
264  * Description : The function provides write interface for the given UART bus.
265  * It writes the data sequentially to the device byte at a time.
266  *
267  ***************************************************************************/
268 isf_status_t uart_adapter_write(void* apEndpointHandle, int32 offset, void* pWriteBuffer, uint32 buffsize, uint32 nByteWrite, uart_writeFlags_t aFlags)
269 {
270  if((NULL == apEndpointHandle) || (NULL == pWriteBuffer)){
271  return COMM_ERROR_NULL_PTR;
272  }
273  if(buffsize < nByteWrite){
274  return COMM_ERROR_BUF_SIZE;
275  }
276  isf_status_t ret;
277  uart_Endpoint_t *pEndpoint = (uart_Endpoint_t *)apEndpointHandle;
278  uart_busHandle_t* pBusHandle = (uart_busHandle_t*)pEndpoint->pBusHandle->pHandle;
279 
280  // Invalid bus state, cannot perform the write operation.
281  if(pBusHandle->busState != COMM_STATE_OK ){
282  return COMM_ERROR_INIT;
283  }
284 
285  ret = bus_lock(pEndpoint->pBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
286  if(ret != ISF_SUCCESS){
287  return ret;
288  }
289 
290  if(aFlags == UART_ASYNC) {
291  // invoke driver specific asynchronized write functions.
292  switch(g_uartUserDefinedVars[pBusHandle->uartHandle.instance]->uartMode)
293  {
294  case UART_MODE_INT:
295  ret = UART_DRV_SendData(pBusHandle->uartHandle.instance, pWriteBuffer, nByteWrite);
296  break;
297  }
298  } else {
299  // invoke driver specific synchronized write function.
300  switch(g_uartUserDefinedVars[pBusHandle->uartHandle.instance]->uartMode)
301  {
302  case UART_MODE_INT:
303  ret = UART_DRV_SendDataBlocking(pBusHandle->uartHandle.instance, pWriteBuffer, nByteWrite, pBusHandle->busConfig.timeout);
304  break;
305  }
306  }
307 
308  bus_unlock(pEndpoint->pBusHandle, UART_LOCK_COMMON);
309  return ret;
310 
311  }
312 /***********************************************************************
313  *
314  * Function Name : uart_adapter_write
315  * Description : The function provides read interface for the given UART bus.
316  * It reads the data sequentially from the device byte at a time.
317  *
318  ***************************************************************************/
319 isf_status_t uart_adapter_read(void* apEndpointHandle, int32 offset, void* pReadBuffer, uint32 buffsize, uint32 nByteRead, uart_readFlags_t aFlags)
320 {
321 
322  if((NULL == apEndpointHandle) || (NULL == pReadBuffer)){
323  return COMM_ERROR_NULL_PTR;
324  }
325  if(buffsize < nByteRead){
326  return COMM_ERROR_BUF_SIZE;
327  }
329  uart_Endpoint_t *pEndpoint = (uart_Endpoint_t *)apEndpointHandle;
330  uart_busHandle_t* pBusHandle = (uart_busHandle_t*)pEndpoint->pBusHandle->pHandle;
331  // Invalid bus state, cannot perform the read operation.
332  if(pBusHandle->busState != COMM_STATE_OK ){
333  return COMM_ERROR_INIT;
334  }
335  ret = bus_lock(pEndpoint->pBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_READ);
336  if(ret != ISF_SUCCESS){
337  return ret;
338  }
339  if(aFlags == UART_ASYNC) {
340  // invoke driver specific asynchronized read function.
341  switch(g_uartUserDefinedVars[pBusHandle->uartHandle.instance]->uartMode)
342  {
343  case UART_MODE_DMA:
344  case UART_MODE_INT:
345  ret = UART_DRV_ReceiveData(pBusHandle->uartHandle.instance, pReadBuffer, nByteRead);
346  break;
347  }
348  } else {
349  // invoke driver specific synchronized read function.
350  switch(g_uartUserDefinedVars[pBusHandle->uartHandle.instance]->uartMode)
351  {
352  case UART_MODE_DMA:
353  case UART_MODE_INT:
354  ret = UART_DRV_ReceiveDataBlocking(pBusHandle->uartHandle.instance,pReadBuffer, nByteRead, OSA_WAIT_FOREVER);
355  break;
356  }
357  }
358 
359  bus_unlock(pEndpoint->pBusHandle, UART_LOCK_READ);
360 
361  return ret;
362 }
363 /***********************************************************************
364  *
365  * Function Name : bus_lock
366  * Description : Internal function uses to lock the UART.
367  * Each UART has own lock that enables the concurrent access to bus safely.
368  * It uses mqx synchronization object mutex.
369  *
370  ***************************************************************************/
371  static isf_status_t bus_lock(busHandle_t *apBusHandle, isf_duration_t aTimeout, uint8 type)
372  {
373  uint8 *pnLock;
374  void* pLock;
375  if(type == UART_LOCK_READ){
376  pLock = apBusHandle->pRdLock;
377  pnLock = &apBusHandle->nRdLock;
378  }else{
379  pLock = apBusHandle->pLock;
380  pnLock = &apBusHandle->nLock;
381  }
382  // Invalid bus.
383  if (NULL == pLock){
384  return COMM_ERROR_LOCK;
385  }
386  //if there is a lock on the specific handler. should not take the mutex multiple time
387  // for the same handler
388  if (ISF_LOCK_DEFAULT == *pnLock){
389  if(kStatus_OSA_Success != OSA_MutexLock ((mutex_t*)pLock, OSA_WAIT_FOREVER)){
390  return COMM_ERROR_LOCK;
391  }
392  }
393  (*pnLock)++;
394  return ISF_SUCCESS;
395  }
396  /***********************************************************************
397  *
398  * Function Name : bus_unlock
399  * Description : Internal function uses to un-lock the UART.
400  *
401  ***************************************************************************/
402  static isf_status_t bus_unlock(busHandle_t *apBusHandle, uint8 type )
403  {
404  uint8 *pnLock;
405  void* pLock;
406  if(type == UART_LOCK_READ){
407  pLock = apBusHandle->pRdLock;
408  pnLock = &apBusHandle->nRdLock;
409  }else{
410  pLock = apBusHandle->pLock;
411  pnLock = &apBusHandle->nLock;
412  }
413  //if there is no lock associate with the handler
414  if(NULL == pLock){
415  // No lock is associated with this bus.
416  return COMM_ERROR_LOCK;
417  }
418  if(0 == *pnLock){
419  return ISF_SUCCESS;
420  }else if (ISF_LOCK_DEFAULT == --*pnLock){
421  // release the resource
422  OSA_MutexUnlock((mutex_t*)pLock);
423  }
424  return ISF_SUCCESS;
425  }
426 /***********************************************************************
427 *
428 * Function Name : uart_user_init
429 * Description : The function initializes parameters for user defined values.
430 *
431  ***************************************************************************/
432 uart_status_t uart_user_init(uint32_t instance, const uart_UserDefinedVars_t * userDefinedVars)
433 {
434  assert(g_uartBase[instance]);
435  assert(instance < UART_INSTANCE_COUNT);
436 
437  g_uartUserDefinedVars[instance] = userDefinedVars;
438 
439  return kStatus_UART_Success;
440 }
441 
const uart_UserDefinedVars_t * g_uartUserDefinedVars[UART_INSTANCE_COUNT]
unsigned char uint8
Definition: isf_types.h:76
uint32_t instance
uint32 comm_Id_t
This type is for a numeric channel identifier- index into an array of channels in the system...
Definition: isf_comm.h:50
isf_status_t uart_adapter_release_lock(busHandle_t *apBusHandle)
This function releases exclusive bus access.
isf_duration_t timeout
This structure defines the data bus handle.
uart_BusConfig_t busConfig
isf_status_t uart_adapter_get_endpoint(busHandle_t *apBusHandle, void *apDevice, void **apEndpointHandle)
This function creates a endpoint at a already initialized bus.
isf_status_t uart_adapter_acquire_lock(busHandle_t *apBusHandle, isf_duration_t aTimeout)
This function locks the bus for exclusive access.
uart_user_config_t config
isf_status_t uart_adapter_read(void *apEndpointHandle, int32 offset, void *pReadBuffer, uint32 buffsize, uint32 nByteRead, uart_readFlags_t aFlags)
This function reads from a uart device.
uart_status_t uart_user_init(uint32_t instance, const uart_UserDefinedVars_t *userDefinedVars)
Initializes UART User defined parameters.
isf_status_t uart_adapter_write(void *apEndpointHandle, int32 offset, void *pWriteBuffer, uint32 buffsize, uint32 nByteWrite, uart_writeFlags_t aFlags)
This function writes to a uart device.
isf_protocol_adapter.h defines the general interface definition for the protocol adapter.
mutex_t uart_lock[]
uint8 gSys_NumUartBuses
isf_status_t uart_adapter_stop(busHandle_t *apBusHandle)
This function stops the given uart bus.
isf_status_t uart_adapter_release_endpoint(uart_Endpoint_t *apEndpoint)
This function closes a particular endpoint.
isf_status_t uart_adapter_init(comm_Id_t aBusId, busHandle_t *apBusHandle)
This function initializes a uart bus.
The isf_util.h file contains the utility method declarations and macros.
This structure is a declaration of a BusHandle type.
isf_uart_state_t uartHandle
comm_Flags_t uart_readFlags_t
comm_Flags_t uart_writeFlags_t
isf_status_t uart_adapter_get_config(busHandle_t *apBusHandle, void *apBusConfig)
This function returns the current bus configuration.
uint32 isf_duration_t
ISF time duration in microseconds.
Definition: isf.h:84
Main ISF header file. Contains code common to all ISF components.
uart_busHandle_t uart_busHandle[]
comm_State_t uart_adapter_get_state(busHandle_t *apBusHandle)
This function returns the current bus state.
signed long int int32
Definition: isf_types.h:74
This structure defines a device endpoint encapsulation for uart handler.
isf_uart_types.h defines the uart protocol adapter structure and types.
#define ISF_LOCK_DEFAULT
int32 isf_status_t
ISF return status type.
Definition: isf.h:76
mutex_t uart_rdlock[]
isf_uart_adapter.h defines the API definitions and types for the uart protocol adapter.
enum comm_State_vals comm_State_t
This enum holds an enumerated value describing the state of a channel.
Definition: isf_comm.h:53
unsigned long int uint32
Definition: isf_types.h:78
isf_status_t uart_adapter_start(busHandle_t *apBusHandle)
This function starts a bus.
isf_devmsg.h defines the API definitions and types for the Intelligent Sensing (ISF) Device Messaging...
isf_status_t uart_adapter_configure(busHandle_t *apBusHandle, uart_user_config_t *apBusConfig)
This function reconfigures an already initialized bus.