Problem with Bluetooth in Dell Precision M4600
No connection neither from Linux nor Windows 7. The point is everything worked properly some time ago. Now Bluetooth seems to work and find devices, but after connection attempt it is broken instantly.
'hciconfig' shows device properly and from 'bluetoothctl', command 'paired-devices' shows devices properly.
Then using 'connect <dev>' everything worked again.
niedziela, 18 stycznia 2015
sobota, 1 listopada 2014
Fundamental types initialization
Consider something as complicated as:
the problem is value of member 'f'.
Structure A is of course POD therefore rules for member initialization can be really tricky.
Differences comes from three sources:
- way of initalization,
- C++ standard version,
- compiler vendor.
Possible ways of initialization are:
Note two things:
- it is impossible to use second case directly i.e.:
To use second initialization method, syntax can be:
Initialization of fundamental type variables and PODs is subject of constant changes and obscurity between C++ standards.
In C++98 initialization of non-POD object without constructor (e.g. struct with desctructor only or inherited) does not initialize fundamental type fields to 0 (but as it is visible below it is not truth for current compilers).
This was changed in C++03.
Also compilers can introduce surprising behaviours. VSC++ (before version 2013) was famous of not initializing PODs with A() syntax (still visible for some cases).
Below are test results of initialization results for different types and compilers.
Cases are
Compilers used
1. fundamental type
2. simplest POD struct
3. simplest non-POD struct (destructor added)
4. non-POD struct with field default initialization in constructor
5. non-POD struct without field initialization in constructor
6. non-POD struct with inheritance and no constructors
7. non-POD struct with inheritance and field default initialization in base class constructor
8. non-POD struct with inheritance and field default initialization in derived class constructor
Legend
And what lesson comes form data above - to be really sure field is initialized, you have to explicitly use initialization construct for the field (in constructor initialization list).
Test application available for downlowad here. Please note placement new used to avoid false 0-positive answers. For stack allocated items it is not that easy - there is try with recursive function (to pollute stack with non 0 values) but it is not always enough (false 0 answers can happen).
Note that in VSC++2013 "__cplusplus" is defined as 199711 (like for C++98 standard) but compiler allows for C++11 usage (perhaps not complete and therefore "__cplusplus" is not defined as 201103).
struct A
{
int f;
};
the problem is value of member 'f'.
Structure A is of course POD therefore rules for member initialization can be really tricky.
Differences comes from three sources:
- way of initalization,
- C++ standard version,
- compiler vendor.
Possible ways of initialization are:
A;
A();
A{};
which should be same to version with dynamic allocation:new A;
new A();
new A{};
Note two things:
- it is impossible to use second case directly i.e.:
A a();because in C++ this is function declaration (declaration can appear also inside function body).
To use second initialization method, syntax can be:
A a = A();- third way of initialization is from C++11 and allows for:
A a{};
Initialization of fundamental type variables and PODs is subject of constant changes and obscurity between C++ standards.
In C++98 initialization of non-POD object without constructor (e.g. struct with desctructor only or inherited) does not initialize fundamental type fields to 0 (but as it is visible below it is not truth for current compilers).
This was changed in C++03.
Also compilers can introduce surprising behaviours. VSC++ (before version 2013) was famous of not initializing PODs with A() syntax (still visible for some cases).
Below are test results of initialization results for different types and compilers.
Cases are
- fundamental type,
- simplest POD struct,
- simplest non-POD struct (destructor added),
- non-POD struct with field default initialization in constructor,
- non-POD struct without field initialization in constructor,
- non-POD struct with inheritance and no constructors,
- non-POD struct with inheritance and field default initialization in base class constructor,
- non-POD struct with inheritance and field default initialization in derived class constructor.
Compilers used
- gcc 4.8.2
- clang 3.3
- VisualStudio C++ 2013
1. fundamental type
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| int a; | - | - | - | - | - | - | - |
| int a = int(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| int a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| int *a = new int; | - | - | - | - | - | - | - |
| int *a = new int(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| int *a = new int{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
2. simplest POD struct
struct A
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
3. simplest non-POD struct (destructor added)
struct A
{
~A() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | - |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | - |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
4. non-POD struct with field default initialization in constructor
struct A
{
A() : f() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
5. non-POD struct without field initialization in constructor
struct A
{
A() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | - | - | - | - | - | - | - |
| A a{}; | - | n.a. | n.a. | - | n.a. | n.a. | - |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | - | - | - | - | - | - | - |
| A *a = new A{}; | - | n.a. | n.a. | - | n.a. | n.a. | - |
6. non-POD struct with inheritance and no constructors
struct P
{
int g;
};
struct A : public P
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- |
| A a = A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:- |
| A a{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:- |
| A *a = new A; | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- |
| A *a = new A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 |
| A *a = new A{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:- |
7. non-POD struct with inheritance and field default initialization in base class constructor
struct P
{
P() : g() {}
int g;
};
struct A : public P
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 |
| A a = A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:0 |
| A a{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:0 |
| A *a = new A; | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 |
| A *a = new A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:0 |
| A *a = new A{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:0 |
8. non-POD struct with inheritance and field default initialization in derived class constructor
struct P
{
int g;
};
struct A : public P
{
A() : f() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A a = A(); | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A a{}; | f:0, g:- | n.a. | n.a. | f:0, g:- | n.a. | n.a. | f:0, g:- |
| A *a = new A; | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A *a = new A(); | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A *a = new A{}; | f:0, g:- | n.a. | n.a. | f:0, g:- | n.a. | n.a. | f:0, g:- |
Legend
- "0" - initialized to 0
- "-" - not initialized
- "n.a." - available only in C++11
And what lesson comes form data above - to be really sure field is initialized, you have to explicitly use initialization construct for the field (in constructor initialization list).
Test application available for downlowad here. Please note placement new used to avoid false 0-positive answers. For stack allocated items it is not that easy - there is try with recursive function (to pollute stack with non 0 values) but it is not always enough (false 0 answers can happen).
Note that in VSC++2013 "__cplusplus" is defined as 199711 (like for C++98 standard) but compiler allows for C++11 usage (perhaps not complete and therefore "__cplusplus" is not defined as 201103).
wtorek, 19 sierpnia 2014
Acoustics absorption calculation (impedance tube)
Here is bunch of equations to calculate acoustic absorption coefficient according to transfer function method (ISO 10534-2:1998).
Absorption coefficient as function of frequency can be calculated from pressure reflection factor with:
Reflection factor is calculated from calculation (corrected) transfer function:
where 's' is microphones' spacing, 'x1' is distance form specimen to closer microphone and 'k0' is wave number.
Calculation (corrected) transfer function comes from:
Correction transfer function is obtained from:
and calculated as:
Please note that absorption coefficient calculation does not really need 'x1' distance to be known.
This is visible when following substitution is used in equation for reflection factor:
Then square of absolute value is given as (which is free from 'x1'):
Taking above into account ready to use equation can be derived:
taking following into account:
can be simplified to:
where:
Note that calculations are a bit simpler using polar representation for complex numbers.
Absorption coefficient as function of frequency can be calculated from pressure reflection factor with:
Reflection factor is calculated from calculation (corrected) transfer function:
where 's' is microphones' spacing, 'x1' is distance form specimen to closer microphone and 'k0' is wave number.
Calculation (corrected) transfer function comes from:
Correction transfer function is obtained from:
and calculated as:
Please note that absorption coefficient calculation does not really need 'x1' distance to be known.
This is visible when following substitution is used in equation for reflection factor:
Then square of absolute value is given as (which is free from 'x1'):
Taking above into account ready to use equation can be derived:
taking following into account:
can be simplified to:
where:
Note that calculations are a bit simpler using polar representation for complex numbers.
niedziela, 3 sierpnia 2014
Real time (stream) acquisition with ADS1278 and MMB0 (ADS1278EVM-PDK)
MMB0 with ADS1278 board is perfect tool to start adventure with DSP programming, especially in A/D conversion context.
Solution presented below is development of first Linux approach presented here.
ADS1278EVM-PDK is delivered with ready to use Windows software called ADCPro which is post processing tool for data gathered. The tool is build using LabVIEW environment and allows for basic estimation of A/D converter features and performance.
Main weakness of ADCPro (which is of course out of its original purpose) is lack of data streaming handling. Data acquisition is realized within MMB0 using its 16MB SDRAM memory. After acquisition is finished, data is transferred to PC for further analysis and presentation. This of course limits length of data that can be acquired in single measurement.
It is tempting idea to create alternative software to provide data streaming from MMB0 functionality. Obvious limitation here is USB 1.1 used in TMS320VC5509A which drives MMB0 (Rev.D in my case).
For USB 1.1 bandwidth is practically limited to about 1MB/s, which does not allow for all 8 channels utilisation with high sample rate. But this limitation makes the problem even more attractive - try to get all possible performance from MMB0 and check limits of USB 1.1.
Prepared solution contains two parts: firmware for MMB0 prepared with free Linux version of CCS and simple PC (Linux) app for control and data acquisition.
In order to limit usage of precious bandwidth data samples transferred to PC are 24-bit length (1/4 less than original 32-bit samples). As 24-bit is native resolution of ADS1278 therefore this has no impact on measurement precision (no real downsampling).
Also transfers are performed using maximal possible buffer size for BULK transfers (close to TMS320VC5509A's limit 64kB) which gives maximal performance.
As MMB0 has 16MB of SDRAM memory it gives additional advantage when handling short time gathering even for sampling rates out of USB 1.1 transfer possibilities.
SDRAM used as cyclic buffer stores data before transfer and in case of overflow acquisition is stopped, but gathered data can be transferred to PC. Please also note that due to transfer being parallel to acquisition real acquisition length is more than SDRAM size (some data is transferred and additional acquisitions can be stored before overflow takes place).
As SDRAM buffer usage is critical parameter for application performance, MMB0's led segment is used to present digit which represents decimals of buffer usage (and letter 'o' in case of overflow).
To gather data transferred using USB interface, simple app was developed. The app handles start and stop commands and stores gathered data to a file.
Application parameters allows for easy setup i.e. to specify cpu clock (via APLL divider and multiplier), 5509 output clock divider, also settings for external PLL (for ADS1278 clock) shall be specified (multiplier and dividers). The settings allows for arbitrary sample rate selection.
Beside clocks ADS operating settings shall be specified i.e. CLKDIV 1 or 0 and mode (highspeed, highresolution, lowpower or lowspeed).
Here are results obtained for maximal transfer rates for each mode (acquisition time before overflow occurs)
Generally maximal sampling which can be performed without overflow (or with overflow after long time) is about 45kSPS (for 8 channels).
Please note that other devices connected to USB host may influence bandwidth for transfer. Also I have noticed with my computer that USB 2.0 host has better max throughput for USB 1.1 connection than USB 3.0 host.
TODO list:
Solution presented below is development of first Linux approach presented here.
ADS1278EVM-PDK is delivered with ready to use Windows software called ADCPro which is post processing tool for data gathered. The tool is build using LabVIEW environment and allows for basic estimation of A/D converter features and performance.
Main weakness of ADCPro (which is of course out of its original purpose) is lack of data streaming handling. Data acquisition is realized within MMB0 using its 16MB SDRAM memory. After acquisition is finished, data is transferred to PC for further analysis and presentation. This of course limits length of data that can be acquired in single measurement.
It is tempting idea to create alternative software to provide data streaming from MMB0 functionality. Obvious limitation here is USB 1.1 used in TMS320VC5509A which drives MMB0 (Rev.D in my case).
For USB 1.1 bandwidth is practically limited to about 1MB/s, which does not allow for all 8 channels utilisation with high sample rate. But this limitation makes the problem even more attractive - try to get all possible performance from MMB0 and check limits of USB 1.1.
Prepared solution contains two parts: firmware for MMB0 prepared with free Linux version of CCS and simple PC (Linux) app for control and data acquisition.
In order to limit usage of precious bandwidth data samples transferred to PC are 24-bit length (1/4 less than original 32-bit samples). As 24-bit is native resolution of ADS1278 therefore this has no impact on measurement precision (no real downsampling).
Also transfers are performed using maximal possible buffer size for BULK transfers (close to TMS320VC5509A's limit 64kB) which gives maximal performance.
As MMB0 has 16MB of SDRAM memory it gives additional advantage when handling short time gathering even for sampling rates out of USB 1.1 transfer possibilities.
SDRAM used as cyclic buffer stores data before transfer and in case of overflow acquisition is stopped, but gathered data can be transferred to PC. Please also note that due to transfer being parallel to acquisition real acquisition length is more than SDRAM size (some data is transferred and additional acquisitions can be stored before overflow takes place).
As SDRAM buffer usage is critical parameter for application performance, MMB0's led segment is used to present digit which represents decimals of buffer usage (and letter 'o' in case of overflow).
To gather data transferred using USB interface, simple app was developed. The app handles start and stop commands and stores gathered data to a file.
Application parameters allows for easy setup i.e. to specify cpu clock (via APLL divider and multiplier), 5509 output clock divider, also settings for external PLL (for ADS1278 clock) shall be specified (multiplier and dividers). The settings allows for arbitrary sample rate selection.
Beside clocks ADS operating settings shall be specified i.e. CLKDIV 1 or 0 and mode (highspeed, highresolution, lowpower or lowspeed).
Here are results obtained for maximal transfer rates for each mode (acquisition time before overflow occurs)
- High-speed mode, 8ch, 144500 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 2), ADS f_clk=36.992 MHz (p: 289, q: 75, post: 10)
max acquisition time ~6.5 sec, acquired 22866480 bytes (in 21.8 sec)
- High-resolution mode, 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
max acquisition time ~70 sec, acquired 89107200 bytes (in 85.7 sec)
- Low-power mode (CLKDIV = 1), 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
max acquisition time ~63 sec, acquired79541280 bytes (in 78.6 sec)
- Low-power mode (CLKDIV = 0), 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=13.4976 MHz (p: 703, q: 100, post: 25)
max acquisition time ~63 sec, acquired 79541280 bytes (in 78.5 sec)
- Low-speed mode (CLKDIV = 1), 8ch, 10545 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
no overflow occurred, continuous streaming possible, average transfer rate ~250kB/s
- Low-speed mode (CLKDIV = 0), 8ch, 10545 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=5.39904 MHz (p: 703, q: 125, post: 50)
no overflow occurred, continuous streaming possible, average transfer rate ~250kB/s
Generally maximal sampling which can be performed without overflow (or with overflow after long time) is about 45kSPS (for 8 channels).
Please note that other devices connected to USB host may influence bandwidth for transfer. Also I have noticed with my computer that USB 2.0 host has better max throughput for USB 1.1 connection than USB 3.0 host.
TODO list:
- Add downsampling to 16-bit option for further bandwidth save and higher sampling rates handling.
- Add possibility to limit number of (or select) channels transferred to have even more bandwidth saving.
- Implement as Linux (and Windows) driver.
Etykiety:
ADS1278,
ADS1278EVM-PDK,
MMB0,
real-time streaming
poniedziałek, 6 stycznia 2014
gcc link-time optimization
Link optimization can give impressive results (at least regarding executable size as presented below).
Here is output from simple program build. The program consists of 3 modules and 2 header files (6 functions in total).
Please note that compilation time and output code speed was not taken into account in simple example consideration above.
Also for sure example is far too simple to treat it as meaningful case, please treat it just as remark of LTO possibilities.
Here is output from simple program build. The program consists of 3 modules and 2 header files (6 functions in total).
- Normal compilation (and linking), no optimization 'gcc mod1.c mod2.c mod3.c -o test'
stripped executable size - 14480. - Normal compilation (and linking), optimized for size 'gcc mod1.c mod2.c mod3.c -o test -Os'
stripped executable size - 10384. - LTO compilation (and linking), no optimization 'gcc mod1.c mod2.c mod3.c -o test -flto'
stripped executable size - 10384. - LTO compilation (and linking), optimized for size 'gcc mod1.c mod2.c mod3.c -o test -flto -Os'
stripped executable size - 6288.
Please note that compilation time and output code speed was not taken into account in simple example consideration above.
Also for sure example is far too simple to treat it as meaningful case, please treat it just as remark of LTO possibilities.
References
poniedziałek, 11 listopada 2013
How to skip every n-th byte in binary file from Linux command
Here is solution to do it from shell using 'xxd' and 'sed'.
E.g. to copy every 4th byte from binary in_file to out_file:
E.g. to copy every 4th byte from binary in_file to out_file:
xxd -p -c4 in_file | sed 's/\(.\{6\}\)\(..\)/\2/g' | xxd -p -r >out_file
wtorek, 29 października 2013
ADS1278EVM-PDK in Linux
Please take into account that I do not take any responsibility for any damage caused through use of presented solution.
As TI does not support Linux for its evaluation module here is presented simple solution to trigger data acquisition from Linux command line.
First step in order to run under Linux firmware has to be loaded into MMB0 board.
Firmware exists in "ads1278.bin" file somewhere in "ProgramFiles\ADSPro\...".
According to documentation parameters necessary to communicate with MMB0 via USB are following:
VENDOR_ID = 0x0451
PRODUCT_ID = 0x9001
ENDPOINT_ADDR = 0x06
Endpoint is bulk type waiting for data from PC.
Here is simple app to load firmware from userspace.
Application uses libusb-1.0 library therefore can be build with e.g.:
g++ -I /usr/include/libusb-1.0/ -l usb-1.0 usbfirmwareload.cpp -o usbfirmwareload
To load firmware just run "usbfirmwareload" from folder where "ads1278.bin" is stored (to do that perhaps you should be root).
After firmware is successfully uploaded led segment shall show letter "S" (BTW it looks quite strange).
Next step is to perform communication with loaded software.
First thing to spot is change in USB configuration, now we have:
VENDOR_ID = 0x0451
PRODUCT_ID = 0x5718
As TI does not support Linux for its evaluation module here is presented simple solution to trigger data acquisition from Linux command line.
First step in order to run under Linux firmware has to be loaded into MMB0 board.
Firmware exists in "ads1278.bin" file somewhere in "ProgramFiles\ADSPro\...".
According to documentation parameters necessary to communicate with MMB0 via USB are following:
VENDOR_ID = 0x0451
PRODUCT_ID = 0x9001
ENDPOINT_ADDR = 0x06
Endpoint is bulk type waiting for data from PC.
Here is simple app to load firmware from userspace.
Application uses libusb-1.0 library therefore can be build with e.g.:
g++ -I /usr/include/libusb-1.0/ -l usb-1.0 usbfirmwareload.cpp -o usbfirmwareload
To load firmware just run "usbfirmwareload" from folder where "ads1278.bin" is stored (to do that perhaps you should be root).
After firmware is successfully uploaded led segment shall show letter "S" (BTW it looks quite strange).
Next step is to perform communication with loaded software.
First thing to spot is change in USB configuration, now we have:
VENDOR_ID = 0x0451
PRODUCT_ID = 0x5718
and two endpoints have appeared - for both data directions:
0x01 - output endpoint,
0x81 - input endpoint.
Communication protocol is build upon "cstyx" library which provides bunch of function that realizes communication as virtual filesystem. Library can be downloaded using SVN:
svn checkout svn://svn.berlios.de/cstyx
In following location archive with minimal version of the library necessary for communication is prepared. It also contains simple and dirty makefile to build the library.
With prepared library it is possible to send requests to MMB0 and receive data. Application to perform arbitrary operation in cstyx virtual filesystem is also available in archive file - please use makefile from "app" folder (after library is built in "cstyxminlib" folder).
Note that cstyx uses libusb and not libusb-1.0 library for USB communication therefore libusb is also required to be available in system.
Note that cstyx uses libusb and not libusb-1.0 library for USB communication therefore libusb is also required to be available in system.
With "adscomm" application it is easy to invoke operations on MMB0, e.g. to change digit in led segment to "8" following command can be used:
./adscomm -p "/mmb0/led/ch" -w 8
allowed params are:
- -p XXX - use path XXX in cstyx virtual filessytem,
- -w YYY- write YYY to file XXX specified with -p,
- -r - read from file XXX specified with -p,
- -f ZZZ - read from file XXX specified with -p and stored values in file ZZZ.
Command can be chained to perform multiple actions one after another, e.g.:
./adscomm -p "/version" -r -p "/mmb0/led/ch" -w 1
prints version read from MMB0 and changes led digit to 1.
In "app" directory simple scripts are available:
- initcomm - performs default initialization (tries to mimic ADCPro initialization for ADS1278EVM),
- inithighres - initializes ADS1278EVM for high-resolution acquisiton,
- record - reads 10000 samples from all channels and stores data in "data" file (in current directory).
After measurement is finished it would be nice to see the values - it can be done with last file "plotdata".
The file contains description to parse binary file content for gnuplot application.
After following command invoked:
gnuplot -p plotdata
one can see the results:
Subskrybuj:
Posty (Atom)













