LINUX.ORG.RU

Не могу вывести звук через PCM на модуль SIMCOM

 , ,


0

1

Делаю систему на SoC Allwinner H3 и сотовом модуле SIM7600E. Связь модуля с SoC для обслуживания голосовых вызовов по PCM интерфейсу. Принимать голос с модуля получается, а передавать в модуль - нет. Запись wav, полученная только что через arecord, передаётся обратно в модуль через aplay примерно в 8 раз быстрее и звучит похоже на покорёженный звук, не как белый шум. Уже всё прогуглил вдоль и поперёк, не могу сообразить, что надо допилить для правильного воспроизведения…

ОС Armbian 5.4.33-sunxi. Драйвер для DAI переделал из стандартного драйвера для ADC/DAC AK4554 до требований модуля: один канал, 8/16 кГц (2G,3G/4G), 16 бит, MSB, формат данных в терминах linux’а DSP_A. Модуль - мастер. Модуль никаких настроек не принимает. Основные изменения драйвера такие:

static const struct snd_soc_dapm_widget simcompcm_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("AIN"),
SND_SOC_DAPM_OUTPUT("AOUT"),
};

static const struct snd_soc_dapm_route simcompcm_dapm_routes[] = {
	{ "Capture", NULL, "AIN" },
	{ "AOUT", NULL, "Playback" },
};

static struct snd_soc_dai_driver simcompcm_dai = {
	.name = "simcompcm",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 1,
		.channels_max = 1,
		.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
		.formats = SND_SOC_DAIFMT_DSP_A,
	},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 1,
		.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
		.formats = SND_SOC_DAIFMT_DSP_A,
	},
	.symmetric_rates = 1,
};

Сделал оверлей для DT:

/dts-v1/;
/plugin/;

/ {
        compatible = "allwinner,sun8i-h3";

        fragment@0 {
                target-path = "/";
                __overlay__ {
                        simcom_codec: simcom_codec {
                                status = "okay";
                                compatible = "simcom,simcompcm";
                                #sound-dai-cells = <0>;
                        };
                };
        };

        fragment@1 {
                target = <&i2s0>;
                __overlay__ {
                        status = "okay";
                        pinctrl-0 = <&i2s0_pins>;
                        sound-dai = <&simcom_codec>;
                        pinctrl-names = "default";
                };
        };

        fragment@2 {
                target-path = "/";
                __overlay__ {
                        sound {
                                status = "okay";
                                compatible = "simple-audio-card";
                                simple-audio-card,name = "simcom_pcm";
                                simple-audio-card,mclk-fs = <256>;
                                simple-audio-card,format = "dsp_a";
                                simple-audio-card,widgets =
                                        "Line", "Line In",
                                        "Line", "Line Out";
                                simple-audio-card,routing =
                                        "AIN", "Line In",
                                        "Line Out", "AOUT";
                                simple-audio-card,bitclock-master = <&dailink0>;
                                simple-audio-card,frame-master = <&dailink0>;
                                simple-audio-card,cpu {
                                        sound-dai = <&i2s0>;
                                };
                                dailink0: simple-audio-card,codec {
                                        sound-dai = <&simcom_codec>;
                                };
                        };
                };
        };
};

Пробовал крутить это: simple-audio-card,mclk-fs = <256>; - вообще никакой реакции. Меня смущает вот это сочетание клоков модуля в даташите:

Frame cycle time: 125 us (8.0 kHz) / 62.5 us (16.0 kHz)
Bit cycle time: 488 ns (~2049 kHz) / 244 ns (~4098 kHz)

Значения в скобках я сам пересчитал из указанных спеков на диаграммы сигналов, а в общем спеке на формат PCM дают «округлённые» числа:

PCM clock rate 2048kHz / 4096 kHz

Что-то я не догоняю таких нестыковок по частотам. И ещё получается, что в один фрейм можно 16 каналов по 16 бит затолкать, а у меня один только, может выходной поток неправильно режется на фреймы, 8 семплов кладётся в один фрейм? Как этим управлять тоже не могу найти. Буду благодарен за идеи.

В уверены, что:

simple-audio-card,format = "dsp_a"
а не i2s? Но я так, просто мимо крокодил.

И ещё получается, что в один фрейм можно 16 каналов по 16 бит затолкать

Может я неправильно понимаю i2s, вроде там данные передаются только после фронта PCM_SYNC, а в остальное время пусто. У вас там один канал — передача стартует по падающему фронту, который раз в 125 мкс.

mky ★★★★★
()

ОС Armbian 5.4.33-sunxi. Драйвер для DAI переделал из стандартного драйвера для ADC/DAC AK4554 до требований модуля: один канал, 8/16 кГц (2G,3G/4G), 16 бит, MSB, формат данных в терминах linux’а DSP_A.

попробуй для начала по примеру для либрема

кодек

https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/sound/gtm601.txt

https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts#L160

карта

https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts#L193

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.