Exemplo n.º 1
0
void * rs485_pkt_drain(struct rs485_link * lnk)
{
	struct stm32_usart * uart = lnk->uart;
	void * pend_pkt = NULL;
	uint32_t sr;
	uint32_t cr;

	if (lnk->tx.pend_pkt) {
		/* wait for the DMA transfer to complete */
		while (!lnk->tx.isr[TCIF_BIT]) {
			if (lnk->tx.isr[TEIF_BIT]) {
				lnk->tx.ifcr[TEIF_BIT] = 1;
			}
			thinkos_irq_wait(lnk->tx.dma_irq);
		} 
		/* clear the the DMA trasfer complete flag */
		lnk->tx.ifcr[TCIF_BIT] = 1;

		/* return a reference to the packet just transmitted */
		pend_pkt = lnk->tx.pend_pkt;

		if ((sr = uart->sr) & USART_TC) {
			/* pulse the TE bit to generate an idle frame */
			cr = uart->cr1;
			uart->cr1 = cr & ~USART_TE;
			uart->cr1 = cr | USART_TE;
		} else {
			thinkos_sleep(lnk->idle_tm);
		}
	} 

	lnk->tx.pend_pkt = NULL;
	
	/* return previous pending packet */
	return pend_pkt;
}
Exemplo n.º 2
0
int __rs485_pkt_receive(struct rs485_link * lnk, void ** ppkt, int max_len)
{
	struct stm32f_dma_stream * dma_strm = lnk->rx.dma_strm;
	struct stm32_usart * uart = lnk->uart;
	void * rcvd_pkt;
	uint32_t sr;
	int len;

	DCC_LOG2(LOG_INFO, "DMA stream[%d]=0x%p", lnk->rx.dma_id, dma_strm);

//	tracef(".");
	if (lnk->rx.pend_pkt == NULL) {
		rcvd_pkt = NULL;
		len = 0;
	} else {
		DCC_LOG(LOG_TRACE, "pending packet...");

		trace("pending packet...");

		/* wait for completion of DMA transfer */
		while (!lnk->rx.isr[TCIF_BIT]) {

			if (lnk->rx.isr[TEIF_BIT]) {
				DCC_LOG(LOG_ERROR, "DMA transfer error!");
				trace("DMA transfer error...");
				lnk->rx.ifcr[TEIF_BIT] = 1;
			}

			if (lnk->rx.isr[FEIF_BIT]) {
				trace("DMA fifo error...");
				lnk->rx.ifcr[FEIF_BIT] = 1;
			}

			if (lnk->rx.isr[HTIF_BIT]) {
//				trace("DMA half transfer...");
				lnk->rx.ifcr[HTIF_BIT] = 1;
			}

			trace("wait...");
			thinkos_irq_wait(lnk->rx.dma_irq);
		} 

		/* return a reference to the packet just received */
		rcvd_pkt = lnk->rx.pend_pkt;

		/* Number of data items transfered... */
		len = lnk->rx.max_len - dma_strm->ndtr;

		/* clear the the DMA trasfer complete flag */
		lnk->rx.ifcr[TCIF_BIT] = 1;

		tracef("DMA received len=%d max_len=%d.", len, max_len);
	}

	if (dma_strm->cr & DMA_EN) {
		DCC_LOG(LOG_ERROR, "DMA enabled");
		trace("ERROR: DMA enabled!");
	}

	lnk->rx.pend_pkt = *ppkt;
	lnk->rx.max_len = max_len;

	/* set DMA memory address */
	dma_strm->m0ar = (void *)lnk->rx.pend_pkt;
	/* set DMA number of data items to transfer */
	dma_strm->ndtr = max_len;

	/* clear the TC bit to start transfer */
	if ((sr = uart->sr) & USART_TC) {
		DCC_LOG(LOG_INFO, "TC=1");
		trace("TC=1");
		uart->sr = 0;
	}

	/* enable DMA */
	dma_strm->cr |= DMA_EN;

	/* return previous pending packet */
	*ppkt = rcvd_pkt;

	return len;
}
Exemplo n.º 3
0
void * rs485_pkt_enqueue(struct rs485_link * lnk, void * pkt, int len)
{
	struct stm32_usart * uart = lnk->uart;
	struct stm32f_dma_stream * dma_strm = lnk->tx.dma_strm;
	uint32_t sr;
	uint32_t cr;
	void * pend_pkt = NULL;

	DCC_LOG2(LOG_TRACE, "DMA stream[%d]=0x%p", lnk->tx.dma_id, dma_strm);

	if (lnk->tx.pend_pkt) {
		DCC_LOG(LOG_TRACE, "pending packet...");

		/* wait for the DMA transfer to complete */
		while (!lnk->tx.isr[TCIF_BIT]) {
			if (lnk->tx.isr[TEIF_BIT]) {
				DCC_LOG(LOG_ERROR, "DMA transfer error!");
				lnk->tx.ifcr[TEIF_BIT] = 1;
			}
			thinkos_irq_wait(lnk->tx.dma_irq);
		} 
		/* clear the the DMA trasfer complete flag */
		lnk->tx.ifcr[TCIF_BIT] = 1;

		/* return a reference to the packet just transmitted */
		pend_pkt = lnk->tx.pend_pkt;

		if ((sr = uart->sr) & USART_TC) {
//			trace("USART TC=1, generating an idle frame");
			/* pulse the TE bit to generate an idle frame */
			cr = uart->cr1;
			uart->cr1 = cr & ~USART_TE;
			uart->cr1 = cr | USART_TE;
		} else {
			DCC_LOG(LOG_TRACE, "IDLE");
			thinkos_sleep(lnk->idle_tm);
		}
	}
	
	if (dma_strm->cr & DMA_EN) {
		DCC_LOG(LOG_ERROR, "DMA enabled");
		trace("ERROR: DMA enabled!");
	}

	/* set this packet as pending */
	lnk->tx.pend_pkt = pkt;
	/* set DMA memory address */
	dma_strm->m0ar = (void *)pkt;
	/* set DMA number of data items to transfer */
	dma_strm->ndtr = len;

	/* clear the TC bit */
	if ((sr = uart->sr) & USART_TC) {
		DCC_LOG(LOG_INFO, "TC=1");
		uart->sr = 0;
	}

	/* enable DMA */
	dma_strm->cr |= DMA_EN;

	/* return previous pending packet */
	return pend_pkt;
}
Exemplo n.º 4
0
int lis302_rd(int reg, void * buf, unsigned int len)
{
	struct stm32f_spi * spi = STM32F_SPI1;
	uint8_t * data = (uint8_t *)buf;
	unsigned int addr;
	unsigned int sr;
	unsigned int dummy;
	int i;

	if (len == 0)
		return 0;

	addr = (reg & 0x3f) | 0x80 | ((len > 1) ? 0x40 : 0x00);

	gpio_clr(lis302_cs);

	udelay(1);

	sr = spi->sr;
	
	if (!(sr & SPI_TXE))
		return -1;

	if (sr & SPI_MODF)
		return -2;

	if (sr & SPI_RXNE) {
		/* clear input buffer */
		dummy = spi->dr;
		(void)dummy;
	}

	/* send the address */
	spi->dr = addr;

	while (!((sr = spi->sr) & SPI_TXE)) {
		thinkos_irq_wait(STM32F_IRQ_SPI1);
	} 

	/* send first dummy data */
	spi->dr = 0;

	/* wait for incomming data */
	while (!((sr = spi->sr) & SPI_RXNE)) {
		thinkos_irq_wait(STM32F_IRQ_SPI1);
	} 

	/* discard */
	dummy = spi->dr;
	(void)dummy;

	for (i = 0; i < (len - 1); ++i) {
		while (!((sr = spi->sr) & SPI_TXE)) {
			thinkos_irq_wait(STM32F_IRQ_SPI1);
		} 

		/* send dummy data */
		spi->dr = 0;

		/* wait for incomming data */
		while (!((sr = spi->sr) & SPI_RXNE)) {
			thinkos_irq_wait(STM32F_IRQ_SPI1);
		} 

		data[i] = spi->dr;
	}

	while (!((sr = spi->sr) & SPI_RXNE)) {
		thinkos_irq_wait(STM32F_IRQ_SPI1);
	}

	data[i] = spi->dr;

	udelay(1);

	gpio_set(lis302_cs);

	return len;
}