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

Revision 689, 7.8 kB (checked in by ppalmers, 13 years ago)

more echo firmware work

Line 
1 /*
2  * Copyright (C) 2007 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 library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
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.