Пример #1
0
/* @defgroup SPI hardware implementation
 * @brief transfer32()
 *
 * private method used by transfer(byte) and transfer16(sort)
 * to send/recv one uint32_t
 *
 * SPI transfer is based on a simultaneous send and receive:
 * the received data is returned in receivedVal (or receivedVal16).
 *
 * 		receivedVal = SPI.transfer(val)			: single byte
 * 		receivedVal16 = SPI.transfer16(val16)	: single short
 */
uint32 SPIClass::transfer32(uint32 data, uint8 bits)
{
	uint32_t regvalue = READ_PERI_REG(SPI_USER(SPI_NO)) & (SPI_WR_BYTE_ORDER | SPI_RD_BYTE_ORDER | SPI_CK_OUT_EDGE);

	while(READ_PERI_REG(SPI_CMD(SPI_NO))&SPI_USR);

	regvalue |=  SPI_USR_MOSI | SPI_DOUTDIN | SPI_CK_I_EDGE;
	WRITE_PERI_REG(SPI_USER(SPI_NO), regvalue);


	WRITE_PERI_REG(SPI_USER1(SPI_NO),
			( (bits-1 & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S ) |
			( (bits-1 & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S ) );

	// copy data to W0
	if(READ_PERI_REG(SPI_USER(SPI_NO))&SPI_WR_BYTE_ORDER) {
		WRITE_PERI_REG(SPI_W0(SPI_NO), data<<(32-bits));
	} else {
 		WRITE_PERI_REG(SPI_W0(SPI_NO), data);
	}

	SET_PERI_REG_MASK(SPI_CMD(SPI_NO), SPI_USR);   // send

	while (READ_PERI_REG(SPI_CMD(SPI_NO)) & SPI_USR);

	// wait a while before reading the register into the buffer
//	delayMicroseconds(2);

	if(READ_PERI_REG(SPI_USER(SPI_NO))&SPI_RD_BYTE_ORDER) {
		return READ_PERI_REG(SPI_W0(SPI_NO)) >> (32-bits); //Assuming data in is written to MSB. TBC
	} else {
		return READ_PERI_REG(SPI_W0(SPI_NO)); //Read in the same way as DOUT is sent. Note existing contents of SPI_W0 remain unless overwritten!
/**
 * @brief Receive status register from slave(ESP8266).
 *
 */
int ICACHE_FLASH_ATTR SPIMasterRecvStatus (SpiNum spiNum)
{
	if (spiNum > SpiNum_HSPI)
	{
		return -1;
	}

	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;
	// Enable MISO
	SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
	CLEAR_PERI_REG_MASK(SPI_USER(spiNum),
	        SPI_USR_MOSI | SPI_USR_DUMMY | SPI_USR_ADDR);

	// 8bits cmd, 0x06 is eps8266 slave read status cmd value
	WRITE_PERI_REG(SPI_USER2(spiNum),
	        ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S)
	        | MASTER_READ_STATUS_FROM_SLAVE_CMD);
	// Set revcive buffer length.
	SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN,
	        7, SPI_USR_MISO_BITLEN_S);

	// start spi module.
	SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;

	uint8_t data = (uint8) (READ_PERI_REG(SPI_W0(spiNum)) & 0xff);

	return (uint8) (READ_PERI_REG(SPI_W0(spiNum)) & 0xff);
}
/**
 * @brief Send data to slave(ESP8266 register of RD_STATUS or WR_STATUS).
 *
 */
void ICACHE_FLASH_ATTR SPIMasterSendStatus (SpiNum spiNum, uint8_t data)
{
	if (spiNum > SpiNum_HSPI)
	{
		return;
	}
	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;
	// Enable MOSI
	SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
	CLEAR_PERI_REG_MASK(SPI_USER(spiNum),
	        SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);

	// 8bits cmd, 0x04 is eps8266 slave write cmd value
	WRITE_PERI_REG(SPI_USER2(spiNum),
	        ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S)
	        | MASTER_WRITE_STATUS_TO_SLAVE_CMD);
	// Set data send buffer length.
	SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN,
	        ( (sizeof (data) << 3) - 1), SPI_USR_MOSI_BITLEN_S);

	WRITE_PERI_REG(SPI_W0(spiNum), (uint32 ) (data));
	// Start SPI
	SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

}
Пример #4
0
int do_flash_read_chip_id() {
  uint32_t chip_id = 0;
  WRITE_PERI_REG(SPI_CMD(0), SPI_RDID);
  while (READ_PERI_REG(SPI_CMD(0)) & SPI_RDID) {
  }
  chip_id = READ_PERI_REG(SPI_W0(0)) & 0xFFFFFF;
  send_packet(&chip_id, sizeof(chip_id));
  return 0;
}
Пример #5
0
//esp8266 slave isr handle funtion,tiggered when any transmission is finished.
//the function is registered in spi_slave_init.
static void ICACHE_FLASH_ATTR
spi_slave_isr_handler(void *para)
{
    uint32 regvalue;

    if(READ_PERI_REG(0x3ff00020)&BIT4)
    {
        //following 3 lines is to clear isr signal
        CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI), 0x3ff);
    }
    else if(READ_PERI_REG(0x3ff00020)&BIT7)   //bit7 is for hspi isr,
    {
        regvalue=READ_PERI_REG(SPI_SLAVE(HSPI));
        CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),
                            SPI_TRANS_DONE_EN|
                            SPI_SLV_WR_STA_DONE_EN|
                            SPI_SLV_RD_STA_DONE_EN|
                            SPI_SLV_WR_BUF_DONE_EN|
                            SPI_SLV_RD_BUF_DONE_EN);
        SET_PERI_REG_MASK(SPI_SLAVE(HSPI), SPI_SYNC_RESET);
        CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),
                            SPI_TRANS_DONE|
                            SPI_SLV_WR_STA_DONE|
                            SPI_SLV_RD_STA_DONE|
                            SPI_SLV_WR_BUF_DONE|
                            SPI_SLV_RD_BUF_DONE);
        SET_PERI_REG_MASK(SPI_SLAVE(HSPI),
                          SPI_TRANS_DONE_EN|
                          SPI_SLV_WR_STA_DONE_EN|
                          SPI_SLV_RD_STA_DONE_EN|
                          SPI_SLV_WR_BUF_DONE_EN|
                          SPI_SLV_RD_BUF_DONE_EN);

        if(regvalue&SPI_SLV_WR_BUF_DONE)
        {
            uint32_t i, reg, recv_data;

            GPIO_OUTPUT_SET(0, 0);

            for(reg = SPI_W0(HSPI); reg < SPI_W8(HSPI); reg += 4)
            {
                recv_data = READ_PERI_REG(reg);
                for(i = 0; i < 4; ++i, ++idx, recv_data >>= 8)
                    spi_data[idx] = recv_data & 0xff;
            }

            /* TODO: post task event ... 
            *
            * system_os_post(USER_TASK_PRIO_1, ut_sig_mosi, (ETSParam)spi_data);
            * */

            GPIO_OUTPUT_SET(0, 1);
        }
