bool spicommon_dma_chan_claim (int dma_chan) { bool ret = false; assert( dma_chan == 1 || dma_chan == 2 ); portENTER_CRITICAL(&spi_dma_spinlock); if ( !(spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan)) ) { // get the channel only when it's not claimed yet. spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan); ret = true; } periph_module_enable( PERIPH_SPI_DMA_MODULE ); portEXIT_CRITICAL(&spi_dma_spinlock); return ret; }
esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data) { assert((s_phy_rf_init_count <= 1) && (s_phy_rf_init_count >= 0)); _lock_acquire(&s_phy_rf_init_lock); if (s_phy_rf_init_count == 0) { // Enable WiFi/BT common peripheral clock periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d", init_data, calibration_data, mode); phy_set_wifi_mode_only(0); register_chipv7_phy(init_data, calibration_data, mode); coex_bt_high_prio(); } else { #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif } s_phy_rf_init_count++; _lock_release(&s_phy_rf_init_lock); return ESP_OK; }
/** * @brief EXPERIMENTAL */ void I2S::cameraMode(dma_config_t config, int desc_count, int sample_count) { ESP_LOGD(LOG_TAG, ">> cameraMode"); ESP32CPP::GPIO::setInput(config.pin_d0); ESP32CPP::GPIO::setInput(config.pin_d1); ESP32CPP::GPIO::setInput(config.pin_d2); ESP32CPP::GPIO::setInput(config.pin_d3); ESP32CPP::GPIO::setInput(config.pin_d4); ESP32CPP::GPIO::setInput(config.pin_d5); ESP32CPP::GPIO::setInput(config.pin_d6); ESP32CPP::GPIO::setInput(config.pin_d7); //ESP32CPP::GPIO::setInput(config.pin_xclk); ESP32CPP::GPIO::setInput(config.pin_vsync); ESP32CPP::GPIO::setInput(config.pin_href); ESP32CPP::GPIO::setInput(config.pin_pclk); //ESP32CPP::GPIO::setOutput(config.pin_reset); const uint32_t const_high = 0x38; gpio_matrix_in(config.pin_d0, I2S0I_DATA_IN0_IDX, false); gpio_matrix_in(config.pin_d1, I2S0I_DATA_IN1_IDX, false); gpio_matrix_in(config.pin_d2, I2S0I_DATA_IN2_IDX, false); gpio_matrix_in(config.pin_d3, I2S0I_DATA_IN3_IDX, false); gpio_matrix_in(config.pin_d4, I2S0I_DATA_IN4_IDX, false); gpio_matrix_in(config.pin_d5, I2S0I_DATA_IN5_IDX, false); gpio_matrix_in(config.pin_d6, I2S0I_DATA_IN6_IDX, false); gpio_matrix_in(config.pin_d7, I2S0I_DATA_IN7_IDX, false); gpio_matrix_in(config.pin_vsync, I2S0I_V_SYNC_IDX, true); gpio_matrix_in(config.pin_href, I2S0I_H_SYNC_IDX, false); // gpio_matrix_in(const_high, I2S0I_V_SYNC_IDX, false); // gpio_matrix_in(const_high, I2S0I_H_SYNC_IDX, false); gpio_matrix_in(const_high, I2S0I_H_ENABLE_IDX, false); gpio_matrix_in(config.pin_pclk, I2S0I_WS_IN_IDX, false); // Enable and configure I2S peripheral periph_module_enable(PERIPH_I2S0_MODULE); // Toggle some reset bits in LC_CONF register // Toggle some reset bits in CONF register // Enable slave mode (sampling clock is external) i2s_conf_reset(); // Switch on Slave mode. // I2S_CONF_REG -> I2S_RX_SLAVE_MOD // Set to 1 to enable slave mode. I2S0.conf.rx_slave_mod = 1; // Enable parallel mode // I2S_CONF2_REG -> I2S_LCD_END // Set to 1 to enable LCD mode. I2S0.conf2.lcd_en = 1; // Use HSYNC/VSYNC/HREF to control sampling // I2S_CONF2_REG -> I2S_CAMERA_EN // Set to 1 to enable camera mode. I2S0.conf2.camera_en = 1; // Configure clock divider I2S0.clkm_conf.clkm_div_a = 1; I2S0.clkm_conf.clkm_div_b = 0; I2S0.clkm_conf.clkm_div_num = 2; // I2S_FIFO_CONF_REG -> I2S_DSCR_EN // FIFO will sink data to DMA I2S0.fifo_conf.dscr_en = 1; // FIFO configuration // I2S_FIFO_CONF_REG -> RX_FIFO_MOD I2S0.fifo_conf.rx_fifo_mod = 1; // 0-3??? // I2S_FIFO_CONF_REG -> RX_FIFO_MOD_FORCE_EN I2S0.fifo_conf.rx_fifo_mod_force_en = 1; // I2S_CONF_CHAN_REG -> I2S_RX_CHAN_MOD I2S0.conf_chan.rx_chan_mod = 1; // Clear flags which are used in I2S serial mode // I2S_SAMPLE_RATE_CONF_REG -> I2S_RX_BITS_MOD I2S0.sample_rate_conf.rx_bits_mod = 0; // I2S_CONF_REG -> I2S_RX_RIGHT_FIRST I2S0.conf.rx_right_first = 0; //I2S0.conf.rx_right_first = 0; // I2S_CONF_REG -> I2S_RX_MSB_RIGHT I2S0.conf.rx_msb_right = 0; //I2S0.conf.rx_msb_right = 1; // I2S_CONF_REG -> I2S_RX_MSB_SHIFT I2S0.conf.rx_msb_shift = 0; //I2S0.conf.rx_msb_shift = 1; // I2S_CONF_REG -> I2S_RX_MSB_MONO I2S0.conf.rx_mono = 0; // I2S_CONF_REG -> I2S_RX_SHORT_SYNC I2S0.conf.rx_short_sync = 0; I2S0.timing.val = 0; ESP_LOGD(LOG_TAG, "Initializing %d descriptors", desc_count); DMABuffer* pFirst = new DMABuffer(); // TODO: POTENTIAL LEAK DMABuffer* pLast = pFirst; for (int i = 1; i < desc_count; i++) { DMABuffer* pNewDMABuffer = new DMABuffer(); // TODO: POTENTIAL LEAK pLast->setNext(pNewDMABuffer); pLast = pNewDMABuffer; } pLast->setNext(pFirst); pCurrentDMABuffer = pFirst; // I2S_RX_EOF_NUM_REG I2S0.rx_eof_num = sample_count; // I2S_IN_LINK_REG -> I2S_INLINK_ADDR I2S0.in_link.addr = (uint32_t) pFirst; // I2S_IN_LINK_REG -> I2S_INLINK_START I2S0.in_link.start = 1; I2S0.int_clr.val = I2S0.int_raw.val; I2S0.int_ena.val = 0; I2S0.int_ena.in_done = 1; // Register the interrupt handler. esp_intr_alloc( ETS_I2S0_INTR_SOURCE, ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_IRAM, &i2s_isr, this, &i2s_intr_handle); m_dmaSemaphore.take(); // Start the interrupt handler esp_intr_enable(i2s_intr_handle); I2S0.conf.rx_start = 1; /* while(1) { m_dmaSemaphore.wait(); uint32_t dataLength = pLastDMABuffer->getLength(); ESP_LOGD(LOG_TAG, "Got a DMA buffer; length=%d", dataLength); //pLastDMABuffer->dump(); uint8_t *pData = new uint8_t[dataLength]; pLastDMABuffer->getData(pData, dataLength); GeneralUtils::hexDump(pData, dataLength); delete[] pData; m_dmaSemaphore.take(); } */ ESP_LOGD(LOG_TAG, "<< cameraMode"); }
//Returns true if this peripheral is successfully claimed, false if otherwise. bool spicommon_periph_claim(spi_host_device_t host) { bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true); if (ret) periph_module_enable(io_signal[host].module); return ret; }
esp_err_t rmt_config(const rmt_config_t* rmt_param) { uint8_t mode = rmt_param->rmt_mode; uint8_t channel = rmt_param->channel; uint8_t gpio_num = rmt_param->gpio_num; uint8_t mem_cnt = rmt_param->mem_block_num; int clk_div = rmt_param->clk_div; uint32_t carrier_freq_hz = rmt_param->tx_config.carrier_freq_hz; bool carrier_en = rmt_param->tx_config.carrier_en; RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG); RMT_CHECK(GPIO_IS_VALID_GPIO(gpio_num), RMT_GPIO_ERROR_STR, ESP_ERR_INVALID_ARG); RMT_CHECK((mem_cnt + channel <= 8 && mem_cnt > 0), RMT_MEM_CNT_ERROR_STR, ESP_ERR_INVALID_ARG); RMT_CHECK((clk_div > 0), RMT_CLK_DIV_ERROR_STR, ESP_ERR_INVALID_ARG); if (mode == RMT_MODE_TX) { RMT_CHECK((!carrier_en || carrier_freq_hz > 0), "RMT carrier frequency can't be zero", ESP_ERR_INVALID_ARG); } periph_module_enable(PERIPH_RMT_MODULE); RMT.conf_ch[channel].conf0.div_cnt = clk_div; /*Visit data use memory not FIFO*/ rmt_set_data_mode(RMT_DATA_MODE_MEM); /*Reset tx/rx memory index */ portENTER_CRITICAL(&rmt_spinlock); RMT.conf_ch[channel].conf1.mem_rd_rst = 1; RMT.conf_ch[channel].conf1.mem_wr_rst = 1; portEXIT_CRITICAL(&rmt_spinlock); if(mode == RMT_MODE_TX) { uint32_t rmt_source_clk_hz = 0; uint16_t carrier_duty_percent = rmt_param->tx_config.carrier_duty_percent; uint8_t carrier_level = rmt_param->tx_config.carrier_level; uint8_t idle_level = rmt_param->tx_config.idle_level; portENTER_CRITICAL(&rmt_spinlock); RMT.conf_ch[channel].conf1.tx_conti_mode = rmt_param->tx_config.loop_en; /*Memory set block number*/ RMT.conf_ch[channel].conf0.mem_size = mem_cnt; RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX; /*We use APB clock in this version, which is 80Mhz, later we will release system reference clock*/ RMT.conf_ch[channel].conf1.ref_always_on = RMT_BASECLK_APB; rmt_source_clk_hz = RMT_SOURCE_CLK(RMT_BASECLK_APB); /*Set idle level */ RMT.conf_ch[channel].conf1.idle_out_en = rmt_param->tx_config.idle_output_en; RMT.conf_ch[channel].conf1.idle_out_lv = idle_level; portEXIT_CRITICAL(&rmt_spinlock); /*Set carrier*/ RMT.conf_ch[channel].conf0.carrier_en = carrier_en; if (carrier_en) { uint32_t duty_div, duty_h, duty_l; duty_div = rmt_source_clk_hz / carrier_freq_hz; duty_h = duty_div * carrier_duty_percent / 100; duty_l = duty_div - duty_h; RMT.conf_ch[channel].conf0.carrier_out_lv = carrier_level; RMT.carrier_duty_ch[channel].high = duty_h; RMT.carrier_duty_ch[channel].low = duty_l; } else { RMT.conf_ch[channel].conf0.carrier_out_lv = 0; RMT.carrier_duty_ch[channel].high = 0; RMT.carrier_duty_ch[channel].low = 0; } ESP_LOGD(RMT_TAG, "Rmt Tx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Carrier_Hz %u|Duty %u", channel, gpio_num, rmt_source_clk_hz, clk_div, carrier_freq_hz, carrier_duty_percent); } else if(RMT_MODE_RX == mode) { uint8_t filter_cnt = rmt_param->rx_config.filter_ticks_thresh; uint16_t threshold = rmt_param->rx_config.idle_threshold; portENTER_CRITICAL(&rmt_spinlock); /*clock init*/ RMT.conf_ch[channel].conf1.ref_always_on = RMT_BASECLK_APB; uint32_t rmt_source_clk_hz = RMT_SOURCE_CLK(RMT_BASECLK_APB); /*memory set block number and owner*/ RMT.conf_ch[channel].conf0.mem_size = mem_cnt; RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX; /*Set idle threshold*/ RMT.conf_ch[channel].conf0.idle_thres = threshold; /* Set RX filter */ RMT.conf_ch[channel].conf1.rx_filter_thres = filter_cnt; RMT.conf_ch[channel].conf1.rx_filter_en = rmt_param->rx_config.filter_en; portEXIT_CRITICAL(&rmt_spinlock); ESP_LOGD(RMT_TAG, "Rmt Rx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Thresold %u|Filter %u", channel, gpio_num, rmt_source_clk_hz, clk_div, threshold, filter_cnt); } rmt_set_pin(channel, mode, gpio_num); return ESP_OK; }