diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp
index 510602c80..e8f434b62 100644
--- a/plugins/channeltx/modnfm/nfmmod.cpp
+++ b/plugins/channeltx/modnfm/nfmmod.cpp
@@ -279,46 +279,45 @@ void NFMMod::applySettings(const NFMModSettings& settings, bool force)
     if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
         reverseAPIKeys.append("inputFrequencyOffset");
     }
-
     if ((settings.m_fmDeviation != m_settings.m_fmDeviation) || force) {
         reverseAPIKeys.append("fmDeviation");
     }
-
     if ((settings.m_volumeFactor != m_settings.m_volumeFactor) || force) {
         reverseAPIKeys.append("volumeFactor");
     }
-
     if ((settings.m_ctcssOn != m_settings.m_ctcssOn) || force) {
         reverseAPIKeys.append("ctcssOn");
     }
-
     if ((settings.m_channelMute != m_settings.m_channelMute) || force) {
         reverseAPIKeys.append("channelMute");
     }
-
     if ((settings.m_playLoop != m_settings.m_playLoop) || force) {
         reverseAPIKeys.append("playLoop");
     }
-
     if ((settings.m_modAFInput != m_settings.m_modAFInput) || force) {
         reverseAPIKeys.append("modAFInput");
     }
-
     if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
         reverseAPIKeys.append("rfBandwidth");
     }
-
     if ((settings.m_afBandwidth != m_settings.m_afBandwidth) || force) {
         reverseAPIKeys.append("afBandwidth");
     }
-
     if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
         reverseAPIKeys.append("toneFrequency");
     }
-
     if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) || force) {
         reverseAPIKeys.append("ctcssIndex");
     }
+    if ((settings.m_dcsOn != m_settings.m_dcsOn) || force) {
+        reverseAPIKeys.append("dcsOn");
+    }
+    if ((settings.m_dcsCode != m_settings.m_dcsCode) || force) {
+        reverseAPIKeys.append("dcsCode");
+    }
+    if ((settings.m_dcsPositive != m_settings.m_dcsPositive) || force) {
+        reverseAPIKeys.append("dcsPositive");
+    }
     if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
         reverseAPIKeys.append("audioDeviceName");
     }
@@ -482,6 +481,15 @@ void NFMMod::webapiUpdateChannelSettings(
     if (channelSettingsKeys.contains("volumeFactor")) {
         settings.m_volumeFactor = response.getNfmModSettings()->getVolumeFactor();
     }
+    if (channelSettingsKeys.contains("dcsCode")) {
+        settings.m_dcsCode = response.getNfmModSettings()->getDcsCode() % 512;
+    }
+    if (channelSettingsKeys.contains("dcsOn")) {
+        settings.m_dcsOn = response.getNfmModSettings()->getDcsOn() != 0;
+    }
+    if (channelSettingsKeys.contains("dcsPositive")) {
+        settings.m_dcsPositive = response.getNfmModSettings()->getDcsPositive() != 0;
+    }
     if (channelSettingsKeys.contains("streamIndex")) {
         settings.m_streamIndex = response.getNfmModSettings()->getStreamIndex();
     }
@@ -545,6 +553,9 @@ void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
         response.getNfmModSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName));
     }
 
