Exemplo n.º 1
0
/**
@ingroup spi_function
@brief Send an array of bytes to to the SPI bus.

@note Can only be used if SPI_USE_BUFFER are enabled in spi_iha_defs.h

@see spi_iha_defs.h for SPI_USE_BUFFER setup.

@return SPI_OK: OK byte send to SPI bus or put in tx_buffer.\n
SPI_NO_ROOM_IN_TX_BUFFER: Buffer full no data send\n
SPI_ILLEGAL_INSTANCE: instance is null.
@param spi to send to.
@param *buf pointer to buffer to be send.
@param len no of bytes to send.
*/
uint8_t spi_send_bytes(spi_p spi, uint8_t buf[], uint8_t len) {
	uint8_t result = SPI_OK;
	uint32_t value;
	uint8_t tmp = 0;	
	
	if (spi == NULL) {
		return SPI_ILLEGAL_INSTANCE;
	}

	// Select correct instance
	if (_this != spi ) {
		_select_instance(spi);
	}

	// Critical section
	 	{
 		// disable interrupt
		spi_disable_interrupt(_spi_base, SPI_IDR_TDRE | SPI_IDR_RDRF);

		// Check if buffer is free
		if (len > fifo_get_free_size(spi->_spi_tx_fifo_desc)) {
			result = SPI_NO_ROOM_IN_TX_BUFFER;
		} else {
			// If SPI in idle send the first byte
			if (!_spi_active) {
				_spi_active = 1;
					
				// Send first byte
				value = SPI_TDR_TD(buf[0]) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
				if (len == 1) {
					// It was last byte
					value |= SPI_TDR_LASTXFER;
				}					

				// Send byte
				_spi_base->SPI_TDR = value;
				//spi_enable_interrupt(_spi_base, SPI_IER_TDRE);
				tmp = 1;
			}
				
			// Put in the tx buffer
			for (uint8_t i = tmp; i < len; i++) {
				value = SPI_TDR_TD(buf[i]) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
				if (i == len-1) {
					// It was last byte
					value |= SPI_TDR_LASTXFER;
				}
				if ( fifo_push_uint32(spi->_spi_tx_fifo_desc, value) == FIFO_ERROR_OVERFLOW ) {
					result = SPI_NO_ROOM_IN_TX_BUFFER;			
				}
			}
		}

 		// restore interrupt state
		spi_enable_interrupt(_spi_base, SPI_IER_TDRE | SPI_IER_RDRF);
	}
	return result;
}
Exemplo n.º 2
0
Arquivo: spi.c Projeto: JMR-b/RIOT
void spi_transmission_begin(spi_t dev, char reset_val)
{
    switch (dev) {
#if SPI_0_EN
        case SPI_0:
            SPI_0_DEV->SPI_TDR = SPI_TDR_TD(reset_val);
            break;
#endif /* SPI_0_EN */
    }
}
Exemplo n.º 3
0
Arquivo: spi.c Projeto: JMR-b/RIOT
static inline void irq_handler_transfer(Spi *spi, spi_t dev)
{
    if (spi->SPI_SR & SPI_SR_RDRF) {
        char data;
        data = spi->SPI_RDR & SPI_RDR_RD_Msk;
        data = spi_config[dev].cb(data);
        spi->SPI_TDR = SPI_TDR_TD(data);
    }

    /* See if a thread with higher priority wants to run now */
    if (sched_context_switch_request) {
        thread_yield();
    }
}
Exemplo n.º 4
0
uint8_t spi_send_byte(spi_p spi, uint8_t byte, uint8_t last_byte)
{
	uint8_t result = SPI_OK;
	uint32_t value;
	
	if (spi == NULL) {
		return SPI_ILLEGAL_INSTANCE;
	}

	// Select correct instance
	if (_this != spi ) {
		_select_instance(spi);
	}

	// Critical section
	{
		// disable interrupt
		spi_disable_interrupt(_spi_base, SPI_IDR_TDRE | SPI_IDR_RDRF);
		
		value = SPI_TDR_TD(byte) | SPI_TDR_PCS(spi_get_pcs(spi->_cs_pin));
		if (last_byte) {
			value |= SPI_TDR_LASTXFER;
		}

		// If SPI in idle send the byte
		if (!_spi_active) {
			_spi_active = 1;

			// Send byte
			_spi_base->SPI_TDR = value;
		} else {
			// Put in the TX buffer
			if ( fifo_push_uint32(spi->_spi_tx_fifo_desc, value) == FIFO_ERROR_UNDERFLOW )
				result = SPI_NO_ROOM_IN_TX_BUFFER;
		}
		// Enable interrupt
		spi_enable_interrupt(_spi_base, SPI_IER_TDRE | SPI_IER_RDRF);
	}

	return result;
}
Exemplo n.º 5
0
Arquivo: spi.c Projeto: JMR-b/RIOT
int spi_transfer_byte(spi_t dev, char out, char *in)
{
    Spi *spi_port;

    switch (dev) {
#if SPI_0_EN
        case SPI_0:
            spi_port = SPI_0_DEV;
            break;
#endif /* SPI_0_EN */
        default:
            return -1;
    }

    while (!(spi_port->SPI_SR & SPI_SR_TDRE));

    spi_port->SPI_TDR = SPI_TDR_TD(out);

    while (!(spi_port->SPI_SR & SPI_SR_RDRF));

    *in = spi_port->SPI_RDR & SPI_RDR_RD_Msk;

    return 1;
}