bool UARTInit(UARTDEV *pDev, const UARTCFG *pCfg)
{
	LPCUARTREG *reg = NULL;
	//g_UartClkDiv = 1;

	switch (pCfg->DevNo)
	{
		case 0:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART0_EN;
	        reg = (void*)LPC_USART;
	        LPC_SYSCON->UARTCLKDIV = 2;//g_UartClkDiv; //PCLKSEL0 &= ~LPC_PCLKSEL0_UART0_MASK;	// CCLK/4
			break;
/*		case 1:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART1_EN;
	        pDev->pUartReg = (LPC_UART_TypeDef*)LPC_UART1;
	        LPC_SC->PCLKSEL0 &= ~LPC_PCLKSEL0_UART1_MASK;	// CCLK/4
			break;
		case 2:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART2_EN;
	        pDev->pUartReg = LPC_UART2;
	        LPC_SC->PCLKSEL1 &= ~LPC_PCLKSEL1_UART2_MASK;	// CCLK/4
			break;*/
		default:
			return false;
	}

	//LPC_USART_Type *reg = (LPC_USART_Type *)pDev->pUartReg;

	// Configure I/O pins
	int idx = 0;

	while (pCfg->PinCfg[idx].PortNo >= 0 && idx < UART_NB_PINS)
	{
		IOPinCfg(&pCfg->PinCfg[idx], 1);
		idx++;
	}


	reg->TER = 0;	// Disable Tx
	reg->IER = 0;	// Disable all interrupts
	reg->ACR = 0;	// Disable auto baudrate

	// Clear all FIFO
	reg->FCR = LPCUART_FCR_RST_RXFIFO | LPCUART_FCR_RST_TXFIFO;


//	if (pCfg->DMAMode)
//		pDev->pUartReg->FCR |= LPCUART_FCR_DMA_MODE | LPCUART_FCR_RX_TRIG8;

	reg->LCR = (pCfg->DataBits - 5);
	if (pCfg->Parity != UART_PARITY_NONE)
	{
		reg->LCR |= (pCfg->Parity << 4);
	}

	if (pCfg->StopBits > 1)
		reg->LCR |= LPCUART_LCR_STOPBIT_MASK;

	reg->ICR = 0;
	if (pCfg->IrDAMode)
	{
		if (pCfg->IrDAInvert)
			reg->ICR |= LPCUART_ICR_IRDAINV;
		if (pCfg->IrDAFixPulse)
			reg->ICR |= LPCUART_ICR_IRDA_FIXPULSE | ((pCfg->IrDAPulseDiv & 7) << 3);
		reg->ICR |= LPCUART_ICR_IRDAEN;
	}

	g_LpcUartDev[pCfg->DevNo].DMAMode = pCfg->DMAMode;
	g_LpcUartDev[pCfg->DevNo].pUartReg = reg;
	g_LpcUartDev[pCfg->DevNo].pUartDev = pDev;

	pDev->SerIntrf.pDevData = (void*)&g_LpcUartDev[pCfg->DevNo];

	if (pCfg->Rate)
		pDev->Rate = LpcUARTSetRate(&pDev->SerIntrf, pCfg->Rate);
	else
	{
		// Auto baudrate
		reg->ACR = 7;
	}
	reg->FCR |= LPCUART_FCR_FIFOEN;

	uint32_t val = 0;

	while (LPC_USART->LSR & ~(3<<5))
	{
		val = LPC_USART->RBR;
	}

	val = LPC_USART->IIR;	// Clear interrupts

	// Start tx
	LPC_USART->TER = LPCUART_TER_TXEN;


	pDev->DataBits = pCfg->DataBits;
	pDev->FlowControl = pCfg->FlowControl;
	pDev->StopBits = pCfg->StopBits;
	pDev->IrDAFixPulse = pCfg->IrDAFixPulse;
	pDev->IrDAInvert = pCfg->IrDAInvert;
	pDev->IrDAMode = pCfg->IrDAMode;
	pDev->IrDAPulseDiv = pCfg->IrDAPulseDiv;
	pDev->Parity = pCfg->Parity;
	pDev->SerIntrf.Disable = LpcUARTDisable;
	pDev->SerIntrf.Enable = LpcUARTEnable;
	pDev->SerIntrf.GetRate = LpcUARTGetRate;
	pDev->SerIntrf.SetRate = LpcUARTSetRate;
	pDev->SerIntrf.StartRx = LpcUARTStartRx;
	pDev->SerIntrf.RxData = LpcUARTRxData;
	pDev->SerIntrf.StopRx = LpcUARTStopRx;
	pDev->SerIntrf.StartTx = LpcUARTStartTx;
	pDev->SerIntrf.TxData = LpcUARTTxData;
	pDev->SerIntrf.StopTx = LpcUARTStopTx;

	NVIC_EnableIRQ(UART_IRQn);
	LPC_USART->IER = LPCUART_IER_THRE | LPCUART_IER_RBR | LPCUART_IER_RLS;

	return true;
}
Exemple #2
0
bool UARTInit(UARTDEV *pDev, const UARTCFG *pCfg)
{
	LPCUARTREG *reg = NULL;
	//g_UartClkDiv = 1;

	switch (pCfg->DevNo)
	{
		case 0:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART0_EN;
	        reg = (void*)LPC_USART;
	        LPC_SYSCON->UARTCLKDIV = 2;//g_UartClkDiv; //PCLKSEL0 &= ~LPC_PCLKSEL0_UART0_MASK;	// CCLK/4
			break;
/*		case 1:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART1_EN;
	        pDev->pUartReg = (LPC_UART_TypeDef*)LPC_UART1;
	        LPC_SC->PCLKSEL0 &= ~LPC_PCLKSEL0_UART1_MASK;	// CCLK/4
			break;
		case 2:
	        LPC_SYSCON->SYSAHBCLKCTRL |= LPC_SYSAHBCLKCTRL_UART2_EN;
	        pDev->pUartReg = LPC_UART2;
	        LPC_SC->PCLKSEL1 &= ~LPC_PCLKSEL1_UART2_MASK;	// CCLK/4
			break;*/
		default:
			return false;
	}

	//LPC_USART_Type *reg = (LPC_USART_Type *)pDev->pUartReg;

	// Configure I/O pins
	int idx = 0;

	while (pCfg->PinCfg[idx].PortNo >= 0 && idx < UART_NB_PINS)
	{
		IOPinCfg(&pCfg->PinCfg[idx], 1);
		idx++;
	}
/*
	LPC_GPIO->SET[pCfg->PinCfg[UARTPIN_TX_IDX].PortNo] = (1 << pCfg->PinCfg[UARTPIN_TX_IDX].PinNo);
	if (pCfg->PinCfg[UARTPIN_CTS_IDX].PortNo >= 0)
		LPC_GPIO->CLR[pCfg->PinCfg[UARTPIN_CTS_IDX].PortNo] = (1 << pCfg->PinCfg[UARTPIN_CTS_IDX].PinNo);

	if (pCfg->PinCfg[UARTPIN_RTS_IDX].PortNo >= 0)
	{
		LPC_GPIO->CLR[pCfg->PinCfg[UARTPIN_RTS_IDX].PortNo] = (1 << pCfg->PinCfg[UARTPIN_RTS_IDX].PinNo);
	}
*/

	reg->TER = 0;	// Disable Tx
	reg->IER = 0;	// Disable all interrupts
	reg->ACR = 0;	// Disable auto baudrate

	// Clear all FIFO
	reg->FCR = LPCUART_FCR_RST_RXFIFO | LPCUART_FCR_RST_TXFIFO;


//	if (pCfg->DMAMode)
//		pDev->pUartReg->FCR |= LPCUART_FCR_DMA_MODE | LPCUART_FCR_RX_TRIG8;

	// Data bis, Parity, Stop bit
	reg->LCR = (pCfg->DataBits - 5);
	if (pCfg->Parity != UART_PARITY_NONE)
	{
		reg->LCR |= (pCfg->Parity << 4);
	}

	if (pCfg->StopBits > 1)
		reg->LCR |= LPCUART_LCR_STOPBIT_MASK;

	reg->ICR = 0;
	if (pCfg->bIrDAMode)
	{
		if (pCfg->bIrDAInvert)
			reg->ICR |= LPCUART_ICR_IRDAINV;
		if (pCfg->bIrDAFixPulse)
			reg->ICR |= LPCUART_ICR_IRDA_FIXPULSE | ((pCfg->IrDAPulseDiv & 7) << 3);
		reg->ICR |= LPCUART_ICR_IRDAEN;
	}

	g_LpcUartDev[pCfg->DevNo].DMAMode = pCfg->bDMAMode;
	g_LpcUartDev[pCfg->DevNo].pUartReg = reg;
	g_LpcUartDev[pCfg->DevNo].pUartDev = pDev;

	pDev->SerIntrf.pDevData = (void*)&g_LpcUartDev[pCfg->DevNo];

	if (pCfg->Rate)
		pDev->Rate = LpcUARTSetRate(&pDev->SerIntrf, pCfg->Rate);
	else
	{
		// Auto baudrate
		reg->ACR = 7;
	}

	if (pCfg->FlowControl == UART_FLWCTRL_HW)
	{
//		LPC_GPIO->CLR[pCfg->PinCfg[UARTPIN_CTS_IDX].PortNo] = (1 << pCfg->PinCfg[UARTPIN_CTS_IDX].PinNo);
//		LPC_GPIO->CLR[pCfg->PinCfg[UARTPIN_RTS_IDX].PortNo] = (1 << pCfg->PinCfg[UARTPIN_RTS_IDX].PinNo);
		reg->MCR |= (3 << 6);	// Auto CTS/RTS flow control

	}
	else
	{
		reg->MCR &= ~(3 << 6);
	}

	reg->FCR = LPCUART_FCR_FIFOEN | LPCUART_FCR_RST_RXFIFO | LPCUART_FCR_RST_TXFIFO |
			   LPCUART_FCR_RX_TRIG8;

	uint32_t val = 0;

	while (LPC_USART->LSR & ~(3<<5))
	{
		val = LPC_USART->RBR;
	}

	val = LPC_USART->IIR;	// Clear interrupts
	pDev->LineState = 0;

	//LPC_USART->MCR |= (1<<4); // Loopback

	if (pCfg->pRxMem && pCfg->RxMemSize > 0)
	{
		pDev->hRxFifo = CFifoInit(pCfg->pRxMem, pCfg->RxMemSize, 1);
	}
	else
	{
		pDev->hRxFifo = CFifoInit(s_UARTRxFifoMem, UART_RX_CFIFO_MEM_SIZE, 1);
	}

	if (pCfg->pTxMem && pCfg->TxMemSize > 0)
	{
		pDev->hTxFifo = CFifoInit(pCfg->pTxMem, pCfg->TxMemSize, 1);
	}
	else
	{
		pDev->hTxFifo = CFifoInit(s_UARTTxFifoMem, UART_TX_CFIFO_MEM_SIZE, 1);
	}

	// Start tx
	LPC_USART->TER = LPCUART_TER_TXEN;


	pDev->DataBits = pCfg->DataBits;
	pDev->FlowControl = pCfg->FlowControl;
	pDev->StopBits = pCfg->StopBits;
	pDev->bIrDAFixPulse = pCfg->bIrDAFixPulse;
	pDev->bIrDAInvert = pCfg->bIrDAInvert;
	pDev->bIrDAMode = pCfg->bIrDAMode;
	pDev->IrDAPulseDiv = pCfg->IrDAPulseDiv;
	pDev->Parity = pCfg->Parity;
	pDev->SerIntrf.Disable = LpcUARTDisable;
	pDev->SerIntrf.Enable = LpcUARTEnable;
	pDev->SerIntrf.GetRate = LpcUARTGetRate;
	pDev->SerIntrf.SetRate = LpcUARTSetRate;
	pDev->SerIntrf.StartRx = LpcUARTStartRx;
	pDev->SerIntrf.RxData = LpcUARTRxData;
	pDev->SerIntrf.StopRx = LpcUARTStopRx;
	pDev->SerIntrf.StartTx = LpcUARTStartTx;
	pDev->SerIntrf.TxData = LpcUARTTxData;
	pDev->SerIntrf.StopTx = LpcUARTStopTx;
	pDev->EvtCallback = pCfg->EvtCallback;

	g_LpcUartDev[pCfg->DevNo].bTxReady = true;

	pDev->LineState = 0;

	if (pCfg->bIntMode)
	{
		LPC_USART->IER = LPCUART_IER_THRE | LPCUART_IER_RBR | LPCUART_IER_RLS | LPCUART_IER_MS | (1<<7);
		NVIC_ClearPendingIRQ(UART_IRQn);
		NVIC_SetPriority(UART_IRQn, pCfg->IntPrio);
		NVIC_EnableIRQ(UART_IRQn);
	}

	return true;
}