OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-hex2quartus/] [main.c] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 jlechner
/* Copyright (C) 2010, 2011 Embedded Computing Systems Group,
2
Department of Computer Engineering, Vienna University of Technology.
3
Contributed by Martin Walter <mwalter@opencores.org>
4
 
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published
7
by the Free Software Foundation, either version 2.1 of the License, or
8
(at your option) any later version.
9
 
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU Lesser General Public License for more details.
14
 
15
You should have received a copy of the GNU Lesser General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
 
18
 
19
#include <inttypes.h>
20
#include <stdio.h>
21
#include <string.h>
22
 
23
#define SCARTS_INSN_SIZE 2
24
 
25
#define NUM_HEX_CHARS_PER_BYTE         2
26
#define IHEX_MAX_LINE_LEN             50
27
#define IHEX_FIELD_BYTE_COUNT_OFFSET   1
28
#define IHEX_FIELD_BYTE_COUNT_LEN      2
29
#define IHEX_FIELD_ADDRESS_OFFSET      3
30
#define IHEX_FIELD_ADDRESS_LEN         4
31
#define IHEX_FIELD_RECORD_TYPE_OFFSET  7
32
#define IHEX_FIELD_RECORD_TYPE_LEN     2
33
#define IHEX_FIELD_PAYLOAD_OFFSET      9
34
#define IHEX_FIELD_CHECKSUM_LEN        2
35
#define IHEX_REC_TYPE_DATA             0
36
#define IHEX_REC_TYPE_EOF              1
37
#define IHEX_REC_TYPE_EXT_SEG_ADDR     2
38
#define IHEX_REC_TYPE_EXT_LIN_ADDR     4
39
 
40
 
41
typedef struct
42
{
43
  uint8_t  byte_count;
44
  uint16_t address;
45
  uint8_t  type;
46
  uint8_t  checksum_offset;
47
  uint8_t  checksum;
48
} ihex16_t;
49
 
50
static uint8_t compute_checksum (char *);
51
static uint8_t char_to_int (char);
52
static char    int_to_char (uint8_t);
53
 
54
static uint8_t
55
compute_checksum (char *buffer)
56
{
57
  uint8_t checksum, i, j;
58
  checksum = 0;
59
 
60
  for (i = 1; i < (strlen(buffer) - IHEX_FIELD_CHECKSUM_LEN) / NUM_HEX_CHARS_PER_BYTE; ++i)
61
  {
62
    j = NUM_HEX_CHARS_PER_BYTE * i - 1;
63
    checksum += (char_to_int (buffer[j]) << 4) + char_to_int (buffer[j + 1]);
64
  }
65
 
66
  checksum ^= 0xFF;
67
  checksum += 1;
68
 
69
  return (uint8_t) checksum;
70
}
71
 
72
static uint8_t
73
char_to_int (char c)
74
{
75
  if (c >= '0' && c <= '9')
76
    return c - 48;
77
  else if (c >= 'A' && c <= 'F')
78
    return c - 55;
79
  else
80
    return 0;
81
}
82
 
83
static char
84
int_to_char (uint8_t i)
85
{
86
  if (i >= 0 && i <= 9)
87
    return i + 48;
88
  else if (i >= 10 && i <= 15)
89
    return i + 55;
90
  else
91
    return '0';
92
}
93
 
94
int main (int argc, char *argv[])
95
{
96
  char buffer[IHEX_MAX_LINE_LEN + 1];
97
  uint8_t i;
98
  ihex16_t ihex;
99
 
100
  while (1)
101
  {
102
    if (fgets (buffer, IHEX_MAX_LINE_LEN, stdin) == NULL)
103
      break;
104
 
105
    /* Check if the line starts with a ':'. */
106
    if (buffer[0] != ':')
107
      continue;
108
 
109
    /* Extract the byte count.*/
110
    ihex.byte_count = 0;
111
    for (i = 0; i < IHEX_FIELD_BYTE_COUNT_LEN; ++i)
112
      ihex.byte_count += char_to_int (buffer[IHEX_FIELD_BYTE_COUNT_OFFSET + i]) << 4 * (IHEX_FIELD_BYTE_COUNT_LEN - i - 1);
113
 
114
    /* Extract the address. */
