00001
00002
00003
00004
00005
00006
00007 #include "fztatCtrl.h"
00008 #include <stdio.h>
00009
00010
00011 FZTAT_Ctrl::FZTAT_Ctrl(const char* device, long writeBaudrate)
00012 : error_message("no error"), con(NULL), debug_level(0), view_callback(NULL),
00013 con_device(device), write_baudrate(writeBaudrate), mode(NotInitialized) {
00014
00015 char* level = getenv("DEBUG_VIEW");
00016 if (level) {
00017 debug_level = atoi(level);
00018 }
00019 }
00020
00021
00022 FZTAT_Ctrl::~FZTAT_Ctrl(void) {
00023 disconnect();
00024 }
00025
00026
00027 const char* FZTAT_Ctrl::what(void) {
00028 return error_message.c_str();
00029 }
00030
00031
00032 int FZTAT_Ctrl::connect(long baudrate) {
00033 disconnect();
00034
00035 con = new SerialDevice;
00036 int ret_value = con->connect(con_device, baudrate);
00037 if (!ret_value) {
00038 error_message = con->what();
00039 }
00040 return ret_value;
00041 }
00042
00043
00044 void FZTAT_Ctrl::disconnect(void) {
00045 delete con;
00046 con = NULL;
00047 }
00048
00049
00050 bool FZTAT_Ctrl::adjustBaudrate(void) {
00051 if (mode != NotInitialized) {
00052 error_message = "adjustBaudrate() must be called 1st.";
00053 return false;
00054 }
00055 mode = Invalid;
00056 if (debug_level >= 2) {
00057 mode = BaudrateAdjusted;
00058 return true;
00059 }
00060
00061
00062 enum { FirstBaudrate = 9600, SendTimes = 64 };
00063 if (connect(FirstBaudrate) < 0) {
00064 return false;
00065 }
00066
00067 int i;
00068 char send_ch = 0x00;
00069 for (i = 0; i < SendTimes; ++i) {
00070 for (int j = 0; j < 3; ++j) {
00071 con->send(&send_ch, 1);
00072 }
00073 unsigned char recv_ch = 0xff;
00074 if ((con->recv((char*)&recv_ch, 1, 1) > 0) && (recv_ch == 0x00)) {
00075 break;
00076 }
00077 }
00078 if (i == SendTimes) {
00079 error_message = "no reply! (expected 0x00)";
00080 return false;
00081 }
00082 con->flush();
00083
00084 send_ch = 0x55;
00085 unsigned char recv_ch = 0xff;
00086 con->send(&send_ch, 1);
00087 int n = con->recv((char*)&recv_ch, 1, Timeout);
00088 if ((n > 0) && (recv_ch == 0xaa)) {
00089 mode = BaudrateAdjusted;
00090 return true;
00091 }
00092
00093 error_message = "no reply! (expected 0xaa)";
00094 return false;
00095 }
00096
00097
00098 bool FZTAT_Ctrl::sendWriteProgram(char* code, int size) {
00099 if (mode != BaudrateAdjusted) {
00100 error_message = "sendWriteProgram() must be called 2nd.";
00101 return false;
00102 }
00103 mode = Invalid;
00104 if (debug_level >= 2) {
00105 mode = ProgramSended;
00106 return true;
00107 }
00108
00109
00110 char size_array[] = { size >> 8, size & 0xff };
00111 con->send(size_array, 2);
00112
00113 char recv_buffer[2];
00114 int n = con->recv(recv_buffer, 2, Timeout);
00115 if ((n < 2) || strncmp(size_array, recv_buffer, 2)) {
00116 error_message = "send program size: echo back fail!";
00117 return false;
00118 }
00119
00120
00121 con->send(code, size);
00122 for (int i = 0; i < size; ++i) {
00123 char echoback_ch;
00124 con->recv(&echoback_ch, 1, Timeout);
00125 }
00126
00127 if ((con->recv(recv_buffer, 1, Timeout) <= 0) ||
00128 (static_cast<unsigned char>(recv_buffer[0]) != 0xaa)) {
00129 error_message = "no reply! (expected 0xaa)";
00130 return false;
00131 }
00132 con->setBaudrate(write_baudrate);
00133
00134 mode = ProgramSended;
00135 return true;
00136 }
00137
00138
00139 void FZTAT_Ctrl::setProgressCallback(progressView_t func) {
00140 view_callback = func;
00141 }
00142
00143
00144 bool FZTAT_Ctrl::isLF(const char ch) {
00145 return ((ch == '\r') || (ch == '\n')) ? true : false;
00146 }
00147
00148
00149 long FZTAT_Ctrl::setDataBuffer(char* buffer, SFormat_Ctrl::srec_t* srec) {
00150
00151
00152 long address = srec->address & 0xffffffe0;
00153 buffer[0] = static_cast<char>(address >> 24);
00154 buffer[1] = static_cast<char>(address >> 16);
00155 buffer[2] = static_cast<char>(address >> 8);
00156 buffer[3] = static_cast<char>(address);
00157
00158
00159 int offset = (srec->address & 0x00000010) ? 16 : 0;
00160 for (int i = 0; i < 16; ++i) {
00161 buffer[4 + offset + i] = srec->byte_data[i];
00162 }
00163
00164
00165 char sum = 0;
00166 for (int i = 0; i < 4 + 32; ++i) {
00167 sum += buffer[i];
00168 }
00169 buffer[4 + 32] = sum;
00170
00171 return address;
00172 }
00173
00174
00175 bool FZTAT_Ctrl::fillSendBuffer(int* sended,
00176 char* buffer, const char* code, int left) {
00177 enum { InvalidAddress = -1 };
00178 long now_address = InvalidAddress;
00179 int index = 0;
00180 bool doSend = false;
00181 memset(buffer, 0, 4 + 32 + 1);
00182
00183 for (int i = 0; (i < 2) && (index < left); ) {
00184 SFormat_Ctrl::srec_t srec;
00185 int n = SFormat_Ctrl::parseSFormat(&srec, &code[index]);
00186 if (n <= 0) {
00187 *sended = n;
00188 return doSend;
00189 }
00190 if (debug_level > 0) {
00191 for (int j = 0; j < n; ++j) {
00192 fprintf(stderr, "%c", code[index + j]);
00193 }
00194 fprintf(stderr, "\n");
00195 }
00196
00197 if ((srec.type < 1) || (srec.type > 3)) {
00198 index += n;
00199 continue;
00200 }
00201
00202 long set_address = srec.address & 0xffffffe0;
00203 if ((now_address != InvalidAddress) && (now_address != set_address)) {
00204 *sended = index;
00205 return doSend;
00206 }
00207 now_address = setDataBuffer(buffer, &srec);
00208 index += n;
00209 doSend = true;
00210
00211 ++i;
00212 }
00213 *sended = index;
00214 return doSend;
00215 }
00216
00217
00218 bool FZTAT_Ctrl::writeRom(char* code, int size, long baudrate) {
00219 if (mode != ProgramSended) {
00220 error_message = "writeRom() must be called 3rd.";
00221 return false;
00222 }
00223 mode = Invalid;
00224
00225
00226 char send_buffer[LineMax];
00227 sprintf(send_buffer, "S%ld\n", write_baudrate);
00228 int len = strlen(send_buffer);
00229 if (debug_level > 0) {
00230 fprintf(stderr, "%s", send_buffer);
00231 }
00232
00233 char recv_buffer[LineMax];
00234 if (debug_level < 2) {
00235 con->send(send_buffer, len);
00236 con->setBaudrate(write_baudrate);
00237 if ((con->recv(recv_buffer, 1, Timeout) <= 0) || (recv_buffer[0] != '0')) {
00238 error_message = "no reply! (expected '0')";
00239 return false;
00240 }
00241 }
00242
00243
00244 int retry_times = 0;
00245 int sended = 0;
00246 do {
00247 retry_times = 0;
00248
00249 int srec_size = 0;
00250 bool doSend = fillSendBuffer(&srec_size,
00251 send_buffer, &code[sended], size - sended);
00252 if (srec_size <= 0) {
00253 error_message = "S-Format file error!";
00254 return false;
00255 }
00256 if (doSend && (debug_level > 0)) {
00257 for (int i = 0; i < 4 + 32 + 1; ++i) {
00258 fprintf(stderr, "%02x", (unsigned char)send_buffer[i]);
00259 }
00260 fprintf(stderr, "\n");
00261 }
00262 sended += srec_size;
00263 if (view_callback) {
00264 view_callback(sended, size);
00265 }
00266 if (debug_level >= 2) {
00267 continue;
00268 }
00269
00270 do {
00271 if (doSend) {
00272 con->send(send_buffer, 4 + 32 + 1);
00273 }
00274 int n = con->recv(recv_buffer, 1, Timeout);
00275 if (!doSend || ((n > 0) && (recv_buffer[0] == '0'))) {
00276 break;
00277 }
00278 if (n < 1) {
00279 error_message = "reply timeout!";
00280 return false;
00281
00282 } else if (recv_buffer[0] == 'E') {
00283 error_message = "flush writing fail!";
00284 return false;
00285 }
00286
00287 } while (retry_times++ < RetryMax);
00288 if (retry_times == RetryMax) {
00289 error_message = "retry times over";
00290 return false;
00291 }
00292 } while (sended < size);
00293
00294 mode = Writed;
00295 return true;
00296 }
00297