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 (audio_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+ audio_fsm_step = 2 ;
29+ exec_once = 1 ;
30+ rt_thread_mdelay (10 );
31+ }
32+ else if (audio_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+ audio_fsm_step = 3 ;
37+ rt_thread_mdelay (10 );
38+ }
39+ else if (audio_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