Skip to content

Commit

Permalink
Merge pull request #23 from lucianomartin/feature/support_rpi4
Browse files Browse the repository at this point in the history
Support for Buster Raspian on RPi3 and RPi4
  • Loading branch information
xluciano authored Oct 14, 2020
2 parents da241e0 + a7d29d3 commit 4c1ba1e
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 249 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# VocalFusion Raspberry Pi Setup Change Log

## 3.0.0

* Update clock dividers for RPi3 to generate a 12.288MHz clock, since the RPi4 clock at 24.576MHz has glitches
* Add support for RPi4 on I2S loader kernel module
* Add delay in loading I2S drivers needed for Buster on RPi3
* Add script compute_clock_dividers.py to compute dividers for MCLK and BCLK
* Fix some indentations and general tidy up

## 2.3.0

* Add support for 16kHz BCLK generation
Expand Down
14 changes: 11 additions & 3 deletions loader/i2s_master/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
obj-m := loader.o
obj-m := i2s_master_loader.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

i2s_master: $(PWD)/loader.c
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
all:
# copy the source file to avoid maintaining multiple copies inside the Makefile folders
# We tried to use KBUILD_OUTPUT but the module was not compiling
cp ../src/loader.c i2s_master_loader.c
$(MAKE) -C $(KDIR) M=$(PWD) modules
rm i2s_master_loader.c

clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean

14 changes: 11 additions & 3 deletions loader/i2s_slave/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
obj-m := loader.o
obj-m := i2s_slave_loader.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

i2s_slave: $(PWD)/loader.c
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
all:
# copy the source file to avoid maintaining multiple copies inside the Makefile folders
# We tried to use KBUILD_OUTPUT but the module was not compiling
cp ../src/loader.c i2s_slave_loader.c
$(MAKE) -C $(KDIR) M=$(PWD) modules
rm i2s_slave_loader.c

clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean

74 changes: 0 additions & 74 deletions loader/i2s_slave/loader.c

This file was deleted.

30 changes: 20 additions & 10 deletions loader/i2s_master/loader.c → loader/src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,26 @@ N.B. playback vs capture is determined by the codec choice

void device_release_callback(struct device *dev) { /* do nothing */ };

#ifdef RPI_4B
#define CARD_PLATFORM_STR "fe203000.i2s"
#else
#define CARD_PLATFORM_STR "3f203000.i2s"
#endif

#ifdef I2S_MASTER
#define SND_SOC_DAIFMT_CBS_FLAG SND_SOC_DAIFMT_CBS_CFS
#else
#define SND_SOC_DAIFMT_CBS_FLAG SND_SOC_DAIFMT_CBM_CFM
#endif

static struct asoc_simple_card_info snd_rpi_simple_card_info = {
.card = "snd_rpi_simple_card", // -> snd_soc_card.name
.name = "simple-card_codec_link", // -> snd_soc_dai_link.name
.codec = "snd-soc-dummy", // -> snd_soc_dai_link.codec_name
.platform = "3f203000.i2s",
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS,
.platform = CARD_PLATFORM_STR,
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_FLAG,
.cpu_dai = {
.name = "3f203000.i2s", // -> snd_soc_dai_link.cpu_dai_name
.name = CARD_PLATFORM_STR, // -> snd_soc_dai_link.cpu_dai_name
.sysclk = 0
},
.codec_dai = {
Expand All @@ -47,7 +59,7 @@ static struct platform_device snd_rpi_simple_card_device = {
}
};

int hello_init(void)
int snd_rpi_simple_card_init(void)
{
const char *dmaengine = "bcm2708-dmaengine"; //module name
int ret;
Expand All @@ -56,19 +68,17 @@ int hello_init(void)
pr_alert("request module load '%s': %d\n",dmaengine, ret);
ret = platform_device_register(&snd_rpi_simple_card_device);
pr_alert("register platform device '%s': %d\n",snd_rpi_simple_card_device.name, ret);
pr_alert("Hello World :)\n");
return 0;
}

void hello_exit(void)
void snd_rpi_simple_card_exit(void)
{
// you'll have to sudo modprobe -r the card & codec drivers manually (first?)
platform_device_unregister(&snd_rpi_simple_card_device);
pr_alert("Goodbye World!\n");
pr_alert("unregister platform device '%s'\n",snd_rpi_simple_card_device.name);
}

module_init(hello_init);
module_exit(hello_exit);
module_init(snd_rpi_simple_card_init);
module_exit(snd_rpi_simple_card_exit);
MODULE_DESCRIPTION("ASoC simple-card I2S setup");
MODULE_AUTHOR("Plugh Plover");
MODULE_LICENSE("GPL v2");
47 changes: 47 additions & 0 deletions resources/clk_dac_setup/compute_clock_dividers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import argparse

def compute_dividers(source_clock_khz, output_clock_khz):
div_i = int(source_clock_khz / output_clock_khz)
div_f = int(((source_clock_khz / output_clock_khz) - div_i) * 4096)

final_output_clock_khz = float(source_clock_khz)*1000/(div_i + div_f/4096)/1000

return [final_output_clock_khz, div_i, div_f]

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('source_clock_khz', type=int,
help="Source clock frequency in kHz")

parser.add_argument('desired_mclock_khz', type=int,
help="Desired frequency of MCLK in kHz")

parser.add_argument('--mclk_pdm_clk_divider', '-d', type=int, default=1, choices=[1, 2],
help="XCore divider from input master clock to 6.144MHz DDR PDM microphone clock")

args = parser.parse_args()

[mclk_khz, mclk_div_i, mclk_div_f] = compute_dividers(args.source_clock_khz, args.desired_mclock_khz)

mclk_bclk_ratio = 4 * args.mclk_pdm_clk_divider

# The MCLK must be an exact multiple of the BCLK to avoid glitches in the I2S audio
desired_bclk_48khz = float(mclk_khz) / mclk_bclk_ratio
[bclk_48khz, bclk_48khz_div_i, bclk_48khz_div_f] = compute_dividers(args.source_clock_khz, desired_bclk_48khz)

desired_bclk_16khz = mclk_khz / (mclk_bclk_ratio * 3)
[bclk_16khz, bclk_16khz_div_i, bclk_16khz_div_f] = compute_dividers(args.source_clock_khz, desired_bclk_16khz)


print(f"Given source clock: {args.source_clock_khz}kHz the dividers are:")
print(f"\tMCLK: freq {mclk_khz}kHz CLK_I {mclk_div_i} CLK_F {mclk_div_f}")
print(f"\tBCLK at 48kHz: freq {bclk_48khz}kHz, ratio {mclk_khz/bclk_48khz}, CLK_I {bclk_48khz_div_i}, CLK_F {bclk_48khz_div_f}")
print(f"\tBCLK at 16kHz: freq {bclk_16khz}kHz, ratio {mclk_khz/bclk_16khz}, CLK_I {bclk_16khz_div_i} CLK_F {bclk_16khz_div_f}")
if int(args.desired_mclock_khz) != mclk_khz:
print(f"Warning: perfect value for MCLK couldn't be found: expected {args.desired_mclock_khz}, found {mclk_khz}\n")
if desired_bclk_48khz != bclk_48khz:
print(f"Warning: perfect value for BCLK at 48kHz couldn't be found: expected {desired_bclk_48khz}, found {bclk_48khz}\n")
if desired_bclk_16khz != bclk_16khz:
print(f"Warning: perfect value for BCLK at 16kHz couldn't be found: expected {desired_bclk_16khz}, found {bclk_16khz}")


Loading

0 comments on commit 4c1ba1e

Please sign in to comment.