/*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ #include #include "k_debug.h" #include "k_file.h" #include "bsl.h" #include "bslcomm.h" unsigned char rxFrame[MAX_FRAME_SIZE]; unsigned char txFrame[MAX_FRAME_SIZE]; //extern int try_sync; //extern int bsl_timeout; static struct k_file *kfp=NULL; /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ void CloseCom(void) { if( kfp ) K_CLOSE(kfp); kfp=NULL; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int Init_Com(char *comport, unsigned int baud) { int rv=0; kfp = K_OPEN(comport,O_NONBLOCK | O_RDONLY,0); if( kfp==NULL ) { _D("k_open of %s failed\n",comport); return ERR_OPEN_COMM_INIT; } rv=SetBaudrate(kfp,baud); if( rv<0 ) { _E("SetBaudrate to %d failed (%d)\n",baud,rv); return ERR_OPEN_COMM_INIT; } return ERR_NONE; } /*-------------------------------------------------------------------------------------*\ * Calculates a checksum of "data". \*-------------------------------------------------------------------------------------*/ unsigned short calcChecksum(unsigned char data[], unsigned short length) { unsigned short* i_data; unsigned short checksum= 0; unsigned char i= 0; i_data= (unsigned short*)data; for (i= 0; i < length/2; i++) { checksum^= i_data[i]; /* xor-ing */ } return(checksum ^ 0xffff); /* inverting */ } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ static int Rx( unsigned char *buf, int len, int timeout ) { int rv=0; int tt = timeout; while( tt-- && len ) { rv = K_READ( kfp, buf, len ); //_D("K_READ(%d)->%d [EAGAIN=%d]\n",len,rv,-EAGAIN); if( rv<0 && rv==-EAGAIN) { msleep(100); } else { return rv; } } return rv; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ static int Tx( unsigned char *buf, int len, int timeout ) { int rv=0; int tt = timeout; while( tt-- && len ) { rv = K_WRITE( kfp, buf, len ); if( rv<0 && rv==-EAGAIN) { msleep(100); } else { return rv; } } return rv; } /*-------------------------------------------------------------------------------------*\ * Transmits Synchronization character and expects to * receive Acknowledge character * Return == 0: OK * Return == 1: Sync. failed. * timeout - value * 100ms -> 3 equals 300ms \*-------------------------------------------------------------------------------------*/ int bslSync(int trys, int timeout) { unsigned char ch; int rv=0; while (trys--) { ch = BSL_CMD_SYNC; /* Send synchronization byte: */ rv = Tx( &ch, 1, timeout ); if( rv!=1 ) { return ERR_BSL_SYNC; } msleep(100); rv = Rx( &ch, 1, timeout ); if( rv!=1 ) { return ERR_BSL_SYNC; } if (ch == BSL_DATA_ACK) { return ERR_NONE; } } return ERR_BSL_SYNC; } /*-------------------------------------------------------------------------------------*\ \*-------------------------------------------------------------------------------------*/ int comTxRx(unsigned char cmd, unsigned char dataOut[], unsigned char length) { int error = ERR_TIMEOUT; int rv = 0; unsigned short checksum= 0; unsigned int all_received, no_timeout; int index; /*--- Transmitting part - Prepare data for transmit ---*/ if ((length % 2) != 0) { /*--- Fill with one byte to have even number of bytes to send ---*/ txFrame[BSL_AL_OFF + length++]= 0xFF; /*--- fill with 0xFF ---*/ } txFrame[BSL_HDR_OFF]= BSL_DATA_FRAME; txFrame[BSL_CMD_OFF]= cmd; txFrame[BSL_L1_OFF]= length; txFrame[BSL_L2_OFF]= length; length += 4; /*--- consider Headerlen ---*/ checksum= calcChecksum(txFrame, length); txFrame[length++]= (unsigned char)(checksum); txFrame[length++]= (unsigned char)(checksum >> 8); #if 0 { unsigned short accessAddr= (0x0212 + (checksum^0xffff)) & 0xfffe; /* 0x0212: Address of wCHKSUM */ if (BSLMemAccessWarning && (accessAddr < BSL_CRITICAL_ADDR)) { printf("WARNING: This command might change data " "at address %x or %x!\n", accessAddr, accessAddr + 1); } } #endif index=0; while( index%d\n",error); return(error); } /*-------------------------------------------------------------------------------------*\ * Transmits a command (cmd) with its parameters: * start-address (addr), length (len) and additional * data (blkout) to boot loader. * Parameters return by boot loader are passed via blkin. * Return == 0: OK * Return != 0: Error! \*-------------------------------------------------------------------------------------*/ int bslTxRx(unsigned char cmd, unsigned short addr, unsigned short len, unsigned char* blkout, unsigned char* blkin) { int error; unsigned short length= 4; // /* Make sure that len is even, when sending data to BSL: */ // if ((cmd == BSL_CMD_TXBLK) && ((len % 2) != 0)) // { /* Inc. len and fill blkout with 0xFF // * => even number of bytes to send! // */ // blkout[(len++)]= 0xFF; // } if (cmd == BSL_CMD_TXBLK) { if ((addr % 2) != 0) { /* Align to even start address */ addr--; /* Decrement address and */ memmove(&blkout[1], &blkout[0], len); /* fill first byte of blkout with 0xFF */ blkout[0]= 0xFF; len++; } if ((len % 2) != 0) { /* Make sure that len is even */ blkout[(len++)]= 0xFF; /* Inc. len and fill last byte of blkout with 0xFF */ } } // /* Make sure that len is even, if receiving data from BSL: */ // if ((cmd == BSL_CMD_RXBLK) && ((len % 2) != 0)) { // len++; // } if (cmd == BSL_CMD_RXBLK) { if ((addr % 2) != 0) { /* Align to even start address */ addr--; /* Decrement address but */ len++; /* request an additional byte. */ } if ((len % 2) != 0) { /* Make sure that len is even */ len++; } } if ((cmd == BSL_CMD_TXBLK) || (cmd == BSL_CMD_TXPWORD)) { length = len + 4; } /* Add necessary information data to frame: */ txFrame[BSL_AL_OFF] = (unsigned char)( addr & 0x00ff); txFrame[BSL_AH_OFF] = (unsigned char)((addr >> 8) & 0x00ff); txFrame[BSL_LL_OFF] = (unsigned char)( len & 0x00ff); txFrame[BSL_LH_OFF] = (unsigned char)((len >> 8) & 0x00ff); if (blkout != NULL) { /* Copy data out of blkout into frame: */ memcpy(&txFrame[BSL_DATA_OFF], blkout, len); } if (bslSync(/*try_sync*/2, /*bsl_timeout*/10) != ERR_NONE) { return(ERR_BSL_SYNC); } error = comTxRx(cmd, txFrame, (unsigned char)length); /* Send frame: */ if (blkin != NULL) { /* Copy received data out of frame buffer into blkin: */ memcpy(blkin, &rxFrame[4], rxFrame[2]); } return (error); }