static _mqx_int _io_serial_mix_nextc ( /* [IN] the interrupt I/O context information */ IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr ) { /* Body */ unsigned char c; if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT || (! int_io_dev_ptr->OUTPUT_ENABLED)) { return(-1); } /* Endif */ if (_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) { /* No output */ int_io_dev_ptr->OUTPUT_ENABLED = FALSE; if (_QUEUE_GET_SIZE(int_io_dev_ptr->OUT_WAITING_TASKS)) { _taskq_resume(int_io_dev_ptr->OUT_WAITING_TASKS, TRUE); } /* Endif */ return(-1); }/* Endif */ _CHARQ_DEQUEUE(int_io_dev_ptr->OUT_QUEUE, c); return((_mqx_int)c); } /* Endbody */
static _mqx_int _io_serial_mix_ioctl ( /* [IN] the handle returned from _fopen */ FILE_DEVICE_STRUCT_PTR fd_ptr, /* [IN] the ioctl command */ _mqx_uint cmd, /* [IN] the ioctl parameters */ void *param_ptr ) { /* Body */ IO_DEVICE_STRUCT_PTR io_dev_ptr; IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr; _mqx_uint result = MQX_OK; _mqx_uint_ptr uparam_ptr = (_mqx_uint_ptr)param_ptr; io_dev_ptr = fd_ptr->DEV_PTR; int_io_dev_ptr = (void *)io_dev_ptr->DRIVER_INIT_PTR; switch (cmd) { case IO_IOCTL_FLUSH_OUTPUT: /* Disable interrupts to avoid situation that last TX interrupt comes after successfull !_CHARQ_EMPTY() */ _int_disable(); while(!_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) { /* wait untill all chars are sent from output queue */ _taskq_suspend(int_io_dev_ptr->OUT_WAITING_TASKS); }; _int_enable(); break; default: if (int_io_dev_ptr->DEV_IOCTL != NULL) { result = (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, cmd, param_ptr); } /* Endif */ break; } /* Endswitch */ return result; } /* Endbody */
_mqx_int _io_serial_int_nextc ( /* [IN] the interrupt I/O context information */ IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr ) { /* Body */ uchar c; if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) { if (int_io_dev_ptr->MUST_STOP_INPUT) { int_io_dev_ptr->MUST_STOP_INPUT = FALSE; int_io_dev_ptr->HAVE_STOPPED_INPUT = TRUE; return((int_32)CNTL_S); } else if (int_io_dev_ptr->MUST_START_INPUT) { int_io_dev_ptr->MUST_START_INPUT = FALSE; int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE; return((int_32)CNTL_Q); } /* Endif */ } /* Endif */ if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT || (! int_io_dev_ptr->OUTPUT_ENABLED)) { return(-1); } /* Endif */ if (_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) { /* No output */ int_io_dev_ptr->OUTPUT_ENABLED = FALSE; if (_QUEUE_GET_SIZE(int_io_dev_ptr->OUT_WAITING_TASKS)) { _taskq_resume(int_io_dev_ptr->OUT_WAITING_TASKS, TRUE); } /* Endif */ return(-1); }/* Endif */ _CHARQ_DEQUEUE(int_io_dev_ptr->OUT_QUEUE, c); return((_mqx_int)c); } /* Endbody */
_mqx_int _io_pipe_ioctl ( /* [IN] the handle returned from _fopen */ FILE_DEVICE_STRUCT_PTR fd_ptr, /* [IN] the ioctl command */ uint_32 cmd, /* [IN] the ioctl parameters */ pointer param_ptr ) { /* Body */ IO_PIPE_INFO_STRUCT_PTR io_pipe_info_ptr; uint_32 result = MQX_OK; _mqx_uint_ptr uparam_ptr = param_ptr; io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR; result = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( result != MQX_OK ) { return (result); } /* Endif */ #endif switch (cmd) { case PIPE_IOCTL_CHAR_AVAIL: if ( !_CHARQ_EMPTY(io_pipe_info_ptr->QUEUE) ) { *uparam_ptr = (uint_32)TRUE; } else { *uparam_ptr = (uint_32)FALSE; } /* Endif */ break; case PIPE_IOCTL_GET_SIZE: *uparam_ptr = io_pipe_info_ptr->QUEUE_SIZE; break; case PIPE_IOCTL_FULL: if ( _CHARQ_FULL(io_pipe_info_ptr->QUEUE) ) { *uparam_ptr = (uint_32)TRUE; } else { *uparam_ptr = (uint_32)FALSE; } /* Endif */ break; case PIPE_IOCTL_EMPTY: if ( _CHARQ_EMPTY(io_pipe_info_ptr->QUEUE) ) { *uparam_ptr = (uint_32)TRUE; } else { *uparam_ptr = (uint_32)FALSE; } /* Endif */ break; case PIPE_IOCTL_RE_INIT: _CHARQ_INIT(io_pipe_info_ptr->QUEUE, io_pipe_info_ptr->QUEUE_SIZE) io_pipe_info_ptr->KM_ABORT_READ = TRUE; io_pipe_info_ptr->KM_ABORT_WRITE = TRUE; result = _lwsem_post(&io_pipe_info_ptr->EMPTY_SEM); #if MQX_CHECK_ERRORS if ( result != MQX_OK ) { return (-1); } /* Endif */ #endif result = _lwsem_post(&io_pipe_info_ptr->FULL_SEM); #if MQX_CHECK_ERRORS if ( result != MQX_OK ) { return (-1); } /* Endif */ #endif break; case PIPE_IOCTL_NUM_CHARS_FULL: *uparam_ptr = _CHARQ_SIZE(io_pipe_info_ptr->QUEUE); break; case PIPE_IOCTL_NUM_CHARS_FREE: *uparam_ptr = io_pipe_info_ptr->QUEUE_SIZE - _CHARQ_SIZE(io_pipe_info_ptr->QUEUE); break; default: break; } /* Endswitch */ result = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( result != MQX_OK ) { return (result); } /* Endif */ #endif return result; } /* Endbody */
_mqx_int _io_pipe_read ( /* [IN] the handle returned from _fopen */ FILE_DEVICE_STRUCT_PTR fd_ptr, /* [IN] where the characters are to be stored */ char _PTR_ data_ptr, /* [IN] the number of characters to input */ _mqx_int num ) { /* Body */ volatile IO_PIPE_INFO_STRUCT_PTR io_pipe_info_ptr; uchar c; uint_32 i = num + 1; volatile CHARQ_STRUCT _PTR_ pipe_queue; uint_32 error; io_pipe_info_ptr = fd_ptr->DEV_DATA_PTR; pipe_queue = io_pipe_info_ptr->QUEUE; /* Turn off pipe abort flags */ io_pipe_info_ptr->KM_ABORT_READ = FALSE; /* Lock out other reading tasks */ error = _mutex_lock(&io_pipe_info_ptr->READ_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif /* Lock out access of a writer task to the pipe data structures */ error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif /* Start reading characters from the pipe*/ while ( --i ) { /* If the pipe is empty, wait until the pipe is not empty */ while (_CHARQ_EMPTY(pipe_queue)) { error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif error = _lwsem_post(&io_pipe_info_ptr->FULL_SEM); #if MQX_CHECK_ERRORS if ( error != MQX_OK ) { return (-1); } /* Endif */ #endif error = _lwsem_wait(&io_pipe_info_ptr->EMPTY_SEM); #if MQX_CHECK_ERRORS if ( error != MQX_OK ) { return (-1); } /* Endif */ #endif if(io_pipe_info_ptr->KM_ABORT_READ) { error = _mutex_unlock(&io_pipe_info_ptr->READ_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif return num - i; } /* Lock out access of a writer task to the pipe data structures */ error = _mutex_lock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif } /* Endwhile */ /* Read char from pipe */ _CHARQ_DEQUEUE(pipe_queue,c); /* Copy data to the returned buffer */ *data_ptr++ = c; } /* Endwhile */ error = _lwsem_post(&io_pipe_info_ptr->FULL_SEM); #if MQX_CHECK_ERRORS if ( error != MQX_OK ) { return (-1); } /* Endif */ #endif /* Unlock access access mutex and read mutex */ error = _mutex_unlock(&io_pipe_info_ptr->ACCESS_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif error = _mutex_unlock(&io_pipe_info_ptr->READ_MUTEX); #if MQX_CHECK_ERRORS if ( error != MQX_EOK ) { return (-1); } /* Endif */ #endif return num; } /* Endbody */
_mqx_int _io_serial_int_ioctl ( /* [IN] the handle returned from _fopen */ FILE_DEVICE_STRUCT_PTR fd_ptr, /* [IN] the ioctl command */ _mqx_uint cmd, /* [IN] the ioctl parameters */ pointer param_ptr ) { /* Body */ IO_DEVICE_STRUCT_PTR io_dev_ptr; IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr; _mqx_uint result = MQX_OK; _mqx_uint_ptr uparam_ptr = (_mqx_uint_ptr)param_ptr; io_dev_ptr = fd_ptr->DEV_PTR; int_io_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR; switch (cmd) { case IO_IOCTL_CHAR_AVAIL: if ( _CHARQ_SIZE(int_io_dev_ptr->IN_QUEUE) ) { *((boolean _PTR_)param_ptr) = TRUE; } else { *((boolean _PTR_)param_ptr) = FALSE; } /* Endif */ break; case IO_IOCTL_SERIAL_GET_FLAGS: *((_mqx_uint_ptr)param_ptr) = int_io_dev_ptr->FLAGS; break; case IO_IOCTL_SERIAL_SET_FLAGS: int_io_dev_ptr->FLAGS = *((_mqx_uint_ptr)param_ptr); fd_ptr->FLAGS = *((_mqx_uint_ptr)param_ptr); if (int_io_dev_ptr->DEV_IOCTL != NULL) { result = (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, cmd, param_ptr); } /* Endif */ break; case IO_IOCTL_SERIAL_TRANSMIT_DONE: *((boolean _PTR_)param_ptr) = !(int_io_dev_ptr->OUTPUT_ENABLED); break; case IO_IOCTL_FLUSH_OUTPUT: /* Disable interrupts to avoid situation that last TX interrupt comes after successfull !_CHARQ_EMPTY() */ _int_disable(); while(!_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) { /* wait untill all chars are sent from output queue */ _taskq_suspend(int_io_dev_ptr->OUT_WAITING_TASKS); }; _int_enable(); break; case IO_IOCTL_DEVICE_IDENTIFY: /* return the device identify */ uparam_ptr[0] = IO_DEV_TYPE_PHYS_SERIAL_INTERRUPT; uparam_ptr[1] = 0; uparam_ptr[2] = IO_DEV_ATTR_INTERRUPT | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE; result = MQX_OK; break; case IO_IOCTL_SERIAL_CAN_TRANSMIT: *uparam_ptr = (int_io_dev_ptr->OUT_QUEUE->MAX_SIZE - int_io_dev_ptr->OUT_QUEUE->CURRENT_SIZE); result = MQX_OK; break; case IO_IOCTL_SERIAL_CAN_RECEIVE: *uparam_ptr = (int_io_dev_ptr->IN_QUEUE->MAX_SIZE - int_io_dev_ptr->IN_QUEUE->CURRENT_SIZE); result = MQX_OK; break; default: if (int_io_dev_ptr->DEV_IOCTL != NULL) { result = (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, cmd, param_ptr); } /* Endif */ break; } /* Endswitch */ return result; } /* Endbody */