Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0270c43

Browse filesBrowse files
committed
components: drivers: audio: Add audio driver test framework
Achieve driver framework by operating memory to simulate audio peripheral drivers. And it could be as a draft standrad for other drivers test framework. Signed-off-by: 1078249029 <1078249029@qq.com>
1 parent 05699d6 commit 0270c43
Copy full SHA for 0270c43

File tree

7 files changed

+667
-0
lines changed
Filter options

7 files changed

+667
-0
lines changed

‎components/drivers/audio/Kconfig

Copy file name to clipboardExpand all lines: components/drivers/audio/Kconfig
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ config RT_USING_AUDIO
1414
config RT_AUDIO_RECORD_PIPE_SIZE
1515
int "Record pipe size"
1616
default 2048
17+
18+
config RT_UTEST_USING_AUDIO_DRIVER
19+
bool "Enable rt_audio_api testcase"
20+
default n
1721
endif

‎components/drivers/audio/SConscript

Copy file name to clipboardExpand all lines: components/drivers/audio/SConscript
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@ CPPPATH = [cwd]
66

77
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_AUDIO'], CPPPATH = CPPPATH)
88

9+
list = os.listdir(cwd)
10+
for item in list:
11+
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
12+
group = group + SConscript(os.path.join(item, 'SConscript'))
13+
914
Return('group')
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Import('rtconfig')
2+
from building import *
3+
4+
cwd = GetCurrentDir()
5+
src = []
6+
CPPPATH = [cwd]
7+
8+
if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('RT_UTEST_USING_AUDIO_DRIVER'):
9+
src += Glob('tc_*.c')
10+
11+
group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
12+
13+
Return('group')
+50Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-02 wumingzi first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <rttypes.h>
14+
#include "utest.h"
15+
16+
/* DMA buffer of audio player device refresh is triggered only when the amount of transmitted data is
17+
* greater than the size of a single block in the data queue */
18+
#define TX_DMA_BLOCK_SIZE RT_AUDIO_REPLAY_MP_BLOCK_SIZE
19+
#define TX_DMA_FIFO_SIZE (RT_AUDIO_REPLAY_MP_BLOCK_SIZE * 2)
20+
#define RX_DMA_BLOCK_SIZE RT_AUDIO_RECORD_PIPE_SIZE
21+
#define RX_DMA_FIFO_SIZE (RT_AUDIO_RECORD_PIPE_SIZE * 2)
22+
23+
#define SOUND_PLAYER_DEVICE_NAME "sound0"
24+
#define SOUND_MIC_DEVICE_NAME "mic0"
25+
26+
#define PLAYER_SAMPLEBITS 16
27+
#define PLAYER_SAMPLERATE 16000
28+
#define PLAYER_CHANNEL 2
29+
#define PLAYER_VOLUME 30
30+
31+
#define MIC_SAMPLEBITS 16
32+
#define MIC_SAMPLERATE 16000
33+
#define MIC_CHANNEL 2
34+
#define MIC_TIME_MS 5000
35+
36+
extern rt_uint8_t fsm_step ;
37+
38+
struct mic_device
39+
{
40+
struct rt_audio_device audio;
41+
struct rt_audio_configure config;
42+
rt_uint8_t *rx_fifo;
43+
};
44+
struct sound_device
45+
{
46+
struct rt_audio_device audio;
47+
struct rt_audio_configure config;
48+
rt_uint8_t volume;
49+
rt_uint8_t *tx_fifo;
50+
};
+136Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-02 wumingzi First version
9+
*/
10+
11+
#include "tc_audio_common.h"
12+
13+
#define THREAD_PRIORITY 9
14+
#define THREAD_TIMESLICE 5
15+
#define thread_simulate_intr_create_stacksize 1024
16+
static rt_thread_t thread_simulate_intr_handle;
17+
static struct mic_device mic_dev;
18+
19+
/* Simulate callback function */
20+
static void thread_simulate_intr(void *parameter)
21+
{
22+
/* Send the data(0xAA) from DMA buffer to kernel */
23+
rt_memset((void*)&mic_dev.rx_fifo[0], 0xAA, RX_DMA_BLOCK_SIZE);
24+
rt_audio_rx_done((struct rt_audio_device *)&(mic_dev.audio), mic_dev.rx_fifo, RX_DMA_BLOCK_SIZE);
25+
fsm_step = 1;
26+
27+
while (1)
28+
{
29+
if(fsm_step == 2)
30+
{
31+
/* Send the the data(0x55) from DMA buffer to kernel */
32+
rt_memset((void*)&mic_dev.rx_fifo[RX_DMA_BLOCK_SIZE], 0x55, RX_DMA_BLOCK_SIZE);
33+
rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[RX_DMA_BLOCK_SIZE], RX_DMA_BLOCK_SIZE);
34+
fsm_step = 3;
35+
break;
36+
}
37+
if(fsm_step == 4)
38+
{
39+
rt_thread_mdelay(10);
40+
rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[RX_DMA_BLOCK_SIZE], RX_DMA_BLOCK_SIZE);
41+
break;
42+
}
43+
rt_thread_mdelay(10);
44+
}
45+
46+
while(1)
47+
{
48+
rt_thread_mdelay(10);
49+
}
50+
}
51+
52+
static void thread_simulate_intr_create(void)
53+
{
54+
thread_simulate_intr_handle = rt_thread_create(
55+
"thread_simulate_intr",
56+
thread_simulate_intr,
57+
RT_NULL,
58+
thread_simulate_intr_create_stacksize,
59+
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
60+
61+
if (thread_simulate_intr_handle == RT_NULL)
62+
{
63+
rt_kprintf("Error: Failed to create thread!\n");
64+
return;
65+
}
66+
if (rt_thread_startup(thread_simulate_intr_handle) != RT_EOK)
67+
{
68+
rt_kprintf("Error: Failed to start thread!\n");
69+
thread_simulate_intr_handle = RT_NULL;
70+
}
71+
72+
}
73+
74+
static rt_err_t mic_device_init(struct rt_audio_device *audio)
75+
{
76+
return RT_EOK;
77+
}
78+
79+
/* Simulate DMA interrupt */
80+
static rt_err_t mic_device_start(struct rt_audio_device *audio, int stream)
81+
{
82+
thread_simulate_intr_create();
83+
return RT_EOK;
84+
}
85+
86+
static rt_err_t mic_device_stop(struct rt_audio_device *audio, int stream)
87+
{
88+
if (thread_simulate_intr_handle != RT_NULL)
89+
{
90+
rt_thread_delete(thread_simulate_intr_handle);
91+
thread_simulate_intr_handle = RT_NULL;
92+
}
93+
return RT_EOK;
94+
}
95+
96+
static rt_err_t mic_device_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
97+
{
98+
return RT_EOK;
99+
}
100+
101+
static rt_err_t mic_device_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
102+
{
103+
return RT_EOK;
104+
}
105+
106+
static struct rt_audio_ops _mic_audio_ops =
107+
{
108+
.getcaps = mic_device_getcaps,
109+
.configure = mic_device_configure,
110+
.init = mic_device_init,
111+
.start = mic_device_start,
112+
.stop = mic_device_stop,
113+
.transmit = RT_NULL,
114+
.buffer_info = RT_NULL,
115+
};
116+
117+
static int rt_hw_mic_init(void)
118+
{
119+
struct rt_audio_device *audio = &mic_dev.audio;
120+
/* mic default */
121+
mic_dev.rx_fifo = rt_malloc(RX_DMA_FIFO_SIZE);
122+
if (mic_dev.rx_fifo == RT_NULL)
123+
{
124+
return -RT_ENOMEM;
125+
}
126+
mic_dev.config.channels = MIC_CHANNEL;
127+
mic_dev.config.samplerate = MIC_SAMPLERATE;
128+
mic_dev.config.samplebits = MIC_SAMPLEBITS;
129+
130+
/* register mic device */
131+
audio->ops = &_mic_audio_ops;
132+
rt_audio_register(audio, SOUND_MIC_DEVICE_NAME, RT_DEVICE_FLAG_RDONLY, (void *)&mic_dev);
133+
134+
return RT_EOK;
135+
}
136+
INIT_DEVICE_EXPORT(rt_hw_mic_init);
+150Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-02 wumingzi First version
9+
*/
10+
11+
#include "tc_audio_common.h"
12+
13+
#define THREAD_PRIORITY 9
14+
#define THREAD_TIMESLICE 5
15+
#define thread_simulate_intr_create_stacksize 1024
16+
static rt_thread_t thread_simulate_intr_handle;
17+
static struct sound_device snd_dev;
18+
19+
static void thread_simulate_intr(void *parameter)
20+
{
21+
rt_flag_t exec_once = 0;
22+
while(1)
23+
{
24+
if(fsm_step == 1 && exec_once == 0)
25+
{
26+
/* Move the data(0xAA) from kernel to DMA buffer */
27+
rt_audio_tx_complete(&snd_dev.audio);
28+
fsm_step = 2;
29+
exec_once = 1;
30+
rt_thread_mdelay(10);
31+
}
32+
else if(fsm_step == 2 && exec_once == 1)
33+
{
34+
/* Move the data(0x55) from kernel to DMA buffer */
35+
rt_audio_tx_complete(&snd_dev.audio);
36+
fsm_step = 3;
37+
rt_thread_mdelay(10);
38+
}
39+
else if(fsm_step == 4)
40+
{
41+
/* rt_device_close will call rt_completion_wait(FOREVER), so we need delay to
42+
* let system run the point */
43+
rt_thread_mdelay(10);
44+
rt_audio_tx_complete(&snd_dev.audio);
45+
break;
46+
}
47+
rt_thread_mdelay(10);
48+
}
49+
while (1)
50+
{
51+
rt_thread_mdelay(10);
52+
}
53+
}
54+
55+
static void thread_simulate_intr_create(void)
56+
{
57+
thread_simulate_intr_handle = rt_thread_create(
58+
"thread_simulate_intr",
59+
thread_simulate_intr,
60+
RT_NULL,
61+
thread_simulate_intr_create_stacksize,
62+
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
63+
64+
rt_thread_startup(thread_simulate_intr_handle);
65+
}
66+
67+
static rt_err_t player_device_init(struct rt_audio_device *audio)
68+
{
69+
return RT_EOK;
70+
}
71+
72+
/* Simulate DMA interrupt */
73+
static rt_err_t player_device_start(struct rt_audio_device *audio, int stream)
74+
{
75+
thread_simulate_intr_create();
76+
return RT_EOK;
77+
}
78+
79+
static rt_err_t player_device_stop(struct rt_audio_device *audio, int stream)
80+
{
81+
rt_thread_delete(thread_simulate_intr_handle);
82+
return RT_EOK;
83+
}
84+
85+
static rt_err_t player_device_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
86+
{
87+
return RT_EOK;
88+
}
89+
90+
static rt_err_t player_device_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
91+
{
92+
return RT_EOK;
93+
}
94+
95+
static rt_ssize_t player_device_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size)
96+
{
97+
return size;
98+
}
99+
100+
static void player_device_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
101+
{
102+
RT_ASSERT(audio != RT_NULL);
103+
/**
104+
* TX_FIFO
105+
* +----------------+----------------+
106+
* | block1 | block2 |
107+
* +----------------+----------------+
108+
* \ block_size /
109+
*/
110+
info->buffer = snd_dev.tx_fifo;
111+
info->total_size = TX_DMA_FIFO_SIZE;
112+
info->block_size = TX_DMA_BLOCK_SIZE;
113+
info->block_count = RT_AUDIO_REPLAY_MP_BLOCK_COUNT;
114+
}
115+
116+
static struct rt_audio_ops audio_ops =
117+
{
118+
.getcaps = player_device_getcaps,
119+
.configure = player_device_configure,
120+
.init = player_device_init,
121+
.start = player_device_start,
122+
.stop = player_device_stop,
123+
.transmit = player_device_transmit,
124+
.buffer_info = player_device_buffer_info,
125+
};
126+
127+
static int rt_hw_sound_init(void)
128+
{
129+
rt_uint8_t *tx_fifo = RT_NULL;
130+
131+
tx_fifo = rt_malloc(TX_DMA_FIFO_SIZE);
132+
if (tx_fifo == NULL)
133+
{
134+
return -RT_ENOMEM;
135+
}
136+
snd_dev.tx_fifo = tx_fifo;
137+
138+
/* Init default configuration */
139+
{
140+
snd_dev.config.samplerate = PLAYER_SAMPLERATE;
141+
snd_dev.config.channels = PLAYER_CHANNEL;
142+
snd_dev.config.samplebits = PLAYER_SAMPLEBITS;
143+
snd_dev.volume = PLAYER_VOLUME;
144+
}
145+
146+
snd_dev.audio.ops = &audio_ops;
147+
rt_audio_register(&snd_dev.audio, SOUND_PLAYER_DEVICE_NAME, RT_DEVICE_FLAG_WRONLY, &snd_dev);
148+
return RT_EOK;
149+
}
150+
INIT_DEVICE_EXPORT(rt_hw_sound_init);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.