int32_t dw_uart_control()

in hw/mcu/arc/src/ext/sdk/device/designware/uart/dw_uart.c [638:787]


int32_t dw_uart_control (DEV_UART *uart_obj, uint32_t ctrl_cmd, void *param)
{
	int32_t ercd = E_OK;
	DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info);

	/* START ERROR CHECK */
	VALID_CHK_UART_INFO_OBJECT(uart_info_ptr);
	DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED);
	/* END OF ERROR CHECK */

	uint32_t val32; /** to receive unsigned int value */
	int32_t baud_divisor = 0;
	DEV_BUFFER *devbuf;
	UART_DPS_FORMAT *dps_ptr;
	UART_HW_FLOW_CONTROL hwfc_local;

	DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl);
	DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase);

	/* check whether current device is disabled */
	if ((uart_info_ptr->status & DEV_ENABLED) == 0) {
		/** When device is disabled,
		 * only UART_CMD_ENA_DEV, UART_CMD_DIS_DEV, UART_CMD_GET_STATUS
		 * are available, other commands will return E_SYS
		 */
		if ((ctrl_cmd != UART_CMD_ENA_DEV) && \
			(ctrl_cmd != UART_CMD_DIS_DEV) && \
			(ctrl_cmd != UART_CMD_GET_STATUS) ) {
			return E_SYS;
		}
	}

	switch (ctrl_cmd) {
		case UART_CMD_SET_BAUD:
			val32 = (uint32_t)param;
			DW_UART_CHECK_EXP(val32>0, E_PAR);
			if (val32 != uart_info_ptr->baudrate) {
				baud_divisor = DW_UART_BAUD2DIV(uart_ctrl_ptr->dw_apb_bus_freq, val32);
				dw_uart_set_baud(uart_reg_ptr, baud_divisor);
				uart_info_ptr->baudrate = val32;
			}
			break;
		case UART_CMD_GET_STATUS:
			DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
			*((int32_t *)param) = uart_info_ptr->status;
			break;
		case UART_CMD_ENA_DEV:
			dw_uart_enable_device(uart_info_ptr);
			break;
		case UART_CMD_DIS_DEV:
			dw_uart_disable_device(uart_info_ptr);
			break;
		case UART_CMD_FLUSH_OUTPUT:
			dw_uart_flush_output(uart_info_ptr);
			break;
		case UART_CMD_GET_RXAVAIL:
			DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
			*((int32_t *)param) = dw_uart_get_rxavail(uart_ctrl_ptr);
			break;
		case UART_CMD_GET_TXAVAIL:
			DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
			*((int32_t *)param) = dw_uart_get_txavail(uart_ctrl_ptr);
			break;
		case UART_CMD_BREAK_SET:
			dw_uart_set_break(uart_reg_ptr);
			break;
		case UART_CMD_BREAK_CLR:
			dw_uart_clr_break(uart_reg_ptr);
			break;
		case UART_CMD_SET_DPS_FORMAT:
			DW_UART_CHECK_EXP(param!=NULL, E_PAR);
			dps_ptr = (UART_DPS_FORMAT *)param;
			if (dw_uart_set_dps(uart_reg_ptr, dps_ptr) == 0) {
				uart_info_ptr->dps_format = *dps_ptr;
			} else {
				ercd = E_PAR;
			}
			break;
		case UART_CMD_SET_HWFC:
			hwfc_local = (UART_HW_FLOW_CONTROL)param;
			DW_UART_CHECK_EXP(((hwfc_local>=UART_FC_NONE) && (hwfc_local<=UART_FC_BOTH)), E_PAR);
			dw_uart_set_hwfc(uart_reg_ptr, hwfc_local);
			uart_info_ptr->hwfc = hwfc_local;
			break;
		case UART_CMD_SET_TXCB:
			DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
			uart_info_ptr->uart_cbs.tx_cb = param;
			break;
		case UART_CMD_SET_RXCB:
			DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
			uart_info_ptr->uart_cbs.rx_cb = param;
			break;
		case UART_CMD_SET_ERRCB:
			DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
			uart_info_ptr->uart_cbs.err_cb = param;
			break;
		case UART_CMD_ABORT_TX:
			dw_uart_abort_tx(uart_obj);
			break;
		case UART_CMD_ABORT_RX:
			dw_uart_abort_rx(uart_obj);
			break;
		case UART_CMD_SET_TXINT:
			val32 = (uint32_t)param;
			if (val32 == 0) {
				dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND);
			} else {
				dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_SND);
			}
			break;
		case UART_CMD_SET_RXINT:
			val32 = (uint32_t)param;
			if (val32 == 0) {
				dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV);
			} else {
				dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_RCV);
			}
			break;
		case UART_CMD_SET_TXINT_BUF:
			DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
			if (param != NULL) {
				devbuf = (DEV_BUFFER *)param;
				uart_info_ptr->tx_buf = *devbuf;
				uart_info_ptr->tx_buf.ofs = 0;
			} else {
				uart_info_ptr->tx_buf.buf = NULL;
				uart_info_ptr->tx_buf.len = 0;
				uart_info_ptr->tx_buf.ofs = 0;
			}
			break;
		case UART_CMD_SET_RXINT_BUF:
			DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
			if (param != NULL) {
				devbuf = (DEV_BUFFER *)param;
				uart_info_ptr->rx_buf = *devbuf;
				uart_info_ptr->rx_buf.ofs = 0;
			} else {
				uart_info_ptr->rx_buf.buf = NULL;
				uart_info_ptr->rx_buf.len = 0;
				uart_info_ptr->rx_buf.ofs = 0;
			}
			break;
		default:
			ercd = E_NOSPT;
			break;
	}

error_exit:
	return ercd;
}