aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--busdevice.c5
-rw-r--r--devicedeployment.c60
-rw-r--r--devicedeployment.h10
-rw-r--r--pcserialport.c87
-rw-r--r--simplemotion_defs.h2
-rw-r--r--tcpclient.c12
6 files changed, 125 insertions, 51 deletions
diff --git a/busdevice.c b/busdevice.c
index b73da3f..4bc0ee0 100644
--- a/busdevice.c
+++ b/busdevice.c
@@ -137,6 +137,7 @@ static int parseIpAddress(const char *s, char *ip, size_t ipsize, short *port)
{
const char *ip_end, *port_start;
+ //ip_end and port_start are pointers to memory area of s, not offsets or indexes to s
if (validateIpAddress(s, &ip_end, &port_start) == -1)
return -1;
@@ -144,7 +145,7 @@ static int parseIpAddress(const char *s, char *ip, size_t ipsize, short *port)
if (!ip)
return 0;
- if (ipsize < ip_end - s + 1)
+ if (ipsize < (size_t)(ip_end - s + 1))
return -1;
memcpy(ip, s, ip_end - s);
@@ -182,7 +183,7 @@ smbusdevicehandle smBDOpen( const char *devicename )
//all handles in use
if(handle>=SM_MAX_BUSES) return -1;
- if(strncmp(devicename,"COM",3) == 0 || strncmp(devicename,"/dev/tty",8) == 0) //use rs232 lib
+ if(strncmp(devicename,"COM",3) == 0 || strncmp(devicename,"/dev/tty",8) == 0 || strncmp(devicename,"/dev/cu.",8) == 0) //use rs232 lib
{
BusDevice[handle].comPort=serialPortOpen( devicename, SMBusBaudrate );
if( BusDevice[handle].comPort == -1 )
diff --git a/devicedeployment.c b/devicedeployment.c
index fbf909a..c832575 100644
--- a/devicedeployment.c
+++ b/devicedeployment.c
@@ -36,7 +36,7 @@ unsigned int readFileLine( const smuint8 *data, const int dataLen, int *readPosi
char c;
do
{
- if(*readPosition>=dataLen)//end of data buffer
+ if((*readPosition)>=dataLen)//end of data buffer
{
*eof=smtrue;
c=0;
@@ -44,12 +44,12 @@ unsigned int readFileLine( const smuint8 *data, const int dataLen, int *readPosi
else
{
*eof=smfalse;
- c=data[*readPosition+len];
+ c=data[(*readPosition)];
(*readPosition)++;
}
//eol or eof
- if( *eof==smtrue || c=='\n' || c=='\r' || len>=charlimit-1 )
+ if( (*eof)==smtrue || c=='\n' || c=='\r' || len>=charlimit-1 )
{
output[len]=0;//terminate str
return len;
@@ -538,12 +538,11 @@ smbool flashFirmwarePrimaryMCU( smbus smhandle, int deviceaddress, const smuint8
typedef enum { StatIdle=0, StatEnterDFU, StatFindDFUDevice, StatLoadFile, StatUpload, StatLaunch } UploadState;//state machine status
-//free buffer and return given status code
-FirmwareUploadStatus abortFWUpload( FirmwareUploadStatus stat, smuint8 *fwData, UploadState *state, int errorDetailCode )
+//handle error in FW upload
+FirmwareUploadStatus abortFWUpload( FirmwareUploadStatus stat, UploadState *state, int errorDetailCode )
{
globalErrorDetailCode=errorDetailCode;
*state=StatIdle;
- free(fwData);
return stat;
}
@@ -558,6 +557,41 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
{
static smuint8 *fwData=NULL;
static int fwDataLength;
+ static smbool fileLoaded=smfalse;
+ FirmwareUploadStatus state;
+
+ //load file to buffer if not loaded yet
+ if(fileLoaded==smfalse)
+ {
+ if(loadBinaryFile(firmware_filename,&fwData,&fwDataLength)!=smtrue)
+ return FWFileNotReadable;
+ fileLoaded=smtrue;
+ }
+
+ //update FW, called multiple times per upgrade
+ state=smFirmwareUploadFromBuffer( smhandle, smaddress, fwData, fwDataLength );
+
+ //if process complete, due to finish or error -> unload file.
+ if(((int)state<0 || state==FWComplete) && fileLoaded==smtrue)
+ {
+ free(fwData);
+ fileLoaded=smfalse;
+ }
+
+ return state;
+}
+
+
+/**
+ * @brief smFirmwareUpload Sets drive in firmware upgrade mode if necessary and uploads a new firmware. Call this many until it returns value 100 (complete) or a negative value (error).
+ * @param smhandle SM bus handle, must be opened before call
+ * @param smaddress Target SM device address. Can be device in DFU mode or main operating mode. For Argon, one device in a bus must be started into DFU mode by DIP switches and smaddress must be set to 255.
+ * @param fwData pointer to memory address where .gdf file contents are loaded. Note: on some architectures (such as ARM Cortex M) fwData must be aligned to nearest 4 byte boundary to avoid illegal machine instructions.
+ * @param fwDataLenght number of bytes in fwData
+ * @return Enum FirmwareUploadStatus that indicates errors or Complete status. Typecast to integer to get progress value 0-100.
+ */
+FirmwareUploadStatus smFirmwareUploadFromBuffer( const smbus smhandle, const int smaddress, smuint8 *fwData, const int fwDataLength )
+{
static smuint32 primaryMCUDataOffset, primaryMCUDataLenth;
static smuint32 secondaryMCUDataOffset,secondaryMCUDataLength;
static UploadState state=StatIdle;//state machine status
@@ -582,7 +616,7 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
{
if(deviceType==4000)//argon does not support restarting in DFU mode by software
{
- return abortFWUpload(FWConnectionError,fwData,&state,200);
+ return abortFWUpload(FWConnectionError,&state,200);
}
//restart device into DFU mode
@@ -590,7 +624,7 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
stat=smSetParameter(smhandle,smaddress,SMP_SYSTEM_CONTROL,64);//reset device to DFU command
if(stat!=SM_OK)
- return abortFWUpload(FWConnectionError,fwData,&state,300);
+ return abortFWUpload(FWConnectionError,&state,300);
}
else
state=StatFindDFUDevice;//search DFU device in brute force, fallback for older BL versions that don't preserve same smaddress than non-DFU mode
@@ -633,22 +667,19 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
}
if(i==256)//DFU device not found
- return abortFWUpload(FWConnectingDFUModeFailed,fwData,&state,400);//setting DFU mode failed
+ return abortFWUpload(FWConnectingDFUModeFailed,&state,400);//setting DFU mode failed
progress=3;
}
else if(state==StatLoadFile)
{
- if(loadBinaryFile(firmware_filename,&fwData,&fwDataLength)!=smtrue)
- return FWFileNotReadable;
-
FirmwareUploadStatus stat=verifyFirmwareData(fwData, fwDataLength, deviceType,
&primaryMCUDataOffset, &primaryMCUDataLenth,
&secondaryMCUDataOffset, &secondaryMCUDataLength);
if(stat!=FWComplete)//error in verify
{
- return abortFWUpload(stat,fwData,&state,100);
+ return abortFWUpload(stat,&state,100);
}
//all good, upload firmware
@@ -662,7 +693,7 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
smbool ret=flashFirmwarePrimaryMCU(smhandle,DFUAddress,fwData+primaryMCUDataOffset,primaryMCUDataLenth,&progress);
if(ret==smfalse)//failed
{
- return abortFWUpload(FWConnectionError,fwData,&state,1000);
+ return abortFWUpload(FWConnectionError,&state,1000);
}
else
{
@@ -685,3 +716,4 @@ FirmwareUploadStatus smFirmwareUpload( const smbus smhandle, const int smaddress
+
diff --git a/devicedeployment.h b/devicedeployment.h
index 4ba793e..f9cfaa1 100644
--- a/devicedeployment.h
+++ b/devicedeployment.h
@@ -54,6 +54,16 @@ typedef enum
*/
LIB FirmwareUploadStatus smFirmwareUpload(const smbus smhandle, const int smaddress, const char *firmware_filename );
+/**
+ * @brief smFirmwareUpload Sets drive in firmware upgrade mode if necessary and uploads a new firmware. Call this many until it returns value 100 (complete) or a negative value (error).
+ * @param smhandle SM bus handle, must be opened before call
+ * @param smaddress Target SM device address. Can be device in DFU mode or main operating mode. For Argon, one device in a bus must be started into DFU mode by DIP switches and smaddress must be set to 255.
+ * @param fwData pointer to memory address where .gdf file contents are loaded. Note: on some architectures (such as ARM Cortex M) fwData must be aligned to nearest 4 byte boundary to avoid illegal machine instructions.
+ * @param fwDataLenght number of bytes in fwData
+ * @return Enum FirmwareUploadStatus that indicates errors or Complete status. Typecast to integer to get progress value 0-100.
+ */
+FirmwareUploadStatus smFirmwareUploadFromBuffer( const smbus smhandle, const int smaddress, smuint8 *fwData, const int fwDataLength );
+
typedef enum
{
CFGComplete=100,
diff --git a/pcserialport.c b/pcserialport.c
index 35a7668..5134a6d 100644
--- a/pcserialport.c
+++ b/pcserialport.c
@@ -41,16 +41,32 @@ smint32 serialPortOpen(const char * port_device_name, smint32 baudrate_bps)
struct termios new_port_settings;
int customBaudRate = 0;
- port_handle = open(port_device_name, O_RDWR | O_NOCTTY);
+ port_handle = open(port_device_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(port_handle==-1)
{
smDebug(-1, Low, "Serial port error: port open failed");
- return(port_handle);
+ return -1;
+ }
+
+
+ // open() follows POSIX semantics: multiple open() calls to the same file will succeed
+ // unless the TIOCEXCL ioctl is issued (except for root)
+ if (ioctl(port_handle, TIOCEXCL) == -1) {
+ smDebug(-1, Low, "Serial port error: error setting TIOCEXCL");
+ close(port_handle);
+ return -1;
+ }
+
+ // as the port is now open, clear O_NONBLOCK flag for subsequent I/O calls
+ if (fcntl(port_handle, F_SETFL, 0) == -1) {
+ smDebug(-1, Low, "Serial port error: error clearing O_NONBLOCK");
+ close(port_handle);
+ return -1;
}
switch(baudrate_bps)
- {
+ {
#if defined(B9600)
case 9600 : baudrateEnumValue = B9600; break;
#endif
@@ -107,48 +123,61 @@ smint32 serialPortOpen(const char * port_device_name, smint32 baudrate_bps)
#endif
default:
customBaudRate = 1;
-#if defined(__APPLE__)
- if (ioctl(port_handle, IOSSIOSPEED, &baudrate_bps) == -1)
- {
- smDebug(-1, Low, "Serial port error: unsupported baudrate\n");
- close(port_handle);
- return -1;
- }
-#else
- smDebug(-1,Low,"Serial port error: unsupported baudrate\n");
- close(port_handle);
- return(-1);
- break;
-#endif
- }
+ baudrateEnumValue=B9600;//must set something initially, changed later
+ break;
+ }
memset(&new_port_settings, 0, sizeof(new_port_settings)); //reset struct
-
+ cfmakeraw(&new_port_settings);//reset struct
new_port_settings.c_cflag = CS8 | CLOCAL | CREAD;
- new_port_settings.c_iflag = IGNPAR;
- new_port_settings.c_oflag = 0;
- new_port_settings.c_lflag = 0;
+ new_port_settings.c_iflag = IGNPAR;
+ new_port_settings.c_oflag = 0;
+ new_port_settings.c_lflag = 0;
new_port_settings.c_cc[VMIN] = 0; /* non blocking mode */
new_port_settings.c_cc[VTIME] = readTimeoutMs/100; /* timeout 100 ms steps */
- if (!customBaudRate)
- {
#if defined(_BSD_SOURCE)
- cfsetspeed(&new_port_settings, baudrateEnumValue);
+ cfsetspeed(&new_port_settings, baudrateEnumValue);
#else
- cfsetispeed(&new_port_settings, baudrateEnumValue);
- cfsetospeed(&new_port_settings, baudrateEnumValue);
+ cfsetispeed(&new_port_settings, baudrateEnumValue);
+ cfsetospeed(&new_port_settings, baudrateEnumValue);
#endif
- }
// Activate settings
err = tcsetattr(port_handle, TCSANOW, &new_port_settings);
if(err==-1)
- {
+ {
close(port_handle);
smDebug(-1, Low, "Serial port error: failed to set port parameters");
return -1;
- }
+ }
+
+ if(customBaudRate)
+ {
+ #if defined(IOSSIOSPEED)
+ speed_t bps = baudrate_bps;
+ if (ioctl(port_handle, IOSSIOSPEED, &bps) == -1)
+ {
+ smDebug(-1, Low, "Serial port error: unsupported baudrate\n");
+ close(port_handle);
+ return -1;
+ }
+ #else
+ smDebug(-1, Low, "Serial port error: unsupported baudrate\n");
+ close(port_handle);
+ return -1;
+ #endif
+ }
+
+ // set receive latency to 1 ms
+ #if defined(IOSSDATALAT)
+ unsigned long microsecs = 1000UL;
+ if (ioctl(port_handle, IOSSDATALAT, &microsecs) == -1) {
+ smDebug(-1, Low, "Serial port error: error setting read latency");
+ close(port_handle);
+ return -1;
+ }
+ #endif
//flush any stray bytes from device receive buffer that may reside in it
//note: according to following page, delay before this may be necessary http://stackoverflow.com/questions/13013387/clearing-the-serial-ports-buffer
diff --git a/simplemotion_defs.h b/simplemotion_defs.h
index 34dca1e..4f1bd96 100644
--- a/simplemotion_defs.h
+++ b/simplemotion_defs.h
@@ -576,6 +576,8 @@
#define SMP_TORQUE_EFFECT_FRICTION 242
//define inertia effect gain in torque control mode, torque added to setpoint equals -acceleration*gain
#define SMP_TORQUE_EFFECT_INERTIA 243
+//special smoothing filter. 0=disabled, other choices application dependent. this value is not saved in flash at the time of release, set it in run-time.
+#define SMP_SETPOINT_FILTER_MODE 244
//secondary feedback loop 300-399
//NOT IMPLEMENTED YET
diff --git a/tcpclient.c b/tcpclient.c
index 31fb2f2..09d2426 100644
--- a/tcpclient.c
+++ b/tcpclient.c
@@ -56,7 +56,7 @@ int OpenTCPPort(const char * ip_addr, int port)
fd_set myset;
int res, valopt;
socklen_t lon;
- long arg;
+ unsigned long arg;
#if defined(_WIN32)
initwsa();
@@ -98,7 +98,7 @@ int OpenTCPPort(const char * ip_addr, int port)
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO(&myset);
- FD_SET(sockfd, &myset);
+ FD_SET((unsigned int)sockfd, &myset);
if (select(sockfd+1, NULL, &myset, NULL, &tv) > 0)
{
lon = sizeof(int);
@@ -138,7 +138,7 @@ int PollTCPPort(int sockfd, unsigned char *buf, int size)
int n;
fd_set input;
FD_ZERO(&input);
- FD_SET(sockfd, &input);
+ FD_SET((unsigned int)sockfd, &input);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = readTimeoutMs * 1000;
@@ -155,14 +155,14 @@ int PollTCPPort(int sockfd, unsigned char *buf, int size)
return(-1);
}
- n = read(sockfd, buf, size);
+ n = read(sockfd, (char*)buf, size);
return(n);
}
int SendTCPByte(int sockfd, unsigned char byte)
{
int n;
- n = write(sockfd, &byte, 1);
+ n = write(sockfd, (char*)&byte, 1);
if(n<0)
return(1);
return(0);
@@ -171,7 +171,7 @@ int SendTCPByte(int sockfd, unsigned char byte)
int SendTCPBuf(int sockfd, unsigned char *buf, int size)
{
- int sent = write(sockfd, buf, size);
+ int sent = write(sockfd, (char*)buf, size);
if (sent != size)
{
return sent;