MCU: add iCON V1-M support

This commit is contained in:
Franke Burgarino 2025-10-02 17:10:07 -05:00
parent 6d9df568fe
commit 833d4142b1
7 changed files with 111 additions and 12 deletions

View file

@ -61,6 +61,7 @@ DeviceInfo::DeviceInfo()
, _uses_ipmidi (false)
, _no_handshake (false)
, _is_qcon(false)
, _is_v1m(false)
, _is_platformMp(false)
, _is_proG2(false)
, _is_xtouch(false)
@ -347,6 +348,12 @@ DeviceInfo::set_state (const XMLNode& node, int /* version */)
_is_qcon = false;
}
if ((child = node.child ("IsV1M")) != 0) {
child->get_property ("value", _is_v1m);
} else {
_is_v1m = false;
}
if ((child = node.child ("IsXTouch")) != 0) {
child->get_property ("value", _is_xtouch);
} else {
@ -525,6 +532,12 @@ DeviceInfo::is_qcon () const
return _is_qcon;
}
bool
DeviceInfo::is_v1m () const
{
return _is_v1m;
}
bool DeviceInfo::is_platformMp () const
{
return _is_platformMp;

View file

@ -80,6 +80,7 @@ class DeviceInfo
bool uses_ipmidi() const;
bool no_handshake() const;
bool is_qcon() const;
bool is_v1m() const;
bool is_platformMp() const;
bool is_proG2() const;
bool is_xtouch() const;
@ -116,6 +117,7 @@ class DeviceInfo
bool _uses_ipmidi;
bool _no_handshake;
bool _is_qcon;
bool _is_v1m;
bool _is_platformMp;
bool _is_proG2;
bool _is_xtouch;

View file

@ -108,7 +108,7 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<MACKIE_N
, _controls_locked (false)
, _transport_is_rolling (false)
, _metering_active (true)
, _lcd2_available (true)
, _lcd2_available (false)
, _lcd2_label_pitch (7)
, _block_screen_redisplay_until (0)
, return_to_vpot_mode_display_at (UINT64_MAX)
@ -128,9 +128,9 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<MACKIE_N
if (s.mcp().device_info().has_qcon_second_lcd()) {
_lcd2_available = true;
// The main unit has 9 faders under the second display.
// The Qcon Pro X has 9 faders under the second display.
// Extenders have 8 faders.
if (s.number() == s.mcp().device_info().master_position()) {
if (s.mcp().device_info().is_qcon() && s.number() == s.mcp().device_info().master_position()) {
_lcd2_label_pitch = 6;
}
}
@ -947,31 +947,44 @@ Strip::redisplay (PBD::microseconds_t now, bool force)
_block_screen_redisplay_until = 0;
}
bool changed = false;
if (force || (current_display[0] != pending_display[0])) {
_surface->write (display (0, 0, pending_display[0]));
current_display[0] = pending_display[0];
changed = true;
}
if (return_to_vpot_mode_display_at <= now) {
return_to_vpot_mode_display_at = UINT64_MAX;
return_to_vpot_mode_display ();
changed = true;
}
if (force || (current_display[1] != pending_display[1])) {
_surface->write (display (0, 1, pending_display[1]));
current_display[1] = pending_display[1];
changed = true;
}
if (_lcd2_available) {
if (force || (lcd2_current_display[0] != lcd2_pending_display[0])) {
_surface->write (display (1, 0, lcd2_pending_display[0]));
lcd2_current_display[0] = lcd2_pending_display[0];
changed = true;
}
if (force || (lcd2_current_display[1] != lcd2_pending_display[1])) {
_surface->write (display (1, 1, lcd2_pending_display[1]));
lcd2_current_display[1] = lcd2_pending_display[1];
changed = true;
}
}
/* The iCON V1-M cannot handle many messages in quick succession.
*
* A small delay is necessary to ensure none are skipped.
*/
if (_surface->mcp().device_info().is_v1m() && changed) { g_usleep(2500); }
}
void
@ -1045,6 +1058,12 @@ Strip::zero ()
lcd2_current_display[1] = string();
}
/* The iCON V1-M cannot handle many messages in quick succession.
*
* A small delay is necessary to ensure none are skipped.
*/
if (_surface->mcp().device_info().is_v1m()) { g_usleep(5000); }
}
MidiByteArray
@ -1093,18 +1112,23 @@ Strip::display (uint32_t lcd_number, uint32_t line_number, const std::string& li
// code for display
retval << 0x13;
if (lcd_label_pitch == 6) {
if (_index == 0) {
if (_index == 0 && lcd_label_pitch == 6) {
add_left_pad_char = true;
}
else {
} else if (_index != 0) {
left_pad_offset = 1;
}
}
}
// offset (0 to 0x37 first line, 0x38 to 0x6f for second line)
if (_surface->mcp().device_info().is_v1m() && lcd_number == 1) {
if (line_number == 0) {
retval << (_index * (lcd_label_pitch - 1) + (line_number * 0x38) + left_pad_offset);
} else {
retval << (_index * lcd_label_pitch + (line_number * 0x38));
}
} else {
retval << (_index * lcd_label_pitch + (line_number * 0x38) + left_pad_offset);
}
if (add_left_pad_char) {
retval << ' '; // add the left pad space

View file

@ -139,8 +139,8 @@ Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, ui
if ( is_qcon ) {
_has_master_display = (mcp.device_info().has_master_fader() && mcp.device_info().has_qcon_second_lcd());
_has_master_meter = mcp.device_info().has_qcon_master_meters();
}
_has_master_meter = mcp.device_info().has_qcon_master_meters();
if (_mcp.device_info().has_global_controls()) {
init_controls ();

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<MackieProtocolDevice>
<Name value="iCON V1-M + V1-X on right"/>
<Strips value="8"/>
<Extenders value="1"/>
<MasterPosition value="1"/>
<MasterFader value="yes"/>
<TimecodeDisplay value="yes"/>
<TwoCharacterDisplay value="no"/>
<HasSeparateMeters value="yes"/>
<GlobalControls value="yes"/>
<JogWheel value="yes"/>
<TouchSenseFaders value="yes"/>
<LogicControlButtons value="yes"/>
<usesIPMIDI value="no"/>
<NoHandShake value="yes"/>
<IsV1M value="yes"/>
<HasQConSecondLCD value="yes"/>
<HasQConMasterMeters value="yes"/>
</MackieProtocolDevice>

20
share/mcp/v1-m.device Normal file
View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<MackieProtocolDevice>
<Name value="iCON V1-M"/>
<Strips value="8"/>
<Extenders value="0"/>
<MasterPosition value="0"/>
<MasterFader value="yes"/>
<TimecodeDisplay value="yes"/>
<TwoCharacterDisplay value="no"/>
<HasSeparateMeters value="yes"/>
<GlobalControls value="yes"/>
<JogWheel value="yes"/>
<TouchSenseFaders value="yes"/>
<LogicControlButtons value="yes"/>
<usesIPMIDI value="no"/>
<NoHandShake value="yes"/>
<IsV1M value="yes"/>
<HasQConSecondLCD value="yes"/>
<HasQConMasterMeters value="yes"/>
</MackieProtocolDevice>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<MackieProtocolDevice>
<Name value="iCON V1-M + V1-X on left"/>
<Strips value="8"/>
<Extenders value="1"/>
<MasterPosition value="2"/>
<MasterFader value="yes"/>
<TimecodeDisplay value="yes"/>
<TwoCharacterDisplay value="no"/>
<HasSeparateMeters value="yes"/>
<GlobalControls value="yes"/>
<JogWheel value="yes"/>
<TouchSenseFaders value="yes"/>
<LogicControlButtons value="yes"/>
<usesIPMIDI value="no"/>
<NoHandShake value="yes"/>
<IsV1M value="yes"/>
<HasQConSecondLCD value="yes"/>
<HasQConMasterMeters value="yes"/>
</MackieProtocolDevice>