Subversion Repositories HomeAutomation

Rev

Rev 328 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include "ihex.h"
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7.  
  8. unsigned char cksum;
  9.  
  10. unsigned char hex2byte(const unsigned char *p) {
  11.     int i;
  12.     unsigned char c, ret=0;
  13.    
  14.     for (i=0; i<2; i++) {
  15.         if (*p>='0' && *p<='9')
  16.             c = *p-'0';
  17.         else if (*p>='A' && *p<='F')
  18.             c = *p-'A'+10;
  19.         else if (*p>='a' && *p<='f')
  20.             c = *p-'a'+10;
  21.         else
  22.             printf("Bad file format.\n");
  23.         ret = (ret << 4) + c;
  24.         p++;
  25.     }
  26.     cksum += ret;
  27.     return ret;
  28. }
  29.  
  30. int ihexLoadFile(char* file, unsigned char* buf, long *start_addr, long *len) {
  31.     int fd;
  32.     char read_char;
  33.     unsigned char hex_byte[2];
  34.     unsigned char reclen, rectyp;
  35.     unsigned int offset, expected_offset=-1;
  36.     unsigned char hex_buf[512], *p;
  37.     int i, segments=0;
  38.     int start_addr_set = 0;
  39.    
  40.     fd = open(file, O_RDONLY);
  41.     *len = 0;
  42.    
  43.     while (1) {
  44.         do {
  45.             if (read(fd, &read_char, 1) != 1) return 0;
  46.         } while (read_char != ':');
  47.         cksum = 0;
  48.        
  49.         if (read(fd, &hex_byte, 2) != 2) return 0;
  50.         reclen = hex2byte(hex_byte);
  51.        
  52.         if (read(fd, &hex_byte, 2) != 2) return 0;
  53.         offset = hex2byte(hex_byte)<<8;
  54.        
  55.         if (read(fd, &hex_byte, 2) != 2) return 0;
  56.         offset += hex2byte(hex_byte);
  57.        
  58.         if (read(fd, &hex_byte, 2) != 2) return 0;
  59.         rectyp = hex2byte(hex_byte);
  60.        
  61.         switch (rectyp) {
  62.         case 0:
  63.             if (offset != expected_offset) {
  64.                 // new segment
  65.                 printf("New segment at offset 0x%x. Previous ended at 0x%x.\n", offset, expected_offset);
  66.                 segments++;
  67.             }
  68.                
  69.             if (read(fd, &hex_buf, reclen*2) != reclen*2) return 0;
  70.             p = hex_buf;
  71.             for (i = 0; i < reclen; i++) {
  72.                 buf[(*len)++] = hex2byte(p);
  73.                 p += 2;
  74.             }
  75.             expected_offset = offset + reclen;
  76.             if (!start_addr_set) {
  77.                 *start_addr = offset;
  78.                 start_addr_set = 1;
  79.             }
  80.             break;
  81.         case 1:
  82.             //*len = expected_offset - *start_addr;
  83.             close(fd);
  84.             return segments;
  85.         case 2:
  86.         case 3:
  87.         case 4:
  88.         case 5:
  89.             if (read(fd, &hex_buf, reclen*2) != reclen*2) return 0;
  90.             p = hex_buf;
  91.             for (i = 0; i < reclen; i++) {
  92.                 hex2byte(p);
  93.                 p += 2;
  94.             }
  95.             break;
  96.         default:
  97.             printf("Error in hex-file!\n");
  98.         }
  99.         if (read(fd, &hex_byte, 2) != 2) return 0;
  100.         hex2byte(hex_byte);
  101.         if (cksum != 0) {
  102.             printf("Invalid checksum!\n");
  103.             return 0;
  104.         }
  105.     }
  106.     return 0;
  107. }
  108.