+    response.getNfmModSettings()->setDcsCode(settings.m_dcsCode);
+    response.getNfmModSettings()->setDcsOn(settings.m_dcsOn ? 1 : 0);
+    response.getNfmModSettings()->setDcsPositive(settings.m_dcsPositive ? 1 : 0);
     response.getNfmModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
 
     if (response.getNfmModSettings()->getReverseApiAddress()) {
@@ -702,6 +713,15 @@ void NFMMod::webapiFormatChannelSettings(
     if (channelSettingsKeys.contains("ctcssIndex") || force) {
         swgNFMModSettings->setCtcssIndex(settings.m_ctcssIndex);
     }
+    if (channelSettingsKeys.contains("dcsCode") || force) {
+        swgNFMModSettings->setDcsCode(settings.m_dcsCode);
+    }
+    if (channelSettingsKeys.contains("dcsOn") || force) {
+        swgNFMModSettings->setDcsOn(settings.m_dcsOn ? 1 : 0);
+    }
+    if (channelSettingsKeys.contains("dcsPositive") || force) {
+        swgNFMModSettings->setDcsPositive(settings.m_dcsPositive ? 1 : 0);
+    }
     if (channelSettingsKeys.contains("streamIndex") || force) {
         swgNFMModSettings->setStreamIndex(settings.m_streamIndex);
     }
diff --git a/swagger/sdrangel/api/swagger/include/NFMMod.yaml b/swagger/sdrangel/api/swagger/include/NFMMod.yaml
index 6fbff54e1..20897b8bb 100644
--- a/swagger/sdrangel/api/swagger/include/NFMMod.yaml
+++ b/swagger/sdrangel/api/swagger/include/NFMMod.yaml
@@ -24,9 +24,27 @@ NFMModSettings:
     playLoop:
       type: integer
     ctcssOn:
+      description: >
+        Enable CTCSS squelch (takes precedence on DCS)
+        * 0 - disabled
+        * 1 - enabled
       type: integer
     ctcssIndex:
       type: integer
+    dcsOn:
+      description: >
+        Enable DCS squelch (only if CTCSS is off)
+        * 0 - disabled
+        * 1 - enabled
+      type: integer
+    dcsCode:
+      type: integer
+    dcsPositive:
+      description: >
+        Modulation direction:
+        * 0 - reverse or negative - 1 for 0 and -1 for 1
+        * 1 - direct or positive - -1 for 0 and 1 for 1
+      type: integer
     rgbColor:
       type: integer
     title:
diff --git a/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.cpp
index 221c3f464..d6d9460d6 100644
--- a/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.cpp
+++ b/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.cpp
@@ -48,6 +48,12 @@ SWGNFMModSettings::SWGNFMModSettings() {
     m_ctcss_on_isSet = false;
     ctcss_index = 0;
     m_ctcss_index_isSet = false;
+    dcs_on = 0;
+    m_dcs_on_isSet = false;
+    dcs_code = 0;
+    m_dcs_code_isSet = false;
+    dcs_positive = 0;
+    m_dcs_positive_isSet = false;
     rgb_color = 0;
     m_rgb_color_isSet = false;
     title = nullptr;
@@ -98,6 +104,12 @@ SWGNFMModSettings::init() {
     m_ctcss_on_isSet = false;
     ctcss_index = 0;
     m_ctcss_index_isSet = false;
+    dcs_on = 0;
+    m_dcs_on_isSet = false;
+    dcs_code = 0;
+    m_dcs_code_isSet = false;
+    dcs_positive = 0;
+    m_dcs_positive_isSet = false;
     rgb_color = 0;
     m_rgb_color_isSet = false;
     title = new QString("");
@@ -135,6 +147,9 @@ SWGNFMModSettings::cleanup() {
 
 
 
+
+
+
     if(title != nullptr) { 
         delete title;
     }
@@ -186,6 +201,12 @@ SWGNFMModSettings::fromJsonObject(QJsonObject &pJson) {
     
     ::SWGSDRangel::setValue(&ctcss_index, pJson["ctcssIndex"], "qint32", "");
     
+    ::SWGSDRangel::setValue(&dcs_on, pJson["dcsOn"], "qint32", "");
+    
+    ::SWGSDRangel::setValue(&dcs_code, pJson["dcsCode"], "qint32", "");
+    
+    ::SWGSDRangel::setValue(&dcs_positive, pJson["dcsPositive"], "qint32", "");
+    
     ::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
     
     ::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
@@ -254,6 +275,15 @@ SWGNFMModSettings::asJsonObject() {
     if(m_ctcss_index_isSet){
         obj->insert("ctcssIndex", QJsonValue(ctcss_index));
     }
+    if(m_dcs_on_isSet){
+        obj->insert("dcsOn", QJsonValue(dcs_on));
+    }
+    if(m_dcs_code_isSet){
+        obj->insert("dcsCode", QJsonValue(dcs_code));
+    }
+    if(m_dcs_positive_isSet){
+        obj->insert("dcsPositive", QJsonValue(dcs_positive));
+    }
     if(m_rgb_color_isSet){
         obj->insert("rgbColor", QJsonValue(rgb_color));
     }
@@ -391,6 +421,36 @@ SWGNFMModSettings::setCtcssIndex(qint32 ctcss_index) {
     this->m_ctcss_index_isSet = true;
 }
 
+qint32
+SWGNFMModSettings::getDcsOn() {
+    return dcs_on;
+}
+void
+SWGNFMModSettings::setDcsOn(qint32 dcs_on) {
+    this->dcs_on = dcs_on;
+    this->m_dcs_on_isSet = true;
+}
+
+qint32
+SWGNFMModSettings::getDcsCode() {
+    return dcs_code;
+}
+void
+SWGNFMModSettings::setDcsCode(qint32 dcs_code) {
+    this->dcs_code = dcs_code;
+    this->m_dcs_code_isSet = true;
+}
+
+qint32
+SWGNFMModSettings::getDcsPositive() {
+    return dcs_positive;
+}
+void
+SWGNFMModSettings::setDcsPositive(qint32 dcs_positive) {
+    this->dcs_positive = dcs_positive;
+    this->m_dcs_positive_isSet = true;
+}
+
 qint32
 SWGNFMModSettings::getRgbColor() {
     return rgb_color;
@@ -536,6 +596,15 @@ SWGNFMModSettings::isSet(){
         if(m_ctcss_index_isSet){
             isObjectUpdated = true; break;
         }
+        if(m_dcs_on_isSet){
+            isObjectUpdated = true; break;
+        }
+        if(m_dcs_code_isSet){
+            isObjectUpdated = true; break;
+        }
+        if(m_dcs_positive_isSet){
+            isObjectUpdated = true; break;
+        }
         if(m_rgb_color_isSet){
             isObjectUpdated = true; break;
         }
diff --git a/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.h b/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.h
index 5683aeaf7..0b9407667 100644
--- a/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.h
+++ b/swagger/sdrangel/code/qt5/client/SWGNFMModSettings.h
@@ -73,6 +73,15 @@ public:
     qint32 getCtcssIndex();
     void setCtcssIndex(qint32 ctcss_index);
 
+    qint32 getDcsOn();
+    void setDcsOn(qint32 dcs_on);
+
+    qint32 getDcsCode();
+    void setDcsCode(qint32 dcs_code);
+
+    qint32 getDcsPositive();
+    void setDcsPositive(qint32 dcs_positive);
+
     qint32 getRgbColor();
     void setRgbColor(qint32 rgb_color);
 
@@ -140,6 +149,15 @@ private:
     qint32 ctcss_index;
     bool m_ctcss_index_isSet;
 
+    qint32 dcs_on;
+    bool m_dcs_on_isSet;
+
+    qint32 dcs_code;
+    bool m_dcs_code_isSet;
+
+    qint32 dcs_positive;
+    bool m_dcs_positive_isSet;
+
     qint32 rgb_color;
     bool m_rgb_color_isSet;