- Timestamp:
- 08/27/09 12:25:28 (14 years ago)
- Files:
-
- trunk/libffado/src/bebob/focusrite/focusrite_generic.h (modified) (1 diff)
- trunk/libffado/src/dice/dice_avdevice.cpp (modified) (7 diffs)
- trunk/libffado/src/dice/dice_avdevice.h (modified) (8 diffs)
- trunk/libffado/src/dice/dice_eap.cpp (modified) (18 diffs)
- trunk/libffado/src/dice/dice_eap.h (modified) (1 diff)
- trunk/libffado/src/dice/focusrite (added)
- trunk/libffado/src/dice/focusrite/saffire_pro40.cpp (added)
- trunk/libffado/src/dice/focusrite/saffire_pro40.h (added)
- trunk/libffado/src/fireworks/fireworks_control.h (modified) (1 diff)
- trunk/libffado/src/libcontrol/CrossbarRouter.cpp (added)
- trunk/libffado/src/libcontrol/CrossbarRouter.h (added)
- trunk/libffado/src/libcontrol/Element.cpp (modified) (1 diff)
- trunk/libffado/src/libcontrol/Element.h (modified) (1 diff)
- trunk/libffado/src/libcontrol/MatrixMixer.h (modified) (1 diff)
- trunk/libffado/src/motu/motu_controls.h (modified) (1 diff)
- trunk/libffado/src/rme/fireface_settings_ctrls.h (modified) (1 diff)
- trunk/libffado/src/SConscript (modified) (2 diffs)
- trunk/libffado/support/dbus/control-interface.xml (modified) (1 diff)
- trunk/libffado/support/dbus/controlserver.cpp (modified) (3 diffs)
- trunk/libffado/support/dbus/controlserver.h (modified) (2 diffs)
- trunk/libffado/support/tools/ffado-diag.in (modified) (4 diffs)
- trunk/libffado/tests/python (added)
- trunk/libffado/tests/python/test-eap-ctrl.py (added)
- trunk/libffado/tests/test-dice-eap.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/src/bebob/focusrite/focusrite_generic.h
r1543 r1630 187 187 virtual int getRowCount( ); 188 188 virtual int getColCount( ); 189 190 // full map updates are unsupported 191 virtual bool getCoefficientMap(int &) {return false;}; 192 virtual bool storeCoefficientMap(int &) {return false;}; 189 193 190 194 protected: trunk/libffado/src/dice/dice_avdevice.cpp
r1550 r1630 46 46 #include "devicemanager.h" 47 47 48 #include "focusrite/saffire_pro40.h" 49 48 50 using namespace std; 49 51 … … 52 54 Device::Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 53 55 : FFADODevice( d, configRom ) 56 , m_eap( NULL ) 54 57 , m_global_reg_offset (0xFFFFFFFFLU) 55 58 , m_global_reg_size (0xFFFFFFFFLU) … … 91 94 unlock(); 92 95 } 96 97 if(m_eap) { 98 delete m_eap; 99 } 100 93 101 } 94 102 … … 111 119 Device::createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 112 120 { 113 return new Device( d, configRom ); 121 unsigned int vendorId = configRom->getNodeVendorId(); 122 unsigned int modelId = configRom->getModelId(); 123 124 switch (vendorId) { 125 case FW_VENDORID_FOCUSRITE: 126 switch(modelId) { 127 case 0x00000005: 128 return new Focusrite::SaffirePro40(d, configRom); 129 default: // return a plain Dice device 130 return new Device(d, configRom); 131 } 132 default: 133 return new Device(d, configRom); 134 } 135 return NULL; 114 136 } 115 137 … … 137 159 } 138 160 161 bool supports_eap = Device::EAP::supportsEAP(*this); 162 if (supports_eap) { // FIXME: move to buildMixer() ?? 163 m_eap = new Device::EAP(*this); 164 if(m_eap == NULL) { 165 debugError("Failed to allocate EAP.\n"); 166 return false; 167 } 168 if(!m_eap->init()) { 169 debugError("Could not init EAP\n"); 170 delete m_eap; 171 m_eap = NULL; 172 return false; 173 } 174 // register the EAP controls to the control structure 175 if(!addElement(m_eap)) { 176 debugError("Failed to add the EAP controls to the control tree\n"); 177 return false; 178 } 179 } 139 180 return true; 140 181 } 141 182 183 enum Device::eDiceConfig 184 Device::getCurrentConfig() 185 { 186 int samplerate = getSamplingFrequency(); 187 if(samplerate > 31999 && samplerate <= 48000) { 188 return eDC_Low; 189 } 190 if(samplerate > 48000 && samplerate <= 96000) { 191 return eDC_Mid; 192 } 193 if(samplerate > 96000 && samplerate <= 192000) { 194 return eDC_High; 195 } 196 return eDC_Unknown; 197 } 198 142 199 int 143 Device::getSamplingFrequency( 200 Device::getSamplingFrequency() { 144 201 int samplingFrequency; 145 202 … … 1744 1801 1745 1802 if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) { 1746 debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr);1803 debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr); 1747 1804 return false; 1748 1805 } … … 1788 1845 1789 1846 if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) { 1790 debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr);1847 debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr); 1791 1848 return false; 1792 1849 } trunk/libffado/src/dice/dice_avdevice.h
r1550 r1630 36 36 #include "libieee1394/ieee1394service.h" 37 37 38 #include "libcontrol/Element.h" 39 #include "libcontrol/MatrixMixer.h" 40 #include "libcontrol/CrossbarRouter.h" 41 42 #include "dice_eap.h" 43 38 44 #include <string> 39 45 #include <vector> … … 52 58 class Device : public FFADODevice { 53 59 // private: 60 typedef std::vector< std::string > diceNameVector; 61 typedef std::vector< std::string >::iterator diceNameVectorIterator; 62 54 63 public: 55 64 class Notifier; 56 65 class EAP; 57 58 public:59 Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ));60 ~Device();61 62 static bool probe( Util::Configuration& c, ConfigRom& configRom, bool generic = false );63 static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ));64 virtual bool discover();65 66 static int getConfigurationId( );67 68 virtual void showDevice();69 70 virtual bool setSamplingFrequency( int samplingFrequency );71 virtual int getSamplingFrequency( );72 virtual std::vector<int> getSupportedSamplingFrequencies();73 74 virtual ClockSourceVector getSupportedClockSources();75 virtual bool setActiveClockSource(ClockSource);76 virtual ClockSource getActiveClockSource();77 78 virtual int getStreamCount();79 virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i);80 81 virtual bool prepare();82 83 virtual bool lock();84 virtual bool unlock();85 86 virtual bool startStreamByIndex(int i);87 virtual bool stopStreamByIndex(int i);88 89 virtual bool enableStreaming();90 virtual bool disableStreaming();91 92 virtual std::string getNickname();93 virtual bool setNickname(std::string name);94 95 protected:96 97 // streaming stuff98 typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector;99 typedef std::vector< Streaming::StreamProcessor * >::iterator StreamProcessorVectorIterator;100 StreamProcessorVector m_receiveProcessors;101 StreamProcessorVector m_transmitProcessors;102 103 private: // streaming & port helpers104 enum EPortTypes {105 ePT_Analog,106 ePT_MIDI,107 };108 109 typedef struct {110 std::string name;111 enum EPortTypes portType;112 unsigned int streamPosition;113 unsigned int streamLocation;114 } diceChannelInfo;115 116 bool addChannelToProcessor( diceChannelInfo *,117 Streaming::StreamProcessor *,118 Streaming::Port::E_Direction direction);119 120 int allocateIsoChannel(unsigned int packet_size);121 bool deallocateIsoChannel(int channel);122 123 private: // helper functions124 bool enableIsoStreaming();125 bool disableIsoStreaming();126 bool isIsoStreamingEnabled();127 128 bool maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask);129 bool maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask);130 131 typedef std::vector< std::string > diceNameVector;132 typedef std::vector< std::string >::iterator diceNameVectorIterator;133 diceNameVector splitNameString(std::string in);134 diceNameVector getTxNameString(unsigned int i);135 diceNameVector getRxNameString(unsigned int i);136 diceNameVector getClockSourceNameString();137 std::string getDeviceNickName();138 bool setDeviceNickName(std::string name);139 140 enum eClockSourceType clockIdToType(unsigned int id);141 bool isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg);142 bool isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg);143 144 private: // register I/O routines145 bool initIoFunctions();146 // quadlet read/write routines147 bool readReg(fb_nodeaddr_t, fb_quadlet_t *);148 bool writeReg(fb_nodeaddr_t, fb_quadlet_t);149 bool readRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t);150 bool writeRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t);151 152 bool readGlobalReg(fb_nodeaddr_t, fb_quadlet_t *);153 bool writeGlobalReg(fb_nodeaddr_t, fb_quadlet_t);154 bool readGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t);155 bool writeGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t);156 fb_nodeaddr_t globalOffsetGen(fb_nodeaddr_t, size_t);157 158 bool readTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *);159 bool writeTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t);160 bool readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length);161 bool writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length);162 fb_nodeaddr_t txOffsetGen(unsigned int, fb_nodeaddr_t, size_t);163 164 bool readRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *);165 bool writeRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t);166 bool readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length);167 bool writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length);168 fb_nodeaddr_t rxOffsetGen(unsigned int, fb_nodeaddr_t, size_t);169 170 fb_quadlet_t m_global_reg_offset;171 fb_quadlet_t m_global_reg_size;172 fb_quadlet_t m_tx_reg_offset;173 fb_quadlet_t m_tx_reg_size;174 fb_quadlet_t m_rx_reg_offset;175 fb_quadlet_t m_rx_reg_size;176 fb_quadlet_t m_unused1_reg_offset;177 fb_quadlet_t m_unused1_reg_size;178 fb_quadlet_t m_unused2_reg_offset;179 fb_quadlet_t m_unused2_reg_size;180 181 fb_quadlet_t m_nb_tx;182 fb_quadlet_t m_tx_size;183 fb_quadlet_t m_nb_rx;184 fb_quadlet_t m_rx_size;185 186 // private:187 public:188 // notification189 Notifier *m_notifier;190 191 /**192 * this class reacts on the DICE device writing to the193 * hosts notify address194 */195 #define DICE_NOTIFIER_BASE_ADDRESS 0x0000FFFFE0000000ULL196 #define DICE_NOTIFIER_BLOCK_LENGTH 4197 class Notifier : public Ieee1394Service::ARMHandler198 {199 public:200 Notifier(Device &, nodeaddr_t start);201 virtual ~Notifier();202 203 private:204 Device &m_device;205 };206 66 207 67 /** … … 209 69 * available on some devices 210 70 */ 211 class EAP 71 class EAP : public Control::Container 212 72 { 213 73 public: 214 class Router;215 class Mixer;216 217 private:218 74 enum eWaitReturn { 219 75 eWR_Error, … … 233 89 eRT_Standalone, 234 90 eRT_Application, 91 eRT_None, 92 }; 93 enum eRouteSource { 94 eRS_AES = 0, 95 eRS_ADAT = 1, 96 eRS_Mixer = 2, 97 eRS_InS0 = 4, 98 eRS_InS1 = 5, 99 eRS_ARM = 10, 100 eRS_ARX0 = 11, 101 eRS_ARX1 = 12, 102 eRS_Muted = 15, 103 eRS_Invalid = 16, 104 }; 105 enum eRouteDestination { 106 eRD_AES = 0, 107 eRD_ADAT = 1, 108 eRD_Mixer0 = 2, 109 eRD_Mixer1 = 3, 110 eRD_InS0 = 4, 111 eRD_InS1 = 5, 112 eRD_ARM = 10, 113 eRD_ATX0 = 11, 114 eRD_ATX1 = 12, 115 eRD_Muted = 15, 116 eRD_Invalid = 16, 117 }; 118 119 public: 120 121 // ---------- 122 class RouterConfig { 123 public: 124 struct Route 125 { 126 enum eRouteSource src; 127 int srcChannel; 128 enum eRouteDestination dst; 129 int dstChannel; 130 int peak; 131 }; 132 typedef std::vector<RouterConfig::Route> RouteVector; 133 typedef std::vector<RouterConfig::Route>::iterator RouteVectorIterator; 134 RouterConfig(EAP &); 135 RouterConfig(EAP &, enum eRegBase, unsigned int offset); 136 virtual ~RouterConfig(); 137 138 virtual bool read() {return read(m_base, m_offset);}; 139 virtual bool write() {return write(m_base, m_offset);}; 140 virtual bool read(enum eRegBase b, unsigned offset); 141 virtual bool write(enum eRegBase b, unsigned offset); 142 virtual void show(); 143 144 145 bool insertRoute(struct Route r) 146 {return insertRoute(r, m_routes.size());}; 147 bool insertRoute(struct Route r, unsigned int index); 148 bool replaceRoute(unsigned int old_index, struct Route new_route); 149 bool replaceRoute(struct Route old_route, struct Route new_route); 150 bool removeRoute(struct Route r); 151 bool removeRoute(unsigned int index); 152 int getRouteIndex(struct Route r); 153 struct Route getRoute(unsigned int index); 154 155 unsigned int getNbRoutes() {return m_routes.size();}; 156 157 struct Route getRouteForDestination(enum eRouteDestination dst, int channel); 158 RouteVector getRoutesForSource(enum eRouteSource src, int channel); 159 160 struct Route decodeRoute(uint32_t val); 161 uint32_t encodeRoute(struct Route r); 162 public: 163 static enum eRouteDestination intToRouteDestination(int); 164 static enum eRouteSource intToRouteSource(int); 165 protected: 166 EAP &m_eap; 167 enum eRegBase m_base; 168 unsigned int m_offset; 169 RouteVector m_routes; 170 protected: 171 DECLARE_DEBUG_MODULE_REFERENCE; 172 }; 173 174 // ---------- 175 // the peak space is a special version of a router config 176 class PeakSpace : public RouterConfig { 177 public: 178 PeakSpace(EAP &p) : RouterConfig(p, eRT_Peak, 0) {}; 179 virtual ~PeakSpace() {}; 180 181 virtual bool read() {return read(m_base, m_offset);}; 182 virtual bool write() {return write(m_base, m_offset);}; 183 virtual bool read(enum eRegBase b, unsigned offset); 184 virtual bool write(enum eRegBase b, unsigned offset); 185 virtual void show(); 186 }; 187 188 // ---------- 189 class StreamConfig { 190 public: 191 struct ConfigBlock { // FIXME: somewhere in the DICE avdevice this is present too 192 uint32_t nb_audio; 193 uint32_t nb_midi; 194 uint32_t names[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS]; 195 uint32_t ac3_map; 196 }; 197 void showConfigBlock(struct ConfigBlock &); 198 diceNameVector getNamesForBlock(struct ConfigBlock &b); 199 public: 200 StreamConfig(EAP &, enum eRegBase, unsigned int offset); 201 ~StreamConfig(); 202 203 bool read() {return read(m_base, m_offset);}; 204 bool write() {return write(m_base, m_offset);}; 205 bool read(enum eRegBase b, unsigned offset); 206 bool write(enum eRegBase b, unsigned offset); 207 208 void show(); 209 210 private: 211 EAP &m_eap; 212 enum eRegBase m_base; 213 unsigned int m_offset; 214 215 uint32_t m_nb_tx; 216 uint32_t m_nb_rx; 217 218 struct ConfigBlock *m_tx_configs; 219 struct ConfigBlock *m_rx_configs; 220 221 DECLARE_DEBUG_MODULE_REFERENCE; 222 }; 223 224 public: // mixer control subclass 225 class Mixer : public Control::MatrixMixer { 226 public: 227 Mixer(EAP &); 228 ~Mixer(); 229 230 bool init(); 231 void show(); 232 233 void updateNameCache(); 234 /** 235 * load the coefficients from the device into the local cache 236 * @return 237 */ 238 bool loadCoefficients(); 239 /** 240 * Stores the coefficients from the cache to the device 241 * @return 242 */ 243 bool storeCoefficients(); 244 245 virtual std::string getRowName( const int ); 246 virtual std::string getColName( const int ); 247 virtual int canWrite( const int, const int ); 248 virtual double setValue( const int, const int, const double ); 249 virtual double getValue( const int, const int ); 250 virtual int getRowCount( ); 251 virtual int getColCount( ); 252 253 // full map updates are unsupported 254 virtual bool getCoefficientMap(int &); 255 virtual bool storeCoefficientMap(int &); 256 257 private: 258 EAP & m_eap; 259 fb_quadlet_t *m_coeff; 260 261 std::map<int, RouterConfig::Route> m_input_route_map; 262 std::map<int, RouterConfig::RouteVector> m_output_route_map; 263 264 DECLARE_DEBUG_MODULE_REFERENCE; 265 }; 266 267 // ---------- 268 class Router : public Control::CrossbarRouter { 269 private: 270 struct Source { 271 std::string name; 272 enum eRouteSource src; 273 int srcChannel; 274 }; 275 typedef std::vector<Source> SourceVector; 276 typedef std::vector<Source>::iterator SourceVectorIterator; 277 278 struct Destination { 279 std::string name; 280 enum eRouteDestination dst; 281 int dstChannel; 282 }; 283 typedef std::vector<Destination> DestinationVector; 284 typedef std::vector<Destination>::iterator DestinationVectorIterator; 285 286 public: 287 Router(EAP &); 288 ~Router(); 289 290 void show(); 291 292 // to be subclassed by the implementing 293 // devices 294 virtual void setupSources(); 295 virtual void setupDestinations(); 296 297 void setupDestinationsAddDestination(const char *name, enum eRouteDestination dstid, 298 unsigned int base, unsigned int cnt); 299 void setupSourcesAddSource(const char *name, enum eRouteSource srcid, 300 unsigned int base, unsigned int cnt); 301 302 int getDestinationIndex(enum eRouteDestination dstid, int channel); 303 int getSourceIndex(enum eRouteSource srcid, int channel); 304 305 // per-coefficient access 306 virtual std::string getSourceName(const int); 307 virtual std::string getDestinationName(const int); 308 virtual int getSourceIndex(std::string); 309 virtual int getDestinationIndex(std::string); 310 virtual NameVector getSourceNames(); 311 virtual NameVector getDestinationNames(); 312 313 virtual IntVector getDestinationsForSource(const int); 314 virtual int getSourceForDestination(const int); 315 316 virtual bool canConnect( const int source, const int dest); 317 virtual bool setConnectionState( const int source, const int dest, const bool enable); 318 virtual bool getConnectionState( const int source, const int dest ); 319 320 virtual bool canConnect(std::string, std::string); 321 virtual bool setConnectionState(std::string, std::string, const bool enable); 322 virtual bool getConnectionState(std::string, std::string); 323 324 virtual bool clearAllConnections(); 325 326 virtual int getNbSources(); 327 virtual int getNbDestinations(); 328 329 // functions to access the entire routing map at once 330 // idea is that the row/col nodes that are 1 get a routing entry 331 virtual bool getConnectionMap(int *); 332 virtual bool setConnectionMap(int *); 333 334 // peak metering support 335 virtual bool hasPeakMetering(); 336 virtual bool getPeakValues(double &) {return false;}; 337 virtual double getPeakValue(const int source, const int dest); 338 339 private: 340 EAP &m_eap; 341 // these contain the sources and destinations available for this 342 // router 343 SourceVector m_sources; 344 DestinationVector m_destinations; 345 346 PeakSpace &m_peak; 347 348 DECLARE_DEBUG_MODULE_REFERENCE; 235 349 }; 236 350 … … 245 359 enum eWaitReturn operationBusy(); 246 360 enum eWaitReturn waitForOperationEnd(int max_wait_time_ms = 100); 361 362 bool updateConfigurationCache(); 363 RouterConfig * getActiveRouterConfig(); 364 StreamConfig * getActiveStreamConfig(); 365 366 bool updateRouterConfig(RouterConfig&, bool low, bool mid, bool high); 367 bool updateCurrentRouterConfig(RouterConfig&); 368 bool updateStreamConfig(StreamConfig&, bool low, bool mid, bool high); 369 bool updateStreamConfig(RouterConfig&, StreamConfig&, bool low, bool mid, bool high); 370 371 bool loadFlashConfig(); 372 bool storeFlashConfig(); 373 374 private: 247 375 bool loadRouterConfig(bool low, bool mid, bool high); 248 376 bool loadStreamConfig(bool low, bool mid, bool high); 249 377 bool loadRouterAndStreamConfig(bool low, bool mid, bool high); 250 bool loadFlashConfig();251 bool storeFlashConfig();252 253 378 private: 254 379 bool m_router_exposed; … … 260 385 bool m_mixer_readonly; 261 386 bool m_mixer_flashstored; 262 uint8_t m_mixer_ input_id;263 uint8_t m_mixer_ output_id;264 uint8_t m_mixer_nb_ inputs;265 uint8_t m_mixer_nb_ outputs;387 uint8_t m_mixer_tx_id; 388 uint8_t m_mixer_rx_id; 389 uint8_t m_mixer_nb_tx; 390 uint8_t m_mixer_nb_rx; 266 391 267 392 bool m_general_support_dynstream; … … 283 408 fb_nodeaddr_t offsetGen(enum eRegBase, unsigned, size_t); 284 409 285 Device &m_device;410 private: 286 411 DECLARE_DEBUG_MODULE_REFERENCE; 412 413 private: 414 Device & m_device; 415 Mixer* m_mixer; 416 Router* m_router; 417 RouterConfig m_current_cfg_routing_low; 418 RouterConfig m_current_cfg_routing_mid; 419 RouterConfig m_current_cfg_routing_high; 420 StreamConfig m_current_cfg_stream_low; 421 StreamConfig m_current_cfg_stream_mid; 422 StreamConfig m_current_cfg_stream_high; 423 public: 424 Mixer* getMixer() {return m_mixer;}; 425 Router* getRouter() {return m_router;}; 426 427 private: 287 428 288 429 fb_quadlet_t m_capability_offset; … … 304 445 fb_quadlet_t m_app_offset; 305 446 fb_quadlet_t m_app_size; 306 307 public: // mixer subclass308 class Mixer {309 public:310 Mixer(EAP &);311 ~Mixer();312 313 bool init();314 void show();315 bool updateCoefficients();316 317 private:318 EAP &m_parent;319 fb_quadlet_t *m_coeff;320 321 DECLARE_DEBUG_MODULE_REFERENCE;322 };323 324 class Router {325 public:326 Router(EAP &);327 ~Router();328 329 bool init();330 void show();331 332 private:333 EAP &m_parent;334 335 DECLARE_DEBUG_MODULE_REFERENCE;336 };337 338 447 }; 448 449 public: 450 Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 451 ~Device(); 452 453 static bool probe( Util::Configuration& c, ConfigRom& configRom, bool generic = false ); 454 static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 455 virtual bool discover(); 456 457 static int getConfigurationId( ); 458 459 virtual void showDevice(); 460 461 virtual bool setSamplingFrequency( int samplingFrequency ); 462 virtual int getSamplingFrequency( ); 463 virtual std::vector<int> getSupportedSamplingFrequencies(); 464 465 virtual ClockSourceVector getSupportedClockSources(); 466 virtual bool setActiveClockSource(ClockSource); 467 virtual ClockSource getActiveClockSource(); 468 469 virtual int getStreamCount(); 470 virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 471 472 virtual bool prepare(); 473 474 virtual bool lock(); 475 virtual bool unlock(); 476 477 virtual bool startStreamByIndex(int i); 478 virtual bool stopStreamByIndex(int i); 479 480 virtual bool enableStreaming(); 481 virtual bool disableStreaming(); 482 483 virtual std::string getNickname(); 484 virtual bool setNickname(std::string name); 485 486 protected: 487 // streaming stuff 488 typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; 489 typedef std::vector< Streaming::StreamProcessor * >::iterator StreamProcessorVectorIterator; 490 StreamProcessorVector m_receiveProcessors; 491 StreamProcessorVector m_transmitProcessors; 492 493 private: // streaming & port helpers 494 enum EPortTypes { 495 ePT_Analog, 496 ePT_MIDI, 497 }; 498 499 typedef struct { 500 std::string name; 501 enum EPortTypes portType; 502 unsigned int streamPosition; 503 unsigned int streamLocation; 504 } diceChannelInfo; 505 506 bool addChannelToProcessor( diceChannelInfo *, 507 Streaming::StreamProcessor *, 508 Streaming::Port::E_Direction direction); 509 510 int allocateIsoChannel(unsigned int packet_size); 511 bool deallocateIsoChannel(int channel); 512 513 private: // active config 514 enum eDiceConfig { 515 eDC_Unknown, 516 eDC_Low, 517 eDC_Mid, 518 eDC_High, 519 }; 520 521 enum eDiceConfig getCurrentConfig(); 522 523 private: // helper functions 524 bool enableIsoStreaming(); 525 bool disableIsoStreaming(); 526 bool isIsoStreamingEnabled(); 527 528 bool maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 529 bool maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 530 531 diceNameVector splitNameString(std::string in); 532 diceNameVector getTxNameString(unsigned int i); 533 diceNameVector getRxNameString(unsigned int i); 534 diceNameVector getClockSourceNameString(); 535 std::string getDeviceNickName(); 536 bool setDeviceNickName(std::string name); 537 538 enum eClockSourceType clockIdToType(unsigned int id); 539 bool isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg); 540 bool isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg); 541 542 // EAP stuff 543 private: 544 EAP* m_eap; 545 public: 546 EAP* getEAP() {return m_eap;}; 547 548 private: // register I/O routines 549 bool initIoFunctions(); 550 // quadlet read/write routines 551 bool readReg(fb_nodeaddr_t, fb_quadlet_t *); 552 bool writeReg(fb_nodeaddr_t, fb_quadlet_t); 553 bool readRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 554 bool writeRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 555 556 bool readGlobalReg(fb_nodeaddr_t, fb_quadlet_t *); 557 bool writeGlobalReg(fb_nodeaddr_t, fb_quadlet_t); 558 bool readGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 559 bool writeGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 560 fb_nodeaddr_t globalOffsetGen(fb_nodeaddr_t, size_t); 561 562 bool readTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 563 bool writeTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 564 bool readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 565 bool writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 566 fb_nodeaddr_t txOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 567 568 bool readRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 569 bool writeRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 570 bool readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 571 bool writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 572 fb_nodeaddr_t rxOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 573 574 fb_quadlet_t m_global_reg_offset; 575 fb_quadlet_t m_global_reg_size; 576 fb_quadlet_t m_tx_reg_offset; 577 fb_quadlet_t m_tx_reg_size; 578 fb_quadlet_t m_rx_reg_offset; 579 fb_quadlet_t m_rx_reg_size; 580 fb_quadlet_t m_unused1_reg_offset; 581 fb_quadlet_t m_unused1_reg_size; 582 fb_quadlet_t m_unused2_reg_offset; 583 fb_quadlet_t m_unused2_reg_size; 584 585 fb_quadlet_t m_nb_tx; 586 fb_quadlet_t m_tx_size; 587 fb_quadlet_t m_nb_rx; 588 fb_quadlet_t m_rx_size; 589 590 // private: 591 public: 592 // notification 593 Notifier *m_notifier; 594 595 /** 596 * this class reacts on the DICE device writing to the 597 * hosts notify address 598 */ 599 #define DICE_NOTIFIER_BASE_ADDRESS 0x0000FFFFE0000000ULL 600 #define DICE_NOTIFIER_BLOCK_LENGTH 4 601 class Notifier : public Ieee1394Service::ARMHandler 602 { 603 public: 604 Notifier(Device &, nodeaddr_t start); 605 virtual ~Notifier(); 606 607 private: 608 Device &m_device; 609 }; 610 611 339 612 340 613 }; trunk/libffado/src/dice/dice_eap.cpp
r1569 r1630 33 33 namespace Dice { 34 34 35 // ----------- helper functions ------------- 36 37 static const char * 38 srcBlockToString(const char id) 39 { 40 switch(id) { 41 case 0: return "AES "; 42 case 1: return "ADAT"; 43 case 2: return "MXR "; 44 case 4: return "INS0"; 45 case 5: return "INS1"; 46 case 10: return "ARM "; 47 case 11: return "AVS0"; 48 case 12: return "AVS1"; 49 case 15: return "MUTE"; 50 default : return "RSVD"; 51 } 52 } 53 54 static const char * 55 dstBlockToString(const char id) 56 { 57 switch(id) { 58 case 0: return "AES "; 59 case 1: return "ADAT"; 60 case 2: return "MXR0"; 61 case 3: return "MXR1"; 62 case 4: return "INS0"; 63 case 5: return "INS1"; 64 case 10: return "ARM "; 65 case 11: return "AVS0"; 66 case 12: return "AVS1"; 67 case 15: return "MUTE"; 68 default : return "RSVD"; 69 } 70 } 71 72 35 73 Device::EAP::EAP(Device &d) 36 : m_device(d) 37 , m_debugModule(d.m_debugModule) 74 : Control::Container(&d, "EAP") 75 , m_debugModule(d.m_debugModule) // NOTE: has to be initialized before creating the config classes 76 // otherwise the reference content used by those is bogus 77 , m_device(d) 78 , m_mixer( NULL ) 79 , m_router( NULL ) 80 , m_current_cfg_routing_low( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_ROUTER) ) 81 , m_current_cfg_routing_mid( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_MID_ROUTER) ) 82 , m_current_cfg_routing_high( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_HIGH_ROUTER) ) 83 , m_current_cfg_stream_low( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_STREAM) ) 84 , m_current_cfg_stream_mid( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_MID_STREAM) ) 85 , m_current_cfg_stream_high( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_HIGH_STREAM) ) 38 86 { 39 87 } … … 41 89 Device::EAP::~EAP() 42 90 { 91 // remove all control elements registered to this device (w/o free) 92 clearElements(false); 93 94 // delete the helper classes 95 if(m_mixer) delete m_mixer; 96 if(m_router) delete m_router; 97 } 98 99 // offsets and sizes are returned in quadlets, but we use byte values, hence the *= 4 100 #define DICE_EAP_READREG_AND_CHECK(base, addr, var) { \ 101 if(!readReg(base, addr, &var)) { \ 102 debugError("Could not initialize " #var "\n"); \ 103 return false; \ 104 } \ 105 var *= 4; \ 43 106 } 44 107 … … 51 114 52 115 // offsets and sizes are returned in quadlets, but we use byte values 53 if(!readReg(eRT_Base, DICE_EAP_CAPABILITY_SPACE_OFF, &m_capability_offset)) { 54 debugError("Could not initialize m_capability_offset\n"); 55 return false; 56 } 57 m_capability_offset *= 4; 58 59 if(!readReg(eRT_Base, DICE_EAP_CAPABILITY_SPACE_SZ, &m_capability_size)) { 60 debugError("Could not initialize m_capability_size\n"); 61 return false; 62 } 63 m_capability_size *= 4; 64 65 if(!readReg(eRT_Base, DICE_EAP_CMD_SPACE_OFF, &m_cmd_offset)) { 66 debugError("Could not initialize m_cmd_offset\n"); 67 return false; 68 } 69 m_cmd_offset *= 4; 70 71 if(!readReg(eRT_Base, DICE_EAP_CMD_SPACE_SZ, &m_cmd_size)) { 72 debugError("Could not initialize m_cmd_size\n"); 73 return false; 74 } 75 m_cmd_size *= 4; 76 77 if(!readReg(eRT_Base, DICE_EAP_MIXER_SPACE_OFF, &m_mixer_offset)) { 78 debugError("Could not initialize m_mixer_offset\n"); 79 return false; 80 } 81 m_mixer_offset *= 4; 82 83 if(!readReg(eRT_Base, DICE_EAP_MIXER_SPACE_SZ, &m_mixer_size)) { 84 debugError("Could not initialize m_mixer_size\n"); 85 return false; 86 } 87 m_mixer_size *= 4; 88 89 if(!readReg(eRT_Base, DICE_EAP_PEAK_SPACE_OFF, &m_peak_offset)) { 90 debugError("Could not initialize m_peak_offset\n"); 91 return false; 92 } 93 m_peak_offset *= 4; 94 95 if(!readReg(eRT_Base, DICE_EAP_PEAK_SPACE_SZ, &m_peak_size)) { 96 debugError("Could not initialize m_peak_size\n"); 97 return false; 98 } 99 m_peak_size *= 4; 100 101 if(!readReg(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_OFF, &m_new_routing_offset)) { 102 debugError("Could not initialize m_new_routing_offset\n"); 103 return false; 104 } 105 m_new_routing_offset *= 4; 106 107 if(!readReg(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_SZ, &m_new_routing_size)) { 108 debugError("Could not initialize m_new_routing_size\n"); 109 return false; 110 } 111 m_new_routing_size *= 4; 112 113 if(!readReg(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_OFF, &m_new_stream_cfg_offset)) { 114 debugError("Could not initialize m_new_stream_cfg_offset\n"); 115 return false; 116 } 117 m_new_stream_cfg_offset *= 4; 118 119 if(!readReg(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_SZ, &m_new_stream_cfg_size)) { 120 debugError("Could not initialize m_new_stream_cfg_size\n"); 121 return false; 122 } 123 m_new_stream_cfg_size *= 4; 124 125 if(!readReg(eRT_Base, DICE_EAP_CURR_CFG_SPACE_OFF, &m_curr_cfg_offset)) { 126 debugError("Could not initialize m_curr_cfg_offset\n"); 127 return false; 128 } 129 m_curr_cfg_offset *= 4; 130 131 if(!readReg(eRT_Base, DICE_EAP_CURR_CFG_SPACE_SZ, &m_curr_cfg_size)) { 132 debugError("Could not initialize m_curr_cfg_size\n"); 133 return false; 134 } 135 m_curr_cfg_size *= 4; 136 137 if(!readReg(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_OFF, &m_standalone_offset)) { 138 debugError("Could not initialize m_standalone_offset\n"); 139 return false; 140 } 141 m_standalone_offset *= 4; 142 143 if(!readReg(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_SZ, &m_standalone_size)) { 144 debugError("Could not initialize m_standalone_size\n"); 145 return false; 146 } 147 m_standalone_size *= 4; 148 149 if(!readReg(eRT_Base, DICE_EAP_APP_SPACE_OFF, &m_app_offset)) { 150 debugError("Could not initialize m_app_offset\n"); 151 return false; 152 } 153 m_app_offset *= 4; 154 155 if(!readReg(eRT_Base, DICE_EAP_APP_SPACE_SZ, &m_app_size)) { 156 debugError("Could not initialize m_app_size\n"); 157 return false; 158 } 159 m_app_size *= 4; 116 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CAPABILITY_SPACE_OFF, m_capability_offset); 117 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CAPABILITY_SPACE_SZ, m_capability_size); 118 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CMD_SPACE_OFF, m_cmd_offset); 119 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CMD_SPACE_SZ, m_cmd_size); 120 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_MIXER_SPACE_OFF, m_mixer_offset); 121 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_MIXER_SPACE_SZ, m_mixer_size); 122 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_PEAK_SPACE_OFF, m_peak_offset); 123 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_PEAK_SPACE_SZ, m_peak_size); 124 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_OFF, m_new_routing_offset); 125 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_SZ, m_new_routing_size); 126 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_OFF, m_new_stream_cfg_offset); 127 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_SZ, m_new_stream_cfg_size); 128 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CURR_CFG_SPACE_OFF, m_curr_cfg_offset); 129 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CURR_CFG_SPACE_SZ, m_curr_cfg_size); 130 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_OFF, m_standalone_offset); 131 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_SZ, m_standalone_size); 132 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_APP_SPACE_OFF, m_app_offset); 133 DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_APP_SPACE_SZ, m_app_size); 160 134 161 135 // initialize the capability info … … 174 148 return false; 175 149 } 176 m_mixer_exposed = (tmp >> DICE_EAP_CAP_ ROUTER_EXPOSED) & 0x01;177 m_mixer_readonly = (tmp >> DICE_EAP_CAP_ ROUTER_EXPOSED) & 0x01;178 m_mixer_flashstored = (tmp >> DICE_EAP_CAP_ ROUTER_EXPOSED) & 0x01;179 m_mixer_ input_id = (tmp >> DICE_EAP_CAP_MIXER_IN_DEV) & 0x000F;180 m_mixer_ output_id = (tmp >> DICE_EAP_CAP_MIXER_OUT_DEV) & 0x000F;181 m_mixer_nb_ inputs= (tmp >> DICE_EAP_CAP_MIXER_INPUTS) & 0x00FF;182 m_mixer_nb_ outputs= (tmp >> DICE_EAP_CAP_MIXER_OUTPUTS) & 0x00FF;150 m_mixer_exposed = (tmp >> DICE_EAP_CAP_MIXER_EXPOSED) & 0x01; 151 m_mixer_readonly = (tmp >> DICE_EAP_CAP_MIXER_READONLY) & 0x01; 152 m_mixer_flashstored = (tmp >> DICE_EAP_CAP_MIXER_FLASHSTORED) & 0x01; 153 m_mixer_tx_id = (tmp >> DICE_EAP_CAP_MIXER_IN_DEV) & 0x000F; 154 m_mixer_rx_id = (tmp >> DICE_EAP_CAP_MIXER_OUT_DEV) & 0x000F; 155 m_mixer_nb_tx = (tmp >> DICE_EAP_CAP_MIXER_INPUTS) & 0x00FF; 156 m_mixer_nb_rx = (tmp >> DICE_EAP_CAP_MIXER_OUTPUTS) & 0x00FF; 183 157 184 158 if(!readReg(eRT_Capability, DICE_EAP_CAPABILITY_GENERAL, &tmp)) { … … 194 168 m_general_chip = (tmp >> DICE_EAP_CAP_GENERAL_CHIP) & 0xFFFF; 195 169 170 // update our view on the current configuration 171 if(!updateConfigurationCache()) { 172 debugError("Could not initialize configuration cache\n"); 173 return false; 174 } 175 176 // initialize the helper classes 177 if (m_mixer_exposed) { 178 // initialize the mixer 179 m_mixer = new EAP::Mixer(*this); 180 if(m_mixer == NULL) { 181 debugError("Could not allocate memory for mixer\n"); 182 return false; 183 } 184 if(!m_mixer->init()) { 185 debugError("Could not initialize mixer\n"); 186 delete m_mixer; 187 m_mixer = NULL; 188 return false; 189 } 190 // add the mixer to the EAP control container 191 if(!addElement(m_mixer)) { 192 debugWarning("Failed to add mixer to control tree\n"); 193 } 194 195 // initialize the peak meter 196 m_router = new EAP::Router(*this); 197 if(m_router == NULL) { 198 debugError("Could not allocate memory for router\n"); 199 return false; 200 } 201 202 // add the router to the EAP control container 203 if(!addElement(m_router)) { 204 debugWarning("Failed to add router to control tree\n"); 205 } 206 } 207 196 208 return true; 197 209 } 198 210 211 bool 212 Device::EAP::updateConfigurationCache() 213 { 214 if(!m_current_cfg_routing_low.read()) { 215 debugError("Could not initialize current routing configuration (low rates)\n"); 216 return false; 217 } 218 if(!m_current_cfg_routing_mid.read()) { 219 debugError("Could not initialize current routing configuration (mid rates)\n"); 220 return false; 221 } 222 if(!m_current_cfg_routing_high.read()) { 223 debugError("Could not initialize current routing configuration (high rates)\n"); 224 return false; 225 } 226 if(!m_current_cfg_stream_low.read()) { 227 debugError("Could not initialize current stream configuration (low rates)\n"); 228 return false; 229 } 230 if(!m_current_cfg_stream_mid.read()) { 231 debugError("Could not initialize current stream configuration (mid rates)\n"); 232 return false; 233 } 234 if(!m_current_cfg_stream_high.read()) { 235 debugError("Could not initialize current stream configuration (high rates)\n"); 236 return false; 237 } 238 if(m_mixer) m_mixer->updateNameCache(); 239 return true; 240 } 241 242 /** 243 * Returns the router configuration for the current rate mode 244 * @return 245 */ 246 Device::EAP::RouterConfig * 247 Device::EAP::getActiveRouterConfig() 248 { 249 switch(m_device.getCurrentConfig()) { 250 case eDC_Low: return &m_current_cfg_routing_low; 251 case eDC_Mid: return &m_current_cfg_routing_mid; 252 case eDC_High: return &m_current_cfg_routing_high; 253 default: 254 debugError("Unsupported configuration mode\n"); 255 return NULL; 256 } 257 } 258 259 /** 260 * Returns the stream configuration for the current rate mode 261 * @return 262 */ 263 Device::EAP::StreamConfig * 264 Device::EAP::getActiveStreamConfig() 265 { 266 switch(m_device.getCurrentConfig()) { 267 case eDC_Low: return &m_current_cfg_stream_low; 268 case eDC_Mid: return &m_current_cfg_stream_mid; 269 case eDC_High: return &m_current_cfg_stream_high; 270 default: 271 debugError("Unsupported configuration mode\n"); 272 return NULL; 273 } 274 } 275 276 /** 277 * Uploads a new router configuration to the device 278 * @param rcfg The new RouterConfig 279 * @param low store as config for the low rates 280 * @param mid store as config for the mid rates 281 * @param high store as config for the high rates 282 * @return true if successful, false otherwise 283 */ 284 bool 285 Device::EAP::updateRouterConfig(RouterConfig& rcfg, bool low, bool mid, bool high) { 286 // write the router config to the appropriate memory space on the device 287 if(!rcfg.write(eRT_NewRouting, 0)) { 288 debugError("Could not write new router configuration\n"); 289 return false; 290 } 291 // perform the store operation 292 if(!loadRouterConfig(low, mid, high)) { 293 debugError("Could not activate new router configuration\n"); 294 updateConfigurationCache(); // for consistency 295 return false; 296 } 297 return updateConfigurationCache(); 298 } 299 300 /** 301 * Uploads a new router configuration to replace the configuration 302 * for the current rate. 303 * @param rcfg The new RouterConfig 304 * @return true if successful, false otherwise 305 */ 306 bool 307 Device::EAP::updateCurrentRouterConfig(RouterConfig& rcfg) { 308 switch(m_device.getCurrentConfig()) { 309 case eDC_Low: return updateRouterConfig(rcfg, true, false, false); 310 case eDC_Mid: return updateRouterConfig(rcfg, false, true, false); 311 case eDC_High: return updateRouterConfig(rcfg, false, false, true); 312 default: 313 debugError("Unsupported configuration mode\n"); 314 return false; 315 } 316 } 317 318 /** 319 * Uploads a new stream configuration to the device 320 * @param scfg The new StreamConfig 321 * @param low store as config for the low rates 322 * @param mid store as config for the mid rates 323 * @param high store as config for the high rates 324 * @return true if successful, false otherwise 325 */ 326 bool 327 Device::EAP::updateStreamConfig(StreamConfig& scfg, bool low, bool mid, bool high) { 328 // write the stream config to the appropriate memory space on the device 329 if(!scfg.write(eRT_NewStreamCfg, 0)) { 330 debugError("Could not write new stream configuration\n"); 331 return false; 332 } 333 // perform the store operation 334 if(!loadStreamConfig(low, mid, high)) { 335 debugError("Could not activate new stream configuration\n"); 336 updateConfigurationCache(); // for consistency 337 return false; 338 } 339 return updateConfigurationCache(); 340 } 341 342 /** 343 * Uploads a new router and stream configuration to the device 344 * @param rcfg The new RouterConfig 345 * @param scfg The new StreamConfig 346 * @param low store as config for the low rates 347 * @param mid store as config for the mid rates 348 * @param high store as config for the high rates 349 * @return true if successful, false otherwise 350 */ 351 bool 352 Device::EAP::updateStreamConfig(RouterConfig& rcfg, StreamConfig& scfg, bool low, bool mid, bool high) { 353 // write the router config to the appropriate memory space on the device 354 if(!rcfg.write(eRT_NewRouting, 0)) { 355 debugError("Could not write new router configuration\n"); 356 return false; 357 } 358 // write the stream config to the appropriate memory space on the device 359 if(!scfg.write(eRT_NewStreamCfg, 0)) { 360 debugError("Could not write new stream configuration\n"); 361 return false; 362 } 363 // perform the store operation 364 if(!loadRouterAndStreamConfig(low, mid, high)) { 365 debugError("Could not activate new router/stream configuration\n"); 366 updateConfigurationCache(); // for consistency 367 return false; 368 } 369 return updateConfigurationCache(); 370 } 371 372 373 bool 374 Device::EAP::loadFlashConfig() { 375 bool retval = true; 376 debugWarning("Untested code\n"); 377 fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_FLASH_CFG; 378 cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 379 if(!commandHelper(cmd)) { 380 debugWarning("Command failed\n"); 381 retval = false; 382 } 383 retval &= updateConfigurationCache(); 384 return retval; 385 } 386 387 bool 388 Device::EAP::storeFlashConfig() { 389 debugWarning("Untested code\n"); 390 fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_ST_FLASH_CFG; 391 cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 392 return commandHelper(cmd); 393 } 394 395 // helpers 199 396 void 200 Device::EAP::show() { 397 Device::EAP::show() 398 { 201 399 printMessage("== DICE EAP ==\n"); 202 400 debugOutput(DEBUG_LEVEL_VERBOSE, "Parameter Space info:\n"); … … 221 419 (m_mixer_readonly?"not ":""), 222 420 (m_mixer_flashstored?"":"not ")); 223 debugOutput(DEBUG_LEVEL_VERBOSE, " input id: %d, output id: %d\n", m_mixer_input_id, m_mixer_output_id); 224 debugOutput(DEBUG_LEVEL_VERBOSE, " nb inputs: %d, nb outputs: %d\n", m_mixer_nb_inputs, m_mixer_nb_outputs); 421 debugOutput(DEBUG_LEVEL_VERBOSE, " tx id: %s [%d], rx id: %s [%d]\n", 422 dstBlockToString(m_mixer_tx_id), m_mixer_tx_id, 423 srcBlockToString(m_mixer_rx_id), m_mixer_rx_id); 424 debugOutput(DEBUG_LEVEL_VERBOSE, " nb tx channels: %d, nb rx channels: %d\n", m_mixer_nb_tx, m_mixer_nb_rx); 225 425 debugOutput(DEBUG_LEVEL_VERBOSE, " General: dynamic stream config %ssupported\n", 226 426 (m_general_support_dynstream?"":"not ")); … … 241 441 debugOutput(DEBUG_LEVEL_VERBOSE, " Chip: DICE Junior (TCD2220)\n"); 242 442 } 443 444 debugOutput(DEBUG_LEVEL_VERBOSE, "--- Mixer configuration ---\n"); 445 if(m_mixer) { 446 m_mixer->show(); 447 } 448 debugOutput(DEBUG_LEVEL_VERBOSE, "--- Router/Peak space ---\n"); 449 if(m_router) { 450 m_router->show(); 451 } 452 453 RouterConfig *rcfg = getActiveRouterConfig(); 454 if(rcfg) { 455 rcfg->show(); 456 } 457 StreamConfig *scfg = getActiveStreamConfig(); 458 if(scfg) { 459 scfg->show(); 460 } 461 462 // fixme 463 // size_t len = 0x1000; 464 // quadlet_t tmp[len]; 465 // if(!readRegBlock( eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_STREAM, tmp, len*4) ) { 466 // debugError("Failed to read block\n"); 467 // } else { 468 // hexDumpQuadlets(tmp, len); 469 // } 470 243 471 } 244 472 … … 282 510 Device::EAP::commandHelper(fb_quadlet_t cmd) { 283 511 // check whether another command is still running 284 if(operationBusy() ) {512 if(operationBusy() == eWR_Busy) { 285 513 debugError("Other operation in progress\n"); 286 514 return false; … … 323 551 bool 324 552 Device::EAP::loadRouterConfig(bool low, bool mid, bool high) { 325 debugWarning("Untested code\n");326 553 fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_ROUTER; 327 554 if(low) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_LOW; … … 350 577 if(mid) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_MID; 351 578 if(high) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_HIGH; 352 cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE;353 return commandHelper(cmd);354 }355 356 bool357 Device::EAP::loadFlashConfig() {358 debugWarning("Untested code\n");359 fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_FLASH_CFG;360 cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE;361 return commandHelper(cmd);362 }363 364 bool365 Device::EAP::storeFlashConfig() {366 debugWarning("Untested code\n");367 fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_ST_FLASH_CFG;368 579 cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 369 580 return commandHelper(cmd); … … 440 651 maxlen = m_app_size; 441 652 break; 653 default: 654 debugError("Unsupported base address\n"); 655 return 0; 442 656 }; 443 657 … … 477 691 // ----------- Mixer ------------- 478 692 Device::EAP::Mixer::Mixer(EAP &p) 479 : m_parent(p) 693 : Control::MatrixMixer(&p.m_device, "MatrixMixer") 694 , m_eap(p) 480 695 , m_coeff(NULL) 481 696 , m_debugModule(p.m_debugModule) … … 494 709 Device::EAP::Mixer::init() 495 710 { 496 if(!m_ parent.m_mixer_exposed) {711 if(!m_eap.m_mixer_exposed) { 497 712 debugError("Device does not expose mixer\n"); 498 713 return false; … … 506 721 507 722 // allocate coefficient array 508 int nb_inputs = m_ parent.m_mixer_nb_inputs;509 int nb_outputs = m_ parent.m_mixer_nb_outputs;723 int nb_inputs = m_eap.m_mixer_nb_tx; 724 int nb_outputs = m_eap.m_mixer_nb_rx; 510 725 511 726 m_coeff = (fb_quadlet_t *)calloc(nb_outputs * nb_inputs, sizeof(fb_quadlet_t)); 512 727 513 728 // load initial values 514 if(! updateCoefficients()) {729 if(!loadCoefficients()) { 515 730 debugWarning("Could not initialize coefficients\n"); 516 731 return false; 517 732 } 518 733 updateNameCache(); 519 734 return true; 520 735 } 521 736 522 737 bool 523 Device::EAP::Mixer:: updateCoefficients()738 Device::EAP::Mixer::loadCoefficients() 524 739 { 525 740 if(m_coeff == NULL) { 526 debugError("Coefficient snot initialized\n");527 return false; 528 } 529 int nb_inputs = m_ parent.m_mixer_nb_inputs;530 int nb_outputs = m_ parent.m_mixer_nb_outputs;531 if(!m_ parent.readRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) {741 debugError("Coefficient cache not initialized\n"); 742 return false; 743 } 744 int nb_inputs = m_eap.m_mixer_nb_tx; 745 int nb_outputs = m_eap.m_mixer_nb_rx; 746 if(!m_eap.readRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) { 532 747 debugError("Failed to read coefficients\n"); 533 748 return false; 534 749 } 535 750 return true; 751 } 752 753 bool 754 Device::EAP::Mixer::storeCoefficients() 755 { 756 if(m_coeff == NULL) { 757 debugError("Coefficient cache not initialized\n"); 758 return false; 759 } 760 if(m_eap.m_mixer_readonly) { 761 debugWarning("Mixer is read-only\n"); 762 return false; 763 } 764 int nb_inputs = m_eap.m_mixer_nb_tx; 765 int nb_outputs = m_eap.m_mixer_nb_rx; 766 if(!m_eap.writeRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) { 767 debugError("Failed to read coefficients\n"); 768 return false; 769 } 770 return true; 771 } 772 773 void 774 Device::EAP::Mixer::updateNameCache() 775 { 776 // figure out the number of i/o's 777 int nb_inputs = m_eap.m_mixer_nb_tx; 778 int nb_outputs = m_eap.m_mixer_nb_rx; 779 780 // clear the previous map 781 m_input_route_map.clear(); 782 m_output_route_map.clear(); 783 784 // find the active router configuration 785 RouterConfig * rcfg = m_eap.getActiveRouterConfig(); 786 if(rcfg == NULL) { 787 debugError("Could not get active routing info\n"); 788 return; 789 } 790 791 // find the inputs 792 for(int i=0; i < nb_inputs; i++) { 793 int ch = i; 794 // the destination id of the mixer input 795 int dest_int = m_eap.m_mixer_tx_id; 796 797 // from the DICE mixer spec: 798 // we can have 16 channels per "block" 799 // if there are more, consecutive block id's are assumed 800 while(ch > 15) { 801 ch -= 16; 802 dest_int += 1; 803 } 804 // the destination block and channel corresponding with this 805 // mixer input is now known 806 enum eRouteDestination dest = rcfg->intToRouteDestination(dest_int); 807 808 // get the source for this mixer channel 809 m_input_route_map[i] = rcfg->getRouteForDestination(dest, ch); 810 811 debugOutput(DEBUG_LEVEL_VERBOSE, "Mixer input channel %2d source: %s\n", i, 812 srcBlockToString(m_input_route_map[i].src), 813 m_input_route_map[i].srcChannel); 814 } 815 816 // find where the outputs are connected to 817 for(int i=0; i < nb_outputs; i++) { 818 int ch = i; 819 // the source id of the mixer input 820 int src_int = m_eap.m_mixer_rx_id; 821 822 // from the DICE mixer spec: 823 // we can have 16 channels per "block" 824 // if there are more, consecutive block id's are assumed 825 while(ch > 15) { 826 ch -= 16; 827 src_int += 1; 828 } 829 830 // the source block and channel corresponding with this 831 // mixer output is now known 832 enum eRouteSource src = rcfg->intToRouteSource(src_int); 833 834 // get the routing destinations for this mixer channel 835 m_output_route_map[i] = rcfg->getRoutesForSource(src, ch); 836 837 #ifdef DEBUG 838 std::string destinations; 839 for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); 840 it != m_output_route_map[i].end(); 841 ++it ) 842 { 843 RouterConfig::Route r = *it; 844 // check whether the destination is valid 845 if((r.dst != eRD_Invalid) && (r.dstChannel >= 0)) { 846 char tmp[128]; 847 snprintf(tmp, 128, "%s:%d,", dstBlockToString(r.dst), r.dstChannel); 848 destinations += tmp; 849 } 850 } 851 debugOutput(DEBUG_LEVEL_VERBOSE, "Mixer output channel %2d destinations: %s\n", i, destinations.c_str()); 852 #endif 853 } 536 854 } 537 855 … … 539 857 Device::EAP::Mixer::show() 540 858 { 541 int nb_inputs = m_parent.m_mixer_nb_inputs; 542 int nb_outputs = m_parent.m_mixer_nb_outputs; 859 int nb_inputs = m_eap.m_mixer_nb_tx; 860 int nb_outputs = m_eap.m_mixer_nb_rx; 861 862 updateNameCache(); 543 863 544 864 const size_t bufflen = 4096; … … 547 867 548 868 cnt = 0; 549 cnt += snprintf(tmp+cnt, bufflen-cnt, "%3s ", ""); 550 for(int j=0; j<nb_inputs; j++) { 551 cnt += snprintf(tmp+cnt, bufflen-cnt, "%8d ", j); 869 for(int j=0; j < nb_inputs; j++) { 870 cnt += snprintf(tmp+cnt, bufflen-cnt, " %02d ", j); 552 871 } 553 872 printMessage("%s\n", tmp); 554 873 874 cnt = 0; 875 for(int j=0; j < nb_inputs; j++) { 876 cnt += snprintf(tmp+cnt, bufflen-cnt, "%s:%02d ", 877 srcBlockToString(m_input_route_map[j].src), 878 m_input_route_map[j].srcChannel); 879 } 880 printMessage("%s\n", tmp); 881 555 882 // display coefficients 556 for(int i=0; i <nb_outputs; i++) {883 for(int i=0; i < nb_outputs; i++) { 557 884 cnt = 0; 558 cnt += snprintf(tmp+cnt, bufflen-cnt, "%03d: ", i); 559 for(int j=0; j<nb_inputs; j++) { 560 cnt += snprintf(tmp+cnt, bufflen-cnt, "%08X ", *(m_coeff + nb_inputs * i + j)); 561 } 885 for(int j=0; j < nb_inputs; j++) { 886 cnt += snprintf(tmp+cnt, bufflen-cnt, "%07d ", *(m_coeff + nb_inputs * i + j)); 887 } 888 889 // construct the set of destinations 890 std::string destinations; 891 for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); 892 it != m_output_route_map[i].end(); 893 ++it ) 894 { 895 RouterConfig::Route r = *it; 896 // check whether the destination is valid 897 if((r.dst != eRD_Invalid) && (r.dstChannel >= 0)) { 898 char tmp[128]; 899 snprintf(tmp, 128, "%s:%d,", dstBlockToString(r.dst), r.dstChannel); 900 destinations += tmp; 901 } 902 } 903 904 cnt += snprintf(tmp+cnt, bufflen-cnt, "=[%02d]=> %s ", i, destinations.c_str()); 562 905 printMessage("%s\n", tmp); 563 906 } … … 565 908 } 566 909 910 // The control interface to the mixer 911 std::string 912 Device::EAP::Mixer::getRowName( const int row ) 913 { 914 return "FIXME"; 915 } 916 917 std::string 918 Device::EAP::Mixer::getColName( const int col ) 919 { 920 return "FIXME"; 921 } 922 923 int 924 Device::EAP::Mixer::canWrite( const int row, const int col) 925 { 926 if(m_eap.m_mixer_readonly) { 927 return false; 928 } 929 return (row >= 0 && row < m_eap.m_mixer_nb_tx && col >= 0 && col < m_eap.m_mixer_nb_rx); 930 } 931 932 double 933 Device::EAP::Mixer::setValue( const int row, const int col, const double val) 934 { 935 if(m_eap.m_mixer_readonly) { 936 debugWarning("Mixer is read-only\n"); 937 return false; 938 } 939 int nb_inputs = m_eap.m_mixer_nb_tx; 940 int addr = ((nb_inputs * row) + col) * 4; 941 quadlet_t tmp = (quadlet_t) val; 942 if(!m_eap.writeRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) { 943 debugError("Failed to write coefficient\n"); 944 return 0; 945 } 946 return (double)(tmp); 947 } 948 949 double 950 Device::EAP::Mixer::getValue( const int row, const int col) 951 { 952 int nb_inputs = m_eap.m_mixer_nb_tx; 953 int addr = ((nb_inputs * row) + col) * 4; 954 quadlet_t tmp; 955 if(!m_eap.readRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) { 956 debugError("Failed to read coefficient\n"); 957 return 0; 958 } 959 return (double)(tmp); 960 } 961 962 int 963 Device::EAP::Mixer::getRowCount() 964 { 965 return m_eap.m_mixer_nb_tx; 966 } 967 968 int 969 Device::EAP::Mixer::getColCount() 970 { 971 return m_eap.m_mixer_nb_rx; 972 } 973 974 // full map updates are unsupported 975 bool 976 Device::EAP::Mixer::getCoefficientMap(int &) { 977 return false; 978 } 979 980 bool 981 Device::EAP::Mixer::storeCoefficientMap(int &) { 982 if(m_eap.m_mixer_readonly) { 983 debugWarning("Mixer is read-only\n"); 984 return false; 985 } 986 return false; 987 } 988 567 989 // ----------- Router ------------- 990 // FIXME: some more efficient datastructure for the 991 // sources and destinations might be good 992 993 568 994 Device::EAP::Router::Router(EAP &p) 569 : m_parent(p) 995 : Control::CrossbarRouter(&p.m_device, "Router") 996 , m_eap(p) 997 , m_peak( *(new PeakSpace(p)) ) 570 998 , m_debugModule(p.m_debugModule) 571 999 { 572 1000 setupSources(); 1001 setupDestinations(); 573 1002 } 574 1003 575 1004 Device::EAP::Router::~Router() 576 1005 { 577 } 578 579 bool 580 Device::EAP::Router::init() 1006 delete &m_peak; 1007 } 1008 1009 void 1010 Device::EAP::Router::setupSourcesAddSource(const char *basename, enum eRouteSource srcid, 1011 unsigned int base, unsigned int cnt) 1012 { 1013 unsigned int i=0; 1014 char name[16]; 1015 for (i=0; i<cnt; i++) { 1016 snprintf(name, 16, "%s:%02d", basename, base+i); 1017 struct Source s = {name, srcid, i}; 1018 m_sources.push_back(s); 1019 } 1020 } 1021 1022 void 1023 Device::EAP::Router::setupDestinationsAddDestination(const char *basename, enum eRouteDestination dstid, 1024 unsigned int base, unsigned int cnt) 1025 { 1026 unsigned int i=0; 1027 char name[16]; 1028 for (i=0; i<cnt; i++) { 1029 snprintf(name, 16, "%s:%02d", basename, base+i); 1030 struct Destination d = {name, dstid, i}; 1031 m_destinations.push_back(d); 1032 } 1033 } 1034 1035 1036 void 1037 Device::EAP::Router::setupSources() { 1038 // add the routing sources and destinations for a DICE chip 1039 switch(m_eap.m_general_chip) { 1040 case DICE_EAP_CAP_GENERAL_CHIP_DICEII: 1041 // router/EAP currently not supported 1042 break; 1043 case DICE_EAP_CAP_GENERAL_CHIP_DICEJR: 1044 // these are unique to the junior 1045 1046 // second audio port 1047 setupSourcesAddSource("InS1", eRS_InS1, 0, 8); 1048 1049 case DICE_EAP_CAP_GENERAL_CHIP_DICEMINI: 1050 // these are common to the mini and junior 1051 1052 // the AES receiver 1053 setupSourcesAddSource("AES", eRS_AES, 0, 8); 1054 1055 // the ADAT receiver 1056 setupSourcesAddSource("ADAT", eRS_ADAT, 0, 8); 1057 1058 // the Mixer outputs 1059 setupSourcesAddSource("MixerOut", eRS_Mixer, 0, 16); 1060 1061 // the first audio port 1062 setupSourcesAddSource("InS0", eRS_InS0, 0, 8); 1063 1064 // the ARM audio port 1065 setupSourcesAddSource("ARM", eRS_ARM, 0, 8); 1066 1067 // the 1394 stream receivers 1068 setupSourcesAddSource("1394_0", eRS_ARX0, 0, 16); 1069 setupSourcesAddSource("1394_1", eRS_ARX1, 0, 16); 1070 1071 // mute 1072 setupSourcesAddSource("Mute", eRS_Muted, 0, 1); 1073 1074 break; 1075 default: 1076 // this is an unsupported chip 1077 break; 1078 } 1079 } 1080 1081 void 1082 Device::EAP::Router::setupDestinations() { 1083 // add the routing sources and destinations for a DICE chip 1084 switch(m_eap.m_general_chip) { 1085 case DICE_EAP_CAP_GENERAL_CHIP_DICEII: 1086 // router/EAP currently not supported 1087 break; 1088 case DICE_EAP_CAP_GENERAL_CHIP_DICEJR: 1089 // these are unique to the junior 1090 1091 // second audio port 1092 setupDestinationsAddDestination("InS1", eRD_InS1, 0, 8); 1093 1094 case DICE_EAP_CAP_GENERAL_CHIP_DICEMINI: 1095 // these are common to the mini and junior 1096 1097 // the AES receiver 1098 setupDestinationsAddDestination("AES", eRD_AES, 0, 8); 1099 1100 // the ADAT receiver 1101 setupDestinationsAddDestination("ADAT", eRD_ADAT, 0, 8); 1102 1103 // the Mixer outputs 1104 setupDestinationsAddDestination("MixerIn", eRD_Mixer0, 0, 16); 1105 setupDestinationsAddDestination("MixerIn", eRD_Mixer1, 16, 2); 1106 1107 // the first audio port 1108 setupDestinationsAddDestination("InS0", eRD_InS0, 0, 8); 1109 1110 // the ARM audio port 1111 setupDestinationsAddDestination("ARM", eRD_ARM, 0, 8); 1112 1113 // the 1394 stream receivers 1114 setupDestinationsAddDestination("1394_0", eRD_ATX0, 0, 16); 1115 setupDestinationsAddDestination("1394_1", eRD_ATX1, 0, 16); 1116 1117 // mute 1118 setupDestinationsAddDestination("Mute", eRD_Muted, 0, 1); 1119 1120 break; 1121 default: 1122 // this is an unsupported chip 1123 break; 1124 } 1125 } 1126 1127 std::string 1128 Device::EAP::Router::getSourceName(const int srcid) 1129 { 1130 if((unsigned)srcid < m_sources.size()) { 1131 return m_sources.at(srcid).name; 1132 } else { 1133 debugWarning("source id out of range (%d)\n", srcid); 1134 return ""; 1135 } 1136 } 1137 1138 std::string 1139 Device::EAP::Router::getDestinationName(const int dstid) 1140 { 1141 if((unsigned)dstid < m_destinations.size()) { 1142 return m_destinations.at(dstid).name; 1143 } else { 1144 debugWarning("destination id out of range (%d)\n", dstid); 1145 return ""; 1146 } 1147 } 1148 1149 int 1150 Device::EAP::Router::getSourceIndex(std::string name) 1151 { 1152 int i = 0; 1153 for ( SourceVectorIterator it = m_sources.begin(); 1154 it != m_sources.end(); 1155 ++it ) 1156 { 1157 if(it->name == name) return i; 1158 i++; 1159 } 1160 return -1; 1161 } 1162 1163 int 1164 Device::EAP::Router::getDestinationIndex(std::string name) 1165 { 1166 int i = 0; 1167 for ( DestinationVectorIterator it = m_destinations.begin(); 1168 it != m_destinations.end(); 1169 ++it ) 1170 { 1171 if(it->name == name) return i; 1172 i++; 1173 } 1174 return -1; 1175 } 1176 1177 int 1178 Device::EAP::Router::getSourceIndex(enum eRouteSource srcid, int channel) 1179 { 1180 int i = 0; 1181 for ( SourceVectorIterator it = m_sources.begin(); 1182 it != m_sources.end(); 1183 ++it ) 1184 { 1185 if((it->src == srcid) && (it->srcChannel == channel)) return i; 1186 i++; 1187 } 1188 return -1; 1189 } 1190 1191 int 1192 Device::EAP::Router::getDestinationIndex(enum eRouteDestination dstid, int channel) 1193 { 1194 int i = 0; 1195 for ( DestinationVectorIterator it = m_destinations.begin(); 1196 it != m_destinations.end(); 1197 ++it ) 1198 { 1199 if((it->dst == dstid) && (it->dstChannel == channel)) return i; 1200 i++; 1201 } 1202 return -1; 1203 } 1204 1205 Control::CrossbarRouter::NameVector 1206 Device::EAP::Router::getSourceNames() 1207 { 1208 Control::CrossbarRouter::NameVector n; 1209 for ( SourceVectorIterator it = m_sources.begin(); 1210 it != m_sources.end(); 1211 ++it ) 1212 { 1213 n.push_back(it->name); 1214 } 1215 return n; 1216 } 1217 1218 Control::CrossbarRouter::NameVector 1219 Device::EAP::Router::getDestinationNames() 1220 { 1221 Control::CrossbarRouter::NameVector n; 1222 for ( DestinationVectorIterator it = m_destinations.begin(); 1223 it != m_destinations.end(); 1224 ++it ) 1225 { 1226 n.push_back(it->name); 1227 } 1228 return n; 1229 } 1230 1231 Control::CrossbarRouter::IntVector 1232 Device::EAP::Router::getDestinationsForSource(const int srcid) 1233 { 1234 IntVector retval; 1235 if((unsigned)srcid < m_sources.size()) { 1236 Source s = m_sources.at(srcid); 1237 1238 // get the routing configuration 1239 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1240 if(rcfg == NULL) { 1241 debugError("Could not request active router configuration\n"); 1242 return retval; 1243 } 1244 // get the source routes 1245 RouterConfig::RouteVector v = rcfg->getRoutesForSource(s.src, s.srcChannel); 1246 1247 for ( RouterConfig::RouteVectorIterator it = v.begin(); 1248 it != v.end(); 1249 ++it ) 1250 { 1251 // FIXME: some more efficient datastructure might be good to 1252 // avoid this loop 1253 RouterConfig::Route &r = *it; 1254 int i = 0; 1255 for ( DestinationVectorIterator it = m_destinations.begin(); 1256 it != m_destinations.end(); 1257 ++it ) 1258 { 1259 if((it->dst == r.dst) && (it->dstChannel == r.dstChannel)) { 1260 retval.push_back(i); 1261 break; // can only match once 1262 } 1263 i++; 1264 } 1265 } 1266 return retval; 1267 } else { 1268 debugWarning("source id out of range (%d)\n", srcid); 1269 return retval; 1270 } 1271 } 1272 1273 int 1274 Device::EAP::Router::getSourceForDestination(const int dstid) 1275 { 1276 if((unsigned)dstid < m_destinations.size()) { 1277 Destination d = m_destinations.at(dstid); 1278 1279 // get the routing configuration 1280 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1281 if(rcfg == NULL) { 1282 debugError("Could not request active router configuration\n"); 1283 return false; 1284 } 1285 1286 RouterConfig::Route r = rcfg->getRouteForDestination(d.dst, d.dstChannel); 1287 if(r.src == eRS_Invalid) { 1288 return -1; 1289 } else { 1290 // FIXME: some more efficient datastructure might be good to 1291 // avoid this loop 1292 int i = 0; 1293 for ( SourceVectorIterator it = m_sources.begin(); 1294 it != m_sources.end(); 1295 ++it ) 1296 { 1297 if((it->src == r.src) && (it->srcChannel == r.srcChannel)) return i; 1298 i++; 1299 } 1300 return -1; 1301 } 1302 } else { 1303 debugWarning("destination id out of range (%d)\n", dstid); 1304 return -1; 1305 } 1306 } 1307 1308 int 1309 Device::EAP::Router::getNbSources() 1310 { 1311 return m_sources.size(); 1312 } 1313 1314 int 1315 Device::EAP::Router::getNbDestinations() 1316 { 1317 return m_destinations.size(); 1318 } 1319 1320 bool 1321 Device::EAP::Router::canConnect(const int source, const int dest) 1322 { 1323 if((unsigned)source >= m_sources.size()) { 1324 debugWarning("source id out of range (%d)\n", source); 1325 return false; 1326 } 1327 Source s = m_sources.at(source); 1328 1329 if((unsigned)dest >= m_destinations.size()) { 1330 debugWarning("destination id out of range (%d)\n", dest); 1331 return false; 1332 } 1333 Destination d = m_destinations.at(dest); 1334 1335 // we can connect anything 1336 // FIXME: can we? 1337 return true; 1338 } 1339 1340 bool 1341 Device::EAP::Router::setConnectionState(const int source, const int dest, const bool enable) 1342 { 1343 if((unsigned)source >= m_sources.size()) { 1344 debugWarning("source id out of range (%d)\n", source); 1345 return false; 1346 } 1347 Source s = m_sources.at(source); 1348 1349 if((unsigned)dest >= m_destinations.size()) { 1350 debugWarning("destination id out of range (%d)\n", dest); 1351 return false; 1352 } 1353 Destination d = m_destinations.at(dest); 1354 1355 // get the routing configuration 1356 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1357 if(rcfg == NULL) { 1358 debugError("Could not request active router configuration\n"); 1359 return false; 1360 } 1361 1362 // build a new routing configuration 1363 RouterConfig newcfg = Device::EAP::RouterConfig(*rcfg); 1364 1365 // construct the routing entry to find 1366 RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel}; 1367 1368 // find the appropriate entry 1369 int idx = newcfg.getRouteIndex(r); 1370 1371 if (idx < 0) { 1372 // we have to add the route 1373 newcfg.insertRoute(r); 1374 } else { 1375 // the route is already present, so we can replace it 1376 if(enable) { 1377 debugOutput(DEBUG_LEVEL_VERBOSE, "connection %d => %d already present\n", source, dest); 1378 return true; 1379 } else { 1380 // remove the route 1381 newcfg.removeRoute(idx); 1382 } 1383 } 1384 1385 // if we get here it means we have to upload a new router config 1386 if(!m_eap.updateCurrentRouterConfig(newcfg)) { 1387 debugError("Could not update router config\n"); 1388 return false; 1389 } 1390 1391 return true; 1392 } 1393 1394 bool 1395 Device::EAP::Router::getConnectionState(const int source, const int dest) 1396 { 1397 if((unsigned)source >= m_sources.size()) { 1398 debugWarning("source id out of range (%d)\n", source); 1399 return false; 1400 } 1401 Source s = m_sources.at(source); 1402 1403 if((unsigned)dest >= m_destinations.size()) { 1404 debugWarning("destination id out of range (%d)\n", dest); 1405 return false; 1406 } 1407 Destination d = m_destinations.at(dest); 1408 1409 // get the routing configuration 1410 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1411 if(rcfg == NULL) { 1412 debugError("Could not request active router configuration\n"); 1413 return false; 1414 } 1415 1416 // build a new routing configuration 1417 RouterConfig newcfg = Device::EAP::RouterConfig(*rcfg); 1418 1419 // construct the routing entry to find 1420 RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel}; 1421 1422 // find the appropriate entry 1423 int idx = newcfg.getRouteIndex(r); 1424 1425 if (idx < 0) { 1426 // the route is not present 1427 return false; 1428 } else { 1429 // the route is already present 1430 return true; 1431 } 1432 } 1433 1434 bool 1435 Device::EAP::Router::canConnect(std::string src, std::string dst) 1436 { 1437 int srcidx = getSourceIndex(src); 1438 int dstidx = getDestinationIndex(dst); 1439 return canConnect(srcidx, dstidx); 1440 } 1441 1442 bool 1443 Device::EAP::Router::setConnectionState(std::string src, std::string dst, const bool enable) 1444 { 1445 int srcidx = getSourceIndex(src); 1446 int dstidx = getDestinationIndex(dst); 1447 return setConnectionState(srcidx, dstidx, enable); 1448 } 1449 1450 bool 1451 Device::EAP::Router::getConnectionState(std::string src, std::string dst) 1452 { 1453 int srcidx = getSourceIndex(src); 1454 int dstidx = getDestinationIndex(dst); 1455 return getConnectionState(srcidx, dstidx); 1456 } 1457 1458 // the map is organized as a matrix where the 1459 // rows are the destinations and the columns are 1460 // the sources 1461 1462 // note that map as assumed to be big enough and 1463 // allocated by the user 1464 bool 1465 Device::EAP::Router::getConnectionMap(int *map) 1466 { 1467 unsigned int nb_sources = getNbSources(); 1468 unsigned int nb_destinations = getNbDestinations(); 1469 1470 // clear the map 1471 memset(map, 0, nb_sources * nb_destinations * sizeof(int)); 1472 1473 // get the routing configuration 1474 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1475 if(rcfg == NULL) { 1476 debugError("Could not request active router configuration\n"); 1477 return false; 1478 } 1479 1480 unsigned int nb_routes = rcfg->getNbRoutes(); 1481 1482 for(unsigned int i=0; i<nb_routes; i++) { 1483 struct RouterConfig::Route r = rcfg->getRoute(i); 1484 int srcidx = getSourceIndex(r.src, r.srcChannel); 1485 int dstidx = getDestinationIndex(r.dst, r.dstChannel); 1486 if(srcidx < 0) { 1487 debugWarning("bogus source (%d, %d) in route table\n", r.src, r.srcChannel); 1488 } else if(dstidx < 0) { 1489 debugWarning("bogus destination (%d, %d) in route table\n", r.dst, r.dstChannel); 1490 } else { 1491 int *ptr = map; 1492 ptr += dstidx * nb_sources; 1493 ptr += srcidx; 1494 *ptr = 1; // route present 1495 } 1496 } 1497 return true; 1498 } 1499 1500 bool 1501 Device::EAP::Router::setConnectionMap(int *map) 581 1502 { 582 1503 return false; 1504 } 1505 1506 bool 1507 Device::EAP::Router::clearAllConnections() 1508 { 1509 // build a new empty routing configuration 1510 RouterConfig newcfg = Device::EAP::RouterConfig(m_eap); 1511 1512 // upload the new router config 1513 if(!m_eap.updateCurrentRouterConfig(newcfg)) { 1514 debugError("Could not update router config\n"); 1515 return false; 1516 } 1517 return true; 1518 } 1519 1520 bool 1521 Device::EAP::Router::hasPeakMetering() 1522 { 1523 return m_eap.m_router_exposed; 1524 } 1525 1526 double 1527 Device::EAP::Router::getPeakValue(const int source, const int dest) 1528 { 1529 if((unsigned)source >= m_sources.size()) { 1530 debugWarning("source id out of range (%d)\n", source); 1531 return false; 1532 } 1533 Source s = m_sources.at(source); 1534 1535 if((unsigned)dest >= m_destinations.size()) { 1536 debugWarning("destination id out of range (%d)\n", dest); 1537 return false; 1538 } 1539 Destination d = m_destinations.at(dest); 1540 1541 debugOutput(DEBUG_LEVEL_VERBOSE, "getting peak info for [%d] %s => [%d] %s\n", 1542 source, s.name.c_str(), 1543 dest, d.name.c_str()); 1544 1545 // update the peak information 1546 m_peak.read(); 1547 1548 // construct the routing entry to find 1549 RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel, 0}; 1550 1551 // find the appropriate entry 1552 int idx = m_peak.getRouteIndex(r); 1553 1554 if (idx < 0) { 1555 // the route is not present 1556 return -1; 1557 } else { 1558 // the route is present 1559 r = m_peak.getRoute(idx); 1560 return r.peak; 1561 } 1562 583 1563 } 584 1564 … … 586 1566 Device::EAP::Router::show() 587 1567 { 588 1568 // print the peak space as it also contains the routing configuration 1569 printMessage("Active router config:\n"); 1570 m_peak.read(); 1571 m_peak.show(); 1572 } 1573 1574 // ----------- routing config ------------- 1575 Device::EAP::RouterConfig::RouterConfig(EAP &p) 1576 : m_eap(p) 1577 , m_base(eRT_None), m_offset(0) 1578 , m_debugModule(p.m_debugModule) 1579 {} 1580 1581 Device::EAP::RouterConfig::RouterConfig(EAP &p, enum eRegBase b, unsigned int o) 1582 : m_eap(p) 1583 , m_base(b), m_offset(o) 1584 , m_debugModule(p.m_debugModule) 1585 {} 1586 1587 Device::EAP::RouterConfig::~RouterConfig() 1588 {} 1589 1590 bool 1591 Device::EAP::RouterConfig::read(enum eRegBase base, unsigned offset) 1592 { 1593 // first clear the current route vector 1594 m_routes.clear(); 1595 1596 uint32_t nb_routes; 1597 if(!m_eap.readRegBlock(base, offset, &nb_routes, 4)) { 1598 debugError("Failed to read number of entries\n"); 1599 return false; 1600 } 1601 if(nb_routes == 0) { 1602 debugWarning("No routes found\n"); 1603 } 1604 1605 // read the route info 1606 uint32_t tmp_entries[nb_routes]; 1607 if(!m_eap.readRegBlock(base, offset+4, tmp_entries, nb_routes*4)) { 1608 debugError("Failed to read router config block information\n"); 1609 return false; 1610 } 1611 1612 // decode into the routing vector 1613 for(unsigned int i=0; i < nb_routes; i++) { 1614 m_routes.push_back(decodeRoute(tmp_entries[i])); 1615 } 1616 return true; 1617 } 1618 1619 bool 1620 Device::EAP::RouterConfig::write(enum eRegBase base, unsigned offset) 1621 { 1622 uint32_t nb_routes = m_routes.size(); 1623 if(nb_routes == 0) { 1624 debugWarning("Writing 0 routes?\n"); 1625 } 1626 uint32_t tmp_entries[nb_routes]; 1627 1628 // encode from the routing vector 1629 int i=0; 1630 for ( RouteVectorIterator it = m_routes.begin(); 1631 it != m_routes.end(); 1632 ++it ) 1633 { 1634 tmp_entries[i] = encodeRoute( *it ); 1635 i++; 1636 } 1637 1638 // write the result to the device 1639 if(!m_eap.writeRegBlock(base, offset+4, tmp_entries, nb_routes*4)) { 1640 debugError("Failed to write router config block information\n"); 1641 return false; 1642 } 1643 if(!m_eap.writeRegBlock(base, offset, &nb_routes, 4)) { 1644 debugError("Failed to write number of entries\n"); 1645 return false; 1646 } 1647 return true; 1648 } 1649 1650 bool 1651 Device::EAP::RouterConfig::insertRoute(struct Route r, unsigned int index) 1652 { 1653 unsigned int nb_routes = getNbRoutes(); 1654 if(index > nb_routes) { 1655 debugError("Index out of range\n"); 1656 return false; 1657 } 1658 if (index == nb_routes) { // append 1659 m_routes.push_back(r); 1660 return true; 1661 } 1662 // insert 1663 RouteVectorIterator pos = m_routes.begin() + index; 1664 m_routes.insert(pos, r); 1665 return true; 1666 } 1667 1668 bool 1669 Device::EAP::RouterConfig::replaceRoute(unsigned int old_index, struct Route new_route) 1670 { 1671 if(old_index >= getNbRoutes()) { 1672 debugError("Index out of range\n"); 1673 return false; 1674 } 1675 if(!removeRoute(old_index)) { 1676 debugError("Could not remove old route\n"); 1677 return false; 1678 } 1679 return insertRoute(new_route, old_index); 1680 } 1681 1682 bool 1683 Device::EAP::RouterConfig::replaceRoute(struct Route old_route, struct Route new_route) 1684 { 1685 int idx = getRouteIndex(old_route); 1686 if(idx < 0) { 1687 debugWarning("Route not found\n"); 1688 return false; 1689 } 1690 return replaceRoute((unsigned int)idx, new_route); 1691 } 1692 1693 bool 1694 Device::EAP::RouterConfig::removeRoute(struct Route r) 1695 { 1696 int idx = getRouteIndex(r); 1697 if(idx < 0) { 1698 debugWarning("Route not found\n"); 1699 return false; 1700 } 1701 return removeRoute((unsigned int)idx); 1702 } 1703 1704 bool 1705 Device::EAP::RouterConfig::removeRoute(unsigned int index) 1706 { 1707 if(index >= getNbRoutes()) { 1708 debugError("Index out of range\n"); 1709 return false; 1710 } 1711 RouteVectorIterator pos = m_routes.begin() + index; 1712 m_routes.erase(pos); 1713 return true; 1714 } 1715 1716 int 1717 Device::EAP::RouterConfig::getRouteIndex(struct Route r) 1718 { 1719 int i = 0; 1720 for ( RouteVectorIterator it = m_routes.begin(); 1721 it != m_routes.end(); 1722 ++it ) 1723 { 1724 struct Route t = *it; 1725 if ((t.src == r.src) && (t.srcChannel == r.srcChannel) && (t.dst == r.dst) && (t.dstChannel == r.dstChannel)) return i; 1726 i++; 1727 } 1728 return -1; 1729 } 1730 1731 struct Device::EAP::RouterConfig::Route 1732 Device::EAP::RouterConfig::getRoute(unsigned int idx) 1733 { 1734 if( (idx < 0) || (idx >= m_routes.size()) ) { 1735 debugWarning("Route index out of range (%d)\n", idx); 1736 Route r = {eRS_Invalid, -1, eRD_Invalid, -1, 0}; 1737 return r; 1738 } 1739 return m_routes.at(idx); 1740 } 1741 1742 #define CASE_INT_EQUAL_RETURN(_x) case (int)(_x): return _x; 1743 enum Device::EAP::eRouteDestination 1744 Device::EAP::RouterConfig::intToRouteDestination(int dst) 1745 { 1746 switch(dst) { 1747 CASE_INT_EQUAL_RETURN(eRD_AES); 1748 CASE_INT_EQUAL_RETURN(eRD_ADAT); 1749 CASE_INT_EQUAL_RETURN(eRD_Mixer0); 1750 CASE_INT_EQUAL_RETURN(eRD_Mixer1); 1751 CASE_INT_EQUAL_RETURN(eRD_InS0); 1752 CASE_INT_EQUAL_RETURN(eRD_InS1); 1753 CASE_INT_EQUAL_RETURN(eRD_ARM); 1754 CASE_INT_EQUAL_RETURN(eRD_ATX0); 1755 CASE_INT_EQUAL_RETURN(eRD_ATX1); 1756 CASE_INT_EQUAL_RETURN(eRD_Muted); 1757 default: return eRD_Invalid; 1758 } 1759 } 1760 1761 enum Device::EAP::eRouteSource 1762 Device::EAP::RouterConfig::intToRouteSource(int src) 1763 { 1764 switch(src) { 1765 CASE_INT_EQUAL_RETURN(eRS_AES); 1766 CASE_INT_EQUAL_RETURN(eRS_ADAT); 1767 CASE_INT_EQUAL_RETURN(eRS_Mixer); 1768 CASE_INT_EQUAL_RETURN(eRS_InS0); 1769 CASE_INT_EQUAL_RETURN(eRS_InS1); 1770 CASE_INT_EQUAL_RETURN(eRS_ARM); 1771 CASE_INT_EQUAL_RETURN(eRS_ARX0); 1772 CASE_INT_EQUAL_RETURN(eRS_ARX1); 1773 CASE_INT_EQUAL_RETURN(eRS_Muted); 1774 default: return eRS_Invalid; 1775 } 1776 } 1777 1778 struct Device::EAP::RouterConfig::Route 1779 Device::EAP::RouterConfig::decodeRoute(uint32_t val) { 1780 int routerval = val & 0xFFFF; 1781 int peak = (val >> 16) & 0x0FFF; 1782 int src_blk = (routerval >> 12) & 0xF; 1783 int src_ch = (routerval >> 8) & 0xF; 1784 int dst_blk = (routerval >> 4) & 0xF; 1785 int dst_ch = (routerval >> 0) & 0xF; 1786 struct Route r = {intToRouteSource(src_blk), src_ch, intToRouteDestination(dst_blk), dst_ch, peak}; 1787 return r; 1788 } 1789 1790 uint32_t 1791 Device::EAP::RouterConfig::encodeRoute(struct Route r) { 1792 if(r.src == eRS_Invalid || r.dst == eRD_Invalid) { 1793 debugWarning("Encoding invalid source/dest (%d/%d)\n", r.src, r.dst); 1794 // return 0xFFFFFFFF; 1795 } 1796 unsigned int src_blk = ((unsigned int)r.src) & 0xF; 1797 unsigned int src_ch = ((unsigned int)r.srcChannel) & 0xF; 1798 unsigned int dst_blk = ((unsigned int)r.dst) & 0xF; 1799 unsigned int dst_ch = ((unsigned int)r.dstChannel) & 0xF; 1800 uint32_t routerval = 0; 1801 routerval |= (src_blk << 12); 1802 routerval |= (src_ch << 8); 1803 routerval |= (dst_blk << 4); 1804 routerval |= (dst_ch << 0); 1805 return routerval; 1806 } 1807 1808 struct Device::EAP::RouterConfig::Route 1809 Device::EAP::RouterConfig::getRouteForDestination(enum eRouteDestination dst, int channel) 1810 { 1811 for ( RouteVectorIterator it = m_routes.begin(); 1812 it != m_routes.end(); 1813 ++it ) 1814 { 1815 struct Route r = *it; 1816 if((r.dst == (int)dst) && (r.dstChannel == channel)) { 1817 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d comes from %s:%02d\n", 1818 dstBlockToString(r.dst), r.dstChannel, 1819 srcBlockToString(r.src), r.srcChannel); 1820 return r; 1821 } 1822 } 1823 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d source can't be found\n", 1824 dstBlockToString((int)dst), channel); 1825 struct Route r = {eRS_Invalid, -1, eRD_Invalid, 0, 0}; 1826 return r; 1827 } 1828 1829 std::vector<struct Device::EAP::RouterConfig::Route> 1830 Device::EAP::RouterConfig::getRoutesForSource(enum eRouteSource src, int channel) 1831 { 1832 std::vector<struct Route>routes; 1833 for ( RouteVectorIterator it = m_routes.begin(); 1834 it != m_routes.end(); 1835 ++it ) 1836 { 1837 struct Route r = *it; 1838 if((r.src == (int)src) && (r.srcChannel == channel)) { 1839 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d goes to %s:%02d\n", 1840 srcBlockToString(r.src), r.srcChannel, 1841 dstBlockToString(r.dst), r.dstChannel); 1842 routes.push_back(r); 1843 } 1844 } 1845 return routes; 1846 } 1847 1848 void 1849 Device::EAP::RouterConfig::show() 1850 { 1851 for ( RouteVectorIterator it = m_routes.begin(); 1852 it != m_routes.end(); 1853 ++it ) 1854 { 1855 struct Route r = *it; 1856 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d\n", 1857 srcBlockToString(r.src), r.srcChannel, 1858 dstBlockToString(r.dst), r.dstChannel); 1859 } 1860 } 1861 1862 1863 // ----------- peak space ------------- 1864 1865 bool 1866 Device::EAP::PeakSpace::read(enum eRegBase base, unsigned offset) 1867 { 1868 // first clear the current route vector 1869 m_routes.clear(); 1870 1871 uint32_t nb_routes; 1872 // we have to figure out the number of entries through the currently 1873 // active router config 1874 RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 1875 if(rcfg == NULL) { 1876 debugError("Could not get active router config\n"); 1877 return false; 1878 } 1879 nb_routes = rcfg->getNbRoutes(); 1880 1881 // read the route info 1882 uint32_t tmp_entries[nb_routes]; 1883 if(!m_eap.readRegBlock(base, offset, tmp_entries, nb_routes*4)) { 1884 debugError("Failed to read peak block information\n"); 1885 return false; 1886 } 1887 1888 // decode into the routing vector 1889 for(unsigned int i=0; i < nb_routes; i++) { 1890 m_routes.push_back(decodeRoute(tmp_entries[i])); 1891 } 1892 // show(); 1893 return true; 1894 } 1895 1896 bool 1897 Device::EAP::PeakSpace::write(enum eRegBase base, unsigned offset) 1898 { 1899 debugError("Peak space is read-only\n"); 1900 return true; 1901 } 1902 1903 void 1904 Device::EAP::PeakSpace::show() 1905 { 1906 for ( RouteVectorIterator it = m_routes.begin(); 1907 it != m_routes.end(); 1908 ++it ) 1909 { 1910 struct Route r = *it; 1911 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d : %06d\n", 1912 srcBlockToString(r.src), r.srcChannel, 1913 dstBlockToString(r.dst), r.dstChannel, 1914 r.peak); 1915 } 1916 } 1917 1918 // ----------- stream config block ------------- 1919 Device::EAP::StreamConfig::StreamConfig(EAP &p, enum eRegBase b, unsigned int o) 1920 : m_eap(p) 1921 , m_base(b), m_offset(o) 1922 , m_nb_tx(0), m_nb_rx(0) 1923 , m_tx_configs(NULL), m_rx_configs(NULL) 1924 , m_debugModule(p.m_debugModule) 1925 { 1926 1927 } 1928 1929 Device::EAP::StreamConfig::~StreamConfig() 1930 { 1931 if(m_tx_configs) delete[]m_tx_configs; 1932 if(m_rx_configs) delete[]m_rx_configs; 1933 } 1934 1935 bool 1936 Device::EAP::StreamConfig::read(enum eRegBase base, unsigned offset) 1937 { 1938 if(!m_eap.readRegBlock(base, offset, &m_nb_tx, 4)) { 1939 debugError("Failed to read number of tx entries\n"); 1940 return false; 1941 } 1942 if(!m_eap.readRegBlock(base, offset+4, &m_nb_rx, 4)) { 1943 debugError("Failed to read number of rx entries\n"); 1944 return false; 1945 } 1946 debugOutput(DEBUG_LEVEL_VERBOSE, " Entries: TX: %lu, RX: %lu\n", m_nb_tx, m_nb_rx); 1947 1948 if(m_tx_configs) { 1949 delete[]m_tx_configs; 1950 m_tx_configs = NULL; 1951 } 1952 if(m_rx_configs) { 1953 delete[]m_rx_configs; 1954 m_rx_configs = NULL; 1955 } 1956 1957 offset += 8; 1958 if(m_nb_tx > 0) { 1959 m_tx_configs = new struct ConfigBlock[m_nb_tx]; 1960 for(unsigned int i=0; i<m_nb_tx; i++) { 1961 fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_tx_configs[i])); 1962 if(!m_eap.readRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 1963 debugError("Failed to read tx entry %d\n", i); 1964 return false; 1965 } 1966 offset += sizeof(struct ConfigBlock); 1967 } 1968 } 1969 1970 if(m_nb_rx > 0) { 1971 m_rx_configs = new struct ConfigBlock[m_nb_rx]; 1972 for(unsigned int i=0; i<m_nb_rx; i++) { 1973 fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_rx_configs[i])); 1974 if(!m_eap.readRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 1975 debugError("Failed to read rx entry %d\n", i); 1976 return false; 1977 } 1978 offset += sizeof(struct ConfigBlock); 1979 } 1980 } 1981 return true; 1982 } 1983 1984 bool 1985 Device::EAP::StreamConfig::write(enum eRegBase base, unsigned offset) 1986 { 1987 if(!m_eap.writeRegBlock(base, offset, &m_nb_tx, 4)) { 1988 debugError("Failed to write number of tx entries\n"); 1989 return false; 1990 } 1991 if(!m_eap.writeRegBlock(base, offset+4, &m_nb_rx, 4)) { 1992 debugError("Failed to write number of rx entries\n"); 1993 return false; 1994 } 1995 1996 offset += 8; 1997 for(unsigned int i=0; i<m_nb_tx; i++) { 1998 fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_tx_configs[i])); 1999 if(!m_eap.writeRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 2000 debugError("Failed to write tx entry %d\n", i); 2001 return false; 2002 } 2003 offset += sizeof(struct ConfigBlock); 2004 } 2005 2006 for(unsigned int i=0; i<m_nb_rx; i++) { 2007 fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_rx_configs[i])); 2008 if(!m_eap.writeRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 2009 debugError("Failed to write rx entry %d\n", i); 2010 return false; 2011 } 2012 offset += sizeof(struct ConfigBlock); 2013 } 2014 return true; 2015 } 2016 2017 Device::diceNameVector 2018 Device::EAP::StreamConfig::getNamesForBlock(struct ConfigBlock &b) 2019 { 2020 diceNameVector names; 2021 char namestring[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES+1]; 2022 2023 memcpy(namestring, b.names, DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES); 2024 2025 // Strings from the device are always little-endian, 2026 // so byteswap for big-endian machines 2027 #if __BYTE_ORDER == __BIG_ENDIAN 2028 byteSwapBlock((quadlet_t *)namestring, DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS); 2029 #endif 2030 2031 namestring[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES]='\0'; 2032 return m_eap.m_device.splitNameString(std::string(namestring)); 2033 } 2034 2035 void 2036 Device::EAP::StreamConfig::showConfigBlock(struct ConfigBlock &b) 2037 { 2038 debugOutput(DEBUG_LEVEL_VERBOSE, " Channel count : %lu audio, %lu midi\n", b.nb_audio, b.nb_midi); 2039 debugOutput(DEBUG_LEVEL_VERBOSE, " AC3 Map : 0x%08X\n", b.ac3_map); 2040 diceNameVector channel_names = getNamesForBlock(b); 2041 debugOutput(DEBUG_LEVEL_VERBOSE," Channel names :\n"); 2042 for ( diceNameVectorIterator it = channel_names.begin(); 2043 it != channel_names.end(); 2044 ++it ) 2045 { 2046 debugOutput(DEBUG_LEVEL_VERBOSE," %s\n", (*it).c_str()); 2047 } 2048 } 2049 2050 void 2051 Device::EAP::StreamConfig::show() 2052 { 2053 for(unsigned int i=0; i<m_nb_tx; i++) { 2054 debugOutput(DEBUG_LEVEL_VERBOSE, "TX Config block %d\n", i); 2055 showConfigBlock(m_tx_configs[i]); 2056 } 2057 for(unsigned int i=0; i<m_nb_rx; i++) { 2058 debugOutput(DEBUG_LEVEL_VERBOSE, "RX Config block %d\n", i); 2059 showConfigBlock(m_rx_configs[i]); 2060 } 589 2061 } 590 2062 trunk/libffado/src/dice/dice_eap.h
r1550 r1630 96 96 97 97 // MIXER registers 98 // TODO 99 100 // PEAK registers 101 // TODO 102 103 // NEW ROUTER registers 104 // TODO 105 106 // NEW STREAM CFG registers 107 // TODO 108 109 // CURRENT CFG registers 110 #define DICE_EAP_CURRCFG_LOW_ROUTER 0x0000 111 #define DICE_EAP_CURRCFG_LOW_STREAM 0x1000 112 #define DICE_EAP_CURRCFG_MID_ROUTER 0x2000 113 #define DICE_EAP_CURRCFG_MID_STREAM 0x3000 114 #define DICE_EAP_CURRCFG_HIGH_ROUTER 0x4000 115 #define DICE_EAP_CURRCFG_HIGH_STREAM 0x5000 116 117 #define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS (64) 118 #define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES (4*DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS) trunk/libffado/src/fireworks/fireworks_control.h
r1336 r1630 68 68 virtual int getRowCount( ); 69 69 virtual int getColCount( ); 70 71 // full map updates are unsupported 72 virtual bool getCoefficientMap(int &) {return false;}; 73 virtual bool storeCoefficientMap(int &) {return false;}; 70 74 71 75 protected: trunk/libffado/src/libcontrol/Element.cpp
r1498 r1630 216 216 } 217 217 218 /** 219 * Finds an element by name 220 * Note that you have to run this with the lock held, 221 * otherwise there is no guarantee that the element will 222 * not be deleted from the tree by an async event (e.g. busreset) 223 * 224 * @param name element name 225 * @return element or null if not found 226 */ 227 Element * 228 Container::getElementByName(std::string name) { 229 if(!getLock().isLocked()) debugWarning("Getting a Config::Element without locking the control tree, dangerous!\n"); 230 for ( ElementVectorIterator it = m_Children.begin(); 231 it != m_Children.end(); 232 ++it ) 233 { 234 if((*it)->getName() == name) { 235 debugOutput( DEBUG_LEVEL_VERBOSE, "Found Element %s (%s) \n", 236 (*it)->getName().c_str(), (*it)->getDescription().c_str()); 237 return *it; 238 } 239 } 240 return NULL; 241 } 242 218 243 bool 219 244 Container::addElement(Element *e) trunk/libffado/src/libcontrol/Element.h
r1568 r1630 163 163 const ElementVector & getElementVector(); 164 164 165 Element * getElementByName(std::string name); 166 167 165 168 virtual void show(); 166 169 virtual void setVerboseLevel(int l); trunk/libffado/src/libcontrol/MatrixMixer.h
r1158 r1630 47 47 virtual void show() = 0; 48 48 49 virtual std::string getRowName( const int ) = 0; 50 virtual std::string getColName( const int ) = 0; 51 virtual int canWrite( const int, const int ) = 0; 52 virtual double setValue( const int, const int, const double ) = 0; 53 virtual double getValue( const int, const int ) = 0; 54 virtual int getRowCount( ) = 0; 55 virtual int getColCount( ) = 0; 49 // per-coefficient access 50 virtual std::string getRowName(const int) = 0; 51 virtual std::string getColName(const int) = 0; 52 virtual int canWrite(const int, const int) = 0; 53 virtual double setValue(const int, const int, const double) = 0; 54 virtual double getValue(const int, const int) = 0; 55 virtual int getRowCount() = 0; 56 virtual int getColCount() = 0; 57 58 // functions to access the entire coefficient map at once 59 virtual bool getCoefficientMap(int &) = 0; 60 virtual bool storeCoefficientMap(int &) = 0; 56 61 57 62 protected: trunk/libffado/src/motu/motu_controls.h
r1531 r1630 190 190 virtual int getColCount(); 191 191 192 // full map updates are unsupported 193 virtual bool getCoefficientMap(int &) {return false;}; 194 virtual bool storeCoefficientMap(int &) {return false;}; 195 192 196 protected: 193 197 struct sSignalInfo { trunk/libffado/src/rme/fireface_settings_ctrls.h
r1616 r1630 99 99 virtual double getValue(const int row, const int col); 100 100 101 // functions to access the entire coefficient map at once 102 virtual bool getCoefficientMap(int &) {return false;}; 103 virtual bool storeCoefficientMap(int &) {return false;}; 104 101 105 protected: 102 106 Device &m_parent; trunk/libffado/src/SConscript
r1626 r1630 67 67 libcontrol/BasicElements.cpp \ 68 68 libcontrol/MatrixMixer.cpp \ 69 libcontrol/CrossbarRouter.cpp \ 69 70 libcontrol/ClockSelect.cpp \ 70 71 libcontrol/Nickname.cpp \ … … 158 159 dice/dice_avdevice.cpp \ 159 160 dice/dice_eap.cpp \ 161 dice/focusrite/saffire_pro40.cpp \ 160 162 ' ) 161 163 trunk/libffado/support/dbus/control-interface.xml
r1498 r1630 203 203 <arg type="i" name="nbrows" direction="out"/> 204 204 </method> 205 205 </interface> 206 207 <interface name="org.ffado.Control.Element.CrossbarRouter"> 208 <method name="getSourceName"> 209 <arg type="i" name="srcid" direction="in"/> 210 <arg type="s" name="sourcename" direction="out"/> 211 </method> 212 <method name="getDestinationName"> 213 <arg type="i" name="dstid" direction="in"/> 214 <arg type="s" name="destinationname" direction="out"/> 215 </method> 216 <method name="getSourceIndex"> 217 <arg type="s" name="sourcename" direction="in"/> 218 <arg type="i" name="srcid" direction="out"/> 219 </method> 220 <method name="getDestinationIndex"> 221 <arg type="s" name="destinationname" direction="in"/> 222 <arg type="i" name="dstid" direction="out"/> 223 </method> 224 <method name="getSourceNames"> 225 <arg type="as" name="sourcenames" direction="out"/> 226 </method> 227 <method name="getDestinationNames"> 228 <arg type="as" name="destinationnames" direction="out"/> 229 </method> 230 <method name="getDestinationsForSource"> 231 <arg type="i" name="srcid" direction="in"/> 232 <arg type="ai" name="dstids" direction="out"/> 233 </method> 234 <method name="getSourceForDestination"> 235 <arg type="i" name="dstid" direction="in"/> 236 <arg type="i" name="srcid" direction="out"/> 237 </method> 238 <method name="canConnect"> 239 <arg type="i" name="srcid" direction="in"/> 240 <arg type="i" name="dstid" direction="in"/> 241 <arg type="i" name="canconnect" direction="out"/> 242 </method> 243 <method name="setConnectionState"> 244 <arg type="i" name="srcid" direction="in"/> 245 <arg type="i" name="dstid" direction="in"/> 246 <arg type="i" name="state" direction="in"/> 247 <arg type="i" name="result" direction="out"/> 248 </method> 249 <method name="getConnectionState"> 250 <arg type="i" name="srcid" direction="in"/> 251 <arg type="i" name="dstid" direction="in"/> 252 <arg type="i" name="state" direction="out"/> 253 </method> 254 <method name="canConnectNamed"> 255 <arg type="s" name="srcname" direction="in"/> 256 <arg type="s" name="dstname" direction="in"/> 257 <arg type="i" name="canconnect" direction="out"/> 258 </method> 259 <method name="setConnectionStateNamed"> 260 <arg type="s" name="srcname" direction="in"/> 261 <arg type="s" name="dstname" direction="in"/> 262 <arg type="i" name="state" direction="in"/> 263 <arg type="i" name="result" direction="out"/> 264 </method> 265 <method name="getConnectionStateNamed"> 266 <arg type="s" name="srcname" direction="in"/> 267 <arg type="s" name="dstname" direction="in"/> 268 <arg type="i" name="state" direction="out"/> 269 </method> 270 <method name="clearAllConnections"> 271 <arg type="i" name="state" direction="out"/> 272 </method> 273 <method name="getNbSources"> 274 <arg type="i" name="state" direction="out"/> 275 </method> 276 <method name="getNbDestinations"> 277 <arg type="i" name="state" direction="out"/> 278 </method> 279 <method name="getConnectionMap"> 280 <arg type="ai" name="map" direction="out"/> 281 </method> 282 <method name="setConnectionMap"> 283 <arg type="ai" name="map" direction="in"/> 284 <arg type="i" name="state" direction="out"/> 285 </method> 286 <method name="hasPeakMetering"> 287 <arg type="i" name="hasmetering" direction="out"/> 288 </method> 289 <method name="getPeakValue"> 290 <arg type="i" name="srcid" direction="in"/> 291 <arg type="i" name="dstid" direction="in"/> 292 <arg type="d" name="value" direction="out"/> 293 </method> 206 294 </interface> 207 295 trunk/libffado/support/dbus/controlserver.cpp
r1621 r1630 26 26 #include "libcontrol/BasicElements.h" 27 27 #include "libcontrol/MatrixMixer.h" 28 #include "libcontrol/CrossbarRouter.h" 28 29 #include "libutil/Time.h" 29 30 #include "libutil/PosixMutex.h" … … 423 424 } 424 425 426 if (dynamic_cast<Control::CrossbarRouter *>(&e) != NULL) { 427 debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::CrossbarRouter\n"); 428 429 return new CrossbarRouter(conn(), std::string(path()+"/"+e.getName()), 430 parent, *dynamic_cast<Control::CrossbarRouter *>(&e)); 431 } 432 425 433 debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n"); 426 434 return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e); … … 811 819 } 812 820 821 // --- CrossbarRouter 822 823 CrossbarRouter::CrossbarRouter( DBus::Connection& connection, std::string p, Element* parent, Control::CrossbarRouter &slave) 824 : Element(connection, p, parent, slave) 825 , m_Slave(slave) 826 { 827 debugOutput( DEBUG_LEVEL_VERBOSE, "Created CrossbarRouter on '%s'\n", 828 path().c_str() ); 829 } 830 831 DBus::String 832 CrossbarRouter::getSourceName(const DBus::Int32 &idx) 833 { 834 return m_Slave.getSourceName(idx); 835 } 836 837 DBus::String 838 CrossbarRouter::getDestinationName(const DBus::Int32 &idx) 839 { 840 return m_Slave.getDestinationName(idx); 841 } 842 843 DBus::Int32 844 CrossbarRouter::getSourceIndex(const DBus::String &name) 845 { 846 return m_Slave.getSourceIndex(name); 847 } 848 849 DBus::Int32 850 CrossbarRouter::getDestinationIndex(const DBus::String &name) 851 { 852 return m_Slave.getDestinationIndex(name); 853 } 854 855 std::vector< DBus::String > 856 CrossbarRouter::getSourceNames() 857 { 858 return m_Slave.getSourceNames(); 859 } 860 861 std::vector< DBus::String > 862 CrossbarRouter::getDestinationNames() 863 { 864 return m_Slave.getDestinationNames(); 865 } 866 867 std::vector< DBus::Int32 > 868 CrossbarRouter::getDestinationsForSource(const DBus::Int32 &idx) 869 { 870 return m_Slave.getDestinationsForSource(idx); 871 } 872 873 DBus::Int32 874 CrossbarRouter::getSourceForDestination(const DBus::Int32 &idx) 875 { 876 return m_Slave.getSourceForDestination(idx); 877 } 878 879 DBus::Int32 880 CrossbarRouter::canConnect(const DBus::Int32 &source, const DBus::Int32 &dest) 881 { 882 return m_Slave.canConnect(source, dest); 883 } 884 885 DBus::Int32 886 CrossbarRouter::setConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest, const DBus::Int32 &enable) 887 { 888 return m_Slave.setConnectionState(source, dest, enable); 889 } 890 891 DBus::Int32 892 CrossbarRouter::getConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest) 893 { 894 return m_Slave.getConnectionState(source, dest); 895 } 896 897 DBus::Int32 898 CrossbarRouter::canConnectNamed(const DBus::String& source, const DBus::String& dest) 899 { 900 return m_Slave.canConnect(source, dest); 901 } 902 903 DBus::Int32 904 CrossbarRouter::setConnectionStateNamed(const DBus::String &source, const DBus::String &dest, const DBus::Int32 &enable) 905 { 906 return m_Slave.setConnectionState(source, dest, enable); 907 } 908 909 DBus::Int32 910 CrossbarRouter::getConnectionStateNamed(const DBus::String &source, const DBus::String &dest) 911 { 912 return m_Slave.getConnectionState(source, dest); 913 } 914 915 DBus::Int32 916 CrossbarRouter::clearAllConnections() 917 { 918 return m_Slave.clearAllConnections(); 919 } 920 921 DBus::Int32 922 CrossbarRouter::getNbSources() 923 { 924 return m_Slave.getNbSources(); 925 } 926 927 DBus::Int32 928 CrossbarRouter::getNbDestinations() 929 { 930 return m_Slave.getNbDestinations(); 931 } 932 933 DBus::Int32 934 CrossbarRouter::hasPeakMetering() 935 { 936 return m_Slave.hasPeakMetering(); 937 } 938 939 DBus::Double 940 CrossbarRouter::getPeakValue(const DBus::Int32 &source, const DBus::Int32 &dest) 941 { 942 return m_Slave.getPeakValue(source, dest); 943 } 944 945 std::vector< DBus::Int32 > 946 CrossbarRouter::getConnectionMap() 947 { 948 std::vector< DBus::Int32 >connmap; 949 unsigned int nb_sources = m_Slave.getNbSources(); 950 unsigned int nb_destinations = m_Slave.getNbDestinations(); 951 unsigned int nb_entries = nb_sources * nb_destinations; 952 953 int map_data[nb_entries]; 954 955 if(!m_Slave.getConnectionMap(map_data)) { 956 debugError("Could not fetch connection map\n"); 957 return connmap; 958 } 959 960 for(unsigned int i=0; i<nb_entries; i++) { 961 connmap.push_back(map_data[i]); 962 } 963 return connmap; 964 } 965 966 DBus::Int32 967 CrossbarRouter::setConnectionMap(const std::vector< DBus::Int32 >&connmap) 968 { 969 unsigned int nb_sources = m_Slave.getNbSources(); 970 unsigned int nb_destinations = m_Slave.getNbDestinations(); 971 unsigned int nb_entries = nb_sources * nb_destinations; 972 973 if(connmap.size() != nb_entries) { 974 debugError("bogus map size\n"); 975 return false; 976 } 977 978 int map_data[nb_entries]; 979 for (unsigned int i=0; i<nb_entries; i++) { 980 map_data[i] = connmap.at(i); 981 } 982 return m_Slave.setConnectionMap(map_data); 983 } 984 985 813 986 } // end of namespace Control trunk/libffado/support/dbus/controlserver.h
r1498 r1630 37 37 namespace Control { 38 38 class MatrixMixer; 39 class CrossbarRouter; 39 40 }; 40 41 … … 318 319 }; 319 320 321 class CrossbarRouter 322 : public org::ffado::Control::Element::CrossbarRouter 323 , public Element 324 { 325 public: 326 CrossbarRouter( DBus::Connection& connection, 327 std::string p, Element *, 328 Control::CrossbarRouter &slave ); 329 330 DBus::String getSourceName(const DBus::Int32 &); 331 DBus::String getDestinationName(const DBus::Int32 &); 332 DBus::Int32 getSourceIndex(const DBus::String &); 333 DBus::Int32 getDestinationIndex(const DBus::String &); 334 335 std::vector< DBus::String > getSourceNames(); 336 std::vector< DBus::String > getDestinationNames(); 337 338 std::vector< DBus::Int32 > getDestinationsForSource(const DBus::Int32 &); 339 DBus::Int32 getSourceForDestination(const DBus::Int32 &); 340 341 DBus::Int32 canConnect(const DBus::Int32 &source, const DBus::Int32 &dest); 342 DBus::Int32 setConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest, const DBus::Int32 &enable); 343 DBus::Int32 getConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest); 344 345 DBus::Int32 canConnectNamed(const DBus::String&, const DBus::String&); 346 DBus::Int32 setConnectionStateNamed(const DBus::String&, const DBus::String&, const DBus::Int32 &enable); 347 DBus::Int32 getConnectionStateNamed(const DBus::String&, const DBus::String&); 348 349 DBus::Int32 clearAllConnections(); 350 351 DBus::Int32 getNbSources(); 352 DBus::Int32 getNbDestinations(); 353 354 DBus::Int32 hasPeakMetering(); 355 DBus::Double getPeakValue(const DBus::Int32 &source, const DBus::Int32 &dest); 356 357 std::vector< DBus::Int32 > getConnectionMap(); 358 DBus::Int32 setConnectionMap(const std::vector< DBus::Int32 >&); 359 360 private: 361 Control::CrossbarRouter &m_Slave; 362 }; 363 320 364 } 321 365 trunk/libffado/support/tools/ffado-diag.in
r1499 r1630 36 36 37 37 ## message strings 38 FFADODIAG_VERSION = " 0.1"38 FFADODIAG_VERSION = "$VERSION-$REVISION" 39 39 40 40 welcome_msg = """ … … 77 77 for l in lines: 78 78 mod = l.split()[0] 79 if mod == modulename :79 if mod == modulename or mod == modulename.replace('-', '_'): 80 80 log.info(" found") 81 81 return True 82 82 log.info(" not found") 83 83 return False 84 84 85 85 def check_for_module_present(modulename): 86 86 log.info("Checking if module '%s' is present... " % modulename) … … 118 118 def check_1394newstack_loaded(): 119 119 retval = True 120 if not check_for_module_loaded('f w-core'):121 retval = False 122 if not check_for_module_loaded('f w-ohci'):120 if not check_for_module_loaded('firewire-core'): 121 retval = False 122 if not check_for_module_loaded('firewire-ohci'): 123 123 retval = False 124 124 return retval … … 126 126 def check_1394newstack_present(): 127 127 retval = True 128 if not check_for_module_present('f w-core'):129 retval = False 130 if not check_for_module_present('f w-ohci'):128 if not check_for_module_present('firewire-core'): 129 retval = False 130 if not check_for_module_present('firewire-ohci'): 131 131 retval = False 132 132 return retval trunk/libffado/tests/test-dice-eap.cpp
r1551 r1630 34 34 #include "libutil/Configuration.h" 35 35 36 #include "libcontrol/MatrixMixer.h" 37 #include "libcontrol/CrossbarRouter.h" 38 36 39 #include "dice/dice_avdevice.h" 37 40 using namespace Dice; … … 41 44 #include <cstdlib> 42 45 #include <cstring> 46 47 #include <signal.h> 48 int run; 49 50 static void sighandler(int sig) 51 { 52 run = 0; 53 } 43 54 44 55 using namespace std; … … 143 154 main(int argc, char **argv) 144 155 { 156 run=1; 157 158 signal (SIGINT, sighandler); 159 signal (SIGPIPE, sighandler); 160 145 161 // arg parsing 146 162 if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) { … … 213 229 } 214 230 printMessage("device supports EAP\n"); 215 216 Device::EAP eap = Device::EAP(*avDevice); 217 218 if(!eap.init()) { 219 printMessage("Could not init EAP\n"); 220 delete m_deviceManager; 221 return -1; 222 } 231 232 Device::EAP &eap = *(avDevice->getEAP()); 223 233 224 234 eap.show(); 225 226 Device::EAP::Mixer m = Device::EAP::Mixer(eap); 227 m.init(); 228 m.show(); 235 eap.lockControl(); 236 Control::Element *e = eap.getElementByName("MatrixMixer"); 237 if(e == NULL) { 238 printMessage("Could not get MatrixMixer control element\n"); 239 } else { 240 Control::MatrixMixer *m = dynamic_cast<Control::MatrixMixer *>(e); 241 if(m == NULL) { 242 printMessage("Element is not a MatrixMixer control element\n"); 243 } else { 244 for(int row=0; row < 16; row++) { 245 for(int col=0; col < 18; col++) { 246 // m->setValue(row, col, 0); 247 } 248 } 249 } 250 } 251 // after unlocking, these should not be used anymore 252 e = NULL; 253 eap.unlockControl(); 254 255 int cnt = 0; 256 257 while(run) { 258 eap.lockControl(); 259 Control::Element *e = eap.getElementByName("Router"); 260 if(e == NULL) { 261 printMessage("Could not get CrossbarRouter control element\n"); 262 } else { 263 Control::CrossbarRouter *c = dynamic_cast<Control::CrossbarRouter *>(e); 264 if(c == NULL) { 265 printMessage("Element is not a CrossbarRouter control element\n"); 266 } else { 267 // if(cnt == 0) { 268 // Control::CrossbarRouter::NameVector n; 269 // n = c->getSourceNames(); 270 // for(int i=0; i<n.size(); i++) { 271 // printMessage("Src %02d: %s\n", i, n.at(i).c_str()); 272 // } 273 // n = c->getDestinationNames(); 274 // for(int i=0; i<n.size(); i++) { 275 // printMessage("Dest %02d: %s\n", i, n.at(i).c_str()); 276 // } 277 // } 278 #define NELEMS 10 279 double peaks[NELEMS]; 280 int srcids[NELEMS]; 281 int dstidx = c->getDestinationIndex("MixerIn:00"); 282 for(int i=0; i<NELEMS; i++) { 283 srcids[i] = c->getSourceForDestination(dstidx + i); 284 peaks[i] = c->getPeakValue(srcids[i], dstidx + i); 285 } 286 for(int i=0; i<NELEMS; i++) { 287 std::string srcname = c->getSourceName(srcids[i]); 288 std::string dstname = c->getDestinationName(dstidx + i); 289 printMessage("Peak %3d (%10s => %10s): %f\n", i, srcname.c_str(), dstname.c_str(), peaks[i]); 290 } 291 } 292 } 293 // after unlocking, these should not be used anymore 294 e = NULL; 295 eap.unlockControl(); 296 sleep(1); 297 } 229 298 230 299 // cleanup