Related
I have written a small program to play PCM audio files using a reference from github with slight modifications for my application. The program is compiling fine, but I am having a few runtime issues regarding dependencies and ALSA devices.
The errors I am receiving are:
ERROR: Failed to load plugin /usr/lib/x86_64-linux-gnu/ao/plugins-4/libsndio.so => dlopen() failed
ERROR: Failed to load plugin /usr/lib/x86_64-linux-gnu/ao/plugins-4/libnas.so => dlopen() failed
ao_alsa WARNING: Unable to open surround playback. Trying default device...
ALSA lib pcm_dmix.c:1089:(snd_pcm_dmix_open) unable to open slave
ao_alsa ERROR: Unable to open ALSA device 'default' for playback => No such file or directory
I have been researching many different solutions and none seem to be working, including adding a line to the alsa.conf file in /etc/modprobe.d (however, these solutions suggest adding a line in reference to intel when I am using an AMD setup.
Here is the full code:
/*
*
* ao_example.c
*
* Written by Stan Seibert - July 2001
*
* Legal Terms:
*
* This source file is released into the public domain. It is
* distributed without any warranty; without even the implied
* warranty * of merchantability or fitness for a particular
* purpose.
*
* Function:
*
* This program opens the default driver and plays a 440 Hz tone for
* one second.
*
* Compilation command line (for Linux systems):
*
* gcc -o ao_example ao_example.c -lao -ldl -lm -lsndfile
*
*/
#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>
#include <sndfile.h>
#define BUF_SIZE 4096
static void clean(ao_device *device, SNDFILE *file){
ao_close(device);
sf_close(file);
ao_shutdown();
}
int main(int argc, char **argv)
{
ao_device *device;
ao_sample_format format;
unsigned long count;
int default_driver;
short *buffer;
int buf_size;
int sample;
int i;
//FILE *fp;
SF_INFO sfinfo;
if (argc != 2){
printf("usage: %s <filename>\n", argv[0]);
exit(1);
}
/* -- Initialize -- */
fprintf(stderr, "libao example program\n");
SNDFILE *fp = sf_open(argv[1], SFM_READ, &sfinfo);
// fp = fopen(argv[1], "rb");
if (fp == NULL){
printf("Cannot open %s.\n", argv[1]);
exit(1);
}
printf("samples: %d\n", sfinfo.frames);
printf("sample rate: %d\n", sfinfo.samplerate);
printf("Channels: %d\n", sfinfo.channels);
ao_initialize();
/* -- Setup for default driver -- */
default_driver = ao_default_driver_id();
switch(sfinfo.format & SF_FORMAT_SUBMASK){
case SF_FORMAT_PCM_16:
format.bits = 16;
break;
case SF_FORMAT_PCM_24:
format.bits = 24;
break;
case SF_FORMAT_PCM_32:
format.bits = 32;
break;
case SF_FORMAT_PCM_S8:
format.bits = 8;
break;
case SF_FORMAT_PCM_U8:
format.bits = 8;
break;
default:
format.bits = 24;
break;
}
format.channels = sfinfo.channels;
format.rate = sfinfo.samplerate;
format.byte_format = AO_FMT_LITTLE;
// format.byte_format = AO_FMT_NATIVE;
format.matrix = 0;
// memset(&format, 0, sizeof(format));
// format.bits = 24;
// format.channels = 16;
// format.rate = 48000;
// format.byte_format = AO_FMT_LITTLE;
/* -- Open driver -- */
device = ao_open_live(default_driver, &format, NULL /* no options */);
if (device == NULL) {
fprintf(stderr, "Error opening device.\n");
return 1;
}
// fseek(fp, 0, SEEK_END);
// count = ftell(fp);
// fseek(fp, 0, SEEK_SET);
// // printf("count: %ld\n", count);
buffer = calloc(BUF_SIZE, sizeof(short));
while(1){
int read = sf_read_short(fp, buffer, BUF_SIZE);
if (ao_play(device, (char *) buffer, (uint_32)(read * sizeof(short))) == 0){
printf("ao_play: failed\n");
clean(device, fp);
break;
}
}
clean(device, fp);
return 0;
}
I hope someone else has had the same trouble and can shed light on the solution. Thank you.
To summarise the discussion:
The problem does not seem to lie within the code per se but in the libao configuration.
According to the libao documentation, the library tries to determine a default driver as follows:
In the absence of configuration files to explicit identify a default
driver, the library will try to detect a suitable default driver. It
does this by testing every available live output driver (using
ao_plugin_test()) and finding the driver with the highest priority
(see the ao_info struct) that works. Drivers with priority 0, such as
the null and file output drivers, are never selected as the default.
The error messages indicate that several drivers including nas, sndio and alsa are tried. Choosing the driver manually with ao_driver_id(...) instead of using ao_default_driver_id() fixes the issue.
Further problems with opening the device with ao_open_live(...) can be investigated by getting the corresponding error number with printf("errno %d\n", errno);. The output can be interpreted as follows:
AO_ENODRIVER (1) - No driver corresponds to driver_id.
AO_ENOTLIVE (3) - This driver is not a live output device.
AO_EBADOPTION (4) - A valid option key has an invalid value.
AO_EOPENDEVICE (5) - Cannot open the device (for example, if /dev/dsp cannot be opened for writing).
AO_EFAIL (100) - Any other cause of failure.
Besides that debugging can be enabled in the ~/.libao configuration file to get further information.
Here is the lsmod output:
Module Size Used by
rfcomm 81920 4
cmac 16384 2
algif_hash 16384 1
algif_skcipher 16384 1
af_alg 28672 6 algif_hash,algif_skcipher
bnep 24576 2
nls_iso8859_1 16384 1
hid_logitech_hidpp 45056 0
input_leds 16384 0
joydev 24576 0
hid_logitech_dj 28672 0
hid_generic 16384 0
snd_hda_codec_realtek 131072 1
snd_hda_codec_generic 81920 1 snd_hda_codec_realtek
ledtrig_audio 16384 1 snd_hda_codec_generic
snd_hda_codec_hdmi 61440 1
snd_hda_intel 53248 4
edac_mce_amd 32768 0
snd_intel_dspcfg 28672 1 snd_hda_intel
iwlmvm 393216 0
snd_hda_codec 139264 4 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec_realtek
snd_hda_core 94208 5 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_codec_realtek
mac80211 905216 1 iwlmvm
snd_hwdep 20480 1 snd_hda_codec
snd_pcm 114688 4 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_core
amdgpu 5218304 11
libarc4 16384 1 mac80211
snd_seq_midi 20480 0
snd_seq_midi_event 16384 1 snd_seq_midi
kvm 712704 0
snd_rawmidi 36864 1 snd_seq_midi
snd_seq 69632 2 snd_seq_midi,snd_seq_midi_event
crct10dif_pclmul 16384 1
snd_seq_device 16384 3 snd_seq,snd_seq_midi,snd_rawmidi
ghash_clmulni_intel 16384 0
iwlwifi 352256 1 iwlmvm
snd_timer 40960 2 snd_seq,snd_pcm
aesni_intel 372736 3
iommu_v2 20480 1 amdgpu
crypto_simd 16384 1 aesni_intel
gpu_sched 36864 1 amdgpu
cryptd 24576 3 crypto_simd,ghash_clmulni_intel
glue_helper 16384 1 aesni_intel
usbhid 57344 1 hid_logitech_dj
ttm 102400 1 amdgpu
wmi_bmof 16384 0
hid 135168 4 usbhid,hid_generic,hid_logitech_dj,hid_logitech_hidpp
rapl 20480 0
drm_kms_helper 217088 1 amdgpu
efi_pstore 16384 0
cfg80211 778240 3 iwlmvm,iwlwifi,mac80211
cec 53248 1 drm_kms_helper
rc_core 61440 1 cec
snd 94208 19 snd_hda_codec_generic,snd_seq,snd_seq_device,snd_hda_codec_hdmi,snd_hwdep,snd_hda_intel,snd_hda_codec,snd_hda_codec_realtek,snd_timer,snd_pcm,snd_rawmidi
fb_sys_fops 16384 1 drm_kms_helper
syscopyarea 16384 1 drm_kms_helper
sysfillrect 16384 1 drm_kms_helper
sysimgblt 16384 1 drm_kms_helper
k10temp 16384 0
ccp 98304 0
soundcore 16384 1 snd
btusb 57344 0
btrtl 24576 1 btusb
btbcm 16384 1 btusb
btintel 28672 1 btusb
mac_hid 16384 0
bluetooth 581632 31 btrtl,btintel,btbcm,bnep,btusb,rfcomm
ecdh_generic 16384 1 bluetooth
ecc 32768 1 ecdh_generic
sch_fq_codel 20480 3
hwmon_vid 16384 0
parport_pc 45056 0
ppdev 24576 0
lp 20480 0
drm 552960 9 gpu_sched,drm_kms_helper,amdgpu,ttm
parport 65536 3 parport_pc,lp,ppdev
ip_tables 32768 0
x_tables 49152 1 ip_tables
autofs4 45056 2
crc32_pclmul 16384 0
xhci_pci 20480 0
nvme 49152 2
i2c_piix4 28672 0
igb 221184 0
ahci 40960 0
libahci 36864 1 ahci
xhci_pci_renesas 20480 1 xhci_pci
i2c_algo_bit 16384 2 igb,amdgpu
nvme_core 114688 4 nvme
dca 16384 1 igb
wmi 32768 1 wmi_bmof
video 49152 0
and here is the aplay -L output:
default
Playback/recording through the PulseAudio sound server
surround21
2.1 Surround output to Front and Subwoofer speakers
surround40
4.0 Surround output to Front and Rear speakers
surround41
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50
5.0 Surround output to Front, Center and Rear speakers
surround51
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
null
Discard all samples (playback) or generate zero samples (capture)
samplerate
Rate Converter Plugin Using Samplerate Library
speexrate
Rate Converter Plugin Using Speex Resampler
jack
JACK Audio Connection Kit
oss
Open Sound System
pulse
PulseAudio Sound Server
upmix
Plugin for channel upmix (4,6,8)
vdownmix
Plugin for channel downmix (stereo) with a simple spacialization
hdmi:CARD=Generic,DEV=0
HD-Audio Generic, HDMI 0
HDMI Audio Output
hdmi:CARD=Generic,DEV=1
HD-Audio Generic, HDMI 1
HDMI Audio Output
hdmi:CARD=Generic,DEV=2
HD-Audio Generic, HDMI 2
HDMI Audio Output
dmix:CARD=Generic,DEV=3
HD-Audio Generic, HDMI 0
Direct sample mixing device
dmix:CARD=Generic,DEV=7
HD-Audio Generic, HDMI 1
Direct sample mixing device
dmix:CARD=Generic,DEV=8
HD-Audio Generic, HDMI 2
Direct sample mixing device
dsnoop:CARD=Generic,DEV=3
HD-Audio Generic, HDMI 0
Direct sample snooping device
dsnoop:CARD=Generic,DEV=7
HD-Audio Generic, HDMI 1
Direct sample snooping device
dsnoop:CARD=Generic,DEV=8
HD-Audio Generic, HDMI 2
Direct sample snooping device
hw:CARD=Generic,DEV=3
HD-Audio Generic, HDMI 0
Direct hardware device without any conversions
hw:CARD=Generic,DEV=7
HD-Audio Generic, HDMI 1
Direct hardware device without any conversions
hw:CARD=Generic,DEV=8
HD-Audio Generic, HDMI 2
Direct hardware device without any conversions
plughw:CARD=Generic,DEV=3
HD-Audio Generic, HDMI 0
Hardware device with all software conversions
plughw:CARD=Generic,DEV=7
HD-Audio Generic, HDMI 1
Hardware device with all software conversions
plughw:CARD=Generic,DEV=8
HD-Audio Generic, HDMI 2
Hardware device with all software conversions
usbstream:CARD=Generic
HD-Audio Generic
USB Stream Output
sysdefault:CARD=Generic_1
HD-Audio Generic, ALC1220 Analog
Default Audio Device
front:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
Front speakers
surround21:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
dmix:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
Direct sample mixing device
dsnoop:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
Direct sample snooping device
hw:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
Direct hardware device without any conversions
plughw:CARD=Generic_1,DEV=0
HD-Audio Generic, ALC1220 Analog
Hardware device with all software conversions
usbstream:CARD=Generic_1
HD-Audio Generic
USB Stream Output
I'm trying to set communication between esp32 (master) and stm32 (slave) over SPI. esp32 is running under micropython and sends four bytes, for example
spi.write_readinto(b'\x31\x32\x33\x34', buf)
stm32' code is here (instead of this i use SPI_InitDef.SPI_NSS = SPI_NSS_Soft;)
void SPI_Init(void) {
...
// initialize SPI slave
// for slave, no need to define SPI_BaudRatePrescaler
SPI_InitDef.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitDef.SPI_Mode = SPI_Mode_Slave;
SPI_InitDef.SPI_DataSize = SPI_DataSize_8b; // 8-bit transactions
SPI_InitDef.SPI_FirstBit = SPI_FirstBit_MSB; // MSB first
SPI_InitDef.SPI_CPOL = SPI_CPOL_Low; // CPOL = 0, clock idle low
SPI_InitDef.SPI_CPHA = SPI_CPHA_2Edge; // CPHA = 1
SPI_InitDef.SPI_NSS = SPI_NSS_Hard; // use hardware SS
SPI_InitDef.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; // APB2 72/64 = 1.125 MHz
SPI_InitDef.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitDef);
SPI_Cmd(SPI1, ENABLE);
NVIC_EnableIRQ(SPI1_IRQn);
//Тут мы разрешаем прерывание по приему
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
}
void main() {
/* Setup SysTick Timer for 10ms interrupts */
if (SysTick_Config(SystemCoreClock / 100))
{
/* Capture error */
while (1);
}
/* Configure the SysTick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x0);
SPI_Init();
while(1) {
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
for (u8 i=0; i<4; i++) {
printf("0x%02x ", SPI_I2S_ReceiveData(SPI1));
}
printf("\r\n");
}
}
But when I send four bytes 0x31 0x32 0x33 0x34 (analyzer confirms bytes were sent) and my stm gets only 0x31 0x32 0x31 0x32
UPD
I use std periph library and SPI_I2S_ReceiveData is a native method to read byte from SPI.
uint16_t SPI_I2S_ReceiveData ( SPI_TypeDef * SPIx )
Returns the most recent received data by the SPIx/I2Sx peripheral.
Parameters:
SPIx,: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
Return values:
The value of the received data.
uint16_t SPI_I2S_ReceiveData ( SPI_TypeDef * SPIx )
Returns the most recent received data by the SPIx/I2Sx peripheral.
Parameters:
SPIx,: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.
Return values:
The value of the received data.
But maybe I exit out from IRQ before all data are read. I found to run the while loop until the transmission of the last byte is complete
I think the following code is not correct (but I don't know what the function SPI_I2S_ReceiveData is doing):
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
for (u8 i=0; i<4; i++) {
printf("0x%02x ", SPI_I2S_ReceiveData(SPI1));
}
You exit from the while as soon as one byte is ready to be read. I assume SPI_I2S_ReceiveData is only reading the SPI FIFO. in that case you try to read 4 bytes when possibly only one or two has been received.
You didn't precise the kind of STM32 you're using so I am describing the SPI of STM32H7 (as far as I know it should be pretty similar in other STM32).
To setup a reception in slave mode you should define in particular these 3 parameters:
the length of the socalled "frame" (number of bytes to be read/written at once). This is the field SPI_DataSize` in the HAL data structure, here 8 bits.
the number of transfer (TSIZE) which specifies when the End Of Transmission event is generated. It is expressed in number of "frames". This parameter must be set through register SPI.CR2 before each reception (provided you know the number of bytes to be received of course).
the "FIFO threshold". It specifies at which frequency an event RXP or TXP is generated. You can change this parameter to decrease the workload on the software but to receive only 4 bytes it has no impact.
In your case I think you should setup a transfer size of 4 (4 bytes) and wait for EOT flag to be set. When it is set you only have to read 4 bytes from SPI Receive Register (you can read all 4 bytes at once by the way).
I suggest you do not use the HAL but write your own SPI reception / transmission routines by reading / writing registers. It is not a very complex peripheral (so it will not cost you a lot of time) and you will understand precisely how it works (instead of digging into the HAL).
I use a IPv6 UDP socket connection in my code. The execution fails, because the device does not exist.
strerror(errno)
responded with
No such device
I use a link local address.
Server
fe80::213:afff:fe94:d75
Client
fe80::f2d5:bfff:fe10:f1b1
I got the scope_id by ifconfig:
bt0: flags=4177<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
inet6 fe80::f2d5:bfff:fe10:f1b1 prefixlen 64 scopeid 0x20<link>
unspec F0-D5-BF-FF-FE-10-F1-B1-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
RX packets 3 bytes 84 (84.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 370 (370.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Since another interface has the same scope_id, I guess the scope_id means here the IPv6 scope. 0x20 = link_local.
enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.4 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::fb58:43b9:10fa:101 prefixlen 64 scopeid 0x20<link>
inet6 2a02:8109:b6bf:ca24:ae7f:b967:932e:b2f4 prefixlen 64 scopeid 0x0<global>
inet6 2a02:8109:b6bf:ca24:51f:6c37:66c4:5282 prefixlen 64 scopeid 0x0<global>
ether c8:5b:76:98:55:bf txqueuelen 1000 (Ethernet)
RX packets 16413820 bytes 20299047086 (20.2 GB)
RX errors 18 dropped 0 overruns 0 frame 16
TX packets 6110718 bytes 714537636 (714.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 16 memory 0xf1200000-f1220000
So, I used this scope_id in my code:
#define CLIENT_ADDRESS { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0xd5, 0xbf, 0xff, 0xfe, 0x10, 0xf1, 0xb1 };
struct sockaddr_in6 client_addr;
unsigned int client_addr_len = sizeof(client_addr);
memset(&client_addr, 0, client_addr_len);
client_addr.sin6_family = AF_INET6;
client_addr.sin6_port = htons(PORT);
client_addr.sin6_scope_id = 0x20;
uint8_t address[16] = CLIENT_ADDRESS;
memcpy(&client_addr.sin6_addr, address, 16);
This is not the correct interface.
So my question: Where can I find the correct scope_id for my interface?
Is there some linux tool to get it?
Maybe if_nametoindex() is what you are looking for:
client_addr.sin6_scope_id = if_nametoindex("tun0");
More information of if_nametoindex in man page.
Okay, I got it. The scope_id in sockaddr_in6 is the interface ID. You can find the interface ID with
ip link show
I have trouble to get second chip select working on the Beaglebone Black.
I used the .dts given in /lib/firmware with my distribution (Angstrom, kernel 3.8.13) :
/*
* Copyright (C) 2013 CircuitCo
*
* Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "BB-SPI1-01";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P9.31", /* spi1_sclk */
"P9.29", /* spi1_d0 */
"P9.30", /* spi1_d1 */
"P9.28", /* spi1_cs0 */
"P9.42", /* spi1_cs1 */
/* the hardware ip uses */
"spi1";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
/* default state has all gpios released and mode set to uart1 */
bb_spi1_pins: pinmux_bb_spi1_pins {
pinctrl-single,pins = <
0x190 0x13 /* mcasp0_aclkx.spi1_sclk, OUTPUT_PULLUP | MODE3 */
0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
0x164 0x12 /* eCAP0_in_PWM0_out.spi1_cs1 OUTPUT_PULLUP | MODE2 */
>;
};
};
};
fragment#1 {
target = <&spi1>; /* spi1 is numbered correctly */
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bb_spi1_pins>;
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio4 17 0>, <&gpio1 7 0>;
spi1_0{
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <0>;
spi-max-frequency = <16000000>;
};
spi1_1{
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <1>;
spi-max-frequency = <16000000>;
};
};
};
};
I compiled it with dtc and activate it with uEnv.txt :
capemgr.enable_partno=BB-SPI1-01
(Both HDMI and HDMIN capes are disabled)
I have the twos SPI device shown in /dev/ :
/dev/spidev2.0 /dev/spidev2.1
and the pins are used by the spi interface as shown :
root#beaglebone:~# cat $PINS | grep spi1
pin 89 (44e10964): 481a0000.spi (GPIO UNCLAIMED) function pinmux_bb_spi1_pins group pinmux_bb_spi1_pins
pin 100 (44e10990): 481a0000.spi (GPIO UNCLAIMED) function pinmux_bb_spi1_pins group pinmux_bb_spi1_pins
pin 101 (44e10994): 481a0000.spi (GPIO UNCLAIMED) function pinmux_bb_spi1_pins group pinmux_bb_spi1_pins
pin 102 (44e10998): 481a0000.spi (GPIO UNCLAIMED) function pinmux_bb_spi1_pins group pinmux_bb_spi1_pins
pin 103 (44e1099c): 481a0000.spi (GPIO UNCLAIMED) function pinmux_bb_spi1_pins group pinmux_bb_spi1_pins
And the mode is good :
pin 89 (44e10964) 00000012 pinctrl-single
pin 100 (44e10990) 00000013 pinctrl-single
pin 101 (44e10994) 00000033 pinctrl-single
pin 102 (44e10998) 00000013 pinctrl-single
pin 103 (44e1099c) 00000013 pinctrl-single
I successfully use a programm in C which use the first spidev (spidev2.0) with the first chip select, but the there are nothing on pin 42 when I use spidev2.1 (MOSI,MISO and CLK are working though).
Any ideas ?
Thanks in advance
Well I found out the answer myself :
The pin 42 is special since it's connected to two I/O. So in order to use one of the I/O, you have to put the other one as input.
source : Beaglebone black system reference manual http://www.digikey.com/web%20export/supplier%20content/ti_296/mkt/boards/BBB_SRM.pdf?redirected=1 page 71.
But now i have an other issue really strange... I posted it here : Trouble with SPIDEV, device tree and .dtbo name with Beaglebone Black
I'm working with the NXP LPC1788 microcontroller and I'm trying to create a driver on the host computer to communicate with it via USB. I believe that I've managed to get the device handling standard USB requests properly (the PC is able to read the string descriptors properly).
I'm having trouble writing a sample USB driver and installing it for the device, though. I'm working with Microsoft Visual Studio 2013. My steps were:
Creating a WinUSB Application, which produces a "Driver" and "Driver Package" project.
Modifying the generated INF file to use my device's VID and PID.
Building the projects - both build successfully. The output folder contains an INF file, a catalog file and WdfCoinstaller01011.dll.
Plugging in the microcontroller via USB, going to Device Manager → Update Driver Software..., browsing to the folder containing the INF file and selecting it.
This causes the following screen to appear:
I select "Install this driver software anyway". After a short while, it presents this screen:
My INF file is given below:
;
; TestCubeDriver.inf
;
; Installs WinUsb
;
[Version]
Signature = "$Windows NT$"
Class = USBDevice
ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
CatalogFile=TestCubeDriver.cat
DriverVer=04/16/2014,15.55.4.44
; ========== Manufacturer/Models sections ===========
[Manufacturer]
%ManufacturerName% = Standard,NTamd64
[Standard.NTamd64]
%DeviceName% =USB_Install, USB\VID_0483&PID_5720
; ========== Class definition ===========
[ClassInstall32]
AddReg = ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2
; =================== Installation ===================
[USB_Install]
Include=winusb.inf
Needs=WINUSB.NT
[USB_Install.Services]
Include=winusb.inf
AddService=WinUsb,0x00000002,WinUsb_ServiceInstall
[WinUsb_ServiceInstall]
DisplayName = %WinUsb_SvcDesc%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\WinUSB.sys
[USB_Install.HW]
AddReg=Dev_AddReg
[Dev_AddReg]
; By default, USBDevice class uses iProduct descriptor to name the device in
; Device Manager on Windows 8 and higher.
; Uncomment for this device to use %DeviceName% on Windows 8 and higher:
;HKR,,FriendlyName,,%DeviceName%
HKR,,DeviceInterfaceGUIDs,0x10000,"{fcb251a5-6a1f-4e5b-9df8-e8de91d04cfe}"
[USB_Install.CoInstallers]
AddReg=CoInstallers_AddReg
CopyFiles=CoInstallers_CopyFiles
[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller"
[CoInstallers_CopyFiles]
WdfCoInstaller01011.dll
[DestinationDirs]
CoInstallers_CopyFiles=11
; ================= Source Media Section =====================
[SourceDisksNames]
1 = %DiskName%
[SourceDisksFiles]
WdfCoInstaller01011.dll=1
; =================== Strings ===================
[Strings]
ManufacturerName=""
ClassName="Universal Serial Bus devices"
DiskName="TestCubeDriver Installation Disk"
WinUsb_SvcDesc="WinUSB Driver"
DeviceName="TestCubeDriver Device"
REG_MULTI_SZ = 0x00010000
.
The relevant part of my setupapi.dev.log file is given here. The following kind of lines appeared multiple times in the log:
sig: Key = testcubedriver.inf
sig: FilePath = C:\Windows\System32\DriverStore\Temp\{1bf7c0e3-30cb-6135-d9b8-7d1ac87a6c7c}\testcubedriver.inf
sig: Catalog = C:\Windows\System32\DriverStore\Temp\{1bf7c0e3-30cb-6135-d9b8-7d1ac87a6c7c}\TestCubeDriver.cat
! sig: Verifying file against specific (valid) catalog failed! (0x800b0109)
! sig: Error 0x800b0109: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
The following also appeared:
ndv: Installing device...
dvi: {DIF_INSTALLDEVICE} 09:58:11.087
dvi: No class installer for 'TestCubeDriver Device'
dvi: CoInstaller 1: Enter 09:58:11.087
inf: Opened PNF: 'C:\Windows\INF\oem68.inf' ([strings])
!!! dvi: CoInstaller 1: failed(0xe0000101)!
!!! dvi: Error 0xe0000101: The required section was not found in the INF.
dvi: {DIF_INSTALLDEVICE - exit(0xe0000101)} 09:58:11.907
!!! ndv: Error(e0000101) installing device!
.
I use the following descriptors for my USB device:
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: USBDESC.C
* Purpose: USB Descriptors
* Version: V1.10
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC family microcontroller devices only. Nothing
* else gives you the right to use this software.
*
* Copyright (c) 2005-2009 Keil Software.
*---------------------------------------------------------------------------*/
#include "lpc_types.h"
#include "usb.h"
#include "usbcore.h"
#include "usbhw.h"
/* USB Standard Device Descriptor */
const uint8_t USB_DeviceDescriptor[] = {
USB_DEVICE_DESC_SIZE, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(0x0200), /* 2.00 */ /* bcdUSB */
0xFF, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
USB_MAX_PACKET_SIZE, /* bMaxPacketSize0 */
WBVAL(0x0483), /* idVendor */
WBVAL(0x5720), /* idProduct */
WBVAL(0x0100), /* 1.00 */ /* bcdDevice */
0x04, /* iManufacturer */
0x30, /* iProduct */
0x42, /* iSerialNumber */
0x01 /* bNumConfigurations */
};
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t USB_ConfigDescriptor[] = {
/* Configuration 1 */
USB_CONFIGURATION_DESC_SIZE, /* bDescriptorType */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL( /* wTotalLength */
1*USB_CONFIGURATION_DESC_SIZE +
1*USB_INTERFACE_DESC_SIZE +
2*USB_ENDPOINT_DESC_SIZE
),
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
USB_CONFIG_SELF_POWERED /*|*/ /* bmAttributes */
/*USB_CONFIG_REMOTE_WAKEUP*/,
USB_CONFIG_POWER_MA(100), /* bMaxPower */
/* Interface 0, Alternate Setting 0, MSC Class */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0xFF, /* bInterfaceClass */
0x0, /* bInterfaceSubClass */
0x0, /* bInterfaceProtocol */
0x5C, /* iInterface */
/* Interrupt In Endpoint */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(2), /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0040), /* wMaxPacketSize */
0xA, /* bInterval */
/* Interrupt Out Endpoint */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_OUT(2), /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0040), /* wMaxPacketSize */
0xA, /* bInterval */
/* Terminator */
0 /* bLength */
};
/* USB String Descriptor (optional) */
const uint8_t USB_StringDescriptor[] = {
/* Index 0x00: LANGID Codes */
0x04, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(0x0409), /* US English */ /* wLANGID */
/* Index 0x04: Manufacturer */
0x2C, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'A',0,
'T',0,
'P',0,
' ',0,
'I',0,
'n',0,
'd',0,
'u',0,
's',0,
't',0,
'r',0,
'i',0,
'e',0,
's',0,
' ',0,
'G',0,
'r',0,
'o',0,
'u',0,
'p',0,
' ',0,
/* Index 0x30: Product */
0x12, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'T',0,
'e',0,
's',0,
't',0,
'C',0,
'u',0,
'b',0,
'e',0,
' ',0,
/* Index 0x42: Serial Number */
0x1A, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'D',0,
'E',0,
'M',0,
'O',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
/* Index 0x5C: Interface 0, Alternate Setting 0 */
0x0E, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'M',0,
'e',0,
'm',0,
'o',0,
'r',0,
'y',0,
};
I tried out the INF template that Daniel K suggested here with my own configurations:
;This .inf file is a modified version of the example INF provided
;in the Microsoft document:
;"How to Use WinUSB to Communicate with a USB Device"
[Version]
Signature = "$Windows NT$"
Class = USBDevices
ClassGuid= {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %MFGNAME%
DriverVer=04/17/2014,1.0.0.0
CatalogFile=winusb.cat ;CAT file needed for a signed driver pacakage
;------------------------------------------------------------------------------
; ========== Manufacturer/Models sections ===========
;------------------------------------------------------------------------------
[Manufacturer]
%MFGNAME% = MyDevice_WinUSB,NTx86,NTamd64
;------------------------------------------------------------------------------
; Vendor and Product ID Definitions
;------------------------------------------------------------------------------
; When developing your custom USB device, the VID and PID used in the PC side
; application program and the firmware on the microcontroller must match.
; Modify the below lines to use your VID and PID. Use the format as shown below.
; Note: One INF file can be used for multiple devices with different VID and PIDs.
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
; There is a maximum number of devices that can be supported per line however.
; If you append a large number of VID/PIDs to the end of the line, and get a:
; "The data area passed to a system call is too small." error when trying to install
; the INF, try removing some of the VIDs/PIDs.
;------------------------------------------------------------------------------
[MyDevice_WinUSB.NTx86]
%DESCRIPTION% =USB_Install, USB\VID_0483&PID_5720
[MyDevice_WinUSB.NTamd64]
%DESCRIPTION% =USB_Install, USB\VID_0483&PID_5720
;=========================================================================================
;ClassInstall32 and ClassInstall_AddReg sections used to make new device manager category.
;=========================================================================================
[ClassInstall32]
AddReg=ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,,%DEVICEMANAGERCATEGORY%
HKR,,Icon,,"-20"
; =================== Installation ===================
[USB_Install]
Include=winusb.inf
Needs=WINUSB.NT
[USB_Install.Services]
Include=winusb.inf
AddService=WinUSB,0x00000002,WinUSB_ServiceInstall
[WinUSB_ServiceInstall]
DisplayName = %WinUSB_SvcDesc%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\WinUSB.sys
[USB_Install.Wdf]
KmdfService=WINUSB, WinUsb_Install
[WinUSB_Install]
KmdfLibraryVersion=1.11
[USB_Install.HW]
AddReg=Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{fcb251a5-6a1f-4e5b-9df8-e8de91d04cfe}"
;When editing the GUID (the big hex number with dashes inside the squiggly
;braces), make sure to write the intended PC application to use the same GUID.
;Otherwise the application won't be able to find the USB device properly.
[USB_Install.CoInstallers]
AddReg=CoInstallers_AddReg
CopyFiles=CoInstallers_CopyFiles
[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller",
[CoInstallers_CopyFiles]
;WinUSBCoInstaller2.dll
WdfCoInstaller01011.dll
[DestinationDirs]
CoInstallers_CopyFiles=11
; ================= Source Media Section =====================
[SourceDisksNames]
1 = %DISK_NAME%
[SourceDisksFiles]
WdfCoInstaller01011.dll=1
; =================== Strings ===================
[Strings]
MFGNAME="ATP Industries Group" ; ManufacturerName
DESCRIPTION="TestCube" ; DeviceName
WinUSB_SvcDesc="WinUSB Device"
DISK_NAME="TestCubeDriver Installation Disk" ; DiskName
DEVICEMANAGERCATEGORY="Universal Serial Bus devices" ; ClassName
My device driver installed successfully and Device Manager reports that the device is working properly. I tried running my application and it's able to find my device and retrieve details about it. It all works now, and I can finally start working on the application-side of things.
Edit: Even though it's all working now, I have no idea what was wrong with the original template - could anyone please explain to me why the second template works and not the first?
You're running 32-bit Windows, right? One reason the original file wouldn't work for you because it doesn't have a section for 32-bit drivers, it only has an NTamd64 section.
From the original file:
[Standard.NTamd64]
%DeviceName% =USB_Install, USB\VID_0483&PID_5720
From the new file, where MyDevice_WinUSB is analogous to Standard:
[MyDevice_WinUSB.NTx86]
%DESCRIPTION% =USB_Install, USB\VID_0483&PID_5720
[MyDevice_WinUSB.NTamd64]
%DESCRIPTION% =USB_Install, USB\VID_0483&PID_5720
The new file has an extra section that your old file didn't have.