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
/**
@ingroup spi_function
@brief Send a single byte to the SPI bus.

@return \n
SPI_OK: OK byte send to SPI bus.\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 byte to be send.
*/
uint8_t spi_send_byte(spi_p spi, uint8_t byte) {
	if (spi == 0) {
		return SPI_ILLEGAL_INSTANCE;
	}

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

	uint8_t result = SPI_OK;

	// Critical section
	{
		// disable interrupt
		uint8_t c_sreg = SREG;
		cli();

		// If SPI in idle send the first byte
		if (!_spi_active) {
			_spi_active = 1;
			_set_cs(CS_ACTIVE);
			// Enable SPI interrupt
			SPCR |= _BV(SPIE);
			// Send first byte
			SPDR = byte;
		}
		#if SPI_USE_BUFFER == 0
		else {
			result = SPI_BUSY;
		}
		#else
		else {
			// Check if buffer is free
			if ( ((spi->_tx_buf != 0) && (BUFFER_SIZE - spi->_tx_buf->no_in_buffer)) || (spi->_tx_buf == 0) ) {
				// Put in the tx buffer
				buffer_put_item(spi->_tx_buf, byte);
				}else {
				result = SPI_NO_ROOM_IN_TX_BUFFER;
			}
		}
		#endif

		// restore interrupt state
		SREG = c_sreg;
	}
Exemplo n.º 3
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;
}