Exemplo n.º 1
0
void PIOS_USART_IRQ_Handler(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	/* Force read of dr after sr to make sure to clear error flags */
	volatile uint16_t sr = usart_dev->cfg->regs->SR;
	volatile uint8_t dr = usart_dev->cfg->regs->DR;

	/* Check if RXNE flag is set */
	if (sr & USART_SR_RXNE) {
		if (PIOS_USART_RxBufferPut(usart_id, dr) < 0) {
			/* Here we could add some error handling */
		}
	}

	/* Check if TXE flag is set */
	if (sr & USART_SR_TXE) {
		if (PIOS_USART_TxBufferUsed(usart_id) > 0) {
			int32_t b = PIOS_USART_TxBufferGet(usart_id);

			if (b < 0) {
				/* Here we could add some error handling */
				usart_dev->cfg->regs->DR = 0xff;
			} else {
				usart_dev->cfg->regs->DR = b & 0xff;
			}
		} else {
			/* Disable TXE interrupt (TXEIE=0) */
			USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
		}
	}
}
Exemplo n.º 2
0
/**
* puts more than one byte onto the transmit buffer (used for atomic sends)
* \param[in] USART USART name
* \param[in] *buffer pointer to buffer to be sent
* \param[in] len number of bytes to be sent
* \return 0 if no error
* \return -1 if buffer full or cannot get all requested bytes (retry)
*/
static int32_t PIOS_USART_TxBufferPutMoreNonBlocking(uint32_t usart_id, const uint8_t *buffer, uint16_t len)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	if (len >= fifoBuf_getFree(&usart_dev->tx)) {
		/* Buffer cannot accept all requested bytes (retry) */
		return -1;
	}

	/* Copy bytes to be transmitted into transmit buffer */
	/* This operation should be atomic! */
	PIOS_IRQ_Disable();

	uint16_t used = fifoBuf_getUsed(&usart_dev->tx);
	fifoBuf_putData(&usart_dev->tx,buffer,len);
	
	if (used == 0) {
		/* enable sending when buffer was previously empty */
		USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
	}

	PIOS_IRQ_Enable();

	/* No error */
	return 0;
}
Exemplo n.º 3
0
static void PIOS_USART_TxStart(uintptr_t usart_id, uint16_t tx_bytes_avail)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
	
	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);
	
	USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
}
Exemplo n.º 4
0
/**
* returns number of used bytes in transmit buffer
* \param[in] USART USART name
* \return number of used bytes
* \return 0 if USART not available
*/
static int32_t PIOS_USART_TxBufferUsed(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	return (fifoBuf_getUsed(&usart_dev->tx));
}
Exemplo n.º 5
0
static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);

	/* Force read of dr after sr to make sure to clear error flags */
	volatile uint16_t sr = usart_dev->cfg->regs->SR;
	volatile uint8_t dr = usart_dev->cfg->regs->DR;

	/* Check if RXNE flag is set */
	bool rx_need_yield = false;
	if (sr & USART_SR_RXNE) {
		uint8_t byte = dr;
		if (usart_dev->rx_in_cb) {
			uint16_t rc;
			rc = (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
			if (rc < 1) {
				/* Lost bytes on rx */
				usart_dev->rx_dropped += 1;
			}
		}
	}

	/* Check if TXE flag is set */
	bool tx_need_yield = false;
	if (sr & USART_SR_TXE) {
		if (usart_dev->tx_out_cb) {
			uint8_t b;
			uint16_t bytes_to_send;

			bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);

			if (bytes_to_send > 0) {
				/* Send the byte we've been given */
				usart_dev->cfg->regs->DR = b;
			} else {
				/* No bytes to send, disable TXE interrupt */
				USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
			}
		} else {
			/* No bytes to send, disable TXE interrupt */
			USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
		}
	}

#if defined(PIOS_INCLUDE_FREERTOS)
	if (rx_need_yield || tx_need_yield) {
		vPortYieldFromISR();
	}
