You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
7.8 KiB

  1. /* This program source code file is part of KiCad, a free EDA CAD application.
  2. *
  3. * Copyright (C) 2022 Mikolaj Wielgus
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 3
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * https://www.gnu.org/licenses/gpl-3.0.html
  19. * or you may search the http://www.gnu.org website for the version 3 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <sim/sim_model_switch.h>
  24. #include <fmt/core.h>
  25. std::string SPICE_GENERATOR_SWITCH::ItemLine( const SPICE_ITEM& aItem ) const
  26. {
  27. std::string result;
  28. switch( m_model.GetType() )
  29. {
  30. case SIM_MODEL::TYPE::SW_V:
  31. {
  32. result = SPICE_GENERATOR::ItemLine( aItem );
  33. break;
  34. }
  35. case SIM_MODEL::TYPE::SW_I:
  36. {
  37. std::string vsourceName = fmt::format( "V__{}", aItem.refName );
  38. wxCHECK_MSG( aItem.pinNetNames.size() >= 2, "", wxS( "Missing two pin net names for SW_I" ) );
  39. // Current switches measure input current through a voltage source.
  40. result.append( fmt::format( "{0} {1} 0\n", aItem.pinNetNames[0], aItem.pinNetNames[1] ) );
  41. SPICE_ITEM item = aItem;
  42. item.modelName = fmt::format( "{0} {1}", vsourceName, aItem.modelName );
  43. result.append( SPICE_GENERATOR::ItemLine( item ) );
  44. break;
  45. }
  46. default:
  47. wxFAIL_MSG( wxS( "Unhandled SIM_MODEL type in SIM_MODEL_SWITCH" ) );
  48. break;
  49. }
  50. return result;
  51. }
  52. std::string SPICE_GENERATOR_SWITCH::ItemParams() const
  53. {
  54. std::string result;
  55. for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
  56. {
  57. const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
  58. if( !param.info.isSpiceInstanceParam )
  59. continue;
  60. // The only instance param is "ic", which is positional.
  61. std::string value = param.value;
  62. if( value != "none" )
  63. result.append( " " + value );
  64. }
  65. return result;
  66. }
  67. std::vector<std::reference_wrapper<const SIM_MODEL_PIN>> SPICE_GENERATOR_SWITCH::GetPins() const
  68. {
  69. switch( m_model.GetType() )
  70. {
  71. case SIM_MODEL::TYPE::SW_V:
  72. return { m_model.GetPin( 2 ), m_model.GetPin( 3 ), m_model.GetPin( 0 ), m_model.GetPin( 1 ) };
  73. case SIM_MODEL::TYPE::SW_I:
  74. return { m_model.GetPin( 2 ), m_model.GetPin( 3 ) };
  75. default:
  76. wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SWITCH" );
  77. return {};
  78. }
  79. }
  80. SIM_MODEL_SWITCH::SIM_MODEL_SWITCH( TYPE aType ) :
  81. SIM_MODEL( aType,
  82. std::make_unique<SPICE_GENERATOR_SWITCH>( *this ) )
  83. {
  84. static std::vector<PARAM::INFO> vsw = makeSwVParamInfos();
  85. static std::vector<PARAM::INFO> isw = makeSwIParamInfos();
  86. switch( aType )
  87. {
  88. case TYPE::SW_V:
  89. for( const PARAM::INFO& paramInfo : vsw )
  90. AddParam( paramInfo );
  91. break;
  92. case TYPE::SW_I:
  93. for( const PARAM::INFO& paramInfo : isw )
  94. AddParam( paramInfo );
  95. break;
  96. default:
  97. wxFAIL_MSG( wxS( "Unhandled SIM_MODEL type in SIM_MODEL_SWITCH" ) );
  98. break;
  99. }
  100. }
  101. const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
  102. {
  103. std::vector<PARAM::INFO> paramInfos;
  104. PARAM::INFO paramInfo;
  105. paramInfo.name = "thr";
  106. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  107. paramInfo.unit = "V";
  108. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  109. paramInfo.defaultValue = "0";
  110. paramInfo.description = "Threshold voltage";
  111. paramInfo.isSpiceInstanceParam = false;
  112. paramInfo.spiceModelName = "vt";
  113. paramInfo.enumValues = {};
  114. paramInfos.push_back( paramInfo );
  115. paramInfo.name = "his";
  116. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  117. paramInfo.unit = "V";
  118. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  119. paramInfo.defaultValue = "0";
  120. paramInfo.description = "Hysteresis voltage";
  121. paramInfo.isSpiceInstanceParam = false;
  122. paramInfo.spiceModelName = "vh";
  123. paramInfo.enumValues = {};
  124. paramInfos.push_back( paramInfo );
  125. paramInfo.name = "ron";
  126. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  127. paramInfo.unit = "Ω";
  128. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  129. paramInfo.defaultValue = "1";
  130. paramInfo.description = "Resistance when closed";
  131. paramInfo.isSpiceInstanceParam = false;
  132. paramInfo.spiceModelName = "";
  133. paramInfo.enumValues = {};
  134. paramInfos.push_back( paramInfo );
  135. paramInfo.name = "roff";
  136. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  137. paramInfo.unit = "Ω";
  138. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  139. paramInfo.defaultValue = "1e+12";
  140. paramInfo.description = "Resistance when open";
  141. paramInfo.isSpiceInstanceParam = false;
  142. paramInfo.spiceModelName = "";
  143. paramInfo.enumValues = {};
  144. paramInfos.push_back( paramInfo );
  145. paramInfo.name = "ic";
  146. paramInfo.type = SIM_VALUE::TYPE_STRING;
  147. paramInfo.unit = "";
  148. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  149. paramInfo.defaultValue = "none";
  150. paramInfo.description = "Initial state";
  151. paramInfo.isSpiceInstanceParam = true;
  152. paramInfo.spiceModelName = "";
  153. paramInfo.enumValues = { "none", "off", "on" };
  154. paramInfos.push_back( paramInfo );
  155. return paramInfos;
  156. }
  157. const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
  158. {
  159. std::vector<PARAM::INFO> paramInfos;
  160. PARAM::INFO paramInfo;
  161. paramInfo.name = "thr";
  162. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  163. paramInfo.unit = "A";
  164. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  165. paramInfo.defaultValue = "0";
  166. paramInfo.description = "Threshold current";
  167. paramInfo.isSpiceInstanceParam = false;
  168. paramInfo.spiceModelName = "it";
  169. paramInfo.enumValues = {};
  170. paramInfos.push_back( paramInfo );
  171. paramInfo.name = "his";
  172. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  173. paramInfo.unit = "A";
  174. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  175. paramInfo.defaultValue = "0";
  176. paramInfo.description = "Hysteresis current";
  177. paramInfo.isSpiceInstanceParam = false;
  178. paramInfo.spiceModelName = "ih";
  179. paramInfo.enumValues = {};
  180. paramInfos.push_back( paramInfo );
  181. paramInfo.name = "ron";
  182. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  183. paramInfo.unit = "Ω";
  184. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  185. paramInfo.defaultValue = "1";
  186. paramInfo.description = "Resistance when closed";
  187. paramInfo.isSpiceInstanceParam = false;
  188. paramInfo.spiceModelName = "";
  189. paramInfo.enumValues = {};
  190. paramInfos.push_back( paramInfo );
  191. paramInfo.name = "roff";
  192. paramInfo.type = SIM_VALUE::TYPE_FLOAT;
  193. paramInfo.unit = "Ω";
  194. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  195. paramInfo.defaultValue = "1e+12";
  196. paramInfo.description = "Resistance when open";
  197. paramInfo.isSpiceInstanceParam = false;
  198. paramInfo.spiceModelName = "";
  199. paramInfo.enumValues = {};
  200. paramInfos.push_back( paramInfo );
  201. paramInfo.name = "ic";
  202. paramInfo.type = SIM_VALUE::TYPE_STRING;
  203. paramInfo.unit = "";
  204. paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
  205. paramInfo.defaultValue = "1";
  206. paramInfo.description = "Initial state";
  207. paramInfo.isSpiceInstanceParam = true;
  208. paramInfo.spiceModelName = "";
  209. paramInfo.enumValues = { "none", "off", "on" };
  210. paramInfos.push_back( paramInfo );
  211. return paramInfos;
  212. }