ISF  2.1
Intelligent Sensing Framework for Kinetis with Processor Expert
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
isf_uart_adapter.c
Go to the documentation of this file.
1 /*!
2 ********************************************************************************
3 * File:isf_uart_adapter.c
4 *
5 * Copyright (c) 2012-2014, 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_target.h"
13 #include <lwevent.h>
14 #include <mqxlite.h>
15 #include <mutex.h>
16 #include "lwmem.h"
17 #include "isf.h"
18 #include "isf_uart_adapter.h"
19 #include "fsl_uart_driver.h"
20 #include "isf_devmsg.h"
21 #include "isf_util.h"
22 #include "isf_protocol_adapter.h"
23 #define ISF_LOCK_DEFAULT (0)
24 
25 static isf_status_t bus_lock(busHandle_t *apBusHandle, isf_duration_t aTimeout, uint8 type);
26 static isf_status_t bus_unlock(busHandle_t *apBusHandle, uint8 type);
27 
28 extern MUTEX_STRUCT uart_lock[];
29 extern MUTEX_STRUCT uart_rdlock[];
33 
34 /*******************************************************************************
35  * Functions
36  ******************************************************************************/
37 /***********************************************************************
38  *
39  * Function Name : uart_adapter_init
40  * Description : This function Initialize the uart driver.
41  * It initialize the bus handle, reset all the registers and configure the control register for interrupt.
42  * This also initialize the lock functionality.
43  *
44  ***************************************************************************/
46 {
47  MUTEX_ATTR_STRUCT mutexattr;
48 
49  if( gSys_NumUARTBuses <= aBusId){
50  return COMM_ERROR_NOEXIST ;
51  }
52  // Initialize the bus handle.
53 
54  _int_disable();
55 
56  uart_busHandle_t *pBusHandle = &uart_busHandle[aBusId];
57 
58  apBusHandle->nLock = ISF_LOCK_DEFAULT;
59  apBusHandle->pLock = &uart_lock[aBusId];
60  apBusHandle->nRdLock = ISF_LOCK_DEFAULT;
61  apBusHandle->pRdLock = &uart_rdlock[aBusId];
62  if(pBusHandle->busState == COMM_STATE_NO_INIT){
63  if (MQX_OK == _mutatr_init(&mutexattr)) {
64  _mutatr_set_sched_protocol(&mutexattr, MUTEX_PRIO_INHERIT);
65  }else{
66  _int_enable();
67  return COMM_ERROR_INIT;
68  }
69  // Initialize the common lock
70  if(MQX_OK != _mutex_init(apBusHandle->pLock, &mutexattr)){
71  _int_enable();
72  return COMM_ERROR_INIT;
73  }
74  // Initialize the read lock
75  if(MQX_OK != _mutex_init(apBusHandle->pRdLock, &mutexattr)){
76  _int_enable();
77  return COMM_ERROR_INIT;
78  }
79 
80  //initialize the driver.
81  pBusHandle->busConfig = gSys_UartBusConfig[aBusId];
82  uart_init(aBusId, &pBusHandle->uartHandle, (const uart_user_config_t*)&pBusHandle->busConfig.config);
83  pBusHandle->busState = COMM_STATE_OK;
84  }
85  apBusHandle->pHandle = pBusHandle;
86  _int_enable();
87  return ISF_SUCCESS;
88 }
89 /***********************************************************************
90  *
91  * Function Name : uart_adapter_configure
92  * Description : This function configure the of the baudrate and timeout.
93  *
94  ***************************************************************************/
96 {
98  if((apBusHandle == NULL) || (apBusConfig == NULL)){
99  return COMM_ERROR_NULL_PTR;
100  }
101 
102  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
103  if(pBusHandle->busState != COMM_STATE_STOPPED){
104  return COMM_ERROR_STOP;
105  }
106  uart_BusConfig_t* pBusConfig = (uart_BusConfig_t*)&pBusHandle->busConfig;
107  ret = bus_lock(apBusHandle, pBusConfig->timeout, UART_LOCK_COMMON);
108  ret = bus_lock(apBusHandle, pBusConfig->timeout, UART_LOCK_READ);
109  // Uart hal init
110  uart_hal_init(pBusHandle->uartHandle.instance, apBusConfig);
111  // Copy the user specific configuration to bushandle.
112  pBusConfig->config.baudRate = apBusConfig->baudRate;
113  pBusConfig->config.parityMode = apBusConfig->parityMode;
114  pBusConfig->config.stopBitCount = apBusConfig->stopBitCount;
115  pBusConfig->config.bitCountPerChar = apBusConfig->bitCountPerChar;
116  //release the both lock.
117  bus_unlock(apBusHandle, UART_LOCK_COMMON);
118  bus_unlock(apBusHandle, UART_LOCK_READ);
119  return ret;
120 }
121 /***********************************************************************
122  *
123  * Function Name : uart_adapter_get_state
124  * Description : This function provides the current state of the bus for a given UART bus.
125  *
126  ***************************************************************************/
128 {
129  if(apBusHandle == NULL){
130  return COMM_ERROR_NULL_PTR;
131  }
132  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
133  return pBusHandle->busState;
134 }
135 /***********************************************************************
136  *
137  * Function Name : uart_adapter_get_config
138  * Description : This function provides the current configuration for a given UART bus.
139  *
140  ***************************************************************************/
141 isf_status_t uart_adapter_get_config(busHandle_t *apBusHandle, void* apBusConfig)
142 {
143  //verify the passed the parameter
144  if((apBusHandle == NULL) || (apBusConfig == NULL)){
145  return COMM_ERROR_NULL_PTR;
146  }
147  *((uart_BusConfig_t*)apBusConfig) = ((uart_busHandle_t *)apBusHandle->pHandle)->busConfig;
148  return ISF_SUCCESS;
149 }
150 /***********************************************************************
151  *
152  * Function Name : uart_adapter_acquire_lock
153  * Description : This function provides explicit lock functionality for
154  * the multiple transactions.
155  * Note: It is important to explicit release by calling uart_adapter_release_lock
156  * once the multi-transaction is done.
157  *
158  ***************************************************************************/
160 {
161  if(apBusHandle == NULL){
162  return COMM_ERROR_NULL_PTR;
163  }
165  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
166  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
167  return ret;
168 }
169 /***********************************************************************
170  *
171  * Function Name : uart_adapter_release_lock
172  * Description : This function provides explicit release lock functionality for
173  * the multiple transactions.
174  *
175  ***************************************************************************/
177 {
178  if(apBusHandle == NULL){
179  return COMM_ERROR_NULL_PTR;
180  }
182  ret = bus_unlock(apBusHandle, UART_LOCK_COMMON);
183  return ret;
184 }
185 /***********************************************************************
186  *
187  * Function Name : uart_adapter_start
188  * Description : This function implements the start functionality of bus.
189  * Once the bus started the bus is ready to use.
190  *
191  ***************************************************************************/
193 {
194  if(apBusHandle == NULL){
195  return COMM_ERROR_NULL_PTR;
196  }
197  isf_status_t ret;
198  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
199 
200  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
201  // Enable the transmitter and receiver.
204  pBusHandle->busState = COMM_STATE_OK;
205  bus_unlock(apBusHandle, UART_LOCK_COMMON);
206  return ret;
207 }
208 /***********************************************************************
209  *
210  * Function Name : uart_adapter_stop
211  * Description : This function implements the stop functionality of bus.
212  * Once the bus stopped the bus is not ready for further use. It is necessary to start the bus again.
213  *
214  ***************************************************************************/
216 {
217  if(apBusHandle == NULL){
218  return COMM_ERROR_NULL_PTR;
219  }
220  isf_status_t ret;
221  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
222  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
223  // Disable the transmitter and receiver.
226  // State settings for the bus.
227  pBusHandle->busState = COMM_STATE_STOPPED;
228  bus_unlock(apBusHandle, UART_LOCK_COMMON);
229  return ret;
230 }
231 /***********************************************************************
232  *
233  * Function Name : uart_adapter_get_endpoint
234  * Description : This function uses to establish a communication endpoint
235  * between the devices for a given UART bus. A bus can have multiple device connected virtually.
236  * Each will be having separate a communication endpoint through which the master can talk the device.
237  *
238  ***************************************************************************/
239 isf_status_t uart_adapter_get_endpoint(busHandle_t *apBusHandle, void *apDevice, void** apEndpointHandle)
240 {
241  isf_status_t ret;
242  uart_busHandle_t *pBusHandle = (uart_busHandle_t *)apBusHandle->pHandle;
243  if((apBusHandle == NULL) || (apEndpointHandle == NULL)){
244  return COMM_ERROR_NULL_PTR;
245  }
246  // Cannot open if the bus is not started.
247  if(pBusHandle->busState != COMM_STATE_OK){
248  return COMM_ERROR_STOP;
249  }
250  ret = bus_lock(apBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
251  if(ret != ISF_SUCCESS){
252  return ret;
253  }
254  uart_Endpoint_t *pEndpoint = _lwmem_alloc_system_zero(sizeof(uart_Endpoint_t));
255  pEndpoint->pBusHandle = apBusHandle;
256  *apEndpointHandle = pEndpoint;
257  bus_unlock(apBusHandle, UART_LOCK_COMMON);
258  return ret;
259 }
260 /***********************************************************************
261  *
262  * Function Name : uart_adapter_release_endpoint
263  * Description : Its designed to release the communication endpoint.
264  * At this point there is nothing to implement.
265  *
266  ***************************************************************************/
267 
269 {
270  if(apEndpoint == NULL){
271  return COMM_ERROR_NULL_PTR;
272  }
273  _lwmem_free(apEndpoint);
274  return ISF_SUCCESS;
275 }
276 /***********************************************************************
277  *
278  * Function Name : uart_adapter_write
279  * Description : The function provides write interface for the given UART bus.
280  * It writes the data sequentially to the device byte at a time.
281  *
282  ***************************************************************************/
283 isf_status_t uart_adapter_write(void* apEndpointHandle, int32 offset, void* pWriteBuffer, uint32 buffsize, uint32 nByteWrite, uart_writeFlags_t aFlags)
284 {
285  if((NULL == apEndpointHandle) || (NULL == pWriteBuffer)){
286  return COMM_ERROR_NULL_PTR;
287  }
288  if(buffsize < nByteWrite){
289  return COMM_ERROR_BUF_SIZE;
290  }
291  isf_status_t ret;
292  uart_Endpoint_t *pEndpoint = (uart_Endpoint_t *)apEndpointHandle;
293  uart_busHandle_t* pBusHandle = (uart_busHandle_t*)pEndpoint->pBusHandle->pHandle;
294  // Invalid bus state, cannot perform the write operation.
295  if(pBusHandle->busState != COMM_STATE_OK ){
296  return COMM_ERROR_INIT;
297  }
298 
299  ret = bus_lock(pEndpoint->pBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_COMMON);
300  if(ret != ISF_SUCCESS){
301  return ret;
302  }
303  if(aFlags == UART_ASYNC){
304  // invoke driver specific asynchronized write functions.
305  ret = uart_send_data_async(&pBusHandle->uartHandle, pWriteBuffer, nByteWrite);
306  }else{
307  // invoke driver specific synchronized write function.
308  ret = uart_send_data(&pBusHandle->uartHandle, pWriteBuffer, nByteWrite, pBusHandle->busConfig.timeout);
309  }
310 
311  bus_unlock(pEndpoint->pBusHandle, UART_LOCK_COMMON);
312  return ret;
313 
314  }
315 /***********************************************************************
316  *
317  * Function Name : uart_adapter_write
318  * Description : The function provides read interface for the given UART bus.
319  * It reads the data sequentially from the device byte at a time.
320  *
321  ***************************************************************************/
322 isf_status_t uart_adapter_read(void* apEndpointHandle, int32 offset, void* pReadBuffer, uint32 buffsize, uint32 nByteRead, uart_readFlags_t aFlags)
323 {
324 
325  if((NULL == apEndpointHandle) || (NULL == pReadBuffer)){
326  return COMM_ERROR_NULL_PTR;
327  }
328  if(buffsize < nByteRead){
329  return COMM_ERROR_BUF_SIZE;
330  }
332  uart_Endpoint_t *pEndpoint = (uart_Endpoint_t *)apEndpointHandle;
333  uart_busHandle_t* pBusHandle = (uart_busHandle_t*)pEndpoint->pBusHandle->pHandle;
334  // Invalid bus state, cannot perform the read operation.
335  if(pBusHandle->busState != COMM_STATE_OK ){
336  return COMM_ERROR_INIT;
337  }
338  ret = bus_lock(pEndpoint->pBusHandle, pBusHandle->busConfig.timeout, UART_LOCK_READ);
339  if(ret != ISF_SUCCESS){
340  return ret;
341  }
342  if(aFlags == UART_ASYNC){
343  // invoke driver specific asynchronized read function.
344  ret = uart_receive_data_async(&pBusHandle->uartHandle, pReadBuffer, nByteRead);
345  }else{
346  // invoke driver specific synchronized read function.
347  ret = uart_receive_data(&pBusHandle->uartHandle, pReadBuffer, nByteRead, 0);
348  }
349 
350  bus_unlock(pEndpoint->pBusHandle, UART_LOCK_READ);
351 
352  return ret;
353 
354 }
355 /***********************************************************************
356  *
357  * Function Name : bus_lock
358  * Description : Internal function uses to lock the UART.
359  * Each UART has own lock that enables the concurrent access to bus safely.
360  * It uses mqx synchronization object mutex.
361  *
362  ***************************************************************************/
363  static isf_status_t bus_lock(busHandle_t *apBusHandle, isf_duration_t aTimeout, uint8 type)
364  {
365 #if 1
366  uint8 *pnLock;
367  void* pLock;
368  if(type == UART_LOCK_READ){
369  pLock = apBusHandle->pRdLock;
370  pnLock = &apBusHandle->nRdLock;
371  }else{
372  pLock = apBusHandle->pLock;
373  pnLock = &apBusHandle->nLock;
374  }
375  // Invalid bus.
376  if (NULL == pLock){
377  return COMM_ERROR_LOCK;
378  }
379  //if there is a lock on the specific handler. should not take the mutex multiple time
380  // for the same handler
381  if (ISF_LOCK_DEFAULT == *pnLock){
382  if(MQX_OK != _mutex_lock ((MUTEX_STRUCT*)pLock)){
383  return COMM_ERROR_LOCK;
384  }
385  }
386  (*pnLock)++;
387  return ISF_SUCCESS;
388 #else
389  if (NULL == apBusHandle->pLock){
390  return COMM_ERROR_LOCK;
391  }
392  //if there is a lock on the specific handler. should not take the mutex multiple time
393  // for the same handler
394  if (ISF_LOCK_DEFAULT == apBusHandle->nLock){
395  if(MQX_OK != _mutex_lock ((MUTEX_STRUCT*)apBusHandle->pLock)){
396  return COMM_ERROR_LOCK;
397  }
398  }
399  apBusHandle->nLock++;
400 
401  return ISF_SUCCESS;
402 #endif
403 
404  }
405  /***********************************************************************
406  *
407  * Function Name : bus_unlock
408  * Description : Internal function uses to un-lock the UART.
409  *
410  ***************************************************************************/
411 
412  static isf_status_t bus_unlock(busHandle_t *apBusHandle, uint8 type )
413  {
414 #if 1
415  uint8 *pnLock;
416  void* pLock;
417  if(type == UART_LOCK_READ){
418  pLock = apBusHandle->pRdLock;
419  pnLock = &apBusHandle->nRdLock;
420  }else{
421  pLock = apBusHandle->pLock;
422  pnLock = &apBusHandle->nLock;
423  }
424  //if there is no lock associate with the handler
425  if(NULL == pLock){
426  // No lock is associated with this bus.
427  return COMM_ERROR_LOCK;
428  }
429  if(0 == *pnLock){
430  return ISF_SUCCESS;
431  }else if (ISF_LOCK_DEFAULT == --*pnLock){
432  // release the resource
433  _mutex_unlock((MUTEX_STRUCT*)pLock);
434  }
435 #else
436  //if there is no lock associate with the handler
437  if(NULL == apBusHandle->pLock){
438  // No lock is associated with this bus.
439  return COMM_ERROR_LOCK;
440  }
441  if(0 == apBusHandle->nLock){
442  return ISF_SUCCESS;
443  }else if (ISF_LOCK_DEFAULT == --apBusHandle->nLock){
444  // release the resource
445  _mutex_unlock((MUTEX_STRUCT*)apBusHandle->pLock);
446  }
447 #endif
448  return ISF_SUCCESS;
449  }
450 
451 
452 
453 
User configuration structure for UART driver.
ISF board support header files.
uart_status_t uart_receive_data_async(uart_state_t *uartState, uint8_t *rxBuffer, uint32_t requestedByteCount)
This function gets (receives) data from the UART module using a non-blocking method.
unsigned char uint8
This defines uint8 as unsigned char.
Definition: isf_types.h:18
void uart_hal_disable_transmitter(uint32 uartInstance)
Disable the UART transmitter.
uint32_t instance
uart_parity_mode_t parityMode
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
void uart_hal_disable_receiver(uint32 uartInstance)
Disable the UART receiver.
isf_status_t uart_adapter_release_lock(busHandle_t *apBusHandle)
This function releases exclusive bus access.
isf_duration_t timeout
uart_state_t uartHandle
This structure defines the data bus handle.
uart_BusConfig_t busConfig
UART configuration structure.
Definition: fsl_uart_hal.h:135
uart_stop_bit_count_t stopBitCount
Definition: fsl_uart_hal.h:139
unsigned long uint32
This defines uint32 as unsigned long.
Definition: isf_types.h:36
MUTEX_STRUCT uart_lock[]
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.
fsl_uart_driver.h defines structures and types for the i2c master driver.
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.
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.
uart_parity_mode_t parityMode
Definition: fsl_uart_hal.h:138
uint32 baudRate
Definition: fsl_uart_hal.h:137
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.
uart_status_t uart_send_data_async(uart_state_t *uartState, const uint8_t *sendBuffer, uint32_t txByteCount)
This function sends (transmits) data through the UART module using a non-blocking method...
The isf_util.h file contains the utility method declarations and macros.
uart_status_t uart_init(uint32_t uartInstance, uart_state_t *uartState, const uart_user_config_t *uartUserConfig)
This function initializes a UART instance for operation.
This structure is a declaration of a BusHandle type.
uart_bit_count_per_char_t bitCountPerChar
Definition: fsl_uart_hal.h:141
isf_status_t uart_adapter_configure(busHandle_t *apBusHandle, uart_config_t *apBusConfig)
This function reconfigures an already initialized bus.
uart_bit_count_per_char_t bitCountPerChar
comm_Flags_t uart_readFlags_t
comm_Flags_t uart_writeFlags_t
void uart_hal_enable_transmitter(uint32 uartInstance)
Enable the UART transmitter.
uart_status_t uart_receive_data(uart_state_t *uartState, uint8_t *rxBuffer, uint32_t requestedByteCount, uint32_t timeout)
This function gets (receives) data from the UART module using a blocking method.
uart_BusConfig_t gSys_UartBusConfig[]
isf_status_t uart_adapter_get_config(busHandle_t *apBusHandle, void *apBusConfig)
This function returns the current bus configuration.
uart_status_t uart_send_data(uart_state_t *uartState, const uint8_t *sendBuffer, uint32_t txByteCount, uint32_t timeout)
This function sends (transmits) data out through the UART module using a blocking method...
uint32 isf_duration_t
ISF time duration in microseconds.
Definition: isf.h:59
long int32
This defines int32 as long.
Definition: isf_types.h:32
uart_stop_bit_count_t stopBitCount
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.
This structure defines a device endpoint encapsulation for uart handler.
#define ISF_LOCK_DEFAULT
MUTEX_STRUCT uart_rdlock[]
uart_status_t uart_hal_init(uint32 uartInstance, const uart_config_t *config)
Initialize the UART controller.
int32 isf_status_t
ISF return status type.
Definition: isf.h:51
uint8 gSys_NumUARTBuses
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
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...
void uart_hal_enable_receiver(uint32 uartInstance)
Enable the UART receiver.