1 //
2 // srecord - manipulate eprom load files
3 // Copyright (C) 2000-2003, 2006-2010, 2012 Peter Miller
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 by
7 // the Free Software Foundation; either version 3 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
17 // <http://www.gnu.org/licenses/>.
18 //
19
20 #include <srecord/arglex/tool.h>
21 #include <srecord/input/filter/message/crc16.h>
22 #include <srecord/memory.h>
23 #include <srecord/memory/walker/crc16.h>
24 #include <srecord/record.h>
25
26
~input_filter_message_crc16()27 srecord::input_filter_message_crc16::~input_filter_message_crc16()
28 {
29 }
30
31
input_filter_message_crc16(const input::pointer & deeper_arg,unsigned long address_arg,endian_t a_end)32 srecord::input_filter_message_crc16::input_filter_message_crc16(
33 const input::pointer &deeper_arg, unsigned long address_arg,
34 endian_t a_end) :
35 input_filter_message(deeper_arg),
36 address(address_arg),
37 end(a_end),
38 seed_mode(crc16::seed_mode_ccitt),
39 augment_flag(true),
40 polynomial(crc16::polynomial_ccitt),
41 bitdir(crc16::bit_direction_most_to_least)
42 {
43 }
44
45
46 srecord::input::pointer
create(const input::pointer & a_deeper,unsigned long a_address,endian_t a_end)47 srecord::input_filter_message_crc16::create(const input::pointer &a_deeper,
48 unsigned long a_address, endian_t a_end)
49 {
50 return
51 pointer
52 (
53 new input_filter_message_crc16(a_deeper, a_address, a_end)
54 );
55 }
56
57
58 void
command_line(arglex_tool * cmdln)59 srecord::input_filter_message_crc16::command_line(arglex_tool *cmdln)
60 {
61 for (;;)
62 {
63 switch (cmdln->token_cur())
64 {
65 case arglex::token_number:
66 polynomial = cmdln->value_number();
67 cmdln->token_next();
68 break;
69
70 case arglex_tool::token_crc16_most_to_least:
71 bitdir = crc16::bit_direction_most_to_least;
72 cmdln->token_next();
73 break;
74
75 case arglex_tool::token_crc16_least_to_most:
76 bitdir = crc16::bit_direction_least_to_most;
77 cmdln->token_next();
78 break;
79
80 case arglex_tool::token_crc16_xmodem:
81 seed_mode = crc16::seed_mode_xmodem;
82 cmdln->token_next();
83 break;
84
85 case arglex_tool::token_crc16_ccitt:
86 seed_mode = crc16::seed_mode_ccitt;
87 polynomial = crc16::polynomial_ccitt;
88 cmdln->token_next();
89 break;
90
91 case arglex_tool::token_polynomial:
92 // polynomial = crc16::polynomial_ansi;
93 switch (cmdln->token_next())
94 {
95 case arglex::token_number:
96 polynomial = cmdln->value_number();
97 break;
98
99 case arglex_tool::token_crc16_ccitt:
100 polynomial = crc16::polynomial_ccitt;
101 break;
102
103 case arglex::token_string:
104 polynomial =
105 crc16::polynomial_by_name(cmdln->value_string().c_str());
106 break;
107
108 default:
109 fatal_error("expected --polynomial <name>");
110 }
111 cmdln->token_next();
112 break;
113
114 case arglex_tool::token_crc16_broken:
115 seed_mode = crc16::seed_mode_broken;
116 cmdln->token_next();
117 break;
118
119 case arglex_tool::token_crc16_augment:
120 augment_flag = true;
121 cmdln->token_next();
122 break;
123
124 case arglex_tool::token_crc16_augment_not:
125 augment_flag = false;
126 cmdln->token_next();
127 break;
128
129 default:
130 return;
131 }
132 }
133 }
134
135
136 void
process(const memory & buffer,record & result)137 srecord::input_filter_message_crc16::process(const memory &buffer,
138 record &result)
139 {
140 //
141 // Now CRC16 the bytes in order from lowest address to highest.
142 // (Holes are ignored, not filled, warning already issued.)
143 //
144 memory_walker_crc16::pointer w =
145 memory_walker_crc16::create
146 (
147 seed_mode,
148 augment_flag,
149 polynomial,
150 bitdir
151 );
152 buffer.walk(w);
153 unsigned crc = w->get();
154
155 //
156 // Turn the CRC into the first data record.
157 //
158 unsigned char chunk[2];
159 record::encode(chunk, crc, sizeof(chunk), end);
160 result = record(record::type_data, address, chunk, sizeof(chunk));
161 }
162
163
164 const char *
get_algorithm_name() const165 srecord::input_filter_message_crc16::get_algorithm_name()
166 const
167 {
168 return "CRC16";
169 }
170