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

Revision 937, 7.8 kB (checked in by ppalmers, 16 years ago)

cleanup some compilation warnings

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     #ifdef DEBUG
107     debugOutput(DEBUG_LEVEL_NORMAL, "Firmware from %s\n", m_filename.c_str());
108     debugOutput(DEBUG_LEVEL_NORMAL, " Type                 : %s\n", eDatTypeToString(m_Type));
109     if (m_Type == eDT_Invalid) return;
110
111     unsigned int version_major = (m_version & 0xFF000000) >> 24;
112     unsigned int version_minor = (m_version & 0x00FF0000) >> 16;
113     unsigned int version_build = (m_version & 0x0000FFFF);
114     debugOutput(DEBUG_LEVEL_NORMAL, " Address Offset       : 0x%08lX\n", m_flash_offset_address);
115     debugOutput(DEBUG_LEVEL_NORMAL, " Lenght (Quadlets)    : 0x%08lX\n", m_length_quads);
116     debugOutput(DEBUG_LEVEL_NORMAL, " CRC 32               : 0x%08lX\n", m_CRC32);
117     debugOutput(DEBUG_LEVEL_NORMAL, " Checksum             : 0x%08lX\n", m_checksum);
118     debugOutput(DEBUG_LEVEL_NORMAL, " Firmware version     : %02u.%02u.%02u (0x%08X)\n",
119                                     version_major, version_minor, version_build, m_version);
120     debugOutput(DEBUG_LEVEL_NORMAL, " Append CRC           : %s\n", (m_append_crc?"Yes":"No"));
121     debugOutput(DEBUG_LEVEL_NORMAL, " Footprint (Quadlets) : 0x%08lX\n", m_footprint_quads);
122     #endif
123 }
124
125 bool
126 Firmware::loadFile(std::string filename)
127 {
128     debugOutput(DEBUG_LEVEL_VERBOSE, "Loading firmware from file %s\n", filename.c_str());
129     fstream fwfile;
130    
131     debugOutput(DEBUG_LEVEL_VERBOSE, " Loading file...\n");
132     fwfile.open( filename.c_str(), ios::in | ios::ate);
133     if ( !fwfile.is_open() ) {
134         debugError("Could not open file.\n");
135         return false;
136     }
137     // get file size
138     int size;
139     size = (int)fwfile.tellg();
140    
141     if( size > ECHO_FIRMWARE_FILE_MAX_LENGTH_BYTES) {
142         debugError("File too large (%d bytes).\n", size);
143         return false;
144     }
145    
146     debugOutput(DEBUG_LEVEL_VERBOSE, " Checking magic...\n");
147     // read magic
148     if( size < ECHO_FIRMWARE_MAGIC_LENGTH_BYTES) {
149         debugError("File too small (%d bytes) to contain the magic header.\n", size);
150         return false;
151     }
152    
153     fwfile.seekg (0, ios::beg);
154     getline(fwfile, m_magic);
155     // get rid of the DOS-Style end of line
156     string::size_type loc = m_magic.find( '\r' );
157     if( loc != string::npos ) {
158         m_magic.erase(loc);
159     }
160     loc = m_magic.find( '\n' );
161     if( loc != string::npos ) {
162         m_magic.erase(loc);
163     }
164    
165     // check the magic
166     if (m_magic != ECHO_FIRMWARE_MAGIC) {
167         debugError("Magic was '%s' but should have been '%s'\n",
168                     m_magic.c_str(), ECHO_FIRMWARE_MAGIC);
169         return false;
170     }
171
172     debugOutput(DEBUG_LEVEL_VERBOSE, "   magic OK...\n");
173    
174     debugOutput(DEBUG_LEVEL_VERBOSE, " Reading header...\n");
175     // read header
176     if( size < ECHO_FIRMWARE_MAGIC_LENGTH_BYTES + ECHO_FIRMWARE_HEADER_LENGTH_BYTES) {
177         debugError("File too small to contain the header.\n");
178         return false;
179     }
180    
181     for (int i=0; i < ECHO_FIRMWARE_HEADER_LENGTH_QUADLETS; i++) {
182         std::string buffer;
183         getline(fwfile, buffer);
184         // get rid of the DOS-Style end of line
185         string::size_type loc = buffer.find( '\r' );
186         if( loc != string::npos ) {
187             buffer.erase(loc);
188         }
189         loc = buffer.find( '\n' );
190         if( loc != string::npos ) {
191             buffer.erase(loc);
192         }
193        
194         if (!from_string<uint32_t>(m_header[i], buffer, std::hex)) {
195             debugWarning("Could not convert '%s' to uint32_t\n", buffer.c_str());
196             return false;
197         }
198        
199         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   Header %02d: %08lX\n",
200                     i, m_header[i]);
201     }
202
203     m_Type                  = intToeDatType(m_header[0]);
204     m_flash_offset_address  = m_header[1];
205     m_length_quads          = m_header[2];
206     m_CRC32                 = m_header[3];
207     m_checksum              = m_header[4];
208     m_version               = m_header[5];
209     m_append_crc            = m_header[6] != 0;
210     m_footprint_quads       = m_header[7];
211     debugOutput(DEBUG_LEVEL_VERBOSE, "  header ok...\n");
212
213     debugOutput(DEBUG_LEVEL_VERBOSE, " Reading data...\n");
214     delete m_data;
215     m_data = new uint32_t[m_length_quads];
216     for (uint32_t i=0; i < m_length_quads; i++) {
217         std::string buffer;
218         getline(fwfile, buffer);
219         // get rid of the DOS-Style end of line
220         string::size_type loc = buffer.find( '\r' );
221         if( loc != string::npos ) {
222             buffer.erase(loc);
223         }
224         loc = buffer.find( '\n' );
225         if( loc != string::npos ) {
226             buffer.erase(loc);
227         }
228        
229         if (!from_string<uint32_t>(m_data[i], buffer, std::hex)) {
230             debugWarning("Could not convert '%s' to uint32_t\n", buffer.c_str());
231             return false;
232         }
233        
234         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   Data %02d: %08lX\n",
235                     i, m_data[i]);
236     }
237     debugOutput(DEBUG_LEVEL_VERBOSE, "  data ok...\n");
238     fwfile.close();
239
240     m_filename =  filename;
241     return false;
242 }
243
244 // the firmware loader helper class
245 FirmwareUtil::FirmwareUtil(FireWorks::Device& p)
246 : m_Parent(p)
247 {
248 }
249
250 FirmwareUtil::~FirmwareUtil()
251 {
252 }
253
254 void
255 FirmwareUtil::show()
256 {
257     debugOutput(DEBUG_LEVEL_NORMAL, "FirmwareUtil\n");
258 }
259
260 } // FireWorks
Note: See TracBrowser for help on using the browser.