/** * @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); }
/****************************************************************************** * 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)<<SPI_CLKDIV_PRE_S)| ((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)| ((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)| ((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div }
static void gpio_intr_reset(uint32 intr_num, uint8 reset) { if (intr_num > 7) { return; } //bit PCNT_CNT_PAUSE_U0-7 CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2 + 1)); //bit PCNT_PLUS_CNT_RST_U0-7 if (reset) { SET_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2)); } else { CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2)); } }
/** * @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); }
FAST static void rx_isr(void *param) { /* TODO(alashkin): add errors checking */ unsigned int peri_reg = READ_PERI_REG(UART_INTR_STATUS(UART_MAIN)); static volatile int tail = 0; if ((peri_reg & UART_RXBUF_FULL) != 0 || (peri_reg & UART_RX_NEW) != 0) { int char_count, i; CLEAR_PERI_REG_MASK(UART_CTRL_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); WRITE_PERI_REG(UART_CLEAR_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); char_count = READ_PERI_REG(UART_DATA_STATUS(UART_MAIN)) & 0x000000FF; /* TODO(mkm): handle overrun */ for (i = 0; i < char_count; i++, tail = (tail + 1) % RX_BUFFER_SIZE) { rx_buf[tail] = READ_PERI_REG(UART_BUF(UART_MAIN)) & 0xFF; if (rx_buf[tail] == UART_SIGINT_CHAR && uart_interrupt_cb) { /* swallow the intr byte */ tail = (tail - 1) % RX_BUFFER_SIZE; uart_interrupt_cb(UART_SIGINT_CHAR); } } WRITE_PERI_REG(UART_CLEAR_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); SET_PERI_REG_MASK(UART_CTRL_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); #ifndef RTOS_SDK system_os_post(TASK_PRIORITY, 0, tail); #else rtos_dispatch_char_handler(tail); #endif } }
//only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) { if (flow_ctrl & USART_HardwareFlowControl_RTS) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S); SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } else { CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } if (flow_ctrl & USART_HardwareFlowControl_CTS) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); } else { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); } }
void esp_uart_set_rx_enabled(int uart_no, int enabled) { struct esp_uart_state *us = s_us[uart_no]; if (us == NULL) return; struct esp_uart_config *cfg = us->cfg; if (enabled) { if (cfg->rx_fc_ena) { SET_PERI_REG_MASK(UART_CONF1(cfg->uart_no), UART_RX_FLOW_EN); } SET_PERI_REG_MASK(UART_INT_ENA(cfg->uart_no), UART_RX_INTS); us->rx_enabled = 1; } else { if (cfg->rx_fc_ena) { /* With UART_SW_RTS = 0 in CONF0 this throttles RX (sets RTS = 1). */ CLEAR_PERI_REG_MASK(UART_CONF1(cfg->uart_no), UART_RX_FLOW_EN); } CLEAR_PERI_REG_MASK(UART_INT_ENA(cfg->uart_no), UART_RX_INTS); us->rx_enabled = 0; } }
void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); if (Parity_mode == USART_Parity_None) { } else { SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN); } }
/****************************************************************************** * FunctionName : uart_config * Description : Internal used function * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled * UART1 just used for debug output * Parameters : uart_no, use UART0 or UART1 defined ahead * Returns : NONE *******************************************************************************/ static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no) { if (uart_no == UART1) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_GPIO2_U); PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); } else { /* rcv_buff size is 0x100 */ ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); PIN_PULLUP_DIS (PERIPHS_IO_MUX_U0TXD_U); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); PIN_PULLUP_DIS (PERIPHS_IO_MUX_U0RXD_U); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_U0RXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, 0); // FUNC_U0RXD==0 } uart_div_modify(uart_no, UART_CLK_FREQ / UartDev.baut_rate); if (uart_no == UART1) //UART 1 always 8 N 1 WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(EIGHT_BITS, NONE_BITS, ONE_STOP_BIT)); else WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(UartDev.data_bits, UartDev.parity, UartDev.stop_bits)); //clear rx and tx fifo,not ready SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); if (uart_no == UART0) { // Configure RX interrupt conditions as follows: trigger rx-full when there are 80 characters // in the buffer, trigger rx-timeout when the fifo is non-empty and nothing further has been // received for 4 character periods. // Set the hardware flow-control to trigger when the FIFO holds 100 characters, although // we don't really expect the signals to actually be wired up to anything. It doesn't hurt // to set the threshold here... // We do not enable framing error interrupts 'cause they tend to cause an interrupt avalanche // and instead just poll for them when we get a std RX interrupt. WRITE_PERI_REG(UART_CONF1(uart_no), ((80 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | ((100 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN | (4 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | UART_RX_TOUT_EN); SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); } else { WRITE_PERI_REG(UART_CONF1(uart_no), ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); } //clear all interrupt WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); }
/** * @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); }
static void finishDma() { //No need to finish if no DMA transfer going on if (!(READ_PERI_REG(I2S_FIFO_CONF_REG(0))&I2S_DSCR_EN)) { return; } //Wait till fifo done while (!(READ_PERI_REG(I2S_INT_RAW_REG(0))&I2S_TX_REMPTY_INT_RAW)) ; //Wait for last bytes to leave i2s xmit thing //ToDo: poll bit in next hw // for (i=0; i<(1<<8); i++); while (!(READ_PERI_REG(I2S_STATE_REG(0))&I2S_TX_IDLE)); //Reset I2S for next transfer CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_START | I2S_RX_START); CLEAR_PERI_REG_MASK(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START | I2S_INLINK_START); SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_RESET | I2S_RX_FIFO_RESET); CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RESET | I2S_TX_FIFO_RESET | I2S_RX_RESET | I2S_RX_FIFO_RESET); // for (i=0; i<(1<<8); i++); while ((READ_PERI_REG(I2S_STATE_REG(0))&I2S_TX_FIFO_RESET_BACK)); }
/****************************************************************************** * FunctionName : spi_master_init * Description : SPI master initial function for common byte units transmission * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid *******************************************************************************/ void ICACHE_FLASH_ATTR spi_master_init(uint8 spi_no) { uint32 regvalue; if(spi_no>1) return; //handle invalid input number 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); WRITE_PERI_REG(SPI_CLOCK(spi_no), ((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)| ((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)| ((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div }
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(); }
void C3WireOutput::output(const uint8_t *pData) { // Stop DMA // Reset descriptor address SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_STOP); // TODO: Ideally this should be moved closer to the rest of the register access // But that will sometimes fail. // I suspect we have to wait for the SLC to actually be stopped before messing with the registers m_pEncoder->encode(pData, m_nLength, m_pBuffer); // Ideally I'd like to adjust the buffer length, // but that will creep out the SLC when it's not properly stopped. // So assume that the rest of the buffer is 0 anyway. // m_qBuffer.datalen = m_qBuffer.blocksize = nOutputLength * 4; // Adjust SLC (DMA) to point to just encoded buffer CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&m_qBuffer) & SLC_RXLINK_DESCADDR_MASK); // Reset FIFO, toggle pin, don't leave high SET_PERI_REG_MASK(I2SCONF, I2S_I2S_TX_FIFO_RESET); CLEAR_PERI_REG_MASK(I2SCONF, I2S_I2S_TX_FIFO_RESET); // Start DMA SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START); }
void pwm_tim1_intr_handler() { CLEAR_PERI_REG_MASK(FRC1_INT_ADDRESS, FRC1_INT_CLR_MASK); if (_pwm_enable) { GPIO_OUTPUT_SET(_gpio_pin_num, _pwm_lvl); _pwm_lvl ^= 1; } else if (_pwm_lvl == _logic_high) { _pwm_lvl = _logic_low; GPIO_OUTPUT_SET(_gpio_pin_num, _pwm_lvl); } WRITE_PERI_REG(FRC1_LOAD_ADDRESS, _frc1_ticks); }
//Set the I2S sample rate, in HZ void ICACHE_FLASH_ATTR i2sSetRate(int rate, int lockBitcount) { //Find closest divider int bestclkmdiv, bestbckdiv, bestbits, bestfreq=0; int tstfreq; int bckdiv, clkmdiv, bits; /* CLK_I2S = 160MHz / I2S_CLKM_DIV_NUM BCLK = CLK_I2S / I2S_BCK_DIV_NUM WS = BCLK/ 2 / (16 + I2S_BITS_MOD) Note that I2S_CLKM_DIV_NUM must be >5 for I2S data I2S_CLKM_DIV_NUM - 5-127 I2S_BCK_DIV_NUM - 2-127 We also have the option to send out more than 2x16 bit per sample. Most I2S codecs will ignore the extra bits and in the case of the 'fake' PWM/delta-sigma outputs, they will just lower the output voltage a bit, so we add them when it makes sense. Some of them, however, won't accept it, that's why we have the option not to do this. */ for (bckdiv=2; bckdiv<128; bckdiv++) { for (clkmdiv=5; clkmdiv<128; clkmdiv++) { for (bits=16; bits<(lockBitcount?17:20); bits++) { tstfreq=BASEFREQ/(bckdiv*clkmdiv*bits*2); if (ABS(rate-tstfreq)<ABS(rate-bestfreq)) { bestfreq=tstfreq; bestclkmdiv=clkmdiv; bestbckdiv=bckdiv; bestbits=bits; } } } } printf("ReqRate %d MDiv %d BckDiv %d Bits %d Frq %d\n", rate, bestclkmdiv, bestbckdiv, bestbits, (int)(BASEFREQ/(bckdiv*clkmdiv*bits*2))); CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD| (I2S_BITS_MOD<<I2S_BITS_MOD_S)| (I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)| (I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S)); SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD| I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT| ((bestbits-16)<<I2S_BITS_MOD_S)| (((bestbckdiv)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)| (((bestclkmdiv)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S)); }
IRAM int esp_uart_dispatch_rx_top(int uart_no) { struct esp_uart_state *us = s_us[uart_no]; if (us == NULL || !us->rx_enabled) return 1; uint32_t rxn = 0; cs_rbuf_t *rxb = &us->rx_buf; /* RX */ if (rxb->avail > 0 && rx_fifo_len(uart_no) > 0) { int linger_counter = 0; /* 32 here is a constant measured (using system_get_time) to provide * linger time of rx_linger_micros. It basically means that one iteration * of the loop takes 3.2 us. * * Note: lingering may starve TX FIFO if the flow is bidirectional. * TODO(rojer): keep transmitting from tx_buf while lingering. */ int max_linger = us->cfg->rx_linger_micros / 10 * 32; #ifdef MEASURE_LINGER_TIME uint32_t st = system_get_time(); #endif while (rxb->avail > 0 && linger_counter <= max_linger) { int rx_len = rx_fifo_len(uart_no); if (rx_len > 0) { while (rx_len-- > 0 && rxb->avail > 0) { cs_rbuf_append_one(rxb, rx_byte(uart_no)); rxn++; } if (linger_counter > 0) { us->stats.rx_linger_conts++; linger_counter = 0; } } else { linger_counter++; } } #ifdef MEASURE_LINGER_TIME fprintf(stderr, "Time spent reading: %u us\n", system_get_time() - st); #endif us->stats.rx_bytes += rxn; } int rfl = rx_fifo_len(uart_no); if (rfl < us->cfg->rx_fifo_full_thresh) { CLEAR_PERI_REG_MASK(UART_INT_CLR(uart_no), UART_RX_INTS); } return rfl == 0; }
void mgos_uart_hal_dispatch_rx_top(struct mgos_uart_state *us) { int uart_no = us->uart_no; struct mbuf *rxb = &us->rx_buf; uint32_t rxn = 0; /* RX */ if (mgos_uart_rxb_free(us) > 0 && esp_uart_rx_fifo_len(uart_no) > 0) { int linger_counter = 0; /* 32 here is a constant measured (using system_get_time) to provide * linger time of rx_linger_micros. It basically means that one iteration * of the loop takes 3.2 us. * * Note: lingering may starve TX FIFO if the flow is bidirectional. * TODO(rojer): keep transmitting from tx_buf while lingering. */ int max_linger = us->cfg.rx_linger_micros / 10 * 32; #ifdef MEASURE_LINGER_TIME uint32_t st = system_get_time(); #endif while (mgos_uart_rxb_free(us) > 0 && linger_counter <= max_linger) { size_t rx_len = esp_uart_rx_fifo_len(uart_no); if (rx_len > 0) { rx_len = MIN(rx_len, mgos_uart_rxb_free(us)); if (rxb->size < rxb->len + rx_len) mbuf_resize(rxb, rxb->len + rx_len); while (rx_len > 0) { uint8_t b = rx_byte(uart_no); mbuf_append(rxb, &b, 1); rx_len--; rxn++; } if (linger_counter > 0) { us->stats.rx_linger_conts++; linger_counter = 0; } } else { linger_counter++; } } #ifdef MEASURE_LINGER_TIME fprintf(stderr, "Time spent reading: %u us\n", system_get_time() - st); #endif us->stats.rx_bytes += rxn; } CLEAR_PERI_REG_MASK(UART_INT_CLR(uart_no), UART_RX_INTS); }
void UARTInit() { //Enable TxD pin PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); //Set baud rate and other serial parameters to 115200,n,8,1 uart_div_modify(0, UART_CLK_FREQ/BIT_RATE_115200); WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| \ (EIGHT_BITS << UART_BIT_NUM_S)); //Reset tx & rx fifo SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); //Clear pending interrupts WRITE_PERI_REG(UART_INT_CLR(0), 0xffff); //Install our own putchar handler os_install_putc1((void *)UARTPutChar); }
static void uartRxInit() { uint32_t reg_val; PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); // reg_val = READ_PERI_REG(UART_CONF1(0)); reg_val = (1 << UART_RXFIFO_FULL_THRHD_S); WRITE_PERI_REG(UART_CONF1_REG(0), reg_val); CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA); printf("Enabling int %d\n", ETS_UART0_INUM); DPORT_REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM); DPORT_REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM); xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL); xt_ints_on(1 << ETS_UART0_INUM); }
void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf) { uint32 reg_val = 0; UART_ClearIntrStatus(uart_no, UART_INTR_MASK); reg_val = READ_PERI_REG(UART_CONF1(uart_no)) & ~((UART_RX_FLOW_THRHD << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN) ; reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_TOUT_INT_ENA) ? ((((pUARTIntrConf->UART_RX_TimeOutIntrThresh)&UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN) : 0); reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_FULL_INT_ENA) ? (((pUARTIntrConf->UART_RX_FifoFullIntrThresh)&UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) : 0); reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_TXFIFO_EMPTY_INT_ENA) ? (((pUARTIntrConf->UART_TX_FifoEmptyIntrThresh)&UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) : 0); WRITE_PERI_REG(UART_CONF1(uart_no), reg_val); CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_INTR_MASK); SET_PERI_REG_MASK(UART_INT_ENA(uart_no), pUARTIntrConf->UART_IntrEnMask); }
int gdb_read_uart_buf(char *buf) { unsigned int peri_reg = READ_PERI_REG(UART_INTR_STATUS(UART_MAIN)); if ((peri_reg & UART_RXBUF_FULL) != 0 || (peri_reg & UART_RX_NEW) != 0) { int char_count, i; CLEAR_PERI_REG_MASK(UART_CTRL_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); WRITE_PERI_REG(UART_CLEAR_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); char_count = READ_PERI_REG(UART_DATA_STATUS(UART_MAIN)) & 0x000000FF; for (i = 0; i < char_count; i++) { buf[i] = READ_PERI_REG(UART_BUF(UART_MAIN)) & 0xFF; } WRITE_PERI_REG(UART_CLEAR_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); SET_PERI_REG_MASK(UART_CTRL_INTR(UART_MAIN), UART_RXBUF_FULL | UART_RX_NEW); return char_count; } return 0; }
void W25QXX_Write_Page(uint8 data,uint32 WriteAddr,uint16 NumByteToWrite) { u16 i=0; spi_mast_byte_write(SPI,0x06); SET_PERI_REG_MASK(SPI_PIN(SPI), SPI_CS_DIS); spi_mast_byte_write(SPI,0x02); spi_mast_byte_write(SPI,(u8)((WriteAddr)>>16)); spi_mast_byte_write(SPI,(u8)((WriteAddr)>>8)); spi_mast_byte_write(SPI,(u8)WriteAddr); while(i<NumByteToWrite) { spi_mast_byte_write(HSPI,data); i++; } CLEAR_PERI_REG_MASK(SPI_PIN(SPI), SPI_CS_DIS); if (i==NumByteToWrite){ spi_mast_byte_write(HSPI,data); } }
/** * @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); }
void HardwareSerial::begin(const uint32_t baud/* = 9600*/) { //TODO: Move to params! UartDev.baut_rate = (UartBautRate)baud; UartDev.parity = NONE_BITS; UartDev.exist_parity = STICK_PARITY_DIS; UartDev.stop_bits = ONE_STOP_BIT; UartDev.data_bits = EIGHT_BITS; ETS_UART_INTR_ATTACH((void*)uart0_rx_intr_handler, &(UartDev.rcv_buff)); PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); uart_div_modify(uart, UART_CLK_FREQ / (UartDev.baut_rate)); WRITE_PERI_REG(UART_CONF0(uart), UartDev.exist_parity | UartDev.parity | (UartDev.stop_bits << UART_STOP_BIT_NUM_S) | (UartDev.data_bits << UART_BIT_NUM_S)); //clear rx and tx fifo,not ready SET_PERI_REG_MASK(UART_CONF0(uart), UART_RXFIFO_RST | UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart), UART_RXFIFO_RST | UART_TXFIFO_RST); //set rx fifo trigger WRITE_PERI_REG(UART_CONF1(uart), (UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); //clear all interrupt WRITE_PERI_REG(UART_INT_CLR(uart), 0xffff); //enable rx_interrupt SET_PERI_REG_MASK(UART_INT_ENA(uart), UART_RXFIFO_FULL_INT_ENA); ETS_UART_INTR_ENABLE(); delay(10); Serial.println("\r\n"); // after SPAM :) }
/****************************************************************************** * FunctionName : uart0_rx_intr_handler * Description : Internal used function * UART0 interrupt handler, add self handle code inside * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg * Returns : NONE *******************************************************************************/ static void // must not use ICACHE_FLASH_ATTR ! uart0_rx_intr_handler(void *para) { // we assume that uart1 has interrupts disabled (it uses the same interrupt vector) uint8 uart_no = UART0; const uint32 one_sec = 1000000; // one second in usecs // we end up largely ignoring framing errors and we just print a warning every second max if (READ_PERI_REG(UART_INT_RAW(uart_no)) & UART_FRM_ERR_INT_RAW) { uint32 now = system_get_time(); if (last_frm_err == 0 || (now - last_frm_err) > one_sec) { #ifdef UART_DBG os_printf("UART framing error (bad baud rate?)\n"); #endif last_frm_err = now; } // clear rx fifo (apparently this is not optional at this point) SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST); // reset framing error WRITE_PERI_REG(UART_INT_CLR(UART0), UART_FRM_ERR_INT_CLR); // once framing errors are gone for 10 secs we forget about having seen them } else if (last_frm_err != 0 && (system_get_time() - last_frm_err) > 10*one_sec) { last_frm_err = 0; } if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST) || UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) { #ifdef UART_DBG os_printf("stat:%02X",*(uint8 *)UART_INT_ENA(uart_no)); #endif ETS_UART_INTR_DISABLE(); system_os_post(recvTaskPrio, 0, 0); } }
static void gpio_intr_init(uint32 intr_num, GPIO_INT_TYPE intr_type) { uint32 cfg0_addr = PCNT_U0_CONF0 + (intr_num * 12); uint32 cfg1_addr = PCNT_U0_CONF1 + (intr_num * 12); uint32 cfg2_addr = PCNT_U0_CONF2 + (intr_num * 12); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_LCTRL_MODE_U0, 0, PCNT_CH1_LCTRL_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_HCTRL_MODE_U0, 0, PCNT_CH1_HCTRL_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_POS_MODE_U0, 0, PCNT_CH1_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_NEG_MODE_U0, 0, PCNT_CH1_NEG_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_LCTRL_MODE_U0, 0, PCNT_CH0_LCTRL_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_HCTRL_MODE_U0, 0, PCNT_CH0_HCTRL_MODE_U0_S); if (intr_type == GPIO_PIN_INTR_NEGEDGE) { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S); } else if (intr_type == GPIO_PIN_INTR_POSEDGE) { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S); } else if (intr_type == GPIO_PIN_INTR_ANYEDGE) { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S); } else { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S); } SET_PERI_REG_BITS(cfg1_addr, PCNT_CNT_THRES0_U0, 1, PCNT_CNT_THRES0_U0_S); SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_L_LIM_U0, 10, PCNT_CNT_L_LIM_U0_S); SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_H_LIM_U0, 10, PCNT_CNT_H_LIM_U0_S); CLEAR_PERI_REG_MASK(cfg0_addr, (PCNT_THR_THRES1_EN_U0 | PCNT_THR_L_LIM_EN_U0 | PCNT_THR_H_LIM_EN_U0 | PCNT_THR_ZERO_EN_U0 | PCNT_FILTER_EN_U0)); SET_PERI_REG_MASK(cfg0_addr, PCNT_THR_THRES0_EN_U0); SET_PERI_REG_MASK(PCNT_INT_ENA, BIT(intr_num)); }
static void lcdIfaceInit() { SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); //Init pins to i2s functions SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO18_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO20_U, 0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2); //11 PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO26_U, 0); //RS WRITE_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG, (148 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC2_OUT_SEL_CFG_REG, (149 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC5_OUT_SEL_CFG_REG, (150 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC16_OUT_SEL_CFG_REG, (151 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC17_OUT_SEL_CFG_REG, (152 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC18_OUT_SEL_CFG_REG, (153 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC19_OUT_SEL_CFG_REG, (154 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC20_OUT_SEL_CFG_REG, (155 << GPIO_FUNC0_OUT_SEL_S)); WRITE_PERI_REG(GPIO_FUNC26_OUT_SEL_CFG_REG, (156 << GPIO_FUNC0_OUT_SEL_S)); //RS WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, (I2S0O_WS_OUT_IDX << GPIO_FUNC0_OUT_SEL_S)); // WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG, (I2S0O_BCK_OUT_IDX<<GPIO_GPIO_FUNC0_OUT_SEL_S)); //GPIO_SET_GPIO_FUNC11_OUT_INV_SEL(1); //old WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, READ_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG) | GPIO_FUNC11_OUT_INV_SEL); //Reset I2S subsystem CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET); SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET); CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET | I2S_TX_RESET); WRITE_PERI_REG(I2S_CONF_REG(0), 0);//I2S_SIG_LOOPBACK); WRITE_PERI_REG(I2S_CONF2_REG(0), 0); WRITE_PERI_REG(I2S_SAMPLE_RATE_CONF_REG(0), (16 << I2S_RX_BITS_MOD_S) | (16 << I2S_TX_BITS_MOD_S) | (1 << I2S_RX_BCK_DIV_NUM_S) | (1 << I2S_TX_BCK_DIV_NUM_S)); WRITE_PERI_REG(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA | I2S_CLK_EN | (1 << I2S_CLKM_DIV_A_S) | (1 << I2S_CLKM_DIV_B_S) | (1 << I2S_CLKM_DIV_NUM_S)); WRITE_PERI_REG(I2S_FIFO_CONF_REG(0), (32 << I2S_TX_DATA_NUM_S) | //Low watermark for IRQ (32 << I2S_RX_DATA_NUM_S)); WRITE_PERI_REG(I2S_CONF1_REG(0), I2S_RX_PCM_BYPASS | I2S_TX_PCM_BYPASS); WRITE_PERI_REG(I2S_CONF_CHAN_REG(0), (2 << I2S_TX_CHAN_MOD_S) | (2 << I2S_RX_CHAN_MOD_S)); //Invert WS to active-low SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST | I2S_RX_RIGHT_FIRST); WRITE_PERI_REG(I2S_TIMING_REG(0), 0); }
//Initialize I2S subsystem for DMA circular buffer use void ICACHE_FLASH_ATTR i2sInit() { int x, y; underrunCnt=0; //First, take care of the DMA buffers. for (y=0; y<I2SDMABUFCNT; y++) { //Allocate memory for this DMA sample buffer. i2sBuf[y]=malloc(I2SDMABUFLEN*4); //Clear sample buffer. We don't want noise. for (x=0; x<I2SDMABUFLEN; x++) { i2sBuf[y][x]=0; } } //Reset DMA SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST); CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST); //Clear DMA int flags SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); //Enable and configure DMA CLEAR_PERI_REG_MASK(SLC_CONF0, (SLC_MODE<<SLC_MODE_S)); SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S)); SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE); CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE); //Initialize DMA buffer descriptors in such a way that they will form a circular //buffer. for (x=0; x<I2SDMABUFCNT; x++) { i2sBufDesc[x].owner=1; i2sBufDesc[x].eof=1; i2sBufDesc[x].sub_sof=0; i2sBufDesc[x].datalen=I2SDMABUFLEN*4; i2sBufDesc[x].blocksize=I2SDMABUFLEN*4; i2sBufDesc[x].buf_ptr=(uint32_t)&i2sBuf[x][0]; i2sBufDesc[x].unused=0; i2sBufDesc[x].next_link_ptr=(int)((x<(I2SDMABUFCNT-1))?(&i2sBufDesc[x+1]):(&i2sBufDesc[0])); } //Feed dma the 1st buffer desc addr //To send data to the I2S subsystem, counter-intuitively we use the RXLINK part, not the TXLINK as you might //expect. The TXLINK part still needs a valid DMA descriptor, even if it's unused: the DMA engine will throw //an error at us otherwise. Just feed it any random descriptor. CLEAR_PERI_REG_MASK(SLC_TX_LINK,SLC_TXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_TX_LINK, ((uint32)&i2sBufDesc[1]) & SLC_TXLINK_DESCADDR_MASK); //any random desc is OK, we don't use TX but it needs something valid CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDesc[0]) & SLC_RXLINK_DESCADDR_MASK); //Attach the DMA interrupt _xt_isr_attach(ETS_SLC_INUM, (_xt_isr)slc_isr, NULL); //Enable DMA operation intr WRITE_PERI_REG(SLC_INT_ENA, SLC_RX_EOF_INT_ENA); //clear any interrupt flags that are set WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff); ///enable DMA intr in cpu _xt_isr_unmask(1<<ETS_SLC_INUM); //We use a queue to keep track of the DMA buffers that are empty. The ISR will push buffers to the back of the queue, //the mp3 decode will pull them from the front and fill them. For ease, the queue will contain *pointers* to the DMA //buffers, not the data itself. The queue depth is one smaller than the amount of buffers we have, because there's //always a buffer that is being used by the DMA subsystem *right now* and we don't want to be able to write to that //simultaneously. dmaQueue=xQueueCreate(I2SDMABUFCNT-1, sizeof(int*)); //Start transmission SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START); SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START); //---- //Init pins to i2s functions PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_I2SO_WS); #ifndef USE_ESP01_MODULE PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_I2SO_BCK); #else GPIO_AS_INPUT(1<<15); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); #endif //Enable clock to i2s subsystem i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1); //Reset I2S subsystem CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); //Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only) CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S)); //Enable DMA in i2s subsystem SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN); //tx/rx binaureal CLEAR_PERI_REG_MASK(I2SCONF_CHAN, (I2S_TX_CHAN_MOD<<I2S_TX_CHAN_MOD_S)|(I2S_RX_CHAN_MOD<<I2S_RX_CHAN_MOD_S)); //Clear int SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); //trans master&rece slave,MSB shift,right_first,msb right CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD| (I2S_BITS_MOD<<I2S_BITS_MOD_S)| (I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)| (I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S)); SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD| I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT| ((16&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)| ((7&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S)); //No idea if ints are needed... //clear int SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); //enable int SET_PERI_REG_MASK(I2SINT_ENA, I2S_I2S_TX_REMPTY_INT_ENA|I2S_I2S_TX_WFULL_INT_ENA| I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_TX_PUT_DATA_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA); //Start transmission SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START); }
/** * @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; } }