OLED Test for USBSTK5515 with CCSv6 - signal-processing

I am trying to run the test code for the OLED display simulation on the DSP board TMSC320C5515 eZdsp UsbStick, variant "USBSTK5515".
I have included the bsl folder and needed included libraries and header files through the spectrum website. Now the problem is that I am being unable to compile; I am getting the error:
**** Build of configuration Debug for project OLED ****
"G:\\TheDevelopmentKitCodeComposerv6\\ccsv6\\utils\\bin\\gmake" -k all
'Building file: ../main.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="main.pp" "../main.c"
'Finished building: ../main.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_gpio.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_gpio.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_gpio.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_gpio.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_i2c.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_i2c.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_i2c.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_i2c.c'
' '
'Building file: ../usbstk5515bsl/bsl/usbstk5515_led.c'
'Invoking: C5500 Compiler'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --include_path="C:/Users/SOURINDU/Desktop/usbstk5515_BSL_RevA/usbstk5515_v1/include" --include_path="C:/Users/SOURINDU/Desktop/usbstk1151_Demo_RevA/USBSTK5515_demo/source/USB_Stick_Sample/inc" --include_path="G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 --preproc_with_compile --preproc_dependency="usbstk5515bsl/bsl/usbstk5515_led.pp" --obj_directory="usbstk5515bsl/bsl" "../usbstk5515bsl/bsl/usbstk5515_led.c"
'Finished building: ../usbstk5515bsl/bsl/usbstk5515_led.c'
' '
'Building target: OLED.out'
'Invoking: C5500 Linker'
"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/bin/cl55" -v5515 --memory_model=large -g --define=c5515 --display_error_number --diag_warning=225 --ptrdiff_size=16 -z -m"OLED.map" --stack_size=0x200 --heap_size=0x400 -i"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/lib" -i"G:/TheDevelopmentKitCodeComposerv6/ccsv6/tools/compiler/c5500_4.4.1/include" --reread_libs --display_error_number --warn_sections --xml_link_info="OLED_linkInfo.xml" --rom_model --sys_stacksize=0x200 -o "OLED.out" "./main.obj" "./usbstk5515bsl/bsl/usbstk5515.obj" "./usbstk5515bsl/bsl/usbstk5515_gpio.obj" "./usbstk5515bsl/bsl/usbstk5515_i2c.obj" "./usbstk5515bsl/bsl/usbstk5515_led.obj" "../lnkx.cmd" "../usbstk5515bsl/usbstk5515bsl.lib" -l"libc.a" -l"rts55x.lib"
<Linking>
undefined first referenced
symbol in file
--------- ----------------
_main G:\TheDevelopmentKitCodeComposerv6\ccsv6\tools\compiler\c5500_4.4.1\lib\rts55x.lib<args_main.obj>
error #10234-D: unresolved symbols remain
error #10010: errors encountered during linking; "OLED.out" not built
>> Compilation failure
gmake: *** [OLED.out] Error 1
gmake: Target `all' not remade because of errors.
**** Build Finished ****
And in the problem window :
Description Resource Path Location Type
#10010 errors encountered during linking; "OLED.out" not built OLED C/C++ Problem
#10234-D unresolved symbols remain OLED C/C++ Problem
unresolved symbol _main, first referenced in G:\TheDevelopmentKitCodeComposerv6\ccsv6\tools\compiler\c5500_4.4.1\lib\rts55x.lib<args_main.obj> OLED C/C++ Problem
My Code as downloaded from spectrum website is
/*
* Copyright 2010 by Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*/
/*
* OSD9616 OLED Test
*
*/
#include "usbstk5515.h"
//#include "usbstk5515_led.h"
#include "usbstk5515_i2c.h"
#include "lcd.h"
#include "usbstk5515_gpio.h"
#define OSD9616_I2C_ADDR 0x3C // OSD9616 I2C address
/* ------------------------------------------------------------------------ *
* *
* Int16 OSD9616_send( Uint16 comdat, Uint16 data ) *
* *
* Sends 2 bytes of data to the OSD9616 *
* *
* ------------------------------------------------------------------------ */
Int16 OSD9616_send( Uint16 comdat, Uint16 data )
{
Uint8 cmd[2];
cmd[0] = comdat & 0x00FF; // Specifies whether data is Command or Data
cmd[1] = data; // Command / Data
return USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 2 );
}
/* ------------------------------------------------------------------------ *
* *
* Int16 OSD9616_multiSend( Uint16 comdat, Uint16 data ) *
* *
* Sends multiple bytes of data to the OSD9616 *
* *
* ------------------------------------------------------------------------ */
Int16 OSD9616_multiSend( Uint8* data, Uint16 len )
{
Uint16 x;
Uint8 cmd[10];
for(x=0;x<len;x++) // Command / Data
{
cmd[x] = data[x];
}
return USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, len );
}
/* ------------------------------------------------------------------------ *
* *
* Int16 printLetter(Uint16 l1,Uint16 l2,Uint16 l3,Uint16 l4) *
* *
* Send 4 bytes representing a Character *
* *
* ------------------------------------------------------------------------ */
Int16 printLetter(Uint16 l1,Uint16 l2,Uint16 l3,Uint16 l4)
{
OSD9616_send(0x40,l1);
OSD9616_send(0x40,l2);
OSD9616_send(0x40,l3);
OSD9616_send(0x40,l4);
OSD9616_send(0x40,0x00);
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* Int16 oled_test() *
* *
* Testing function for the OSD9616 display *
* *
* ------------------------------------------------------------------------ */
Int16 oled_test()
{
Int16 i, i2c_err;
Uint8 cmd[10]; // For multibyte commands
/* Initialize I2C */
USBSTK5515_I2C_init( );
/* Initialize LCD power */
USBSTK5515_GPIO_setDirection( 12, 1 ); // Output
USBSTK5515_GPIO_setOutput( 12, 1 ); // Enable 13V
/* Initialize OSD9616 display */
i2c_err = OSD9616_send(0x00,0x00); // Set low column address
i2c_err = OSD9616_send(0x00,0x10); // Set high column address
if(i2c_err) // Don't setup display if not connected
return 1;
OSD9616_send(0x00,0x40); // Set start line address
cmd[0] = 0x00 & 0x00FF; // Set contrast control register
cmd[1] = 0x81;
cmd[2] = 0x7f;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xa1); // Set segment re-map 95 to 0
OSD9616_send(0x00,0xa6); // Set normal display
cmd[0] = 0x00 & 0x00FF; // Set multiplex ratio(1 to 16)
cmd[1] = 0xa8;
cmd[2] = 0x0f;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xd3); // Set display offset
OSD9616_send(0x00,0x00); // Not offset
OSD9616_send(0x00,0xd5); // Set display clock divide ratio/oscillator frequency
OSD9616_send(0x00,0xf0); // Set divide ratio
cmd[0] = 0x00 & 0x00FF; // Set pre-charge period
cmd[1] = 0xd9;
cmd[2] = 0x22;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
cmd[0] = 0x00 & 0x00FF; // Set com pins hardware configuration
cmd[1] = 0xda;
cmd[2] = 0x02;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xdb); // Set vcomh
OSD9616_send(0x00,0x49); // 0.83*vref
cmd[0] = 0x00 & 0x00FF; //--set DC-DC enable
cmd[1] = 0x8d;
cmd[2] = 0x14;
USBSTK5515_I2C_write( OSD9616_I2C_ADDR, cmd, 3 );
OSD9616_send(0x00,0xaf); // Turn on oled panel
/* Fill page 0 */
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+0); // Set page for page 0 to page 5
for(i=0;i<128;i++)
{
OSD9616_send(0x40,0xff);
}
/* Write to page 0 */
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+0); // Set page for page 0 to page 5
for(i=0;i<22;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x7F,0x30,0x0E,0x7F); // N
printLetter(0x41,0x49,0x49,0x7F); // E
printLetter(0x7F,0x06,0x06,0x7F); // M
printLetter(0x3F,0x40,0x40,0x3F); // U
printLetter(0x46,0x29,0x19,0x7F); // R
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x7F,0x30,0x0E,0x7F); // N
printLetter(0x00,0x7F,0x00,0x00); // I
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x7C,0x09,0x0A,0x7C); // A
printLetter(0x63,0x1C,0x1C,0x63); // X
printLetter(0x41,0x49,0x49,0x7F); // E
printLetter(0x01,0x7F,0x01,0x01); // T
for(i=0;i<23;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
/* Fill page 1*/
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+1); // Set page for page 0 to page 5
for(i=0;i<128;i++)
{
OSD9616_send(0x40,0xff);
}
/* Write to page 1*/
OSD9616_send(0x00,0x00); // Set low column address
OSD9616_send(0x00,0x10); // Set high column address
OSD9616_send(0x00,0xb0+1); // Set page for page 0 to page 5
for(i=0;i<20;i++)
{
OSD9616_send(0x40,0x00);
}
printLetter(0x41,0x22,0x14,0x7F); // K
printLetter(0x22,0x41,0x41,0x3E); // C
printLetter(0x00,0x7F,0x00,0x00); // I
printLetter(0x01,0x7F,0x01,0x01); // T
printLetter(0x32,0x49,0x49,0x26); // S
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x36,0x49,0x49,0x7F); // B
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x3F,0x40,0x40,0x3F); // U
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x06,0x09,0x09,0x7F); // P
printLetter(0x32,0x49,0x49,0x26); // S
printLetter(0x3E,0x41,0x41,0x7F); // D
printLetter(0x43,0x4D,0x51,0x61); // Z
printLetter(0x10,0x58,0x58,0x30); // e
for(i=0;i<5;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x00,0x7F,0x00,0x00); // 1
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x31,0x49,0x49,0x2F); // 5
printLetter(0x22,0x41,0x41,0x3E); // C
for(i=0;i<23;i++)
{
OSD9616_send(0x40,0x00); // Spaces
}
/* Set vertical and horizontal scrolling */
cmd[0] = 0x00;
cmd[1] = 0x29; // Vertical and Right Horizontal Scroll
cmd[2] = 0x00; // Dummy byte
cmd[3] = 0x00; // Define start page address
cmd[4] = 0x03; // Set time interval between each scroll step
cmd[5] = 0x01; // Define end page address
cmd[6] = 0x01; // Vertical scrolling offset
OSD9616_multiSend( cmd, 7 );
OSD9616_send(0x00,0x2f);
/* Keep first 8 rows from vertical scrolling */
cmd[0] = 0x00;
cmd[1] = 0xa3; // Set Vertical Scroll Area
cmd[2] = 0x08; // Set No. of rows in top fixed area
cmd[3] = 0x08; // Set No. of rows in scroll area
OSD9616_multiSend( cmd, 4 );
return 0;
}

Probably a bit late now, but I think the problem is that you don't have a main function defined to call any of the functions, hence message "unresolved symbol _main".
Not familiar with that particular board, but the example that came with my ezdspc5535 had 2 c files, one of which had a main and examples of how to call the functions in oled_test.c

Related

is a Fortran subroutine with a dummy argument specified size array thread safe

The following code compiles in gfortran, with a warning about large_array being larger than the limit for a stack variable, stating that the array will be moved to static memory and is therefore not threadsafe:
subroutine stack_size_warning
implicit none
real :: large_array(65536)
print *, large_array
end subroutine stack_size_warning
This subroutine however compiles with no errors or warnings, and I can call it with n values larger than 65536 without issue, at least in simple cases.
subroutine no_warning(n)
implicit none
integer :: n
real :: automatic_array(n)
print *, automatic_array
end subroutine no_warning
Is this second array threadsafe? Where is the memory allocated for automatic_array in this second subroutine? Is the memory allocated and deallocated on every call making it slower than if it was on the stack or if a preallocated array was passed in as a dummy argument?
I wrote the following program to test 3 scenarios, a subroutine with a small array on the stack, another with a large array over the stack limit and thus stored in static memory, and a third where a dummy argument specifies the size of an array defined inside the routine.
Here is that program:
program main
implicit none
call small
call large
call automatic(65536)
end program main
subroutine small
implicit none
real :: small_array(10)
small_array=1.
print *, small_array
end subroutine small
subroutine large
implicit none
real :: large_array(65536)
large_array=1.
print *, large_array
end subroutine large
subroutine automatic(n)
implicit none
integer :: n
real :: automatic_array(n)
automatic_array=1.
print *, automatic_array
end subroutine automatic
Using steve's recommendation I compiled with a tree dump as follows:
gfortran array_dim_test.f90 -o array_dim_test -fdump-tree-original
The full dump is at the end, but to summarize what I see, the automatic subroutine has a try/finally block. In the try block, a call to malloc allocates the memory, and in the finally block, the memory is freed. So I guess this memory is allocated and deallocated on the heap with every call to the subroutine. This intuitively makes sense as how else would the program know what to do with this array that lives only in the subroutine, and whose size is defined in a call to the subroutine, but it is interesting to see the explicit calls in the tree dump. This would appear to be thread-safe then, but perhaps also not the most efficient thing to do if this routine is called many times with the same array size parameter, allocating and deallocating memory with every call.
Here is the tree dump:
__attribute__((fn spec (". w ")))
void automatic (integer(kind=4) & restrict n)
{
void * restrict D.3964;
integer(kind=8) ubound.0;
integer(kind=8) size.1;
real(kind=4)[0:D.3961] * restrict automatic_array;
integer(kind=8) D.3961;
bitsizetype D.3962;
sizetype D.3963;
try
{
ubound.0 = (integer(kind=8)) *n;
size.1 = NON_LVALUE_EXPR <ubound.0>;
size.1 = MAX_EXPR <size.1, 0>;
D.3961 = size.1 + -1;
D.3962 = (bitsizetype) (sizetype) NON_LVALUE_EXPR <size.1> * 32;
D.3963 = (sizetype) NON_LVALUE_EXPR <size.1> * 4;
D.3964 = (void * restrict) __builtin_malloc (MAX_EXPR <(unsigned long) (size.1 * 4), 1>);
automatic_array = (real(kind=4)[0:D.3961] * restrict) D.3964;
{
integer(kind=8) D.3940;
D.3940 = ubound.0;
{
integer(kind=8) S.2;
S.2 = 1;
while (1)
{
if (S.2 > D.3940) goto L.1;
(*automatic_array)[S.2 + -1] = 1.0e+0;
S.2 = S.2 + 1;
}
L.1:;
}
}
{
struct __st_parameter_dt dt_parm.3;
dt_parm.3.common.filename = &"array_dim_test.f90"[1]{lb: 1 sz: 1};
dt_parm.3.common.line = 27;
dt_parm.3.common.flags = 128;
dt_parm.3.common.unit = 6;
_gfortran_st_write (&dt_parm.3);
{
integer(kind=8) D.3944;
struct array01_real(kind=4) parm.4;
D.3944 = ubound.0;
parm.4.span = 4;
parm.4.dtype = {.elem_len=4, .rank=1, .type=3};
parm.4.dim[0].lbound = 1;
parm.4.dim[0].ubound = D.3944;
parm.4.dim[0].stride = 1;
parm.4.data = (void *) &(*automatic_array)[0];
parm.4.offset = -1;
_gfortran_transfer_array_write (&dt_parm.3, &parm.4, 4, 0);
}
_gfortran_st_write_done (&dt_parm.3);
}
}
finally
{
__builtin_free ((void *) automatic_array);
}
}
__attribute__((fn spec (". ")))
void large ()
{
static real(kind=4) large_array[65536];
{
integer(kind=8) S.5;
S.5 = 1;
while (1)
{
if (S.5 > 65536) goto L.2;
large_array[S.5 + -1] = 1.0e+0;
S.5 = S.5 + 1;
}
L.2:;
}
{
struct __st_parameter_dt dt_parm.6;
dt_parm.6.common.filename = &"array_dim_test.f90"[1]{lb: 1 sz: 1};
dt_parm.6.common.line = 19;
dt_parm.6.common.flags = 128;
dt_parm.6.common.unit = 6;
_gfortran_st_write (&dt_parm.6);
{
struct array01_real(kind=4) parm.7;
parm.7.span = 4;
parm.7.dtype = {.elem_len=4, .rank=1, .type=3};
parm.7.dim[0].lbound = 1;
parm.7.dim[0].ubound = 65536;
parm.7.dim[0].stride = 1;
parm.7.data = (void *) &large_array[0];
parm.7.offset = -1;
_gfortran_transfer_array_write (&dt_parm.6, &parm.7, 4, 0);
}
_gfortran_st_write_done (&dt_parm.6);
}
}
__attribute__((fn spec (". ")))
void small ()
{
real(kind=4) small_array[10];
{
integer(kind=8) S.8;
S.8 = 1;
while (1)
{
if (S.8 > 10) goto L.3;
small_array[S.8 + -1] = 1.0e+0;
S.8 = S.8 + 1;
}
L.3:;
}
{
struct __st_parameter_dt dt_parm.9;
dt_parm.9.common.filename = &"array_dim_test.f90"[1]{lb: 1 sz: 1};
dt_parm.9.common.line = 12;
dt_parm.9.common.flags = 128;
dt_parm.9.common.unit = 6;
_gfortran_st_write (&dt_parm.9);
{
struct array01_real(kind=4) parm.10;
parm.10.span = 4;
parm.10.dtype = {.elem_len=4, .rank=1, .type=3};
parm.10.dim[0].lbound = 1;
parm.10.dim[0].ubound = 10;
parm.10.dim[0].stride = 1;
parm.10.data = (void *) &small_array[0];
parm.10.offset = -1;
_gfortran_transfer_array_write (&dt_parm.9, &parm.10, 4, 0);
}
_gfortran_st_write_done (&dt_parm.9);
}
}
__attribute__((fn spec (". ")))
void MAIN__ ()
{
small ();
large ();
{
static integer(kind=4) C.3993 = 65536;
automatic (&C.3993);
}
}
__attribute__((externally_visible))
integer(kind=4) main (integer(kind=4) argc, character(kind=1) * * argv)
{
static integer(kind=4) options.11[7] = {2116, 4095, 0, 1, 1, 0, 31};
_gfortran_set_args (argc, argv);
_gfortran_set_options (7, &options.11[0]);
MAIN__ ();
return 0;
}

Packet Lost using UART Driver of Telit's LE910Cx MCU

It takes up to 40 min before a packet is lost, (at rate of 1 packet every few minutes),
The MCU use Linux kernel 3.18.48,
Using Scope, (on UART's Rx Pin), I can see the packets, (about 15 bytes long), are sent well.
But the read() doesn't return, with any of the packet's bytes,
(VMIN = 1, VTIME = 0, configured to return if at least 1 byte is in the Rx buffer),
This code is used in 4 other projects, with different HW Board, and we never saw this issue before.
Can you share ideas of how to tackle such issue?
How can I debug the UART driver?
To better understand where the packet got lost,
Thanks,
Logic Analyzer of the Lost Packet
E_UARTDRV_STATUS UartDrv_Open(void *pUart, S_UartDrv_InitData *init_data)
{
struct termios tty;
struct serial_struct serial;
/*
* O_RDWR - Opens the port for reading and writing
* O_NOCTTY - The port never becomes the controlling terminal of the process.
* O_NDELAY - Use non-blocking I/O.
* On some systems this also means the RS232 DCD signal line is ignored.
* Note well: if present, the O_EXCL flag is silently ignored by the kernel when opening a serial device like a modem.
* On modern Linux systems programs like ModemManager will sometimes read and write to your device and possibly corrupt your program state.
* To avoid problems with programs like ModemManager you should set TIOCEXCL on the terminal after associating a terminal with the device.
* You cannot open with O_EXCL because it is silently ignored.
*/
fd = open(init_data->PortName, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) // if there is an invalid descriptor, print the reason {
SYS_LOG_ERR_V("fd invalid whilst trying to open com port %s: %s\n", init_data->PortName, strerror(errno));
return UARTDRV_STATUS_ERROR;
}
if (tcflush(fd, TCIOFLUSH) < 0) {
SYS_LOG_ERR_V("Error failed to flush input output buffers %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
// Enable low latency...this should affect the file /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
if (ioctl(fd, TIOCGSERIAL, &serial) < 0) {
SYS_LOG_ERR_V("Error failed to get latency current value: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
serial.flags |= ASYNC_LOW_LATENCY;
if (ioctl(fd, TIOCSSERIAL, &serial) < 0) {
SYS_LOG_ERR_V("Error failed to set Low latency: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
if (fcntl(fd, F_SETFL, 0) < 0) {
SYS_LOG_ERR_V("Error failed to set file flags: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
/* Get current configuration */
if (tcgetattr(fd, &tty) < 0) {
SYS_LOG_ERR_V("Error failed to get current configuration: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
if (cfsetospeed(&tty, init_data->baud) < 0) {
SYS_LOG_ERR_V("Error failed to set output baud rate: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
if (cfsetispeed(&tty, init_data->baud) < 0) {
SYS_LOG_ERR_V("Error failed to set input baud rate: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
tty.c_cflag |= (CLOCAL | CREAD); /* Enable the receiver and set local mode */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
/*
* Input flags - Turn off input processing
* convert break to null byte, no CR to NL translation,
* no NL to CR translation, don't mark parity errors or breaks
* no input parity check, don't strip high bit off,
* no XON/XOFF software flow control
* BRKINT - If this bit is set and IGNBRK is not set, a break condition clears the terminal input and output queues and raises a SIGINT signal for the foreground process group associated with the terminal.
* If neither BRKINT nor IGNBRK are set, a break condition is passed to the application as a single '\0' character if PARMRK is not set, or otherwise as a three-character sequence '\377', '\0', '\0'.
* INPCK - If this bit is set, input parity checking is enabled. If it is not set, no checking at all is done for parity errors on input; the characters are simply passed through to the application.
* Parity checking on input processing is independent of whether parity detection and generation on the underlying terminal hardware is enabled; see Control Modes.
* For example, you could clear the INPCK input mode flag and set the PARENB control mode flag to ignore parity errors on input, but still generate parity on output.
* If this bit is set, what happens when a parity error is detected depends on whether the IGNPAR or PARMRK bits are set. If neither of these bits are set, a byte with a parity error is passed to the application as a '\0' character.
*/
tty.c_iflag &= ~(BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
/*
* IGNBRK - If this bit is set, break conditions are ignored.
* A break condition is defined in the context of asynchronous serial data transmission as a series of zero-value bits longer than a single byte.
*/
tty.c_iflag |= IGNBRK;
/*
* No line processing
* echo off, echo newline off, canonical mode off,
* extended input processing off, signal chars off
*/
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
/*
* Output flags - Turn off output processing
* no CR to NL translation, no NL to CR-NL translation,
* no NL to CR translation, no column 0 CR suppression,
* no Ctrl-D suppression, no fill characters, no case mapping,
* no local output processing
*
* c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
*/
tty.c_oflag = 0;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 1; // timeout in 10th of second
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
SYS_LOG_ERR_V("Error failed to set new configuration: %s\n", strerror(errno));
return UARTDRV_STATUS_ERROR;
}
uartPeripheral.fd = fd;
return UARTDRV_STATUS_SUCCESS;
}
uint8_t *UartDrv_Rx(S_UartDrv_Handle *handle, uint16_t bytesToRead, uint16_t *numBytesRead)
{
ssize_t n_read;
uint16_t n_TotalReadBytes = 0;
struct timespec timestamp;
struct timespec now;
long diff_ms;
bool Timeout = false, isPartialRead = false;
if (handle == NULL) {
SYS_LOG_ERR("UartDrv Error: async rx error - peripheral error");
exit(EXIT_FAILURE);
}
if (bytesToRead > sizeof(uartPeripheral.buffer_rx)) {
ESILOG_ERR_V("Param Error: Invalid length %u, max length %zu", bytesToRead, sizeof(uartPeripheral.buffer_rx));
*numBytesRead = 0;
return NULL;
}
while(n_TotalReadBytes < bytesToRead && !Timeout) {
do {
n_read = read(uartPeripheral.fd, &uartPeripheral.buffer_rx[n_TotalReadBytes], bytesToRead - n_TotalReadBytes);
if (isPartialRead) {
clock_gettime(CLOCK_REALTIME, &now);
diff_ms = (now.tv_sec - timestamp.tv_sec)*1000;
diff_ms += (now.tv_nsec - timestamp.tv_nsec)/1000000;
if (diff_ms > UART_READ_TIMEOUT_MS) {
SYS_LOG_ERR("UartDrv_Rx: Error, timeout while reading\r\n");
Timeout = true;
}
}
} while ((n_read != -1) && (n_read == 0) && !Timeout);
if (n_read == -1) {
if (errno == EINTR) {
ESILOG_WARN("Uart Interrupted");
continue;
}
ESILOG_ERR_V("Uart Error: [%d, %s]", errno, strerror(errno));
exit(EXIT_FAILURE);
}
n_TotalReadBytes += (uint16_t)n_read;
if (n_TotalReadBytes < bytesToRead) {
//SYS_LOG_DBG_V("UartDrv_Rx: couldn't fetch all bytes, read %hu, expected %hu, continue reading %s\r\n", n_TotalReadBytes, bytesToRead, isPartialRead? "During Partial read": "");
if (!isPartialRead) {
isPartialRead = true;
clock_gettime(CLOCK_REALTIME, &timestamp);
}
}
}
*numBytesRead = n_TotalReadBytes;
return uartPeripheral.buffer_rx;
}

I2S Input configuration Beaglebone ALSA

I am trying to capture sound from a Circular Microphone Board (TIDA-01454) in a Beaglebone AI. I have succesfully configured the ADCs of the CMB via I2C, and checked that the I2S output is working correctly with an external DAC.
However my next step is to capture this I2S into my Beaglebone AI in order to process it later. I think I have configured the pins correctly following this guide and this document. So my show-pins is like this:
And my DTS file is like this:
#include "am5729-beagleboneai.dts"
// make it easy to determine which dtb you're currently running on
// (via /proc/device-tree/chosen/)
/ {
chosen {
base_dtb = "am5729-beagleboneai-custom.dts";
base_dtb_timestamp = __TIMESTAMP__;
};
};
// eventually these should be available in a header
#define P9_14 (0x3400 + 4 * 107)
#define P9_16 (0x3400 + 4 * 108)
#define P9_19a (0x3400 + 4 * 16)
#define P9_19b (0x3400 + 4 * 95)
#define P9_20a (0x3400 + 4 * 17)
#define P9_20b (0x3400 + 4 * 94)
#define P9_12 (0x3400 + 4 * 171)
#define P9_27b (0x3400 + 4 * 172)
#define P9_18b (0x3400 + 4 * 173)
//
/{
pcm5102a: pcm5102a {
#sound-dai-cells = <0>;
compatible = "ti,pcm5102a";
status = "okay";
};
sound {compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "PCM5102a";
simple-audio-card,bitclock-master = <&sound1_master>;
simple-audio-card,frame-master = <&sound1_master>;
simple-audio-card,bitclock-inversion;
simple-audio-card,cpu {
sound-dai = <&mcasp1>;
};
sound1_master: simple-audio-card,codec {
#sound-dai-cells = <0>;
sound-dai = <&pcm5102a>;
};
};
};
// enable i2c-3 on P9.19 (scl) + P9.20 (sda)
&i2c4 {
status = "okay";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c4_pins>;
};
&mcasp1 {
#sound-dai-cells = <0>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&mcasp1_pins>;
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
num-serializer = <4>;
/* 16 serializers */
serial-dir = < /* 1 TX 2 RX 0 unused */
2 0 0 0
>;
rx-num-evt = <1>;
tx-num-evt = <1>;
};
&dra7_pmx_core {
i2c4_pins: i2c4 {
pinctrl-single,pins = <
DRA7XX_CORE_IOPAD( P9_19a, PIN_INPUT_PULLUP | MUX_MODE7 ) // scl
DRA7XX_CORE_IOPAD( P9_19b, PIN_INPUT_PULLUP | MUX_MODE14 ) // (shared pin)
DRA7XX_CORE_IOPAD( P9_20a, PIN_INPUT_PULLUP | MUX_MODE7 ) // sda
DRA7XX_CORE_IOPAD( P9_20b, PIN_INPUT_PULLUP | MUX_MODE14 ) // (shared pin)
>;
};
mcasp1_pins: mcasp1_pins {
pinctrl-single,pins = <
DRA7XX_CORE_IOPAD(P9_12, PIN_INPUT_PULLDOWN | MUX_MODE0) // 12 0 mcasp1_aclkr BIT CLOCK BCLK
DRA7XX_CORE_IOPAD(P9_27b, PIN_INPUT | MUX_MODE0) // 27b 0 mcasp1_fsr FRAME SYNC LRCLK
DRA7XX_CORE_IOPAD(P9_18b, PIN_INPUT | MUX_MODE0) // 18b 0 mcasp1_axr0 I2S INPUT DATA
>;
};
};
// enable pwm-2 on P9.14 (out-A) + P9.16 (out-B)
&epwmss2 {
status = "okay";
};
&ehrpwm2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ehrpwm2_pins>;
};
&dra7_pmx_core {
ehrpwm2_pins: ehrpwm2 {
pinctrl-single,pins = <
DRA7XX_CORE_IOPAD( P9_14, PIN_OUTPUT_PULLDOWN | MUX_MODE10 ) // out A
DRA7XX_CORE_IOPAD( P9_16, PIN_OUTPUT_PULLDOWN | MUX_MODE10 ) // out B
>;
};
};
However I think it doesn't detect it as a capture device. Since the grep and arecord command return this:
debian#beaglebone:/var/lib/cloud9$ dmesg |grep sound
[ 1.385258] asoc-simple-card sound: pcm5102a-hifi <-> 48460000.mcasp mapping ok
debian#beaglebone:/var/lib/cloud9$ arecord -l
**** List of CAPTURE Hardware Devices ****
debian#beaglebone:/var/lib/cloud9$
I think there might be a problem with ALSA configuration, but I am new into this and I dont know how to do it.
My ALSA version is: Advanced Linux Sound Architecture Driver Version k4.14.108-ti-r143.
And my sound cards are:
cat /proc/asound/cards
0 [Black ]: TI_BeagleBone_B - TI BeagleBone Black
TI BeagleBone Black
So the card is not detected? Is it ALSA or driver problem? How can I do it?

How to detect recurrent patterns in a textfile

To simplify a function with many terms, a program would be useful that searches for patterns in a file and arranges them in a ranking list. I can imagine that this is an elaborate process, but I'm sure there are people who have built something like this.
An example of a text:
sin(t1)*cos(t1)*t1+t1-sin(t1)*sin(t1-pi)
This should give me such an output like this (min. 2 letters):
6x: "t1"
4x: "(t1"
3x: "n(t1"
3x: "sin"
3x: "sin("
2x: "sin(t1)"
etc.
Does this problem have a name (which I don't know)? Is there a known algorithm that could solve the problem for me?
I have written a small program with QT, which fulfills the task. The approach is to try everything. To solve my problem, it will probably take a few days, because the text files are very large.
If I have the following text as input ("text.txt"):
sin(t1)*cos(t1)*t1+t1-sin(t1)*sin(t1-pi)
I have with the parameters: length 2-5, minimum occurrence: 3
following result:
t1 6
(t 4
(t1 4
si 3
in 3
n( 3
1) 3
)* 3
sin 3
in( 3
n(t 3
t1) 3
1)* 3
sin( 3
in(t 3
n(t1 3
(t1) 3
t1)* 3
sin(t 3
in(t1 3
(t1)* 3
Code:
#include <QCoreApplication>
#include <qdebug.h>
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString * wholefile = new QString;
uint64_t minchar = 2;
uint64_t maxchar = 5;
uint64_t min_occur = 3;
QFile file("text.txt");
if(!file.open(QIODevice::ReadOnly)) {
qDebug()<<"error reading file";
}
QTextStream in(&file);
while(!in.atEnd()) {
QString line = in.readLine();
wholefile->append(line);
}
file.close();
QStringList * allpatterns = new QStringList;
for(uint64_t i=minchar; i<=maxchar;i++){
for(uint64_t pos=0; pos<wholefile->length()-i;pos++){
QString pattern = wholefile->mid(pos,i);
if(allpatterns->contains(pattern)==0){
allpatterns->append(pattern);
}
}
}
uint64_t * strcnt = new uint64_t[allpatterns->length()];
uint64_t maximum_cnt = 0;
QStringList * interestingpatterns = new QStringList;
uint64_t nr_of_patterns = 0;
for(uint64_t i=0; i<allpatterns->length();i++){
QString str = allpatterns->at(i);
strcnt[nr_of_patterns] = wholefile->count(str);
if(strcnt[nr_of_patterns]>=min_occur){
if(strcnt[nr_of_patterns]>maximum_cnt){
maximum_cnt = strcnt[nr_of_patterns];
}
interestingpatterns->append(str);
nr_of_patterns++;
}
}
/* display result*/
QFile file2("out.txt");
if (!file2.open(QIODevice::WriteOnly | QIODevice::Text))
qDebug()<<"error writing file";
QTextStream out(&file2);
uint64_t current_max = maximum_cnt;
while(current_max>=min_occur){
for(uint64_t i=0; i<interestingpatterns->length();i++){
if(strcnt[i]==current_max){
QString str = interestingpatterns->at(i);
qDebug()<<str<<strcnt[i];
out <<str<<" "<< QString::number(strcnt[i])<<"\n";
}
}
current_max--;
}
file2.close();
return a.exec();
}

Does free Xively account causes QoS 1 or 2 publish failed?

My code (below) is working if I use QoS 0. But for QoS 1 or QoS 2. MQTTClient_publishMessage(...) failed.
Am I missing any configuration? Or, is it because I am using free XIvely account?
I use Paho API.
------------------------------- start of cut -------------------------------------
/**
* #file
*
* Paho MQ Client API to Xively mqtt broker
*
*/
enter code here
#include "MQTTClient.h"
#include <stdlib.h>
void usage()
{
printf("Usage: speicify QoS\n");
printf(" turn on bulb -> ka_pub Qos 1 1\n");
printf(" turn off bulb -> ka_pub Qos 1 0\n");
printf(" send 7 to led -> ka_pub Qos 2 7\n");
printf(" send 2 to led -> ka_pub Qos 2 2\n");
}
int main(int argc, char** argv)
{
int rc = 0;
if (argc < 3) {
usage();
exit (0);
}
char TOPIC[250] ; // given enough space first to avoid malloc
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int QoS = atoi(argv[1]);
if (argv[2][0] == '1') {
strcpy(TOPIC, BULB_TOPIC);
conn_opts.username = BULB_API_KEY ;
conn_opts.password = "" ; // will be ignored
} else
if (argv[2][0] == '2') {
strcpy(TOPIC, LED_TOPIC) ;
conn_opts.username = LED_API_KEY ;
conn_opts.password = "" ; // will be ignored
} else {
printf("Bad arg\n");
usage();
exit (0);
}
setenv("MQTT_C_CLIENT_TRACE", "ON", 1); // same as 'stdout'
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1); //ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM
MQTTClient_create(&client, XIVELY_END_URL, "test", MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);
//conn_opts.keepAliveInterval = 20; // init to 60
//conn_opts.cleansession = 1; // default 1, will clean previous msg in server
conn_opts.reliable = 0 ; //default 1, only 1 can in-flight, 0 - allow 10 msg
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);
}
// prepare publish msg
char tmsg[250] ; // check max 250 boundary later
if (argv[2][0] == '1')
sprintf(tmsg, "{\"id\":\"switch\",\"current_value\":\"%c\"}", argv[3][0]);
else
sprintf(tmsg, "{\"id\":\"num\",\"current_value\":\"%c\"}", argv[3][0]) ;
int tmsg_len = strlen(tmsg);
pubmsg.payload = &tmsg[0] ;
pubmsg.payloadlen = tmsg_len; //mlen
pubmsg.qos = QoS;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
//MQTTClient_publish(client, TOPIC, pubmsg.payloadlen, pubmsg.payload,
// pubmsg.qos, pubmsg.retained, &token);
rc = MQTTClient_waitForCompletion(client, token, 100000);
printf("Finish publish for TOPIC: %s, QoS: %d, msg of '%s'\n", TOPIC, pubmsg.qos, (char *) pubmsg.payload);
if (rc == 0)
MyLog(LOGA_INFO, "verdict pass");
else
MyLog(LOGA_INFO, "verdict fail");
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}
------------------------------- end of cut -------------------------------------
I don't believe Xively supports QoS>0.

Resources