Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / mcu / libfitkit /

filetransfer.c

   1  /*******************************************************************************
   2     filetransfer.c: data transfer routines
   3     Copyright (C) 2009 Brno University of Technology,
   4                        Faculty of Information Technology
   5  
   6     LICENSE TERMS
   7  
   8     Redistribution and use in source and binary forms, with or without
   9     modification, are permitted provided that the following conditions
  10     are met:
  11     1. Redistributions of source code must retain the above copyright
  12        notice, this list of conditions and the following disclaimer.
  13     2. Redistributions in binary form must reproduce the above copyright
  14        notice, this list of conditions and the following disclaimer in
  15        the documentation and/or other materials provided with the
  16        distribution.
  17     3. All advertising materials mentioning features or use of this software
  18        or firmware must display the following acknowledgement:
  19  
  20          This product includes software developed by the University of
  21          Technology, Faculty of Information Technology, Brno and its
  22          contributors.
  23  
  24     4. Neither the name of the Company nor the names of its contributors
  25        may be used to endorse or promote products derived from this
  26        software without specific prior written permission.
  27  
  28     This software or firmware is provided ``as is'', and any express or implied
  29     warranties, including, but not limited to, the implied warranties of
  30     merchantability and fitness for a particular purpose are disclaimed.
  31     In no event shall the company or contributors be liable for any
  32     direct, indirect, incidental, special, exemplary, or consequential
  33     damages (including, but not limited to, procurement of substitute
  34     goods or services; loss of use, data, or profits; or business
  35     interruption) however caused and on any theory of liability, whether
  36     in contract, strict liability, or tort (including negligence or
  37     otherwise) arising in any way out of the use of this software, even
  38     if advised of the possibility of such damage.
  39  
  40     $Id$
  41  *******************************************************************************/
  42  
  43  #include "arch_specific.h"
  44  #include "fitkitlib.h"
  45  #include "define.h"
  46  #include "spi.h"
  47  #include "uart.h"
  48  
  49  char serial_rx_timeout(unsigned short timeout) {
  50    unsigned short tmout = timeout;
  51  
  52    while ((UART_RX_BUF_EMPTY) && (tmout != 0)) {
  53      delay_ms(1);
  54      tmout--;
  55    }
  56  
  57    if (tmout != 0)
  58      return UART_RX_BUF;
  59  
  60    return '\0';
  61  }
  62  
  63  #define flash_status_wait_cond(cond) \
  64   {SPI_set_cs_FLASH(1); SPI_write(OPCODE_STATUS); while (1) { ch=SPI_read_write(0); if (cond) break; }; SPI_set_cs_FLASH(0); }
  65  
  66  #define flash_status(ch) \
  67   {SPI_set_cs_FLASH(1); SPI_write(OPCODE_STATUS); ch=SPI_read_write(0); SPI_set_cs_FLASH(0);}
  68  
  69  void serial_tx_buf(char * buf) {
  70    char *ptr = buf;
  71  
  72    while (*ptr != '\0') {
  73      serial_tx(*ptr);
  74      ptr++;
  75    }
  76  }
  77  
  78  #define STX  0x01
  79  #define ETX  0x03
  80  #define SOT  0x02
  81  #define EOT  0x04
  82  #define ACK  0x06
  83  #define NAK  0x15
  84  
  85  void send_header(char *title, char *mask, unsigned short maxPages) {
  86    char buf[10];
  87    short i;
  88    unsigned long maxSize = maxPages;
  89    maxSize = maxSize * (unsigned long)(PAGE_SIZE);
  90  
  91    serial_tx(STX);
  92    serial_tx_buf("UPLOADFILE;");
  93    if (title != 0) {
  94      serial_tx_buf("title=");
  95      serial_tx_buf(title);
  96      serial_tx_buf(";");
  97    }
  98    if (mask != 0) {
  99      serial_tx_buf("mask=");
 100      serial_tx_buf(mask);
 101      serial_tx_buf(";");
 102    }
 103    if (maxSize != 0) {
 104      serial_tx_buf("maxsize=");
 105      i = 0;
 106      while ((i<10) && (maxSize != 0)) {
 107        buf[i] = digit2chr(maxSize % 10);
 108        i++;
 109        maxSize = maxSize / 10;
 110      }
 111      do {
 112        i--;
 113        serial_tx(buf[i]);
 114      } while (i != 0);
 115    }
 116    serial_tx(ETX);
 117  }
 118  
 119  char writePageToFlash(unsigned short page, unsigned int* param) {
 120    unsigned char ch, bsum;
 121    unsigned char checksum;
 122    short i;
 123  
 124    flash_status_wait_cond((ch & 0x80) != 0);
 125  
 126    //WRITE TO BUFFER
 127    SPI_set_cs_FLASH(1);
 128    SPI_write(OPCODE_WRITE_BUF1);
 129    SPI_write(0);
 130    SPI_write(0); //addr HI
 131    SPI_write(0); //addr LO
 132  
 133    serial_tx(ACK);
 134    serial_rx(checksum);
 135  
 136    bsum = 0;
 137    for (i=0; i < 264; i++) { //data WR
 138      serial_rx(ch);
 139      SPI_write(ch);
 140      bsum += ch;
 141    }
 142    while (SPI_BUSY); //cekat, az je odeslano
 143    SPI_set_cs_FLASH(0);
 144  
 145    if (bsum != checksum) {
 146      serial_tx(NAK);
 147      return 0; //error
 148    }
 149    serial_tx(ACK);
 150  
 151    //WRITE BUFFER TO MEMORY WITH ERASE
 152    /*
 153    while ((TXEPT & U1TCTL) == 0);
 154    */
 155    flash_status_wait_cond((ch & 0x80) != 0);
 156  
 157    SPI_set_cs_FLASH(1);
 158    SPI_write(OPCODE_BUF1_MEMORY_WERASE);
 159    page = page << 1;
 160    SPI_write(page >> 8);
 161    SPI_write(page & 0xFF);
 162    SPI_write(0);
 163    SPI_set_cs_FLASH(0);
 164  
 165    /*
 166    return 0; //ERR
 167    */
 168  
 169    return 1; //OK
 170  }
 171  
 172  void transmittFile(unsigned short startPage, char *title, char *mask,
 173        unsigned short maxPages,
 174        char (*ProcessPageCB)(unsigned short page, unsigned int* param), //callback
 175        void* CBparam) {
 176  
 177    unsigned short page;
 178    unsigned short pagecnt;
 179    char try;
 180    char ch;
 181  
 182    WDG_stop();
 183  
 184    send_header(title, mask, maxPages);
 185  
 186    ch = serial_rx_timeout(2000);
 187    if (ch != ACK) {
 188      serial_tx(NAK);
 189      serial_tx_buf("init timeout");
 190      return;
 191    }
 192    serial_tx(ACK);
 193  
 194    page = startPage;
 195    pagecnt = 0;
 196    try = 3;
 197    while (1) {
 198      serial_rx(ch);
 199  
 200      if (ch != SOT) {
 201        serial_tx((ch == EOT) ? ACK : NAK);
 202        break;
 203      }
 204  
 205      if (ch == SOT) {
 206        if ((maxPages!=0) && (pagecnt == maxPages)) {
 207          /*
 208          serial_tx_buf("ERROR: file too big");
 209          */
 210          serial_tx(0x04); //EOT
 211          return;
 212        }
 213        ch = ProcessPageCB(page, CBparam);
 214        if (ch == 1) {
 215          page++;
 216          pagecnt++;
 217          try = 3;
 218        }
 219        else {
 220          if (try == 0) {
 221            serial_tx(0x04); //EOT
 222            return;
 223          }
 224          try--;
 225        }
 226      }
 227  
 228    }
 229  }
 230  
 231  
 232  char sendPageSPI(unsigned short page, unsigned int* bytes) {
 233    unsigned char ch, bsum;
 234    unsigned char checksum;
 235    short i;
 236  
 237    serial_tx(ACK);
 238    serial_rx(checksum);
 239  
 240    bsum = 0;
 241    for (i=0; i < 264; i++) { //data WR
 242      serial_rx(ch);
 243      if (bytes > 0) {
 244        bytes--;
 245        SPI_read_write(ch);
 246      }
 247      bsum += ch;
 248    }
 249    while (SPI_BUSY); //cekat, az je odeslano
 250  
 251    if (bsum != checksum) {
 252      serial_tx(NAK);
 253      return 0; //error
 254    }
 255    serial_tx(ACK);
 256  
 257    return 1; //OK
 258  }
 259  
 260  void SPI_WriteFile(char *title, char *mask, unsigned long maxSize) {
 261    unsigned short oldIE;
 262    unsigned long len = maxSize;
 263  
 264    #ifdef MSP_16X
 265       oldIE = IE1;
 266       IE1   &= ~(URXIE0 | UTXIE0);          // zakaz preruseni pri prijmu a vysilani
 267       transmittFile(0, title, mask, (unsigned short)((maxSize + PAGE_SIZE-1) / PAGE_SIZE), &sendPageSPI, &len);
 268       IE1 = oldIE;
 269    #endif
 270  
 271    #ifdef MSP_261X
 272       oldIE = IE2;
 273       IE2 &= ~(UCA0RXIE | UCA0TXIE);         // zakaz preruseni pri prijmu/vysilani
 274       transmittFile(0, title, mask, (unsigned short)((maxSize + PAGE_SIZE-1) / PAGE_SIZE), &sendPageSPI, &len);
 275       IE2 = oldIE;
 276    #endif
 277  }
 278  
 279  void FLASH_WriteFile(unsigned short startPage, char *title, char *mask,
 280                       unsigned short maxPages) {
 281    unsigned short oldIE;
 282  
 283    #ifdef MSP_16X
 284       oldIE = IE1;
 285       IE1   &= ~(URXIE0 | UTXIE0);          // zakaz preruseni pri prijmu a vysilani
 286       transmittFile(startPage, title, mask, maxPages, &writePageToFlash, 0);
 287       IE1 = oldIE;
 288    #endif
 289  
 290    #ifdef MSP_261X
 291       oldIE = IE2;
 292       IE2 &= ~(UCA0RXIE | UCA0TXIE);         // zakaz preruseni pri prijmu/vysilani
 293       transmittFile(startPage, title, mask, maxPages, &writePageToFlash, 0);
 294       IE2 = oldIE;
 295    #endif
 296  }
 297  
 298  
 299  char *cb_buf;
 300  char (*cb_fun)(unsigned short page, unsigned char* buf, unsigned short len);
 301  
 302  char cbPage(unsigned short page, unsigned int* bytes) {
 303    unsigned char ch, bsum;
 304    unsigned char checksum;
 305    short i;
 306  
 307    serial_tx(ACK);
 308    serial_rx(checksum);
 309  
 310    bsum = 0;
 311    for (i=0; i < 264; i++) { //data WR
 312      serial_rx(ch);
 313      if (bytes > 0) {
 314        bytes--;
 315        cb_buf[i] = ch;
 316      }
 317      bsum += ch;
 318    }
 319    while (SPI_BUSY); //cekat, az je odeslano
 320  
 321    if (bsum != checksum) {
 322      serial_tx(NAK);
 323      return 0; //error
 324    }
 325    serial_tx(ACK);
 326  
 327    cb_fun(page, cb_buf, i);
 328  
 329    return 1; //OK
 330  }
 331  
 332  void ReceiveFile(char *title, char *mask, unsigned long maxSize, char (*ProcessPageCB)(unsigned short page, unsigned char* buf, unsigned short len) ) {
 333    unsigned short oldIE;
 334    unsigned long len = maxSize;
 335    char sbuf[265];
 336    int i;
 337    for (i =0; i < 265; i++) sbuf[i] = 0xFF;
 338    cb_buf = sbuf;
 339    cb_fun = ProcessPageCB;
 340  
 341    #ifdef MSP_16X
 342       oldIE = IE1;
 343       IE1   &= ~(URXIE0 | UTXIE0);          // zakaz preruseni pri prijmu a vysilani
 344       transmittFile(0, title, mask, (unsigned short)((maxSize + PAGE_SIZE-1) / PAGE_SIZE), &cbPage, &len);
 345       IE1 = oldIE;
 346    #endif
 347  
 348    #ifdef MSP_261X
 349       oldIE = IE2;
 350       IE2 &= ~(UCA0RXIE | UCA0TXIE);         // zakaz preruseni pri prijmu/vysilani
 351       transmittFile(0, title, mask, (unsigned short)((maxSize + PAGE_SIZE-1) / PAGE_SIZE), &cbPage, &len);
 352       IE2 = oldIE;
 353    #endif
 354  }
 355  
 356  
Zobrazeno: 731736x Naposledy: 29.11.2022 04:52:17