/**
 * @brief Receive data from slave.
 *
 */
int ICACHE_FLASH_ATTR SPIMasterRecvData (SpiNum spiNum, SpiData* pOutData)
{
	char idx = 0;
	if ( (spiNum > SpiNum_HSPI)
	        || (NULL == pOutData))
	{
		return -1;
	}

	uint32_t *value = pOutData->data;
	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;
	// Set command by user.
	if (pOutData->cmdLen != 0)
	{
		// Max command length 16 bits.
		SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
		        ( (pOutData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S);
		// Enable command
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
		// Load command
		SPIMasterCfgCmd (spiNum, pOutData->cmd);
	}
	else
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
		SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
		        0, SPI_USR_COMMAND_BITLEN_S);
	}
	// Set Address by user.
	if (pOutData->addrLen == 0)
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
		        0, SPI_USR_ADDR_BITLEN_S);
	}
	else
	{
		if (NULL == pOutData->addr)
		{
			return -1;
		}
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
		        ( (pOutData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S);
		// Enable address
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
		// Load address
		SPIMasterCfgAddr (spiNum, *pOutData->addr);
	}
	// Set data by user.
	if (pOutData->dataLen != 0)
	{
		if (NULL == value)
		{
			return -1;
		}
		// Clear MOSI enable
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
		// Enable MOSI
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
		// Set data send buffer length.Max data length 64 bytes.
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN,
		        ( (pOutData->dataLen << 3) - 1), SPI_USR_MISO_BITLEN_S);
	}
	else
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN,
		        0, SPI_USR_MISO_BITLEN_S);
	}
	// Start send data
	SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);

	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;
	// Read data out
	do
	{
		*pOutData->data++ = READ_PERI_REG(SPI_W0(spiNum) + (idx << 2));
	}
	while ( ++idx < (pOutData->dataLen / 4));

	return 0;
}
/**
 * @brief Send data to slave.
 *
 */
int ICACHE_FLASH_ATTR SPIMasterSendData (SpiNum spiNum, SpiData* pInData)
{
	char idx = 0;
	if ( (spiNum > SpiNum_HSPI)
	        || (NULL == pInData)
	        || (64 < pInData->dataLen))
	{
		return -1;
	}
	uint32_t *value = pInData->data;
	while (READ_PERI_REG(SPI_CMD(spiNum)) & SPI_USR)
		;
	// Set command by user.
	if (pInData->cmdLen != 0)
	{
		// Max command length 16 bits.
		SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
		        ( (pInData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S);
		// Enable command
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
		// Load command
		SPIMasterCfgCmd (spiNum, pInData->cmd);
	}
	else
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND);
		SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
		        0, SPI_USR_COMMAND_BITLEN_S);
	}
	// Set Address by user.
	if (pInData->addrLen == 0)
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
		        0, SPI_USR_ADDR_BITLEN_S);
	}
	else
	{
		if (NULL == pInData->addr)
		{
			return -1;
		}
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN,
		        ( (pInData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S);
		// Enable address
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR);
		// Load address
		SPIMasterCfgAddr (spiNum, *pInData->addr);
	}
	// Set data by user.
	if (pInData->dataLen != 0)
	{
		if (NULL == value)
		{
			return -1;
		}
		// Enable MOSI
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO);
		// Load send buffer
		do
		{
			WRITE_PERI_REG((SPI_W0(spiNum) + (idx << 2)), *value++);
		}
		while ( ++idx < (pInData->dataLen / 4));
		// Set data send buffer length.Max data length 64 bytes.
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN,
		        ( (pInData->dataLen << 3) - 1), SPI_USR_MOSI_BITLEN_S);
	}
	else
	{
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);
		SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN,
		        0, SPI_USR_MOSI_BITLEN_S);
	}
	// Start send data
	SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR);
	// Wait for transmit done
	while ( ! (READ_PERI_REG(SPI_SLAVE(spiNum)) & SPI_TRANS_DONE))
		;
	CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_TRANS_DONE);
	return 0;
}