#endif	/* PIOS_INCLUDE_FREERTOS */
}
Exemplo n.º 6
0
static void PIOS_USART_generic_irq_handler(uintptr_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool rx_need_yield = false;
	bool tx_need_yield = false;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);
	
	/* Check if RXNE flag is set */
	if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_RXNE)) {
		uint8_t byte = (uint8_t)USART_ReceiveData(usart_dev->cfg->regs);
		if (usart_dev->rx_in_cb) {
			(void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
		}
	}
	/* Check if TXE flag is set */
	if (USART_GetITStatus(usart_dev->cfg->regs, USART_IT_TXE)) {
		if (usart_dev->tx_out_cb) {
			uint8_t b;
			uint16_t bytes_to_send;
			
			bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
			
			if (bytes_to_send > 0) {
				/* Send the byte we've been given */
				USART_SendData(usart_dev->cfg->regs, b);
			} else {
				/* No bytes to send, disable TXE interrupt */
				USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
			}
		} else {
			/* No bytes to send, disable TXE interrupt */
			USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
		}
	}
	/* Check for overrun condition
	 * Note i really wanted to use USART_GetITStatus but it fails on getting the
	 * ORE flag although RXNE interrupt is enabled.
	 * Probably a bug in the ST library...
	 */
	if (USART_GetFlagStatus(usart_dev->cfg->regs, USART_FLAG_ORE)) {
		USART_ClearITPendingBit(usart_dev->cfg->regs, USART_IT_ORE);
		++usart_dev->error_overruns;
	}
	
#if defined(PIOS_INCLUDE_FREERTOS)
	portEND_SWITCHING_ISR((rx_need_yield || tx_need_yield) ? pdTRUE : pdFALSE);
#endif	/* PIOS_INCLUDE_FREERTOS */
}
Exemplo n.º 7
0
static void PIOS_USART_RegisterTxCallback(uintptr_t usart_id, pios_com_callback tx_out_cb, uintptr_t context)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);
	
	/* 
	 * Order is important in these assignments since ISR uses _cb
	 * field to determine if it's ok to dereference _cb and _context
	 */
	usart_dev->tx_out_context = context;
	usart_dev->tx_out_cb = tx_out_cb;
}
Exemplo n.º 8
0
/**
* Changes the baud rate of the USART peripheral without re-initialising.
* \param[in] usart_id USART name (GPS, TELEM, AUX)
* \param[in] baud Requested baud rate
*/
static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);

	USART_InitTypeDef USART_InitStructure;

	/* Start with a copy of the default configuration for the peripheral */
	USART_InitStructure = usart_dev->cfg->init;

	/* Adjust the baud rate */
	USART_InitStructure.USART_BaudRate = baud;

	/* Write back the new configuration */
	USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
}
Exemplo n.º 9
0
/**
* Gets a byte from the receive buffer
* \param[in] USART USART name
* \return -1 if no new byte available
* \return >= 0: actual byte received
*/
static int32_t PIOS_USART_RxBufferGet(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	if (fifoBuf_getUsed(&usart_dev->rx) == 0) {
		/* Nothing new in the buffer */
		return -1;
	}

	/* get byte - this operation should be atomic! */
	uint8_t b = fifoBuf_getByte(&usart_dev->rx);

	/* Return received byte */
	return b;
}
Exemplo n.º 10
0
/**
* puts a byte onto the receive buffer
* \param[in] USART USART name
* \param[in] b byte which should be put into Rx buffer
* \return 0 if no error
* \return -1 if buffer full (retry)
*/
static int32_t PIOS_USART_RxBufferPut(uint32_t usart_id, uint8_t b)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	if (fifoBuf_getFree(&usart_dev->rx) < 1) {
		/* Buffer full (retry) */
		return -1;
	}

	/* Copy received byte into receive buffer */
	/* This operation should be atomic! */
	fifoBuf_putByte(&usart_dev->rx, b);

	/* No error */
	return 0;
}
Exemplo n.º 11
0
/**
* Changes the baud rate of the USART peripheral without re-initialising.
* \param[in] usart_id USART name (GPS, TELEM, AUX)
* \param[in] baud Requested baud rate
*/
static void PIOS_USART_ChangeBaud(uintptr_t usart_id, uint32_t baud)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);

	USART_InitTypeDef USART_InitStructure;

	/* Start with a copy of the default configuration for the peripheral */
	USART_InitStructure = usart_dev->cfg->init;

	/* Adjust the baud rate */
	USART_InitStructure.USART_BaudRate = baud;

	/* Write back the new configuration */
	USART_Init(usart_dev->cfg->regs, &USART_InitStructure);

	/* For some reason USART_Init results in the UE bit in USART_CR1 being cleared
	 * so we have to enable it again.
	 */
	USART_Cmd(usart_dev->cfg->regs, ENABLE);
}
Exemplo n.º 12
0
    // FIXME XXX Clear / reset uart here - sends NUL char else

    /* Enable USART */
    USART_Cmd(usart_dev->cfg->regs, ENABLE);

    return 0;

out_fail:
    return -1;
}

static void PIOS_USART_RxStart(uint32_t usart_id, __attribute__((unused)) uint16_t rx_bytes_avail)
{
    struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;

    bool valid = PIOS_USART_validate(usart_dev);

    PIOS_Assert(valid);

    USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
}
static void PIOS_USART_TxStart(uint32_t usart_id, __attribute__((unused)) uint16_t tx_bytes_avail)
{
    struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;

    bool valid = PIOS_USART_validate(usart_dev);

    PIOS_Assert(valid);

    USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
}
Exemplo n.º 13
0
    *usart_id = (uint32_t)usart_dev;

    NVIC_Init((NVIC_InitTypeDef *)&cfg->irq.init);
    USART_ITConfig(cfg->regs, USART_IT_RXNE, ENABLE);
    USART_ITConfig(cfg->regs, USART_IT_TXE, ENABLE);
    USART_ITConfig(cfg->regs, USART_IT_ORE, DISABLE);
    USART_ITConfig(cfg->regs, USART_IT_TC, DISABLE);
    /* Enable USART */
    USART_Cmd(cfg->regs, ENABLE);

    return 0;
}

static void PIOS_USART_RxStart(uint32_t usart_id, __attribute__((unused)) uint16_t rx_bytes_avail)
{
    const struct pios_usart_dev *usart_dev = PIOS_USART_validate(usart_id);

    USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
}
static void PIOS_USART_TxStart(uint32_t usart_id, __attribute__((unused)) uint16_t tx_bytes_avail)
{
    const struct pios_usart_dev *usart_dev = PIOS_USART_validate(usart_id);

    USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
}

/**
 * Changes the baud rate of the USART peripheral without re-initialising.
 * \param[in] usart_id USART name (GPS, TELEM, AUX)
 * \param[in] baud Requested baud rate
 */