コード例 #1
0
/**
 * intel_mid_i2s_close - release and stop the SSP
 * @drv_data : handle of corresponding ssp i2s (given by i2s_open function)
 *
 * WARNING: This is not -yet- allowed to call close from a read/write callback !
 *
 * Output parameters
 *      none
 */
void intel_mid_i2s_close(struct intel_mid_i2s_hdl *drv_data)
{
	void __iomem *reg;
	struct intel_mid_i2s_settings *ssp_settings =
						&(drv_data->current_settings);
	int s;
	struct dma_chan *channel;

	WARN(!drv_data, "Driver data=NULL\n");
	if (!drv_data)
		return;
	mutex_lock(&drv_data->mutex);
	if (!test_bit(I2S_PORT_OPENED, &drv_data->flags)) {
		dev_err(&drv_data->pdev->dev, "not opened but closing?");
		mutex_unlock(&drv_data->mutex);
		return;
	}

	set_bit(I2S_PORT_CLOSING, &drv_data->flags);
	dev_info(&drv_data->pdev->dev, "Status bit pending write=%d read=%d\n",
			test_bit(I2S_PORT_WRITE_BUSY, &drv_data->flags),
			test_bit(I2S_PORT_READ_BUSY, &drv_data->flags));
	if (test_bit(I2S_PORT_WRITE_BUSY, &drv_data->flags) ||
	     test_bit(I2S_PORT_READ_BUSY, &drv_data->flags)) {
		dev_info(&drv_data->pdev->dev, "Pending callback in close...\n");
	}

	if (ssp_settings->ssp_active_tx_slots_map) {
		channel = drv_data->txchan;
		s = channel->device->device_control(channel,
							DMA_TERMINATE_ALL, 0);
		dev_info(&drv_data->pdev->dev, "DMA_TERMINATE tx=%d\n", s);
	}
	if (ssp_settings->ssp_active_rx_slots_map) {
		channel = drv_data->rxchan;
		s = channel->device->device_control(channel,
							DMA_TERMINATE_ALL, 0);
		dev_info(&drv_data->pdev->dev, "DMA_TERMINATE rx=%d\n", s);
	}

	/* release DMA Channel.. */
	i2s_dma_stop(drv_data);
	reg = drv_data->ioaddr;
	dev_dbg(&drv_data->pdev->dev, "Stopping the SSP\n");
	i2s_ssp_stop(drv_data);
	put_device(&drv_data->pdev->dev);
	write_SSCR0(0, reg);

	dev_dbg(&(drv_data->pdev->dev), "SSP Stopped.\n");
	clear_bit(I2S_PORT_CLOSING, &drv_data->flags);
	clear_bit(I2S_PORT_OPENED, &drv_data->flags);

	/* pm runtime */
	pm_runtime_put(&drv_data->pdev->dev);

	mutex_unlock(&drv_data->mutex);
}
コード例 #2
0
void play_task(void *pvParameters)
{
    esp_spiffs_init();
    if (esp_spiffs_mount() != SPIFFS_OK) {
        printf("Error mount SPIFFS\n");
    }

    int fd = open("sample.wav", O_RDONLY);

    if (fd < 0) {
        printf("Error opening file\n");
        return;
    }

    dumb_wav_header_t wav_header;
    read(fd, (void*)&wav_header, sizeof(wav_header));
    printf("Number of channels: %d\n", wav_header.num_channels);
    printf("Bits per sample: %d\n", wav_header.bits_per_sample);
    printf("Sample rate: %d\n", wav_header.sample_rate);
    printf("Data size: %d\n", wav_header.data_size);

    if (wav_header.bits_per_sample != 16) {
        printf("Only 16 bit per sample is supported\n");
        return;
    }

    if (wav_header.num_channels != 2) {
        printf("Only 2 channels is supported\n");
        return;
    }

    i2s_clock_div_t clock_div = i2s_get_clock_div(
            wav_header.sample_rate * 2 * 16);

    printf("i2s clock dividers, bclk=%d, clkm=%d\n",
            clock_div.bclk_div, clock_div.clkm_div);

    i2s_pins_t i2s_pins = {.data = true, .clock = true, .ws = true};

    i2s_dma_init(dma_isr_handler, clock_div, i2s_pins);

    while (1) {
        init_descriptors_list();

        i2s_dma_start(dma_block_list);
        lseek(fd, sizeof(dumb_wav_header_t), SEEK_SET);

        while (play_data(fd)) {};
        i2s_dma_stop();

        vQueueDelete(dma_queue);

        printf("underrun counter: %d\n", underrun_counter);

        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

    close(fd);
}

void user_init(void)
{
    uart_set_baud(0, 115200);

    xTaskCreate(play_task, "test_task", 1024, NULL, 2, NULL);
}