115
    ihex.address = 0;
116
    for (i = 0; i < IHEX_FIELD_ADDRESS_LEN; ++i)
117
      ihex.address += char_to_int (buffer[IHEX_FIELD_ADDRESS_OFFSET + i]) << 4 * (IHEX_FIELD_ADDRESS_LEN - i - 1);
118
 
119
    /* Extract the record type. */
120
    ihex.type = 0;
121
    for (i = 0; i < IHEX_FIELD_RECORD_TYPE_LEN; ++i)
122
      ihex.type += char_to_int (buffer[IHEX_FIELD_RECORD_TYPE_OFFSET + i]) << 4 * (IHEX_FIELD_RECORD_TYPE_LEN - i - 1);
123
 
124
    /* Calculate the checksum offset. */
125
    ihex.checksum_offset = IHEX_FIELD_PAYLOAD_OFFSET + ihex.byte_count * 2;
126
 
127
    /* Only process data and eof records */
128
    if (ihex.type != IHEX_REC_TYPE_DATA &&
129
        ihex.type != IHEX_REC_TYPE_EOF)
130
    {
131
      continue;
132
    }
133
 
134
 
135
    /* Process the current record. */
136
    if (ihex.type == IHEX_REC_TYPE_DATA
137
        || ihex.type == IHEX_REC_TYPE_EXT_SEG_ADDR
138
        || ihex.type == IHEX_REC_TYPE_EXT_LIN_ADDR)
139
    {
140
      switch (ihex.type)
141
      {
142
        case IHEX_REC_TYPE_EXT_SEG_ADDR:
143
        case IHEX_REC_TYPE_EXT_LIN_ADDR:
144
        {
145
          /* Divide the data by SCARTS_INSN_SIZE and write back. */
146
          uint16_t temp = 0;
147
          for (i = 0; i < (ihex.byte_count * 2); ++i)
148
            temp += char_to_int (buffer[IHEX_FIELD_PAYLOAD_OFFSET + i]) << 4 * (ihex.byte_count * 2 - i - 1);
149
 
150
          temp /= SCARTS_INSN_SIZE;
151
 
152
          for (i = 0; i < ihex.byte_count * 2; ++i)
153
          {
154
            char nibble = int_to_char ((temp >> 4 * (ihex.byte_count * 2 - i - 1)) & 0xF);
155
            buffer[IHEX_FIELD_PAYLOAD_OFFSET + i] = nibble;
156
          }
157
 
158
          break;
159
        }
160
        default:
161
          break;
162
      }
163
 
164
      /* Divide the byte count by SCARTS_INSN_SIZE and write back. */
165
      //ihex.byte_count /= SCARTS_INSN_SIZE;
166
      for (i = 0; i < IHEX_FIELD_BYTE_COUNT_LEN; ++i)
167
      {
168
        char nibble = int_to_char ((ihex.byte_count >> 4 * (IHEX_FIELD_BYTE_COUNT_LEN - i - 1)) & 0xF);
169
        buffer[IHEX_FIELD_BYTE_COUNT_OFFSET + i] = nibble;
170
      }
171
 
172
      /* Divide the address by SCARTS_INSN_SIZE and write back. */
173
      ihex.address /= SCARTS_INSN_SIZE;
174
      for (i = 0; i < IHEX_FIELD_ADDRESS_LEN; ++i)
175
      {
176
        char nibble = int_to_char ((ihex.address >> 4 * (IHEX_FIELD_ADDRESS_LEN - i - 1)) & 0xF);
177
        buffer[IHEX_FIELD_ADDRESS_OFFSET + i] = nibble;
178
      }
179
 
180
      /* Compute the checksum and write back. */
181
      ihex.checksum = compute_checksum (buffer);
182
      for (i = 0; i < IHEX_FIELD_CHECKSUM_LEN; ++i)
183
      {
184
        char nibble = int_to_char ((ihex.checksum >> 4 * (IHEX_FIELD_CHECKSUM_LEN - i - 1)) & 0xF);
185
        buffer[ihex.checksum_offset + i] = nibble;
186
      }
187
    }
188
 
189
    printf ("%s", buffer);
190
  }
191
 
192
  return 0;
193
}
194
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.