1 //=============================================================================
3 //=============================================================================
4 // FILE-NAME: serialdownload.cpp
5 // FUNCTION: Serial download of a new image from PC to SIMpad
7 // AUTHOR: Juergen Messerer, Peter Voser
8 // CREAT.-DATE: 01.04.2001 (dd.mm.yy)
12 //=============================================================================
15 #include "serialdownload.h"
18 //=============================================================================
19 //=============================================================================
20 SerialDownload::SerialDownload()
24 //=============================================================================
25 //=============================================================================
26 SerialDownload::~SerialDownload()
30 //=============================================================================
31 //=============================================================================
32 int SerialDownload::openSerialPort(const char* portDev, int& errorNumber)
34 _serialPort = open(portDev, O_RDWR | O_NONBLOCK);
36 if (_serialPort == -1)
42 // Read old serial port setup
43 termios serialPortSetup;
44 int success = tcgetattr(_serialPort, &serialPortSetup );
52 serialPortSetup.c_iflag = 0L;
53 serialPortSetup.c_oflag = 0L;
56 serialPortSetup.c_cflag &= ~(CSTOPB|PARENB|CRTSCTS);
57 serialPortSetup.c_cflag |= (CS8|CLOCAL);
60 serialPortSetup.c_lflag = 0L;
63 serialPortSetup.c_cc[VTIME] = 0;
64 serialPortSetup.c_cc[VMIN] = 0;
66 // Set baud rate = 38.4kBaud
67 cfsetispeed(&serialPortSetup, B38400);
68 cfsetospeed(&serialPortSetup, B38400);
70 success=tcsetattr(_serialPort, TCSANOW, &serialPortSetup);
81 //=============================================================================
82 //=============================================================================
83 int SerialDownload::loadFile(const char *fileName,
89 if((path = fopen(fileName,"rb")) == 0)
91 // Specified file not found.
96 numberOfBytes = ftell(path);
99 buffer = (char*)malloc((size_t)numberOfBytes);
102 // Insufficient memory to load file.
107 if(fread(buffer, numberOfBytes, 1, path) != 1)
118 //=============================================================================
119 //=============================================================================
120 bool SerialDownload::changeBaudRate(const int newBaudRate,
125 struct termios setup;
155 success = tcgetattr(_serialPort, &setup);
163 cfsetispeed(&setup, baudRate);
164 cfsetospeed(&setup, baudRate);
165 success = tcsetattr(_serialPort, TCSANOW, &setup);
176 //=============================================================================
177 //=============================================================================
178 unsigned char SerialDownload::waitForReply(const int transparent)
184 struct pollfd commEvent;
185 commEvent.fd = _serialPort;
186 commEvent.events = POLLIN;
190 // Wait until a character has received.
193 reply = poll(&commEvent, 1, 1000);
197 if(commEvent.revents == POLLIN)
201 numberBytes=read(_serialPort, &c, 1);
202 if(transparent && numberBytes)
222 //=============================================================================
223 //=============================================================================
224 int SerialDownload::connectToSimpad(const int fastBaudRate,
231 // Switch baud rate to low connecting baud rate.
232 if(!changeBaudRate(38400, errorNumber))
237 // Wait for character STX (02) and BEL (07)
238 while(waitForReply(1) != STX);
239 while(waitForReply(1) != BEL);
240 bytesWritten = write(_serialPort, &ACK_BD, 1);
247 // Send byte #2 of baud rate
248 c = (fastBaudRate>>16)&0xff;
249 bytesWritten = write(_serialPort, &c, 1);
256 // Send byte #1 of baud rate
257 c = (fastBaudRate>>8)&0xff;
258 bytesWritten = write(_serialPort, &c, 1);
265 // Send byte #0 of baud rate
266 c = fastBaudRate&0xff;
267 bytesWritten = write(_serialPort, &c, 1);
277 // Switch baud rate to fast baud rate.
278 if(!changeBaudRate(fastBaudRate, errorNumber))
284 // Wait for 1st character with new baud rate.
285 while(waitForReply(1) != STX);
287 bytesWritten = write(_serialPort, &STX, 1);
294 while(waitForReply(1) != STX);
298 //=============================================================================
299 //=============================================================================
300 bool SerialDownload::sendBlock(const char *buffer,
305 unsigned char c, check=0xff;
313 // It's a complete block.
314 bytesWritten = write(_serialPort, buffer, 512);
321 for(i = 0; i < 512; ++i)
323 check=(check<<1) ^ buffer[i];
328 // It's an incomplete block, which must be filled with
329 // the FILLER pattern.
331 for(i = 0; i < 512; ++i)
336 check=(check<<1) ^ buffer[i];
337 lastBlock[i] = buffer[i];
342 check=(check<<1) ^ FILLER;
343 lastBlock[i] = FILLER;
346 bytesWritten = write(_serialPort, lastBlock, 512);
354 while(waitForReply(1) != STX);
358 bytesWritten = write(_serialPort, &STX, 1);
367 // It was the last block.
368 bytesWritten = write(_serialPort, &ETX, 1);
377 bytesWritten = write(_serialPort, &check, 1);
384 // Wait for ACK_OK as confirmation. Send block again otherwise.
388 // The block was successfully sent.
394 //=============================================================================
395 //=============================================================================
396 void SerialDownload::waitForEndOfBurning(void)
398 // Wait for ETX, which indicates the end of burning.
399 while(waitForReply(1) != ETX);
401 // Send the characters "r" (erase registry) and "o" (power off).
404 bytesWritten = write(_serialPort, &c, 1);
406 bytesWritten = write(_serialPort, &c, 1);