2010-01-11 17:14:01 Silica's FireCracker evaluation board
Miklos Jurisits (HUNGARY)
Message: 84426
Hi all!
I have a problem with getting uclinux peripheral drivers working on Silica's FireCracker evaluation board.
I've started evaluating this board because it has a Bluetechnix CM-BF537E core module with a rich set of peripherals including a high quality audio codec, a 3,5" TFT display, SD card slot and ethernet connector.
All these peripherals already have existing drivers in the BF537-STAMP project in uclinux-dist-trunk-svn-9127.
I strongly believe that these drivers are flexible enough, so they should work on the FireCracker board as well.
Can anyone help me with suggestions or experiences?
The peripherals that are actually in my scope are:
- ad1938 audio codec providing stereo Line-In and Line-Out and single Microphone-In
( interfaces: TDM via SPORT for digital audio interface and SPI for control interface )
- TX09D70VM1CDA 3,5" LED Back-lit Hitachi TFT Display
( interfaces: i2c, SPORT, a controller logic is implemented on an FPGA )
- SD-card
( interface: SPI, a controller logic is implemented on an FPGA )
What I've done so far is a few research and some testings regarding the audio codec:
1. I identyfied existing ad1938 asoc drivers in the BF537-STAMP project in uclinux-dist-trunk-svn-9127.
2. I modified the uclinux source code in order to add an ad1938 sound device to the Bluetechnix/CM-BF537 board.
2.1. I added ad1938 codec related lines to /mach-bf537/boards/cm_bf537e.c that I took from stamp.c. I modified chip select to 1.
2.2. I modified /linux-2.6.x/sound/soc/codecs/ad1938.c / ad1938_register() control register settings that I took from the FireCracker "audio loopthrough" example that was supplied with the board.
2.3. I modified size of EXT2_BLOCKS in vendors/Bluetechnix/CM-BF537E/Makefile that was recommended on forums.
3. Configured uclinux:
3.1 In main menuconfig:
Vendor/Product Selection ->
Vendor (Bluetechnix)
Bluetechnix Products (CM-BF537E)
3.2 In Kernel configuration:
General setup --->
Kernel compression mode (Gzip) --->
[*] Enable the block layer --->
Device Drivers --->
[*] SPI support --->
<*> SPI controller driver for ADI Blackfin5xx
<M> Sound card support --->
<M> Advanced Linux Sound Architecture --->
<M> ALSA for SoC audio support --->
<M> SoC I2S(TDM mode) Audio for the ADI BF5xx chip
<M> SoC AD1938 Audio support for Blackfin
<M> SoC AC97 Audio for the ADI BF5xx chip
[*] Enable MMAP Support (NEW)
(1) Set a SPORT for Sound chip
3.3 In User Application Configuration window
Blackfin app programs --->
[*] ALSA utils
4. Performed some audio tests
4.1 Loading the sound modules
root> modprobe snd-ad1938
Module snd_ad1938 and dependencies loaded successfully
4.2 speaker test supplied in alsa utils
preparation: creating device nodes :
root:/> mkdir /dev/snd
root:/> cd /dev/snd
root:/> mknod controlC0 c 116 0
root:/> mknod pcmC0D0p c 116 16
root:/> mknod pcmC0D0c c 116 24
root:/> mknod timer c 116 33
Speaker test:
root:/> speaker-test -Ddefault -r48000 -tpink -l1
Result:
!!! No sound on the DAC output, process finishes, no error message.
The debug messages I applied suggest that the power management switches DAC on, then the audio data is sent to the DMA area, finally the power management switches DAC off.
4.3 aplay test:
preparation: ftp copy of a wav file to FireCracker ( file name /tmp/Front_Center.wav )
Aplay test:
root:/> aplay -Ddefault /tmp/Front_Center.wav
Result:
!!! No sound on the DAC output, process hangs, no error message.
The debug messages I applied suggest that the power management switches DAC on, then the audio data is sent to the DMA area.
The last function call before hanging:
lib/alsa-lib/alsa-lib-1.0.18/src/pcm/pcm.c / snd_pcm_write_areas()
Thanks for any replies!
QuoteReplyEditDelete
2010-01-11 22:44:27 Re: Silica's FireCracker evaluation board
Barry Song (CHINA)
Message: 84431
Don't know exactly about your hardware connection and what you have changed in code. I think you need to provide more information.
For hardware, you can take "blackfin audio ez-extender" board as reference for ad1938. For codes, you can check whether the sound card is really registered successfully and DMA and so on is working. "!!! No sound on the DAC output" is useless for locating problems.
QuoteReplyEditDelete
2010-01-12 13:00:29 Re: Silica's FireCracker evaluation board
Robin Getz (UNITED STATES)
Message: 84476
Miklos:
I don't think anyone here has tried the firecracker board with Linux on it.
-Robin
QuoteReplyEditDelete
2010-01-12 18:19:43 Re: Silica's FireCracker evaluation board
Miklos Jurisits (HUNGARY)
Message: 84488
Hi Barry and Robin!
Thank you for your answers!
Let me provide some detailed information about my HW and SW config and my logs.
1. HW connections on the FireCracker board
Please find Silica_FireCracker V1.2 Schematics.pdf attached for full details
Also find the following documents published on the Silica website:
www.silica.com/fileadmin/03_Engineering/01_Development-and-Evaluation-Tools/FireCracker_Hardware_Manual_2008.pdf
www.silica.com/fileadmin/03_Engineering/01_Development-and-Evaluation-Tools/FireCracker_Application_Manual_2008.pdf
2. Comparing the ad1938 HW connections on FireCracker eval board to those of the EZ Audio Extender board:
( listed by pin numbers )
2, I, MCLKI/XI - Master Clock Input/Crystal Oscillator Input.
EZ_Audio_extender: AD1938_MCLK, The external master clock (MCLK) comes from theADAV801 codec.
Silica_FireCracker: 12,288MHz Quartz
3, O, MCLKO/XO - Master Clock Output/Crystal Oscillator Output.
EZ_Audio_extender: AD1938_A_MCLK_0
Silica_FireCracker: 12,288MHz Quartz
10, I, PD/RST - Power-Down Reset (Active Low).
EZ_Audio_extender: RESET ( push button )
Silica_FireCracker: nRST_AUDIO driven by FPGA IO_L34P_6 ???
15, I/O, DSDATA2 - DAC Input 2. Input to DAC L2 and DAC R2/DAC TDM Data Out/AUX ADC 1 Data In.
EZ_Audio_extender: AUX_DIN1 goes to LDAV801A SPDIF driver
Silica_FireCracker: DT1SEC (SPORT1)
??? SPORT1 SECONDARY
16, I, DSDATA1 - DAC Input 1. Input to DAC L1 and DAC R1/DAC TDM Data In/AUX ADC 2 Data In.
EZ_Audio_extender: SPORT_A_DOUT1 - DT0PRI/DT1PRI
Silica_FireCracker: DT1PRI (SPORT1)
17, I/O, DBCLK - Bit Clock for DACs.
EZ_Audio_extender: AUX_CLK goes to LDAV801A SPDIF driver
Silica_FireCracker: TSCLK1 (SPORT1)
18, I/O, DLRCLK - LR Clock for DACs.
EZ_Audio_extender: AUX_LRCLK goes to LDAV801A SPDIF driver
Silica_FireCracker: TFS1 (SPORT1)
19, I/O, ASDATA2 - ADC Serial Data Output 2 (ADC L2 and ADC R2)/ADC TDM Data Input/Aux DAC 1 Data Out.
EZ_Audio_extender: AUX_DOUT1 goes to LDAV801A SPDIF driver
Silica_FireCracker: DR1SEC (SPORT1)
20, O, ASDATA1 - ADC Serial Data Output 1 (ADC L1 and ADC R1)/ADC TDM Data Output.
EZ_Audio_extender: SPORT_A_DIN1 - DR0PRI/DR1PRI
Silica_FireCracker: DR1PRI (SPORT1)
21, I/O, ABCLK - Bit Clock for ADCs.
EZ_Audio_extender: SPORT_A_CLK - RSCLK0/RSCLK1
Silica_FireCracker: RSCLK1 (SPORT1)
22, I/O, ALRCLK - LR Clock for ADCs.
EZ_Audio_extender: SPORT_A_FS - RFS0/RFS1
Silica_FireCracker: RFS1 (SPORT1)
23, I, CIN - Control Data Input (SPI).
EZ_Audio_extender: MOSI
Silica_FireCracker: MOSI (SPI)
24, I/O, COUT - Control Data Output (SPI).
EZ_Audio_extender: MISO
Silica_FireCracker: MISO (SPI)
26, I, CCLK - Control Clock Input (SPI).
EZ_Audio_extender: SCK
Silica_FireCracker: SCK (SPI)
27, I, CLATCH - Latch Input for Control Data (SPI).
EZ_Audio_extender: AD1938_A_SSEL - BF537_PF5
Silica_FireCracker: SPI_CS1
28, O, OL1 - DAC 1 Left Output.
EZ_Audio_extender: AOUT1_L
Silica_FireCracker: OL1
29, O, OR1 - DAC 1 Right Output.
EZ_Audio_extender: AOUT1_R
Silica_FireCracker: OR1
39, I, ADC1LP - ADC1 Left Positive Input.
EZ_Audio_extender: AIN1_LP
Silica_FireCracker: ADC1LP
40, I, ADC1LN - ADC1 Left Negative Input.
EZ_Audio_extender: AIN1_LN
Silica_FireCracker: ADC1LN
42, I, ADC1RN - ADC1 Right Negative Input.
EZ_Audio_extender: AIN1_RN
Silica_FireCracker: ADC1RN
43, I, ADC2LP - ADC2 Left Positive Input.
EZ_Audio_extender: AIN2_LP
Silica_FireCracker: ADC2LP
44, I, ADC2LN - ADC2 Left Negative Input.
EZ_Audio_extender: AIN2_LN
Silica_FireCracker: VREF
45, I, ADC2RP - ADC2 Right Positive Input.
EZ_Audio_extender: AIN2_RP
Silica_FireCracker: ADC2RP
46, I, ADC2RN - ADC2 Right Negative Input.
EZ_Audio_extender: AIN2_RN
Silica_FireCracker: TO AGND
3. Changes in code
3.1 add lines to /mach-bf537/boards/cm_bf537e.c in definition of bfin_spi_board_info[]:
static struct spi_board_info bfin_spi_board_info[] __initdata = {
...
#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
{
.modalias = "ad1938",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
.chip_select = 1, /* MJ FireCracker */
.controller_data = &ad1938_spi_chip_info,
.mode = SPI_MODE_3,
},
#endif
3.2 add devices to /mach-bf537/boards/cm_bf537e.c before the definition of *cm_bf537e_devices[]
#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
static struct platform_device bfin_i2s = {
.name = "bfin-i2s",
.id = CONFIG_SND_BF5XX_SPORT_NUM,
/* TODO: add platform data here */
};
#endif
#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
static struct platform_device bfin_tdm = {
.name = "bfin-tdm",
.id = CONFIG_SND_BF5XX_SPORT_NUM,
/* TODO: add platform data here */
};
#endif
#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
static struct platform_device bfin_ac97 = {
.name = "bfin-ac97",
.id = CONFIG_SND_BF5XX_SPORT_NUM,
/* TODO: add platform data here */
};
#endif
3.3 add lines in the end of definition for *cm_bf537e_devices[]:
static struct platform_device *cm_bf537e_devices[] __initdata = {
...
#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
&bfin_i2s,
#endif
#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
&bfin_tdm,
#endif
#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
&bfin_ac97,
#endif
}
3.4 modify /linux-2.6.x/sound/soc/codecs/ad1938.c / ad1938_register() control register settings:
/* unmute dac channels */
codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
/* FireCracker: use defaults for DAC Master Mute, Deemphasis, Word width, DAC Output Polarity */
codec->write(codec, AD1938_DAC_CTRL2, 0x0);
/* FireCracker: use TDM for DAC Serial Format, and defaults for DAC Power Down, Sample Rate, SDATA Delay */
codec->write(codec, AD1938_DAC_CTRL0, 0x40);
/* FireCracker: use DAC settings as Master */
codec->write(codec, AD1938_DAC_CTRL1, 0x74);
/* FireCracker: use defaults for ADC Power Down, Highpass Filter, ADC 1L mute, ADC 1R mute, ADC 2L mute, ADC 2R mute, Output Sample Rate */
codec->write(codec, AD1938_ADC_CTRL0, 0x0);
/* FireCracker: use TDM for ADC Serial Format, use defaults for ADC Word width, SDATA delay (BCLK periods), BCLK Active Edge (TDM In) */
codec->write(codec, AD1938_ADC_CTRL1, 0x20);
/* FireCracker: set "Enable: ADC and DAC Active" for Internal MCLK Enable, use defaults for others */
codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x80);
codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x0);
3.5 modify size in vendors/Bluetechnix/CM-BF537E/Makefile:
EXT2_BLOCKS = 8192
4. Logs
Please find attached file log_20100109.txt
The file contains a lot of debugging info, because my kernel is built with: "#define DEBUG 1" and "#define DEBUG_FS 1" in include/linux/kernel.h.
Also I added several debugging messages ( printk or printf ) to the alsa lib and the sound core functions.
The file contains the following sections:
-- bootm
boot messages are copied from console ( minicom )
-- modprobe snd-ad1938
console messages of loading snd-ad1938
dmesg
dmesg log of loading snd-ad1938 ( truncated at the beginning )
-- speaker-test -Ddefault -r48000 -tpink -l1
console messages of speaker-test
dmesg
dmesg log of loading of speaker-test
-- aplay -Ddefault /tmp/Front_Center.wav
console messages of aplay
dmesg
dmesg log of loading of aplay
5. Audio loop-through example code
Please find attached audio_loopthrough.tar, it is part of the example code that was supplied with FireCracker.
The loopthrough.h contains the ad1938 control register settings, which I used for the /linux-2.6.x/sound/soc/codecs/ad1938.c modifications.
Regards
Miklos
log_20100109.txt
Silica_FireCracker V1.2 Schematics.pdf
audio_loopthrough.tar
QuoteReplyEditDelete
2010-01-13 13:47:56 Re: Silica's FireCracker evaluation board
Robin Getz (UNITED STATES)
Message: 84546
Miklos:
I'm not sure what you are asking for - I already said - we don't support that platform. If you want an easier Linux experience - use a supported platform.
-Robin
QuoteReplyEditDelete
2010-01-13 17:49:59 Re: Silica's FireCracker evaluation board
Miklos Jurisits (HUNGARY)
Message: 84549
Sorry for the great deal of details I've posted descibing an unsupported board.
Please allow me to rephrase my question just once:
I have an ad1938 audio codec connected to the Bluetechnix CM-BF537E core module.
My HW connections are very similar to the ADSP-BF537_EZ-KIT_Lite - EZ_Audio_extender connections, the differencies are in Master Clock Input, Power-Down Reset, DSDATA2 and ASDATA2 pin connections.
I have modified the uclinux source code, and configured uclinux in order to add an ad1938 sound device to the Bluetechnix/CM-BF537 board.
I have modified the audio codec register default values ( AD1938_PLL_CLK_CTRL0 etc. ) to follow the above differencies.
Now I can load the driver module snd-ad1938 successfully, and I can get soc-audio: Registered card 'bf5xx_ad1938'.
But aplay test hangs here: lib/alsa-lib/alsa-lib-1.0.18/src/pcm/pcm.c / snd_pcm_write_areas()
Can you please tell me how I supposed to go on with debugging?
What do you think this type of problem originates: DMA, TDM, SPORT or SPI malfunctions?
Regards
Miklos
QuoteReplyEditDelete
2010-09-26 06:31:45 Re: Silica's FireCracker evaluation board
Jan Kratina (CZECH REPUBLIC)
Message: 93858
Your problem is associated with SPI chip select. SPI controler is expecting CS connected to GPIO or SPI_CSx pin of blackfin module.
You can use this ugly hack to make it work...
(and change audio .chip_select from 1 to 2)
in linux-2.6.x/drivers/spi/spi_bfin5xx.c:
static fpga_state = 0x0007;
/* Chip select operation functions for cs_change flag */
static void bfin_spi_cs_active(struct master_data *drv_data, struct slave_data *chip)
{
#if 0
if (likely(chip->chip_select_num < MAX_CTRL_CS)) {
u16 flag = read_FLAG(drv_data);
flag &= ~chip->flag;
write_FLAG(drv_data, flag);
} else {
gpio_set_value(chip->cs_gpio, 0);
}
#endif
switch(chip->chip_select_num) {
case 1: fpga_state &= ~4;break; // Audio codec
case 2: fpga_state &= ~1;break; // MMC
}
bfin_write16(0x202FFFFA,fpga_state);
}
static void bfin_spi_cs_deactive(struct master_data *drv_data, struct slave_data *chip)
{
#if 0
if (likely(chip->chip_select_num < MAX_CTRL_CS)) {
u16 flag = read_FLAG(drv_data);
flag |= chip->flag;
write_FLAG(drv_data, flag);
} else {
gpio_set_value(chip->cs_gpio, 1);
}
#endif
switch(chip->chip_select_num) {
case 1: fpga_state |= (1 << 2);break;
case 2: fpga_state |= 1;break;
}
bfin_write16(0x202FFFFA,fpga_state);
/* Move delay here for consistency */
if (chip->cs_chg_udelay)
udelay(chip->cs_chg_udelay);
}