Exemplo n.º 1
0
/**
 * @brief Disable SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntDisable(SpiNum spiNum, SpiIntSrc intSrc)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc);
}
Exemplo n.º 2
0
/**
 * @brief Enable SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntEnable(SpiNum spiNum, SpiIntSrc intSrc)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    SET_PERI_REG_MASK(SPI_SLAVE(spiNum), (intSrc << 5));
}
Exemplo n.º 3
0
/**
 * Tests SPI by echo what was read
 */
void SPI_TEST()
{
  volatile unsigned char val = 0;
  SPI_INIT();
  
  while(1)
  { 
    val = SPI_SLAVE(val);
  }
}
Exemplo n.º 4
0
/**
 * @brief Clear all of SPI interrupt source.
 *
 */
void ICACHE_FLASH_ATTR SPIIntClear(SpiNum spiNum)
{
    if (spiNum > SpiNum_HSPI) {
        return;
    }
    CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SpiIntSrc_TransDone
                        | SpiIntSrc_WrStaDone
                        | SpiIntSrc_RdStaDone
                        | SpiIntSrc_WrBufDone
                        | SpiIntSrc_RdBufDone);
}
Exemplo n.º 5
0
void SPIIntCfg(SpiNum spiNum, SpiIntInfo *pIntInfo)
{
    if ((spiNum > SpiNum_HSPI)
        || (NULL == pIntInfo)) {
        return;
    }
    // Clear the interrupt source and disable all of the interrupt.
    CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), 0x3FF);
    SPIIntEnable(spiNum, pIntInfo->src);
    os_printf("src=%x\r\n,isrFunc=%x", (pIntInfo->src << 5), pIntInfo->isrFunc);
    //
    ETS_SPI_INTR_ATTACH(pIntInfo->isrFunc, NULL);
    // Enable isr
    ETS_SPI_INTR_ENABLE();    
}
Exemplo n.º 6
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 Based on pAttr initialize SPI module.
 *
 */
void ICACHE_FLASH_ATTR SPIInit (SpiNum spiNum, SpiAttr* pAttr)
{
	if ((spiNum > SpiNum_HSPI) || (NULL == pAttr))
	{
		return;
	}
	// SPI_CPOL & SPI_CPHA
	switch (pAttr->subMode)
	{
	case SpiSubMode_1:
		CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE
		break;
	case SpiSubMode_2:
		SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE
		break;
	case SpiSubMode_3:
		SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE);
		break;
	case SpiSubMode_0:
		default:
		CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE);
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE);
		// To do nothing
		break;
	}

	// SPI bit order
	if (SpiBitOrder_MSBFirst == pAttr->bitOrder)
	{
		CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER);
		CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER);
	}
	else if (SpiBitOrder_LSBFirst == pAttr->bitOrder)
	{
		SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER);
		SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER);
	}
	else
	{
		// To do nothing
	}

	// Disable flash operation mode
	// As earlier as better, if not SPI_CTRL2 can not to be set delay cycles.
	CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_FLASH_MODE);

	// SPI mode type
	if (SpiMode_Master == pAttr->mode)
	{
		// SPI mode type
		CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE);
		// SPI Send buffer
		CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART);// By default slave send buffer C0-C7
		// SPI Speed
		if (1 < (pAttr->speed))
		{
			uint8 i, k;
			i = (pAttr->speed / 40) ? (pAttr->speed / 40) : 1;
			k = pAttr->speed / i;
			CLEAR_PERI_REG_MASK(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK);
			WRITE_PERI_REG(SPI_CLOCK(spiNum),
			        (((i - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
			        (((k - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
			        ((((k + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
			        (((k - 1) & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
		}
		else
		{
			WRITE_PERI_REG(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
		}
		// By default format:CMD+ADDR+DATA
		SET_PERI_REG_MASK(SPI_USER(spiNum),
		        SPI_CS_SETUP | SPI_CS_HOLD | SPI_USR_MOSI);

		//delay num
		SET_PERI_REG_MASK(SPI_CTRL2(spiNum),
		        ((0x1 & SPI_MISO_DELAY_NUM) << SPI_MISO_DELAY_NUM_S));
	}
	else if (SpiMode_Slave == pAttr->mode)
	{
		// BIT19 must do
		SET_PERI_REG_MASK(SPI_PIN(spiNum), BIT19);

		// SPI mode type
		SET_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE);
		// SPI Send buffer
		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART);// By default slave send buffer C8-C15

		SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI);

		// If do not set delay cycles, slave not working,master cann't get the data.
		SET_PERI_REG_MASK(SPI_CTRL2(spiNum),
		        ((0x1 & SPI_MOSI_DELAY_NUM) << SPI_MOSI_DELAY_NUM_S)); //delay num
		// SPI Speed
		WRITE_PERI_REG(SPI_CLOCK(spiNum), 0);

		// By default format::CMD(8bits)+ADDR(8bits)+DATA(32bytes).
		SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN,
		        7, SPI_USR_COMMAND_BITLEN_S);
		SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_WR_ADDR_BITLEN,
		        7, SPI_SLV_WR_ADDR_BITLEN_S);
		SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_RD_ADDR_BITLEN,
		        7, SPI_SLV_RD_ADDR_BITLEN_S);
		SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_BUF_BITLEN,
		        (32 * 8 - 1), SPI_SLV_BUF_BITLEN_S);
		// For 8266 work on slave mode.
		SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_STATUS_BITLEN,
		        7, SPI_SLV_STATUS_BITLEN_S);
	}
	else
	{
		// To do nothing
	}

	//clear Daul or Quad lines transmission mode
	CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum),
	        SPI_QIO_MODE | SPI_DIO_MODE | SPI_DOUT_MODE | SPI_QOUT_MODE);
	// Clear the data buffer.
	uint8 i;
	uint32 regAddr = REG_SPI_BASE(spiNum) + 0x40;
	for (i = 0; i < 16; ++i)
	{
		WRITE_PERI_REG(regAddr, 0);
		regAddr += 4;
	}

}
/**
 * @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;
}