Packet Lost using UART Driver of Telit's LE910Cx MCU - driver

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;
}

Related

472 bytes in 1 blocks are still reachable in loss record 1 of 1 error while opening a file in C

When opening a file called output, for some reason tests get an error 472 bytes in 1 blocks are still reachable in loss record 1 of 1. The program works okay, it is only a memory error that needs to be fixed. The goal of the program is to take a .raw file, scan it 512 bytes at a time for a .jpg file header at the start of the block and recover 50 .jpg pictures (they go one after the other). Error happens on the line where the comment is the error. What do I do to make this mistake go away? I've tried anything I can, nothing seems to help
int x = 0;
char buffer[8];
uint8_t bytes[512];
FILE *output;
//Going through the input file 512 bytes at a time
while (fread(bytes, 1, 512, input))
{
//Checking for .jpg header
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff && ((bytes[3] & 0xf0) == 0xe0))
{
if (x > 0)
{
//Closing the output file if I used it before
fclose(output);
}
//Creating file name string
sprintf(buffer, "%03i.jpg", x);
x++;
//Creating and opening a file to append to
output = fopen(buffer, "a"); //472 bytes in 1 blocks are still reachable in loss record 1 of 1
//Writing the header to the output file
fwrite(bytes, 1, 512, output);
}
else if (x > 0)
{
//Appending bytes until a new header is found
fwrite(bytes, 1, 512, output);
}
}

Is it possible to imitate arbitration on CAN bus?

Setup
I have two nodes connected to one CAN bus. The first node is a black-box, controlled by some real-time hardware. The second node is a Linux machine with attached PEAK-USB CAN controller:
+--------+ +----------+
| HW CAN |--- CAN BUS ---| Linux PC |
+--------+ +----------+
In order to investigate some problem related to occasional frame loss I want to mimic the CAN arbitration process. To do that I am setting the CAN bit-rate to 125Kb/s and flooding it with random CAN frames with 1ms delay, controlling the bus load with canbusload from can-utils. I also monitor CAN error frames running candump can0,0~0,#ffffffff and the overall can statistics with ip -s -d link show can:
26: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
pcan_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0
RX: bytes packets errors dropped overrun mcast
120880 15110 0 0 0 0
TX: bytes packets errors dropped carrier collsns
234123 123412 0 0 0 0
Problem
Now the problem is that the given setup works for hours with zero collisions (arbitration) or any other kind of error frames when the load is at 99%. When I reduce the delay to increase the bus load write(2) fails with either "ENOBUFS 105 No buffer space available" or "EAGAIN 11 Resource temporarily unavailable" - the actual error depends on whether I modify the qlen parameter or set to to defaults.
As I understand it, the load I put is either not enough or too much. What would be the right way to make two nodes enter the arbitration? A successful result would be a received CAN error frame corresponding to the CAN_ERR_LOSTARB constant from can/error.h and a value of collsns other than 0.
Source code
HW Node (Arduino Due with CAN board)
#include <due_can.h>
CAN_FRAME input, output;
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
Serial.println("start");
// Can0.begin(CAN_BPS_10K);
Can0.begin(CAN_BPS_125K);
// Can0.begin(CAN_BPS_250K);
output.id = 0x303;
output.length = 8;
output.data.low = 0x12abcdef;
output.data.high = 0x24abcdef;
}
// the loop function runs over and over again forever
void loop() {
Can0.sendFrame(output);
Can0.read(input);
delay(1);
}
Linux node
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main(int argc, char *argv[])
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
const char *ifname = "can0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
printf("%s at index %d\n", ifname, ifr.ifr_ifindex);
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
frame.can_id = 0x304;
frame.can_dlc = 2;
frame.data[0] = 0x11;
frame.data[1] = 0x22;
int sleep_ms = atoi(argv[1]) * 1000;
for (;;) {
nbytes = write(s, &frame, sizeof(struct can_frame));
if (nbytes == -1) {
perror("write");
return 1;
}
usleep(sleep_ms);
}
return 0;
}
From the documentation subsection 4.1.2 RAW socket option CAN_RAW_ERR_FILTER, it says that the errors are by default not activated which is why the lost arbitration field in ip was not increasing.
In order to toggle on all the errors, you need to add those two lines :
can_err_mask_t err_mask = CAN_ERR_MASK;
setsockopt(socket_can, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask));
But this feature is not available for all drivers and devices because it requires from the hardware to have a loopback mode. In the case of the PEAK-USB, it seems that if the version of the firmware from the device is less than 4.x, there is no loopback [source]. Thus SocketCAN won't be able to detect lost arbitration.

OLED Test for USBSTK5515 with CCSv6

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

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.

Problems with Ethernet shield + arduino

I am currently trying some simple (ready) programs from Arduino examples regardin the ethernet shield. I am still getting no result. Am always receiving that I am not connected or a blank serial monitor. Does anyone knows why? I think I am connected to the DHCP since i am on the DHCP list of my router
<#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for (;;)
;
}
Udp.begin(localPort);
}
void loop()
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ( (epoch % 60) < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
}
// wait ten seconds before asking for the time again
delay(10000);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
If your ethernet shield is a cheap clone, they are known to be faulty.
You will be able to get a DHCP address by plugging it directly into your DHCP server, but you will not get an address if the shield is connected to a switch.
You can fix this by soldering 2 x 100 Ohm resistors to the correct pins of the network socket on the bottom of the shield.
Alternatively, use a static ip address, or buy a different ethernet shield.

Resources