init
This commit is contained in:
0
lib_audio_dsp/test/unit_tests/src/empty.c
Normal file
0
lib_audio_dsp/test/unit_tests/src/empty.c
Normal file
153
lib_audio_dsp/test/unit_tests/src/test_adsp_control.c
Normal file
153
lib_audio_dsp/test/unit_tests/src/test_adsp_control.c
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright 2024-2025 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/// Unit tests for adsp_control.c
|
||||
|
||||
#include <unity.h>
|
||||
|
||||
#include <stages/adsp_control.h>
|
||||
#include <stages/dummy.h>
|
||||
#include <adsp_generated_dummy.h>
|
||||
#include <adsp_instance_id_dummy.h>
|
||||
#include <cmds.h>
|
||||
#include <stdio.h>
|
||||
#include <swlock.h>
|
||||
|
||||
void setUp(){}
|
||||
void tearDown(){}
|
||||
|
||||
/// Test that basic read and write works.
|
||||
void test_basic_control(void) {
|
||||
|
||||
adsp_pipeline_t* p = adsp_dummy_pipeline_init();
|
||||
module_instance_t* dummy_inst = &p->modules[dummy_stage_index];
|
||||
adsp_controller_t ctrl;
|
||||
adsp_controller_init(&ctrl, p);
|
||||
|
||||
int test_val = 5;
|
||||
adsp_stage_control_cmd_t cmd = {
|
||||
.instance_id = dummy_stage_index,
|
||||
.cmd_id = CMD_DUMMY_DUMMY_FIELD,
|
||||
.payload_len = sizeof(int),
|
||||
.payload = &test_val
|
||||
};
|
||||
|
||||
// First write succeeds as stage isn't busy
|
||||
adsp_control_status_t status = adsp_write_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_SUCCESS, status);
|
||||
|
||||
// Now the stage is busy
|
||||
status = adsp_write_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
// Now the stage is busy
|
||||
status = adsp_read_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
// Stage processes control
|
||||
dummy_control(dummy_inst->state, &dummy_inst->control);
|
||||
|
||||
*(int*)cmd.payload = 0; // clear the payload, ready for read.
|
||||
|
||||
// request a read, stage must process it so it is busy
|
||||
status = adsp_read_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
// The stage is busy
|
||||
status = adsp_write_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
// Stage processes control
|
||||
dummy_control(dummy_inst->state, &dummy_inst->control);
|
||||
|
||||
|
||||
// re-request the read, stage must process it so it is busy
|
||||
status = adsp_read_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(test_val, *(int*)cmd.payload);
|
||||
}
|
||||
|
||||
/// Test that when there are two controllers, only the controller who made
|
||||
/// the request will get a response.
|
||||
void test_adsp_control_2_controllers(void) {
|
||||
adsp_pipeline_t* p = adsp_dummy_pipeline_init();
|
||||
module_instance_t* dummy_inst = &p->modules[dummy_stage_index];
|
||||
adsp_controller_t ctrl_a;
|
||||
adsp_controller_init(&ctrl_a, p);
|
||||
adsp_controller_t ctrl_b;
|
||||
adsp_controller_init(&ctrl_b, p);
|
||||
|
||||
int test_val = 5;
|
||||
adsp_stage_control_cmd_t cmd = {
|
||||
.instance_id = dummy_stage_index,
|
||||
.cmd_id = CMD_DUMMY_DUMMY_FIELD,
|
||||
.payload_len = sizeof(int),
|
||||
.payload = &test_val
|
||||
};
|
||||
|
||||
// First write succeeds as stage isn't busy
|
||||
adsp_control_status_t status = adsp_write_module_config(&ctrl_a, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_SUCCESS, status);
|
||||
// stage is now busy for both controllers.
|
||||
status = adsp_write_module_config(&ctrl_a, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
status = adsp_write_module_config(&ctrl_b, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
// Stage processes control
|
||||
dummy_control(dummy_inst->state, &dummy_inst->control);
|
||||
|
||||
*(int*)cmd.payload = 0; // clear the payload, ready for read.
|
||||
|
||||
// request a read, stage must process it so it is busy
|
||||
status = adsp_read_module_config(&ctrl_a, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
// Stage processes control
|
||||
dummy_control(dummy_inst->state, &dummy_inst->control);
|
||||
|
||||
|
||||
// Even though a read was processed, b still gets busy
|
||||
// because it didn't ask for it.
|
||||
status = adsp_read_module_config(&ctrl_b, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
// but a gets the result.
|
||||
status = adsp_read_module_config(&ctrl_a, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(test_val, *(int*)cmd.payload);
|
||||
}
|
||||
|
||||
|
||||
/// Ensure that busy is returned when the lock is taken for both read
|
||||
/// and write.
|
||||
void test_lock_contention(void) {
|
||||
|
||||
adsp_pipeline_t* p = adsp_dummy_pipeline_init();
|
||||
module_instance_t* dummy_inst = &p->modules[dummy_stage_index];
|
||||
adsp_controller_t ctrl;
|
||||
adsp_controller_init(&ctrl, p);
|
||||
|
||||
int test_val = 5;
|
||||
adsp_stage_control_cmd_t cmd = {
|
||||
.instance_id = dummy_stage_index,
|
||||
.cmd_id = CMD_DUMMY_DUMMY_FIELD,
|
||||
.payload_len = sizeof(int),
|
||||
.payload = &test_val
|
||||
};
|
||||
|
||||
// take the lock to emulate contention.
|
||||
swlock_acquire(&dummy_inst->control.lock);
|
||||
|
||||
// Get busy even though the stage isn't doing anything because the lock
|
||||
// is taken.
|
||||
adsp_control_status_t status = adsp_write_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_BUSY, status);
|
||||
|
||||
swlock_release(&dummy_inst->control.lock);
|
||||
|
||||
status = adsp_write_module_config(&ctrl, &cmd);
|
||||
TEST_ASSERT_EQUAL(ADSP_CONTROL_SUCCESS, status);
|
||||
|
||||
// Stage processes control
|
||||
dummy_control(dummy_inst->state, &dummy_inst->control);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user