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