#include "driver/spi.h" /****************************************************************************** * FunctionName : spi_lcd_mode_init * Description : SPI master initial function for driving LCD TM035PDZV36 * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid *******************************************************************************/ void spi_lcd_mode_init(uint8 spi_no) { uint32 regvalue; if(spi_no>1) return; //handle invalid input number //bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock //bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock if(spi_no==SPI){ WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); //clear bit9,and bit8 PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode }else if(spi_no==HSPI){ WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9 PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode } SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE); // SPI clock=CPU clock/8 WRITE_PERI_REG(SPI_CLOCK(spi_no), ((1&SPI_CLKDIV_PRE)<1) return; //handle invalid input number if(high_bit) bytetemp=(low_8bit>>1)|0x80; else bytetemp=(low_8bit>>1)&0x7f; regvalue= ((8&SPI_USR_COMMAND_BITLEN)<1) return; //handle invalid input number if(spi_no==SPI){ WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode } else if(spi_no==HSPI){ WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode } SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_DOUTDIN|SPI_USR_MOSI); //set clock polarity // TODO: This doesn't work //if (cpol == 1) { // SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE<1) return; //handle invalid input number while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR); WRITE_PERI_REG(SPI_W0(HSPI), *data); SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR); while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR); *data = (uint8)(READ_PERI_REG(SPI_W0(spi_no))&0xff); } /****************************************************************************** * FunctionName : spi_byte_write_espslave * Description : SPI master 1 byte transmission function for esp8266 slave, * transmit 1byte data to esp8266 slave buffer needs 16bit transmission , * first byte is command 0x04 to write slave buffer, second byte is data * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid * uint8 data- transmitted data *******************************************************************************/ void spi_byte_write_espslave(uint8 spi_no,uint8 data) { uint32 regvalue; if(spi_no>1) return; //handle invalid input number while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_DUMMY); //SPI_FLASH_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1, // bit15-0 is cmd value. //0x70000000 is for 8bits cmd, 0x04 is eps8266 slave write cmd value WRITE_PERI_REG(SPI_USER2(spi_no), ((7&SPI_USR_COMMAND_BITLEN)<1) return; //handle invalid input number while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI|SPI_USR_ADDR|SPI_USR_DUMMY); //SPI_FLASH_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1, // bit15-0 is cmd value. //0x70000000 is for 8bits cmd, 0x06 is eps8266 slave read cmd value WRITE_PERI_REG(SPI_USER2(spi_no), ((7&SPI_USR_COMMAND_BITLEN)<1) return; //handle invalid input number //clear bit9,bit8 of reg PERIPHS_IO_MUX //bit9 should be cleared when HSPI clock doesn't equal CPU clock //bit8 should be cleared when SPI clock doesn't equal CPU clock ////WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9//TEST if(spi_no==SPI){ PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode }else if(spi_no==HSPI){ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode } //regvalue=READ_PERI_REG(SPI_FLASH_SLAVE(spi_no)); //slave mode,slave use buffers which are register "SPI_FLASH_C0~C15", enable trans done isr //set bit 30 bit 29 bit9,bit9 is trans done isr mask SET_PERI_REG_MASK( SPI_SLAVE(spi_no), SPI_SLAVE_MODE|SPI_SLV_WR_RD_BUF_EN| SPI_SLV_WR_BUF_DONE_EN|SPI_SLV_RD_BUF_DONE_EN| SPI_SLV_WR_STA_DONE_EN|SPI_SLV_RD_STA_DONE_EN| SPI_TRANS_DONE_EN); //disable general trans intr //CLEAR_PERI_REG_MASK(SPI_SLAVE(spi_no),SPI_TRANS_DONE_EN); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);//disable flash operation mode SET_PERI_REG_MASK(SPI_USER(spi_no),SPI_USR_MISO_HIGHPART);//SLAVE SEND DATA BUFFER IN C8-C15 //////**************RUN WHEN SLAVE RECIEVE*******************/////// //tow lines below is to configure spi timing. SET_PERI_REG_MASK(SPI_CTRL2(spi_no),(0x2&SPI_MOSI_DELAY_NUM)<>8)&0xff; spi_data[(idx<<2)+2] = (recv_data>>16)&0xff; spi_data[(idx<<2)+3] = (recv_data>>24)&0xff; idx++; } //add system_os_post here GPIO_OUTPUT_SET(0, 1); } if(regvalue&SPI_SLV_RD_BUF_DONE){ //it is necessary to call GPIO_OUTPUT_SET(2, 1), when new data is preped in SPI_W8-15 and needs to be sended. GPIO_OUTPUT_SET(2, 0); //add system_os_post here //system_os_post(USER_TASK_PRIO_1,WR_RD,regvalue); } }else if(READ_PERI_REG(0x3ff00020)&BIT9){ //bit7 is for i2s isr, } } #ifdef SPI_SLAVE_DEBUG void ICACHE_FLASH_ATTR set_miso_data() { if(GPIO_INPUT_GET(2)==0){ WRITE_PERI_REG(SPI_W8(HSPI),0x05040302); WRITE_PERI_REG(SPI_W9(HSPI),0x09080706); WRITE_PERI_REG(SPI_W10(HSPI),0x0d0c0b0a); WRITE_PERI_REG(SPI_W11(HSPI),0x11100f0e); WRITE_PERI_REG(SPI_W12(HSPI),0x15141312); WRITE_PERI_REG(SPI_W13(HSPI),0x19181716); WRITE_PERI_REG(SPI_W14(HSPI),0x1d1c1b1a); WRITE_PERI_REG(SPI_W15(HSPI),0x21201f1e); GPIO_OUTPUT_SET(2, 1); } } void ICACHE_FLASH_ATTR disp_spi_data() { uint8 i = 0; for(i=0;i<32;i++){ os_printf("data %d : 0x%02x\n\r",i,spi_data[i]); } //os_printf("d31:0x%02x\n\r",spi_data[31]); } void ICACHE_FLASH_ATTR spi_task(os_event_t *e) { uint8 data; switch(e->sig){ case MOSI: disp_spi_data(); break; case STATUS_R_IN_WR : os_printf("SR ERR in WRPR,Reg:%08x \n",e->par); break; case STATUS_W: os_printf("SW ERR,Reg:%08x\n",e->par); break; case TR_DONE_ALONE: os_printf("TD ALO ERR,Reg:%08x\n",e->par); break; case WR_RD: os_printf("WR&RD ERR,Reg:%08x\n",e->par); break; case DATA_ERROR: os_printf("Data ERR,Reg:%08x\n",e->par); break; case STATUS_R_IN_RD : os_printf("SR ERR in RDPR,Reg:%08x\n",e->par); break; default: break; } } void ICACHE_FLASH_ATTR spi_task_init(void) { spiQueue = (os_event_t*)os_malloc(sizeof(os_event_t)*SPI_QUEUE_LEN); system_os_task(spi_task,USER_TASK_PRIO_1,spiQueue,SPI_QUEUE_LEN); } os_timer_t spi_timer_test; void ICACHE_FLASH_ATTR spi_test_init() { os_printf("spi init\n\r"); spi_slave_init(HSPI); os_printf("gpio init\n\r"); gpio_init(); os_printf("spi task init \n\r"); spi_task_init(); #ifdef SPI_MISO os_printf("spi miso init\n\r"); set_miso_data(); #endif //os_timer_disarm(&spi_timer_test); //os_timer_setfn(&spi_timer_test, (os_timer_func_t *)set_miso_data, NULL);//wjl //os_timer_arm(&spi_timer_test,50,1); } #endif