Esempio 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;
}
Esempio n. 2
0
// =============================================================================
// 功能:SPI片选使能,使片选有效,若控制器有具体的配置片选寄存器,可直接返回
// 参数:Reg,本模块内即SPI寄存器基址
//       cs,片选线
// 返回:无
// 说明:SPI控制器上只引出了一个CS,若需要接多个CS,则必须应用程序自己控制CS
// =============================================================================
static bool_t __SPI_BusCsActive(tagSpiReg *Reg, u8 cs)
{
//  s_ChipSelect = cs;
    Reg->SPI_TDR |= SPI_TDR_PCS(cs);
    Reg->SPI_MR  &= ~SPI_MR_PCS(0x0F);
    Reg->SPI_MR  |= SPI_MR_PCS(cs);
    return true;
}
Esempio 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;
}