forked from espressif/esp-idf
Merge branch 'bugfix/add_unity_sig_sync_for_i2s_tdm_test' into 'master'
i2s_test: fixed rx_update stuck issue Closes IDFCI-1527 See merge request espressif/esp-idf!21308
This commit is contained in:
@@ -747,15 +747,15 @@ static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_std_clk_c
|
|||||||
esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0);
|
esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0);
|
||||||
|
|
||||||
// Test common sample rate
|
// Test common sample rate
|
||||||
uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000,
|
uint32_t test_freq[16] = {8000, 10000, 11025, 12000, 16000, 22050, 24000,
|
||||||
32000, 44100, 48000, 64000, 88200, 96000,
|
32000, 44100, 48000, 64000, 88200, 96000,
|
||||||
128000, 144000, 196000};
|
128000, 144000, 196000};
|
||||||
int real_pulse = 0;
|
int real_pulse = 0;
|
||||||
int case_cnt = 15;
|
int case_cnt = 16;
|
||||||
#if SOC_I2S_HW_VERSION_2
|
#if SOC_I2S_HW_VERSION_2
|
||||||
// Can't support a very high sample rate while using XTAL as clock source
|
// Can't support a very high sample rate while using XTAL as clock source
|
||||||
if (clk_cfg->clk_src == I2S_CLK_SRC_XTAL) {
|
if (clk_cfg->clk_src == I2S_CLK_SRC_XTAL) {
|
||||||
case_cnt = 9;
|
case_cnt = 10;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < case_cnt; i++) {
|
for (int i = 0; i < case_cnt; i++) {
|
||||||
|
@@ -2,5 +2,9 @@
|
|||||||
# in this exact order for cmake to work correctly
|
# in this exact order for cmake to work correctly
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS
|
||||||
|
"$ENV{IDF_PATH}/tools/unit-test-app/components"
|
||||||
|
)
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(i2s_tdm_full_duplex_test)
|
project(i2s_tdm_full_duplex_test)
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#define TEST_MEMORY_LEAK_THRESHOLD (-300)
|
#define TEST_MEMORY_LEAK_THRESHOLD (-400)
|
||||||
|
|
||||||
static size_t before_free_8bit;
|
static size_t before_free_8bit;
|
||||||
static size_t before_free_32bit;
|
static size_t before_free_32bit;
|
||||||
|
@@ -11,14 +11,16 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "unity_test_utils.h"
|
#include "unity_test_utils.h"
|
||||||
|
#include "test_utils.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/i2s_tdm.h"
|
#include "driver/i2s_tdm.h"
|
||||||
|
|
||||||
static const char *TAG = "i2s_tdm_full_duplex_test";
|
static const char *TAG = "i2s_tdm_full_duplex_test";
|
||||||
|
|
||||||
#define TEST_I2S_FRAME_SIZE (128)
|
#define TEST_I2S_FRAME_SIZE (128) // Frame numbers in every writing / reading
|
||||||
#define TEST_I2S_PACKET_COUNT (512)
|
#define TEST_I2S_ARRAY_LENGTH (1024) // The loop data length for verification
|
||||||
#define TEST_I2S_BAD_PACKET_THRESHOLD (10)
|
#define TEST_I2S_MAX_FAIL_CNT (3) // Max broken packet count
|
||||||
|
#define TEST_I2S_FRAME_TIMEOUT_SEC (10.0f) // Timeout seconds of waiting for a correct frame
|
||||||
|
|
||||||
#define TEST_I2S_NUM (I2S_NUM_0) // ESP32-C3 has only I2S0
|
#define TEST_I2S_NUM (I2S_NUM_0) // ESP32-C3 has only I2S0
|
||||||
#define TEST_I2S_BCK_IO (GPIO_NUM_4)
|
#define TEST_I2S_BCK_IO (GPIO_NUM_4)
|
||||||
@@ -52,20 +54,22 @@ static void test_i2s_tdm_master_write_task(void *args)
|
|||||||
|
|
||||||
uint32_t data_cnt = 0;
|
uint32_t data_cnt = 0;
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
|
|
||||||
|
/* Block here waiting for the main thread receiving Slave Ready signals */
|
||||||
|
xTaskNotifyWait(0, ULONG_MAX, NULL, portMAX_DELAY);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "I2S TDM master send start");
|
ESP_LOGI(TAG, "I2S TDM master send start");
|
||||||
TEST_ESP_OK(i2s_channel_enable(task_args->tx_channel_handle));
|
|
||||||
while (xTaskNotifyWait(0, ULONG_MAX, NULL, 0) == pdFALSE) { // if main task sends terminate signal, exit the loop
|
while (xTaskNotifyWait(0, ULONG_MAX, NULL, 0) == pdFALSE) { // if main task sends terminate signal, exit the loop
|
||||||
/* Fill in the tx buffer */
|
/* Fill in the tx buffer */
|
||||||
for (uint32_t i = 0; i < tx_buffer_size / sizeof(uint32_t); i ++) {
|
for (uint32_t i = 0; i < tx_buffer_size / sizeof(uint32_t); i ++) {
|
||||||
tx_buffer[i] = data_cnt;
|
tx_buffer[i] = data_cnt;
|
||||||
data_cnt ++;
|
data_cnt++;
|
||||||
|
data_cnt %= TEST_I2S_ARRAY_LENGTH;
|
||||||
}
|
}
|
||||||
TEST_ESP_OK(i2s_channel_write(task_args->tx_channel_handle, tx_buffer, tx_buffer_size,
|
TEST_ESP_OK(i2s_channel_write(task_args->tx_channel_handle, tx_buffer, tx_buffer_size,
|
||||||
&bytes_written, portMAX_DELAY));
|
&bytes_written, 1000));
|
||||||
TEST_ASSERT_EQUAL(tx_buffer_size, bytes_written);
|
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "I2S TDM master send stop");
|
|
||||||
TEST_ESP_OK(i2s_channel_disable(task_args->tx_channel_handle));
|
|
||||||
ESP_LOGI(TAG, "Freeing I2S TDM master tx buffer");
|
ESP_LOGI(TAG, "Freeing I2S TDM master tx buffer");
|
||||||
free(tx_buffer);
|
free(tx_buffer);
|
||||||
|
|
||||||
@@ -106,12 +110,12 @@ static void test_i2s_tdm_master(uint32_t sample_rate, i2s_data_bit_width_t bit_w
|
|||||||
|
|
||||||
/* Create TDM write task */
|
/* Create TDM write task */
|
||||||
TaskHandle_t subtask_handle = NULL;
|
TaskHandle_t subtask_handle = NULL;
|
||||||
test_i2s_tdm_write_task_args_t task_args = {
|
/* Make the variable static in case it become invalid in the write task */
|
||||||
.tx_channel_handle = i2s_tdm_tx_handle,
|
static test_i2s_tdm_write_task_args_t task_args;
|
||||||
.maintask_handle = xTaskGetCurrentTaskHandle(),
|
task_args.tx_channel_handle = i2s_tdm_tx_handle;
|
||||||
.tx_data_bit_width = bit_width,
|
task_args.maintask_handle = xTaskGetCurrentTaskHandle();
|
||||||
.tdm_slot_mask = slot_mask
|
task_args.tx_data_bit_width = bit_width;
|
||||||
};
|
task_args.tdm_slot_mask = slot_mask;
|
||||||
xTaskCreate(test_i2s_tdm_master_write_task, "I2S TDM Write Task", 4096, &task_args, 5, &subtask_handle);
|
xTaskCreate(test_i2s_tdm_master_write_task, "I2S TDM Write Task", 4096, &task_args, 5, &subtask_handle);
|
||||||
|
|
||||||
/* Allocate I2S rx buffer */
|
/* Allocate I2S rx buffer */
|
||||||
@@ -121,42 +125,44 @@ static void test_i2s_tdm_master(uint32_t sample_rate, i2s_data_bit_width_t bit_w
|
|||||||
uint32_t *rx_buffer = malloc(rx_buffer_size);
|
uint32_t *rx_buffer = malloc(rx_buffer_size);
|
||||||
TEST_ASSERT(rx_buffer);
|
TEST_ASSERT(rx_buffer);
|
||||||
|
|
||||||
uint8_t is_packet_valid = 0;
|
uint32_t count = 1;
|
||||||
uint32_t good_packet_cnt = 0;
|
bool is_start = false;
|
||||||
|
uint8_t fail_cnt = 0;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
ESP_LOGI(TAG, "I2S TDM master receive start");
|
float time = 0;
|
||||||
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_rx_handle));
|
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_rx_handle));
|
||||||
for(uint32_t packet_cnt = 0; packet_cnt < TEST_I2S_PACKET_COUNT; packet_cnt ++) {
|
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_tx_handle));
|
||||||
TEST_ESP_OK(i2s_channel_read(i2s_tdm_rx_handle, rx_buffer, rx_buffer_size,
|
unity_send_signal("Master Ready");
|
||||||
&bytes_read, portMAX_DELAY));
|
unity_wait_for_signal("Slave Ready");
|
||||||
TEST_ASSERT_EQUAL(rx_buffer_size, bytes_read);
|
|
||||||
|
|
||||||
/* Check for empty packet */
|
/* Slave is ready, start the writing task */
|
||||||
if (rx_buffer[0] == 0) { // empty packet
|
ESP_LOGI(TAG, "I2S TDM master receive & send start");
|
||||||
if (is_packet_valid == 0) { // omit leading empty packets
|
esp_err_t read_ret = ESP_OK;
|
||||||
packet_cnt = 0;
|
xTaskNotifyGive(subtask_handle);
|
||||||
} else {
|
while (count < TEST_I2S_ARRAY_LENGTH && fail_cnt < TEST_I2S_MAX_FAIL_CNT && time < TEST_I2S_FRAME_TIMEOUT_SEC) {
|
||||||
ESP_LOGW(TAG, "empty packet %"PRIu32, packet_cnt);
|
read_ret = i2s_channel_read(i2s_tdm_rx_handle, rx_buffer, rx_buffer_size, &bytes_read, 1000);
|
||||||
}
|
if (read_ret != ESP_OK) {
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
is_packet_valid = 1;
|
for (int i = 0; i < rx_buffer_size / sizeof(uint32_t); i++) {
|
||||||
/* Check received packet */
|
if (rx_buffer[i] == count) {
|
||||||
uint8_t is_good_packet = 1;
|
count++;
|
||||||
uint32_t last_value = rx_buffer[0];
|
if (count >= TEST_I2S_ARRAY_LENGTH) {
|
||||||
for (uint32_t j = 1; j < rx_buffer_size / sizeof(uint32_t); j ++) {
|
break;
|
||||||
if (rx_buffer[j] == last_value + 1) { // increased by 1
|
}
|
||||||
last_value = rx_buffer[j];
|
if (!is_start) {
|
||||||
} else {
|
is_start = true;
|
||||||
is_good_packet = 0;
|
}
|
||||||
ESP_LOGW(TAG, "corrupted packet %"PRIu32, packet_cnt);
|
} else if (is_start) {
|
||||||
break; // corrupted packet
|
ESP_LOGE(TAG, "Failed at index: %d real: %"PRIu32" expect: %"PRIu32"\n", i, rx_buffer[i], count);
|
||||||
|
is_start = false;
|
||||||
|
count = 1;
|
||||||
|
fail_cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_good_packet) {
|
time += (float)TEST_I2S_MAX_FAIL_CNT / (float)sample_rate;
|
||||||
good_packet_cnt ++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
unity_send_signal("Master Finished");
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Send signal to terminate subtask");
|
ESP_LOGI(TAG, "Send signal to terminate subtask");
|
||||||
xTaskNotifyGive(subtask_handle); // notify subtask to exit
|
xTaskNotifyGive(subtask_handle); // notify subtask to exit
|
||||||
@@ -164,6 +170,8 @@ static void test_i2s_tdm_master(uint32_t sample_rate, i2s_data_bit_width_t bit_w
|
|||||||
ESP_LOGI(TAG, "Deleting subtask");
|
ESP_LOGI(TAG, "Deleting subtask");
|
||||||
unity_utils_task_delete(subtask_handle); // delete subtask
|
unity_utils_task_delete(subtask_handle); // delete subtask
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "I2S TDM master send stop");
|
||||||
|
TEST_ESP_OK(i2s_channel_disable(i2s_tdm_tx_handle));
|
||||||
ESP_LOGI(TAG, "I2S TDM master receive stop");
|
ESP_LOGI(TAG, "I2S TDM master receive stop");
|
||||||
TEST_ESP_OK(i2s_channel_disable(i2s_tdm_rx_handle));
|
TEST_ESP_OK(i2s_channel_disable(i2s_tdm_rx_handle));
|
||||||
|
|
||||||
@@ -172,15 +180,9 @@ static void test_i2s_tdm_master(uint32_t sample_rate, i2s_data_bit_width_t bit_w
|
|||||||
ESP_LOGI(TAG, "Deleting i2s tx and rx channels");
|
ESP_LOGI(TAG, "Deleting i2s tx and rx channels");
|
||||||
TEST_ESP_OK(i2s_del_channel(i2s_tdm_rx_handle));
|
TEST_ESP_OK(i2s_del_channel(i2s_tdm_rx_handle));
|
||||||
TEST_ESP_OK(i2s_del_channel(i2s_tdm_tx_handle));
|
TEST_ESP_OK(i2s_del_channel(i2s_tdm_tx_handle));
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(read_ret == ESP_OK, "Master read timeout ");
|
||||||
uint32_t bad_packet_cnt = TEST_I2S_PACKET_COUNT - good_packet_cnt;
|
TEST_ASSERT_TRUE_MESSAGE(fail_cnt < TEST_I2S_MAX_FAIL_CNT, "Broken data received ");
|
||||||
ESP_LOGI(TAG, "Total Packet: %d Good Packet: %"PRIu32" Bad Packet %"PRIu32,
|
TEST_ASSERT_TRUE_MESSAGE(time < TEST_I2S_FRAME_TIMEOUT_SEC, "Waiting for valid data timeout ");
|
||||||
TEST_I2S_PACKET_COUNT, good_packet_cnt, bad_packet_cnt);
|
|
||||||
/* if the bad packet count exceed the threshold, test failed */
|
|
||||||
if (bad_packet_cnt > TEST_I2S_BAD_PACKET_THRESHOLD) {
|
|
||||||
ESP_LOGE(TAG, "Bad Packet count exceed the threshold %d, test failed", TEST_I2S_BAD_PACKET_THRESHOLD);
|
|
||||||
TEST_FAIL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_i2s_tdm_slave(uint32_t sample_rate, i2s_data_bit_width_t bit_width, i2s_tdm_slot_mask_t slot_mask)
|
static void test_i2s_tdm_slave(uint32_t sample_rate, i2s_data_bit_width_t bit_width, i2s_tdm_slot_mask_t slot_mask)
|
||||||
@@ -223,28 +225,23 @@ static void test_i2s_tdm_slave(uint32_t sample_rate, i2s_data_bit_width_t bit_wi
|
|||||||
uint32_t *rx_buffer = malloc(rx_buffer_size);
|
uint32_t *rx_buffer = malloc(rx_buffer_size);
|
||||||
TEST_ASSERT(rx_buffer);
|
TEST_ASSERT(rx_buffer);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "I2S TDM slave receive & send start");
|
|
||||||
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_rx_handle));
|
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_rx_handle));
|
||||||
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_tx_handle));
|
TEST_ESP_OK(i2s_channel_enable(i2s_tdm_tx_handle));
|
||||||
uint32_t packet_cnt = 0;
|
unity_send_signal("Slave Ready");
|
||||||
size_t bytes_read = 0, bytes_written = 0;
|
unity_wait_for_signal("Master Ready");
|
||||||
while (packet_cnt < TEST_I2S_PACKET_COUNT) {
|
|
||||||
TEST_ESP_OK(i2s_channel_read(i2s_tdm_rx_handle, rx_buffer, rx_buffer_size,
|
|
||||||
&bytes_read, portMAX_DELAY));
|
|
||||||
TEST_ASSERT_EQUAL(rx_buffer_size, bytes_read);
|
|
||||||
|
|
||||||
TEST_ESP_OK(i2s_channel_write(i2s_tdm_tx_handle, rx_buffer, rx_buffer_size,
|
ESP_LOGI(TAG, "I2S TDM slave receive & send start");
|
||||||
&bytes_written, portMAX_DELAY));
|
size_t bytes_read = 0, bytes_written = 0;
|
||||||
TEST_ASSERT_EQUAL(rx_buffer_size, bytes_written);
|
/* Loop until reading or writing failed, which indicates the master has finished and deleted the I2S peripheral */
|
||||||
if (rx_buffer[0]) { // packet is not empty
|
while (true) {
|
||||||
packet_cnt ++;
|
if (i2s_channel_read(i2s_tdm_rx_handle, rx_buffer, rx_buffer_size, &bytes_read, 500) != ESP_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i2s_channel_write(i2s_tdm_tx_handle, rx_buffer, rx_buffer_size, &bytes_written, 500) != ESP_OK) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unity_wait_for_signal("Master Finished");
|
||||||
/* Send empty buffers to flush DMA ringbuffer until timeout */
|
|
||||||
memset(rx_buffer, 0, rx_buffer_size);
|
|
||||||
while (i2s_channel_write(i2s_tdm_tx_handle, rx_buffer, rx_buffer_size,
|
|
||||||
&bytes_written, pdMS_TO_TICKS(200)) != ESP_ERR_TIMEOUT);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "I2S TDM slave receive stop");
|
ESP_LOGI(TAG, "I2S TDM slave receive stop");
|
||||||
TEST_ESP_OK(i2s_channel_disable(i2s_tdm_rx_handle));
|
TEST_ESP_OK(i2s_channel_disable(i2s_tdm_rx_handle));
|
||||||
|
@@ -11,4 +11,4 @@ import pytest
|
|||||||
2,
|
2,
|
||||||
], indirect=True)
|
], indirect=True)
|
||||||
def test_i2s_tdm_full_duplex(case_tester) -> None: # type: ignore
|
def test_i2s_tdm_full_duplex(case_tester) -> None: # type: ignore
|
||||||
case_tester.run_all_cases()
|
case_tester.run_all_cases(timeout=30)
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
CONFIG_FREERTOS_HZ=1000
|
CONFIG_FREERTOS_HZ=1000
|
||||||
CONFIG_ESP_TASK_WDT=n
|
CONFIG_ESP_TASK_WDT=n
|
||||||
|
CONFIG_I2S_ENABLE_DEBUG_LOG=y
|
||||||
|
@@ -419,8 +419,9 @@ finish:
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->tx_conf.tx_update = 0;
|
// Have to update registers before start
|
||||||
hw->tx_conf.tx_update = 1;
|
hw->tx_conf.tx_update = 1;
|
||||||
|
while (hw->tx_conf.tx_update);
|
||||||
hw->tx_conf.tx_start = 1;
|
hw->tx_conf.tx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +432,9 @@ static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->rx_conf.rx_update = 0;
|
// Have to update registers before start
|
||||||
hw->rx_conf.rx_update = 1;
|
hw->rx_conf.rx_update = 1;
|
||||||
|
while (hw->rx_conf.rx_update);
|
||||||
hw->rx_conf.rx_start = 1;
|
hw->rx_conf.rx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -434,8 +434,9 @@ finish:
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->tx_conf.tx_update = 0;
|
// Have to update registers before start
|
||||||
hw->tx_conf.tx_update = 1;
|
hw->tx_conf.tx_update = 1;
|
||||||
|
while (hw->tx_conf.tx_update);
|
||||||
hw->tx_conf.tx_start = 1;
|
hw->tx_conf.tx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,8 +447,9 @@ static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->rx_conf.rx_update = 0;
|
// Have to update registers before start
|
||||||
hw->rx_conf.rx_update = 1;
|
hw->rx_conf.rx_update = 1;
|
||||||
|
while (hw->rx_conf.rx_update);
|
||||||
hw->rx_conf.rx_start = 1;
|
hw->rx_conf.rx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -420,8 +420,9 @@ finish:
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->tx_conf.tx_update = 0;
|
// Have to update registers before start
|
||||||
hw->tx_conf.tx_update = 1;
|
hw->tx_conf.tx_update = 1;
|
||||||
|
while (hw->tx_conf.tx_update);
|
||||||
hw->tx_conf.tx_start = 1;
|
hw->tx_conf.tx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,8 +433,9 @@ static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->rx_conf.rx_update = 0;
|
// Have to update registers before start
|
||||||
hw->rx_conf.rx_update = 1;
|
hw->rx_conf.rx_update = 1;
|
||||||
|
while (hw->rx_conf.rx_update);
|
||||||
hw->rx_conf.rx_start = 1;
|
hw->rx_conf.rx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -419,8 +419,9 @@ finish:
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->tx_conf.tx_update = 0;
|
// Have to update registers before start
|
||||||
hw->tx_conf.tx_update = 1;
|
hw->tx_conf.tx_update = 1;
|
||||||
|
while (hw->tx_conf.tx_update);
|
||||||
hw->tx_conf.tx_start = 1;
|
hw->tx_conf.tx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +432,9 @@ static inline void i2s_ll_tx_start(i2s_dev_t *hw)
|
|||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
static inline void i2s_ll_rx_start(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
hw->rx_conf.rx_update = 0;
|
// Have to update registers before start
|
||||||
hw->rx_conf.rx_update = 1;
|
hw->rx_conf.rx_update = 1;
|
||||||
|
while (hw->rx_conf.rx_update);
|
||||||
hw->rx_conf.rx_start = 1;
|
hw->rx_conf.rx_start = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user