root/trunk/libffado/src/fireworks/fireworks_firmware.cpp

Revision 864, 7.8 kB (checked in by ppalmers, 15 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "fireworks_device.h"
25 #include "fireworks_firmware.h"
26 #include "efc/efc_avc_cmd.h"
27 #include "efc/efc_cmd.h"
28 #include "efc/efc_cmds_flash.h"
29
30 #include <string>
31 #include <sstream>
32 #include <iostream>
33 #include <fstream>
34
35 using namespace std;
36
37 template <class T>
38 bool from_string(T& t,
39                  const std::string& s,
40                  std::ios_base& (*f)(std::ios_base&))
41 {
42   std::istringstream iss(s);
43   return !(iss >> f >> t).fail();
44 }
45
46 // These classes provide support for reading/writing the firmware on
47 // echo fireworks based devices
48 namespace FireWorks {
49
50 IMPL_DEBUG_MODULE( Firmware, Firmware, DEBUG_LEVEL_NORMAL );
51 IMPL_DEBUG_MODULE( FirmwareUtil, FirmwareUtil, DEBUG_LEVEL_NORMAL );
52
53 // the firmware class
54
55 // some generic string generation functions
56 const char *Firmware::eDatTypeToString(const enum Firmware::eDatType type) {
57     switch (type) {
58         case eDT_DspCode:
59             return "Dsp Code";
60         case eDT_IceLynxCode:
61             return "IceLynx Code";
62         case eDT_Data:
63             return "Data";
64         case eDT_FPGACode:
65             return "FPGA Code";
66         case eDT_DeviceName:
67             return "Device Name";
68         default:
69             return "invalid";
70     }
71 }
72
73 const enum Firmware::eDatType Firmware::intToeDatType(int type) {
74     switch (type) {
75         case (int)eDT_DspCode: return eDT_DspCode;
76         case (int)eDT_IceLynxCode: return eDT_IceLynxCode;
77         case (int)eDT_Data: return eDT_Data;
78         case (int)eDT_FPGACode: return eDT_FPGACode;
79         case (int)eDT_DeviceName: return eDT_DeviceName;
80         default:
81             return eDT_Invalid;
82     }
83 }
84
85 Firmware::Firmware()
86 : m_Type ( eDT_Invalid )
87 , m_flash_offset_address ( 0 )
88 , m_length_quads ( 0 )
89 , m_CRC32 ( 0 )
90 , m_checksum ( 0 )
91 , m_version ( 0 )
92 , m_append_crc ( false )
93 , m_footprint_quads ( 0 )
94 , m_data( NULL )
95 {
96 }
97
98 Firmware::~Firmware()
99 {
100     if (m_data) delete[] m_data;
101 }
102
103 void
104 Firmware::show()
105 {
106     debugOutput(DEBUG_LEVEL_NORMAL, "Firmware from %s\n", m_filename.c_str());
107     debugOutput(DEBUG_LEVEL_NORMAL, " Type                 : %s\n", eDatTypeToString(m_Type));
108     if (m_Type == eDT_Invalid) return;
109
110     unsigned int version_major = (m_version & 0xFF000000) >> 24;
111     unsigned int version_minor = (m_version & 0x00FF0000) >> 16;
112     unsigned int version_build = (m_version & 0x0000FFFF);
113     debugOutput(DEBUG_LEVEL_NORMAL, " Address Offset       : 0x%08lX\n", m_flash_offset_address);
114     debugOutput(DEBUG_LEVEL_NORMAL, " Lenght (Quadlets)    : 0x%08lX\n", m_length_quads);
115     debugOutput(DEBUG_LEVEL_NORMAL, " CRC 32               : 0x%08lX\n", m_CRC32);
116     debugOutput(DEBUG_LEVEL_NORMAL, " Checksum             : 0x%08lX\n", m_checksum);
117     debugOutput(DEBUG_LEVEL_NORMAL, " Firmware version     : %02u.%02u.%02u (0x%08X)\n",
118                                     version_major, version_minor, version_build, m_version);
119     debugOutput(DEBUG_LEVEL_NORMAL, " Append CRC           : %s\n", (m_append_crc?"Yes":"No"));
120     debugOutput(DEBUG_LEVEL_NORMAL, " Footprint (Quadlets) : 0x%08lX\n", m_footprint_quads);
121 }
122
123 bool
124 Firmware::loadFile(std::string filename)
125 {
126     debugOutput(DEBUG_LEVEL_VERBOSE, "Loading firmware from file %s\n", filename.c_str());
127     fstream fwfile;
128    
129     debugOutput(DEBUG_LEVEL_VERBOSE, " Loading file...\n");
130     fwfile.open( filename.c_str(), ios::in | ios::ate);
131     if ( !fwfile.is_open() ) {
132         debugError("Could not open file.\n");
133         return false;
134     }
135     // get file size
136     int size;
137     size = (int)fwfile.tellg();
138    
139     if( size > ECHO_FIRMWARE_FILE_MAX_LENGTH_BYTES) {
140         debugError("File too large (%d bytes).\n", size);
141         return false;
142     }
143    
144     debugOutput(DEBUG_LEVEL_VERBOSE, " Checking magic...\n");
145     // read magic
146     if( size < ECHO_FIRMWARE_MAGIC_LENGTH_BYTES) {
147         debugError("File too small (%d bytes) to contain the magic header.\n", size);
148         return false;
149     }
150    
151     fwfile.seekg (0, ios::beg);
152     getline(fwfile, m_magic);
153     // get rid of the DOS-Style end of line
154     string::size_type loc = m_magic.find( '\r' );
155     if( loc != string::npos ) {
156         m_magic.erase(loc);
157     }
158     loc = m_magic.find( '\n' );
159     if( loc != string::npos ) {
160         m_magic.erase(loc);
161     }
162    
163     // check the magic
164     if (m_magic != ECHO_FIRMWARE_MAGIC) {
165         debugError("Magic was '%s' but should have been '%s'\n",
166                     m_magic.c_str(), ECHO_FIRMWARE_MAGIC);
167         return false;
168     }
169
170     debugOutput(DEBUG_LEVEL_VERBOSE, "   magic OK...\n");
171    
172     debugOutput(DEBUG_LEVEL_VERBOSE, " Reading header...\n");
173     // read header
174     if( size < ECHO_FIRMWARE_MAGIC_LENGTH_BYTES + ECHO_FIRMWARE_HEADER_LENGTH_BYTES) {
175         debugError("File too small to contain the header.\n");
176         return false;
177     }
178    
179     for (int i=0; i < ECHO_FIRMWARE_HEADER_LENGTH_QUADLETS; i++) {
180         std::string buffer;
181         getline(fwfile, buffer);
182         // get rid of the DOS-Style end of line
183         string::size_type loc = buffer.find( '\r' );
184         if( loc != string::npos ) {
185             buffer.erase(loc);
186         }
187         loc = buffer.find( '\n' );
188         if( loc != string::npos ) {
189             buffer.erase(loc);
190         }
191        
192         if (!from_string<uint32_t>(m_header[i], buffer, std::hex)) {
193             debugWarning("Could not convert '%s' to uint32_t\n", buffer.c_str());
194             return false;
195         }
196        
197         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   Header %02d: %08lX\n",
198                     i, m_header[i]);
199     }
200
201     m_Type                  = intToeDatType(m_header[0]);
202     m_flash_offset_address  = m_header[1];
203     m_length_quads          = m_header[2];
204     m_CRC32                 = m_header[3];
205     m_checksum              = m_header[4];
206     m_version               = m_header[5];
207     m_append_crc            = m_header[6] != 0;
208     m_footprint_quads       = m_header[7];
209     debugOutput(DEBUG_LEVEL_VERBOSE, "  header ok...\n");
210
211     debugOutput(DEBUG_LEVEL_VERBOSE, " Reading data...\n");
212     delete m_data;
213     m_data = new uint32_t[m_length_quads];
214     for (uint32_t i=0; i < m_length_quads; i++) {
215         std::string buffer;
216         getline(fwfile, buffer);
217         // get rid of the DOS-Style end of line
218         string::size_type loc = buffer.find( '\r' );
219         if( loc != string::npos ) {
220             buffer.erase(loc);
221         }
222         loc = buffer.find( '\n' );
223         if( loc != string::npos ) {
224             buffer.erase(loc);
225         }
226        
227         if (!from_string<uint32_t>(m_data[i], buffer, std::hex)) {
228             debugWarning("Could not convert '%s' to uint32_t\n", buffer.c_str());
229             return false;
230         }
231        
232         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   Data %02d: %08lX\n",
233                     i, m_data[i]);
234     }
235     debugOutput(DEBUG_LEVEL_VERBOSE, "  data ok...\n");
236     fwfile.close();
237
238     m_filename =  filename;
239     return false;
240 }
241
242 // the firmware loader helper class
243 FirmwareUtil::FirmwareUtil(FireWorks::Device& p)
244 : m_Parent(p)
245 {
246 }
247
248 FirmwareUtil::~FirmwareUtil()
249 {
250 }
251
252 void
253 FirmwareUtil::show()
254 {
255     debugOutput(DEBUG_LEVEL_NORMAL, "FirmwareUtil\n");
256 }
257
258 } // FireWorks
Note: See TracBrowser for help on using the browser.