42 Incheckningar 533a2cd5ae ... 0771f3f0d1

Upphovsman SHA1 Meddelande Datum
  Heinrich Blatt 0771f3f0d1 Fix: der ADC misst jetzt keine 40mA offset. 6 månader sedan
  Heinrich Blatt 9f2622ea19 Fix im Temperatursensor: Höhere Adressierung für den 2. Controller wird berücksichtigt. 6 månader sedan
  Heinrich Blatt d66c301764 Temperatursensor korrekt eingebunden. 6 månader sedan
  Heinrich Blatt 8c9864261d Bugfix: Strom setzen funktioniert jetzt 6 månader sedan
  Heinrich Blatt 6bb77fca70 PWM-Funktionalität optimiert: Die Timer werden bei inaktivem PWM ausgeschaltet. 6 månader sedan
  Heinrich Blatt 16c3c8623f Fixes: 6 månader sedan
  Heinrich Blatt 4998bcf2d0 Bugfix: now the controller doesn't restart in the interrupt of the mcu 6 månader sedan
  Heinrich Blatt e141c8a9d1 Refactoring 6 månader sedan
  Heinrich Blatt 972ffe8b23 Timeouts für I2C Kommunikation 6 månader sedan
  Heinrich Blatt 2fdb625a22 move i2c message handling to separate function 7 månader sedan
  Heinrich Blatt 5a4a498aad hotfix: move i2c response to interrupt 7 månader sedan
  Heinrich Blatt 3b812b4c08 Bugfix: Adressierung basierend auf Pins funktioniert jetzt 7 månader sedan
  Heinrich Blatt a17001f7dc Bugfix: I2C Kommunikation failsafe gemacht 7 månader sedan
  Heinrich Blatt ae8e04a4bc Verbesserung: ADC Adressen für höhere slot ids gefixt 7 månader sedan
  Heinrich Blatt 0be7681dff Bugfix: PWMs auswählen angepasst 7 månader sedan
  Heinrich Blatt 92cd570cc5 Verbesserung: Die Response zum externen I2C kann auch zwischen den slots measurement/control funktionen getriggert werden 7 månader sedan
  Heinrich Blatt b825fec4ce Fix: Ignore-Condition für nicht fertig gestellte TX angefügt. 7 månader sedan
  Heinrich Blatt e59f26f85e Support für Temperatursensoren hinzugefügt 7 månader sedan
  Heinrich Blatt 1c24f24635 Fixed i2c communication with external mcu 7 månader sedan
  Heinrich Blatt ede0a220f9 * i2c-target speicher-optimiert 7 månader sedan
  Heinrich Blatt e4aa74cb79 Bugfix auf dem ADC: Das erste Kommando funktioniert jetzt direkt (buffer geleert) 7 månader sedan
  Heinrich Blatt 566a29c1cf Änderungen im config header 7 månader sedan
  Heinrich Blatt 8ba47ea719 PWM Control-loop gefixt. Stromoffset-Problem der High-Side besteht noch. 7 månader sedan
  Heinrich Blatt d0c13cb239 Fix clock cycles aller PWMs auf 100kHz 7 månader sedan
  Heinrich Blatt 32ed47067b Verbesserungen: 7 månader sedan
  Heinrich Blatt 0a6dffb608 Berechnung der Auflösung funktioniert jetzt korrekt 7 månader sedan
  Heinrich Blatt fb29f92c12 * Battery.c: Spannungsmessung gefixt (floating point bug gelöst) 7 månader sedan
  Heinrich Blatt b516164b78 Merge branch '4pwm-config' into control-and-refacotring-improvements 7 månader sedan
  Heinrich Blatt 2de36d406b Fix: Improved ADC code for calculation 7 månader sedan
  Heinrich Blatt 6b5795652d Erweiterung: 4-Channel-Support 8 månader sedan
  Heinrich Blatt 172b023c1b Fix: Pin-Konfiguration für Adressconfig-Pin 8 månader sedan
  Heinrich Blatt a298bb8933 Added configurable ADC single-shot mode support 8 månader sedan
  Heinrich Blatt 576e1bf255 * Add dynamic adressing support (based on gpio 13, including sysconfig) 8 månader sedan
  Heinrich Blatt 525251bf9e DAC verbesserung: Der DAC unterstützt jetzt alle 4 channels 8 månader sedan
  Heinrich Blatt b2a5b2537a Debugging parameter optimiert: 8 månader sedan
  Heinrich Blatt 7a3ef5c37a Konfigurationen in externe config.h ausgelagert 8 månader sedan
  Heinrich Blatt 5bb9297a08 Änderungen: 8 månader sedan
  Heinrich Blatt 07cade2a4c Fix: Compiler errors von letztem Commit 8 månader sedan
  Heinrich Blatt cff9c9979e * Discovery für ADC und DAC implementiert 8 månader sedan
  Heinrich Blatt ef8cfa53ca Fehlerhandling hinzugefügt: 8 månader sedan
  Heinrich Blatt 6907789bf2 Control-Loop implementiert: 8 månader sedan
  Heinrich Blatt 96b028ac2e * Refactoring: Batteries -> BatterySlot 8 månader sedan

+ 35 - 46
.cproject

@@ -15,8 +15,8 @@
             <storageModule moduleId="cdtBuildSystem" version="4.0.0">
                 <configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.321921122" name="Debug" parent="com.ti.ccstudio.buildDefinitions.TMS470.Debug">
                     <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.321921122." name="/" resourcePath="">
-                        <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain.515242079" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.757387606">
-                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1069351396" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
+                        <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain.630004681" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.1137492946">
+                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1652573558" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
                                 <listOptionValue value="DEVICE_CONFIGURATION_ID=Cortex M.MSPM0L1304"/>
                                 <listOptionValue value="DEVICE_CORE_ID="/>
                                 <listOptionValue value="DEVICE_ENDIANNESS=little"/>
@@ -27,17 +27,17 @@
                                 <listOptionValue value="PRODUCT_MACRO_IMPORTS={&quot;MSPM0-SDK&quot;:[&quot;${COM_TI_MSPM0_SDK_INCLUDE_PATH}&quot;,&quot;${COM_TI_MSPM0_SDK_LIBRARY_PATH}&quot;,&quot;${COM_TI_MSPM0_SDK_LIBRARIES}&quot;,&quot;${COM_TI_MSPM0_SDK_SYMBOLS}&quot;,&quot;${COM_TI_MSPM0_SDK_SYSCONFIG_MANIFEST}&quot;],&quot;sysconfig&quot;:[&quot;${SYSCONFIG_TOOL_INCLUDE_PATH}&quot;,&quot;${SYSCONFIG_TOOL_LIBRARY_PATH}&quot;,&quot;${SYSCONFIG_TOOL_LIBRARIES}&quot;,&quot;${SYSCONFIG_TOOL_SYMBOLS}&quot;,&quot;${SYSCONFIG_TOOL_SYSCONFIG_MANIFEST}&quot;]}"/>
                                 <listOptionValue value="OUTPUT_TYPE=executable"/>
                             </option>
-                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.67649367" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="TICLANG_4.0.0.LTS" valueType="string"/>
-                            <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug.1714945800" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug"/>
-                            <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.builderDebug.725824404" keepEnvironmentInBuildfile="false" name="GNU Make" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.builderDebug"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug.864611155" name="Arm Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug">
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH.784128984" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH.thumbv6m" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU.1282070647" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU.cortex-m0plus" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI.1390698216" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI.soft" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE.938260042" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE.MLITTLE_ENDIAN" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB.1905157192" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB.MTHUMB" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL.1841069767" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL.0" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.INCLUDE_PATH.1072446908" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.INCLUDE_PATH" valueType="includePath">
+                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.432611712" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="TICLANG_4.0.0.LTS" valueType="string"/>
+                            <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug.683305228" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug"/>
+                            <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.builderDebug.1070277094" name="GNU Make.Debug" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.builderDebug"/>
+                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug.379884657" name="Arm Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH.1225926116" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MARCH.thumbv6m" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU.1844740802" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MCPU.cortex-m0plus" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI.1662746020" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.MFLOAT_ABI.soft" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE.1796712665" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.ENDIAN_NESS__BIG_LITTLE.MLITTLE_ENDIAN" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB.1203608164" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.SELECT_PROCESSOR_MODE__ARM_THUMB.MTHUMB" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL.1051342874" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.OPT_LEVEL.2" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.INCLUDE_PATH.409563250" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.INCLUDE_PATH" valueType="includePath">
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_INCLUDE_PATH}"/>
                                     <listOptionValue value="${SYSCONFIG_TOOL_INCLUDE_PATH}"/>
                                     <listOptionValue value="${PROJECT_ROOT}"/>
@@ -45,63 +45,52 @@
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_INSTALL_DIR}/source/third_party/CMSIS/Core/Include"/>
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_INSTALL_DIR}/source"/>
                                 </option>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.DEFINE.1013406358" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.DEFINE" valueType="definedSymbols">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.DEFINE.186791723" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.DEFINE" valueType="definedSymbols">
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_SYMBOLS}"/>
                                     <listOptionValue value="${SYSCONFIG_TOOL_SYMBOLS}"/>
                                 </option>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG.802626835" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG.GDWARF_3" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.CMD_FILE.2013188202" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.CMD_FILE" valueType="stringList">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG.1460981436" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.GENERATE_DWARF_DEBUG.GDWARF_3" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.CMD_FILE.621050892" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.CMD_FILE" valueType="stringList">
                                     <listOptionValue value="syscfg/device.opt"/>
                                 </option>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FLTO.976958676" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FLTO" value="false" valueType="boolean"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FFAST_MATH.1223255020" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FFAST_MATH" value="false" valueType="boolean"/>
                             </tool>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.757387606" name="Arm Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug">
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.MAP_FILE.1307010508" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.MAP_FILE" value="${ProjName}.map" valueType="string"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.OUTPUT_FILE.454202117" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.OUTPUT_FILE" value="${ProjName}.out" valueType="string"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.LIBRARY.721795037" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.LIBRARY" valueType="libs">
+                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.1137492946" name="Arm Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.MAP_FILE.1012182218" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.MAP_FILE" value="${ProjName}.map" valueType="string"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.OUTPUT_FILE.786825655" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.OUTPUT_FILE" value="${ProjName}.out" valueType="string"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.HEAP_SIZE.1728456418" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.HEAP_SIZE" value="0x120" valueType="string"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.LIBRARY.574131281" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.LIBRARY" valueType="libs">
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_LIBRARIES}"/>
                                     <listOptionValue value="${SYSCONFIG_TOOL_LIBRARIES}"/>
                                     <listOptionValue value="device.cmd.genlibs"/>
                                     <listOptionValue value="libc.a"/>
                                 </option>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.SEARCH_PATH.1793380014" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.SEARCH_PATH" valueType="libPaths">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.SEARCH_PATH.380806143" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.SEARCH_PATH" valueType="libPaths">
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_LIBRARY_PATH}"/>
                                     <listOptionValue value="${SYSCONFIG_TOOL_LIBRARY_PATH}"/>
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_INSTALL_DIR}/source"/>
                                     <listOptionValue value="${PROJECT_BUILD_DIR}/syscfg"/>
                                     <listOptionValue value="${CG_TOOL_ROOT}/lib"/>
                                 </option>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.REREAD_LIBS.1669358129" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.REREAD_LIBS" value="false" valueType="boolean"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP.1639231868" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DISPLAY_ERROR_NUMBER.1371843990" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.XML_LINK_INFO.1480395410" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.XML_LINK_INFO" value="${ProjName}_linkInfo.xml" valueType="string"/>
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.HEAP_SIZE.1226675406" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.HEAP_SIZE" value="0x120" valueType="string"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.REREAD_LIBS.1374713835" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.REREAD_LIBS" value="false" valueType="boolean"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP.266243495" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DISPLAY_ERROR_NUMBER.1121404874" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.VERBOSE_DIAGNOSTICS.956171569" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.VERBOSE_DIAGNOSTICS" value="true" valueType="boolean"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.ABSOLUTE_EXE.444307112" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.ABSOLUTE_EXE" value="true" valueType="boolean"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.XML_LINK_INFO.1943004326" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.linkerID.XML_LINK_INFO" value="${ProjName}_linkInfo.xml" valueType="string"/>
                             </tool>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.63786416" name="Arm Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy.1063716615" name="Arm Objcopy Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.sysConfig.1034218035" name="SysConfig" superClass="com.ti.ccstudio.buildDefinitions.sysConfig">
-                                <option id="com.ti.ccstudio.buildDefinitions.sysConfig.PRODUCTS.1980049847" superClass="com.ti.ccstudio.buildDefinitions.sysConfig.PRODUCTS" valueType="stringList">
+                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.465545696" name="Arm Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex">
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.ENTRYPOINT.947978690" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.ENTRYPOINT" value="main" valueType="string"/>
+                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.OUTPUT_FORMAT.208454576" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.OUTPUT_FORMAT" value="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.OUTPUT_FORMAT.TI_TXT" valueType="enumerated"/>
+                            </tool>
+                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy.1301045432" name="Arm Objcopy Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy"/>
+                            <tool id="com.ti.ccstudio.buildDefinitions.sysConfig.277147194" name="SysConfig" superClass="com.ti.ccstudio.buildDefinitions.sysConfig">
+                                <option id="com.ti.ccstudio.buildDefinitions.sysConfig.PRODUCTS.732286544" superClass="com.ti.ccstudio.buildDefinitions.sysConfig.PRODUCTS" valueType="stringList">
                                     <listOptionValue value="${COM_TI_MSPM0_SDK_SYSCONFIG_MANIFEST}"/>
                                     <listOptionValue value="${SYSCONFIG_TOOL_SYSCONFIG_MANIFEST}"/>
                                 </option>
                             </tool>
                         </toolChain>
                     </folderInfo>
-                    <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.321921122.src" name="src" resourcePath="src">
-                        <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain.2140273750" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.DebugToolchain" unusedChildren="">
-                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1069351396.425268750" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1069351396"/>
-                            <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.67649367.1491981951" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.67649367"/>
-                            <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.targetPlatformDebug"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug.602155337" name="Arm Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.compilerDebug.864611155">
-                                <option id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FLTO.752156111" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.compilerID.FLTO" value="false" valueType="boolean"/>
-                            </tool>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.1172497316" name="Arm Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.exe.linkerDebug.757387606"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.550316384" name="Arm Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.hex.63786416"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy.230466678" name="Arm Objcopy Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_TICLANG_4.0.objcopy.1063716615"/>
-                            <tool id="com.ti.ccstudio.buildDefinitions.sysConfig.266481718" name="SysConfig" superClass="com.ti.ccstudio.buildDefinitions.sysConfig.1034218035"/>
-                        </toolChain>
-                    </folderInfo>
                 </configuration>
             </storageModule>
             <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>

+ 2 - 0
.settings/org.eclipse.core.resources.prefs

@@ -12,5 +12,7 @@ encoding//Debug/src/peripherals/adc/subdir_rules.mk=UTF-8
 encoding//Debug/src/peripherals/adc/subdir_vars.mk=UTF-8
 encoding//Debug/src/peripherals/dac/subdir_rules.mk=UTF-8
 encoding//Debug/src/peripherals/dac/subdir_vars.mk=UTF-8
+encoding//Debug/src/peripherals/temp/subdir_rules.mk=UTF-8
+encoding//Debug/src/peripherals/temp/subdir_vars.mk=UTF-8
 encoding//Debug/subdir_rules.mk=UTF-8
 encoding//Debug/subdir_vars.mk=UTF-8

+ 98 - 0
.theia/launch.json

@@ -0,0 +1,98 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "empty_mspm0l1304_nortos_ticlang",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "empty_mspm0l1304_nortos_ticlang",
+                "resourceId": "/empty_mspm0l1304_nortos_ticlang/empty_mspm0l1304.syscfg"
+            }
+        },
+        {
+            "name": "charge_controller_target_mspm0L1304",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "charge_controller_target_mspm0L1304",
+                "resourceId": "/charge_controller_target_mspm0L1304"
+            },
+            "debuggerSettings": {
+                "targetConfigs/MSPM0L1304.ccxml": {
+                    "Texas Instruments XDS110 USB Debug Probe/CORTEX_M0P": {
+                        "data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<PropertyValues>\n\n  <property id=\"FlashFiles\">\n    <curValue></curValue>\n  </property>\n\n</PropertyValues>\n"
+                    }
+                }
+            }
+        },
+        {
+            "name": "charge_controller_target_mspm0L1304 (1)",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "charge_controller_target_mspm0L1304",
+                "resourceId": "/charge_controller_target_mspm0L1304/main_target.c"
+            }
+        },
+        {
+            "name": "charge_controller_target_mspm0L1304 (2)",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "charge_controller_target_mspm0L1304",
+                "resourceId": "/charge_controller_target_mspm0L1304/src/battery_data/battery.c"
+            }
+        },
+        {
+            "name": "gpio_test",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "gpio_test",
+                "resourceId": "/gpio_test"
+            },
+            "debuggerSettings": {
+                "targetConfigs/MSPM0L1304.ccxml": {
+                    "Texas Instruments XDS110 USB Debug Probe/CORTEX_M0P": {
+                        "data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<PropertyValues/>\n"
+                    }
+                }
+            }
+        },
+        {
+            "name": "empty_mspm0l1304_nortos_gcc",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "empty_mspm0l1304_nortos_gcc",
+                "resourceId": "/empty_mspm0l1304_nortos_gcc"
+            },
+            "debuggerSettings": {
+                "targetConfigs/MSPM0L1304.ccxml": {
+                    "Texas Instruments XDS110 USB Debug Probe/CORTEX_M0P": {
+                        "data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<PropertyValues/>\n"
+                    }
+                }
+            }
+        },
+        {
+            "name": "charge_controller_target_mspm0L1304 (3)",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "charge_controller_target_mspm0L1304",
+                "resourceId": "/charge_controller_target_mspm0L1304/src/peripherals/temp/tmp1075.c"
+            }
+        },
+        {
+            "name": "charge_controller_target_mspm0L1304 (4)",
+            "type": "ccs-debug",
+            "request": "launch",
+            "projectInfo": {
+                "name": "charge_controller_target_mspm0L1304",
+                "resourceId": "/charge_controller_target_mspm0L1304/src/interfaces/i2c_target.c"
+            }
+        }
+    ]
+}

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "battery.h": "c"
+    }
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
MSPM0L1304.uniflash


+ 33 - 80
main_target.c

@@ -1,70 +1,16 @@
 
 #include "src/battery_data/battery.h"
+#include "ti/driverlib/dl_i2c.h"
 #include "ti_msp_dl_config.h"
 //#include "ti/driverlib/dl_i2c.h"
 #include <stdio.h>
-#include "src/peripherals/adc/adc.h"
-#include "src/peripherals/adc/adc_interface.h"
-#include "src/i2c_comm/mcu_slave_interface.h"
-#include "src/interfaces/i2c_controller_interface.h"
+#include "src/interfaces/i2c_target.h"
+#include "src/interfaces/i2c_controller.h"
+#include "src/config.h"
 
-
-#define DELAY_CYCLE  (100000000)
-
-volatile bool mcu_CommandPending= false;
-
-/*
-Scans all the addresses of the peripherals:
-*/
-/*void I2C_scanBus(I2C_Regs *i2c) {
-    printf("1");
-    // **Step 1: Reset I2C Controller if Busy**
-    if (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) {
-        printf("I2C Bus Busy! Resetting I2C Controller...\n");
-        DL_I2C_disableController(i2c);  // Disable I2C
-        delay_cycles(20000);
-        DL_I2C_enableController(i2c);   // Re-enable I2C
-        delay_cycles(20000);
-    }
-    uint32_t i2c_status;
-    // **Step 2: Scan I2C Bus**
-    for (uint8_t addr = 0x08; addr < 0x78; addr++) {  // Valid I2C Address Range
-        printf("Scanning 0x%02X\n", addr);
-        DL_I2C_startControllerTransfer(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
-        delay_cycles(5000);
-
-        if (addr != 0x60 && addr != 0x68) {
-            continue;
-        }
-
-        i2c_status = DL_I2C_getControllerStatus(i2c);
-        printf("DL_I2C_getControllerStatus(i2c): %d\n", i2c_status);
-        printf("busy?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_BUSY));
-        printf("error?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ERROR));
-        printf("addr_ack?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ADDR_ACK));
-        printf("data_ack?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_DATA_ACK));
-        printf("arb_lost?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ARBITRATION_LOST));
-        printf("idle?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_IDLE));
-        printf("busy_bus?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_BUSY_BUS));
-        
-        if (!(DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
-            printf("Device found at: 0x%02X\n", addr);
-            DL_I2C_disableController(i2c);
-            DL_I2C_enableController(i2c);
-        }else {
-            // Clear the error by resetting the I2C controller
-            printf("Device not found...\n");
-            DL_I2C_disableController(i2c);
-            DL_I2C_enableController(i2c);
-        }
-    }
-
-    //printf("I2C Scan Complete!\n");
-}
-*/
+int8_t handle_read_pending_slot = -1;
 
 void I2C_controller_INST_IRQHandler(void) {
-  // printf("I2C Interrupt Triggered to ADC!\n");
   switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { 
     
     case DL_I2C_IIDX_CONTROLLER_START:
@@ -129,24 +75,23 @@ void I2C_target_INST_IRQHandler(void) {
   uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
   switch (status) {
   case DL_I2C_IIDX_TARGET_START:
-    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
     break;
   case DL_I2C_IIDX_TARGET_STOP:
-    mcu_CommandPending= true;
-    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
-    DL_I2C_flushTargetRXFIFO(I2C_target_INST);
     break;
   case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
-    if (DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
-      return;
+    // only use this function if we are async (filling buffers) - the rest is handled by the mainloop
+    if (handle_read_pending_slot == -1) {
+        handle_read_pending_slot = mcu_i2c_handle(I2C_target_INST);
     }
-    mcu_CommandPending= true;
     break;
   case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
-    mcu_CommandPending= true;
     break;
   case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
     break;
+  case DL_I2C_IIDX_TIMEOUT_A:
+  case DL_I2C_IIDX_TIMEOUT_B:
+    DL_I2C_flushTargetRXFIFO(I2C_target_INST);
+    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
   default:
     break;
   }
@@ -156,27 +101,35 @@ int main(void)
 
 {   
     SYSCFG_DL_init();
-    Battery_Init();
-    //I2C_scanBus(I2C_controller_INST);
     NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
-    
+
+    battery_slotmgr.init();
+
+    initialize_target_address();
+
     while (1) {
 
-        if(mcu_CommandPending){
-            printf("Step 1: Calling MCU target interrupt\n");
-            mcu_i2c_handle(I2C_target_INST);
-            mcu_CommandPending= false;
-            continue;
-        }
-        
         for(uint8_t slot= 0; slot< NUM_SLOTS; slot++){
-            for(uint8_t channel= 0; channel< 2; channel++){
-                updateADCReading_multichannel(slot, channel);
+            if (handle_read_pending_slot != -1) {
+                mcu_i2c_handle_read(I2C_target_INST, handle_read_pending_slot);
+                handle_read_pending_slot = -1;
+            }
+        
+            // step 1: update the voltage readings
+            battery_slotmgr.read_state(slot);
+
+            // step 2: control loop to adjust the dac / adc values,
+            // but only if no error happens
+            // (0x80 is the error flag of the state)
+            if ((*battery_slots[slot].state & 0x80) == 0) {
+                battery_slotmgr.adjust_current(slot);
+            } else {
+                battery_slotmgr.disable(slot);
             }
         }
         
-        delay_cycles(DELAY_CYCLE);
+        delay_cycles(MAINLOOP_DELAY);
         
     }
 }

+ 72 - 14
main_target.syscfg

@@ -9,17 +9,32 @@
 /**
  * Import the modules used in this configuration.
  */
+const Board         = scripting.addModule("/ti/driverlib/Board");
+const GPIO          = scripting.addModule("/ti/driverlib/GPIO", {}, false);
+const GPIO1         = GPIO.addInstance();
 const I2C           = scripting.addModule("/ti/driverlib/I2C", {}, false);
 const I2C1          = I2C.addInstance();
 const I2C2          = I2C.addInstance();
 const PWM           = scripting.addModule("/ti/driverlib/PWM", {}, false);
 const PWM1          = PWM.addInstance();
+const PWM2          = PWM.addInstance();
+const PWM3          = PWM.addInstance();
+const PWM4          = PWM.addInstance();
 const SYSCTL        = scripting.addModule("/ti/driverlib/SYSCTL");
 const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig");
 
 /**
  * Write custom configuration values to the imported modules.
  */
+Board.peripheral.$assign          = "DEBUGSS";
+Board.peripheral.swclkPin.$assign = "PA20";
+Board.peripheral.swdioPin.$assign = "PA19";
+
+GPIO1.$name                         = "GPIOS";
+GPIO1.associatedPins[0].direction   = "INPUT";
+GPIO1.associatedPins[0].$name       = "ADDR";
+GPIO1.associatedPins[0].pin.$assign = "PA24/OPA0.IN0-";
+
 I2C1.$name                             = "I2C_controller";
 I2C1.basicEnableController             = true;
 I2C1.intController                     = ["ARBITRATION_LOST","NACK","RXFIFO_TRIGGER","RX_DONE","TXFIFO_TRIGGER","TX_DONE"];
@@ -39,15 +54,15 @@ I2C1.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
 I2C1.sclPinConfig.enableConfig         = true;
 I2C1.sclPinConfig.internalResistor     = "PULL_UP";
 
-const Board                       = scripting.addModule("/ti/driverlib/Board", {}, false);
-Board.peripheral.$assign          = "DEBUGSS";
-Board.peripheral.swclkPin.$assign = "PA20";
-Board.peripheral.swdioPin.$assign = "PA19";
-
 I2C2.$name                             = "I2C_target";
 I2C2.basicEnableTarget                 = true;
-I2C2.basicTargetAddress                = 0x48;
 I2C2.intTarget                         = ["RXFIFO_TRIGGER","START","STOP","TXFIFO_TRIGGER"];
+I2C2.basicTargetAddress                = 0x48;
+I2C2.enableTimeoutA                    = true;
+I2C2.timeoutACount                     = 125;
+I2C2.enableTimeoutB                    = true;
+I2C2.timeoutBCount                     = 125;
+I2C2.intGeneric                        = ["TIMEOUT_A","TIMEOUT_B"];
 I2C2.peripheral.sdaPin.$assign         = "PA0";
 I2C2.peripheral.sclPin.$assign         = "PA1/NRST";
 I2C2.sdaPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric2";
@@ -61,13 +76,57 @@ I2C2.sclPinConfig.onlyInternalResistor = scripting.forceWrite(false);
 I2C2.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
 I2C2.sclPinConfig.enableConfig         = true;
 
-PWM1.$name                      = "PWM_0";
-PWM1.ccIndex                    = [0];
-PWM1.timerCount                 = 320;
-PWM1.peripheral.ccp0Pin.$assign = "PA26";
-PWM1.PWM_CHANNEL_0.$name        = "ti_driverlib_pwm_PWMTimerCC0";
-PWM1.PWM_CHANNEL_0.dutyCycle    = 10;
-PWM1.ccp0PinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric4";
+PWM1.timerCount                         = 320;
+PWM1.ccIndex                            = [1];
+PWM1.$name                              = "PWM_3";
+PWM1.peripheral.$assign                 = "TIMG0";
+PWM1.peripheral.ccp1Pin.$assign         = "PA6";
+PWM1.ccp1PinConfig.direction            = scripting.forceWrite("OUTPUT");
+PWM1.ccp1PinConfig.hideOutputInversion  = scripting.forceWrite(false);
+PWM1.ccp1PinConfig.onlyInternalResistor = scripting.forceWrite(false);
+PWM1.ccp1PinConfig.passedPeripheralType = scripting.forceWrite("Digital");
+PWM1.ccp1PinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric11";
+PWM1.PWM_CHANNEL_1.$name                = "ti_driverlib_pwm_PWMTimerCC0";
+PWM1.PWM_CHANNEL_1.invert               = true;
+
+PWM2.ccIndex                            = [1];
+PWM2.$name                              = "PWM_2";
+PWM2.timerCount                         = 320;
+PWM2.peripheral.$assign                 = "TIMG1";
+PWM2.peripheral.ccp1Pin.$assign         = "PA2";
+PWM2.ccp1PinConfig.direction            = scripting.forceWrite("OUTPUT");
+PWM2.ccp1PinConfig.hideOutputInversion  = scripting.forceWrite(false);
+PWM2.ccp1PinConfig.onlyInternalResistor = scripting.forceWrite(false);
+PWM2.ccp1PinConfig.passedPeripheralType = scripting.forceWrite("Digital");
+PWM2.ccp1PinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric6";
+PWM2.PWM_CHANNEL_1.$name                = "ti_driverlib_pwm_PWMTimerCC1";
+PWM2.PWM_CHANNEL_1.invert               = true;
+
+PWM3.ccIndex                            = [1];
+PWM3.$name                              = "PWM_1";
+PWM3.timerCount                         = 320;
+PWM3.peripheral.$assign                 = "TIMG2";
+PWM3.peripheral.ccp1Pin.$assign         = "PA22";
+PWM3.ccp1PinConfig.direction            = scripting.forceWrite("OUTPUT");
+PWM3.ccp1PinConfig.hideOutputInversion  = scripting.forceWrite(false);
+PWM3.ccp1PinConfig.onlyInternalResistor = scripting.forceWrite(false);
+PWM3.ccp1PinConfig.passedPeripheralType = scripting.forceWrite("Digital");
+PWM3.ccp1PinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric8";
+PWM3.PWM_CHANNEL_1.$name                = "ti_driverlib_pwm_PWMTimerCC2";
+PWM3.PWM_CHANNEL_1.invert               = true;
+
+PWM4.ccIndex                            = [1];
+PWM4.$name                              = "PWM_0";
+PWM4.timerCount                         = 320;
+PWM4.peripheral.$assign                 = "TIMG4";
+PWM4.peripheral.ccp1Pin.$assign         = "PA25";
+PWM4.ccp1PinConfig.direction            = scripting.forceWrite("OUTPUT");
+PWM4.ccp1PinConfig.hideOutputInversion  = scripting.forceWrite(false);
+PWM4.ccp1PinConfig.onlyInternalResistor = scripting.forceWrite(false);
+PWM4.ccp1PinConfig.passedPeripheralType = scripting.forceWrite("Digital");
+PWM4.ccp1PinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric10";
+PWM4.PWM_CHANNEL_1.$name                = "ti_driverlib_pwm_PWMTimerCC3";
+PWM4.PWM_CHANNEL_1.invert               = true;
 
 SYSCTL.disableNRSTPin     = true;
 SYSCTL.peripheral.$assign = "SYSCTL";
@@ -80,4 +139,3 @@ ProjectConfig.migrationCondition = true;
  * re-solve from scratch.
  */
 I2C2.peripheral.$suggestSolution = "I2C0";
-PWM1.peripheral.$suggestSolution = "TIMG1";

+ 215 - 11
src/battery_data/battery.c

@@ -1,25 +1,229 @@
 #include "battery.h"
 #include "ti/driverlib/dl_i2c.h"
+#include "ti/driverlib/dl_timerg.h"
 #include "ti_msp_dl_config.h"
+#include "src/peripherals/dac/dac.h"
+#include "src/peripherals/adc/adc.h"
+#include "src/interfaces/i2c_controller.h"
+// we need the itnerface for the ADC_TARGET_BASE_ADDRESS constant
+// refactor this somewhen to a general constants file
+#include "src/peripherals/adc/adc_interface.h"
+#include "src/peripherals/temp/tmp1075.h"
+#include "src/config.h"
+
+BatterySlot battery_slots[NUM_SLOTS];
+
+static void set_dac(uint8_t slot, uint16_t value) {
+    battery_slots[slot].dac_value = value;
+    DAC_SingleWrite(slot, value);
+}
+static void set_pwm(uint8_t slot, uint16_t value) {
+    battery_slots[slot].pwm_value = value;
+    DL_TimerG_setCaptureCompareValue(battery_slots[slot].timer, value, DL_TIMER_CC_1_INDEX);
+    if (value > 0 && !DL_TimerG_isRunning(battery_slots[slot].timer)) {
+        DL_TimerG_startCounter(battery_slots[slot].timer);
+    }
+    if (value == 0 && DL_TimerG_isRunning(battery_slots[slot].timer)) {
+        DL_TimerG_stopCounter(battery_slots[slot].timer);
+    }
+}
+static void batteryslots_disable(uint8_t slot) {
+    if (battery_slots[slot].dac_value != 0) {
+        set_dac(slot, 0);
+    }
+    if (battery_slots[slot].pwm_value != 0) {
+        set_pwm(slot, 0);
+    }
+}
 
-// Permissible charge temperature for LiIon battery is 0.0 degree Celsius to 45.0 degree Celsius
-// Correct temp_threshold yet to be analyzed
-#define TEMP_THRESHOLD  (460)
-//#define VOLTAGE_THRESHOLD ()
-// for extern -> variable definition
-Battery batteries[NUM_SLOTS];
 /*Initialize battery array and default parameters*/
-void Battery_Init(){
+static void batteryslots_init() {
+
+    // initialize data structures
+    battery_slots[0].timer = PWM_0_INST;
+    battery_slots[0].adc_addr = ADC_TARGET_BASE_ADDRESS;
+    battery_slots[1].timer = PWM_1_INST;
+    battery_slots[1].adc_addr = ADC_TARGET_BASE_ADDRESS+4;
+    battery_slots[2].timer = PWM_2_INST;
+    battery_slots[2].adc_addr = ADC_TARGET_BASE_ADDRESS+2;
+    battery_slots[3].timer = PWM_3_INST;
+    battery_slots[3].adc_addr = ADC_TARGET_BASE_ADDRESS+6;
+
     for(uint8_t i=0; i< NUM_SLOTS; i++){
 
-        batteries[i].voltage= 0;
-        batteries[i].current= 0;
-        batteries[i].temperature= 0;
-        batteries[i].slot_id= 0;
+        battery_slots[i].measurement.state = SLOT_STATE_OK;
+        // convinience trick:
+        // with that we can set *battery_slots[i].state = SLOT_STATE_* or SLOT_ERR_*
+        // like e.g. *battery_slots[i].state = SLOT_ERR_OVERTEMPERATURE
+        battery_slots[i].state = &battery_slots[i].measurement.state;
+
+        battery_slots[i].measurement.voltage = 0;
+        battery_slots[i].measurement.current = 0;
+        battery_slots[i].measurement.temperature = 0;
+        battery_slots[i].set_current = 0;
+
+        set_pwm(i, 0);
+        set_dac(i, 0);
+        delay_cycles(PWM_INITIALIZATION_DELAY);
+    }
+
+    
+    /*if (!i2c_discover(DAC_TARGET_ADDRESS)) {
+        // there is only 1 DAC for all 4 slots
+        for(uint8_t i=0; i< NUM_SLOTS; i++) {
+            *battery_slots[i].state = SLOT_ERR_NO_DAC;
+        }
+        // Error state - no I2C on bus - we cannot continue.
+        return;
     }
+
+    for(uint8_t i=0; i< NUM_SLOTS; i++){
+
+        set_dac(i, 0);
+        
+        if (!i2c_discover(ADC_TARGET_BASE_ADDRESS+i)) {
+            // this automatically translates to the other addresses
+            *battery_slots[i].state = SLOT_ERR_NO_ADC1+i;
+        }
+    }*/
 }
+static void batteryslots_read_state(uint8_t slot) {
+    /*
+     * Strategy:
+     * 1. updateADCReading calls the ADC function that does the control loop for getting the values
+     * 2. the updateADCReading also calls internally the HAL to send the i2c commands,
+     *    construct the configuration byte and calculate the values (voltage, current)
+     * 3. the adc updates the battery slot value directly
+     */
+ 
+    // step 1: read channel 0 (voltage reading of the cell)
+    uint16_t bare_voltage = read_adc_channel(slot, 0);
+    if (bare_voltage == 0xffff) {
+        // the voltage reading is invalid -> ignore this cycle.
+        return;
+    }
+    battery_slots[slot].measurement.voltage = bare_voltage*(56+100)/56; // We have that voltage divider
+
+    // DAC branch: we can calculate the current based on the shunt
+    if (battery_slots[slot].set_current >= 0) {
+        // read channel 1 (current reading on charge)
+        bare_voltage = read_adc_channel(slot, 1);
+        if (bare_voltage == 0xffff) {
+            // the voltage reading is invalid -> ignore this cycle.
+            return;
+        }
+        battery_slots[slot].measurement.current = bare_voltage*10/1000; // current comes in microvolts
+#ifdef DEBUG_CTRL
+        printf("Slot %d voltage: %d mV and %d mA (dac shunt)\n", slot, battery_slots[slot].measurement.voltage, battery_slots[slot].measurement.current);
+#endif
+    } else {
+        // we are in PWM mode, the shunt is on the high side
+        // read channel 2 (voltage reading on 5V side)
+        bare_voltage = read_adc_channel(slot, 2);
+        if (bare_voltage == 0xffff) {
+            // the voltage reading is invalid -> ignore this cycle.
+            return;
+        }
+        uint16_t shunt_current = 10*bare_voltage/1000;
 
+        // read channel 3 (current reading after step conversion, 5V side)
+        bare_voltage = read_adc_channel(slot, 3);
+        if (bare_voltage == 0xffff) {
+            // the voltage reading is invalid -> ignore this cycle.
+            return;
+        }
+        uint16_t hi_voltage = bare_voltage*(56+100)/56;
 
+        uint32_t hi_power = shunt_current*hi_voltage;
+
+        // calculate the result
+        battery_slots[slot].measurement.current = (int16_t)(hi_power/battery_slots[slot].measurement.voltage)*-1;
+#ifdef DEBUG_CTRL
+        printf("Slot %d voltage: %d mV and %d mA (pwm shunt) (hi side voltage: %d mV, hi side current: %d mA)\n", slot, battery_slots[slot].measurement.voltage, battery_slots[slot].measurement.current, hi_voltage, shunt_current);
+#endif
+    }
+
+    battery_slots[slot].measurement.temperature = read_temperature(slot);
+}
 
+static void batteryslots_adjust_current(uint8_t slot) {
+
+    if (battery_slots[slot].set_current > 0) {
+        // positive current -> charge (with DAC)
+
+        if (battery_slots[slot].pwm_value != 0) {
+            // seems like we switched from a charging before
+            // -> disable DAC before getting active
+            set_pwm(slot, 0);
+        }
+
+        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upper limit
+            // -> update dac value, decrease the voltage
+            if (battery_slots[slot].dac_value-1 >= 0) {
+                set_dac(slot, --battery_slots[slot].dac_value);
+            }
+            else {
+                // we want to give more current, but we can't ?!
+                *battery_slots[slot].state = SLOT_WARN_LOWER_DAC_NOT_POSSIBLE;
+            }
+        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upplowerer limit
+            // -> update dac value, increase the voltage
+            if (battery_slots[slot].dac_value+1 <= MAX_DAC_VALUE) {
+                set_dac(slot, ++battery_slots[slot].dac_value);
+            }
+            else {
+                // we want to give more current, but we can't ?!
+                *battery_slots[slot].state = SLOT_WARN_HIGHER_DAC_NOT_POSSIBLE;
+            }
+        }
+        // no else statement here: we are ok, since we are in the tolerance measure
+    } else if (battery_slots[slot].set_current < 0) {
+        // negative current -> discharge (with PWM)
+        if (battery_slots[slot].dac_value != 0) {
+            // seems like we switched from a charging before
+            // -> disable DAC before getting active
+            set_dac(slot, 0);
+        }
+
+        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upper limit
+            // -> update pwm value, decrease the voltage
+
+            if (battery_slots[slot].pwm_value+1 <= MAX_PWM_CYCLE) {
+                // pwm is inverse to the DAC since dragging more current means more negative
+                set_pwm(slot, ++battery_slots[slot].pwm_value);
+            }
+            else {
+                // we want to give more current, but we can't ?!
+                *battery_slots[slot].state = SLOT_WARN_HIGHER_PWM_NOT_POSSIBLE;
+            }
+        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upplowerer limit
+            // -> update pwm value, increase the voltage
+            if (battery_slots[slot].pwm_value-1 >= 0) {
+                set_pwm(slot, --battery_slots[slot].pwm_value);
+            }
+            else {
+                // we want to give more current, but we can't ?!
+                *battery_slots[slot].state = SLOT_WARN_LOWER_PWM_NOT_POSSIBLE;
+            }
+        }
+    } else {
+        // we have 0 -> stop charging and discharging
+        batteryslots_disable(slot);
+    }
+}
 
+BatterySlotManager battery_slotmgr = {
+    .init = batteryslots_init,
+    .read_state = batteryslots_read_state,
+    .adjust_current = batteryslots_adjust_current,
+    .disable = batteryslots_disable
+};
 

+ 50 - 36
src/battery_data/battery.h

@@ -3,51 +3,65 @@
 
 #include <stdint.h>
 #include <stdbool.h>
-//define macro to be used by multiple files in the program witout the variable being overwritten
-//for testing
-#define NUM_SLOTS (1)
-//Battery Tolerance
-#define BATTERY_THRESHOLD (50)
-// for i2c communication to know battery health
-#define BOOST_SOV_THRESHOLD_MV (4900)
-#define BOOST_HOV_THRESHOLD_MV (5400)
-#define TEMPERATURE_MAX_C (60)
-// Discharge hysterisis
-#define HYSTERISIS (50)
-
-//Battery states
-typedef enum{
-    STATE_EMPTY= 0x01,
-    STATE_BATTERY_DETECTED= 0x02,
-    STATE_WAITING_FOR_LIMITS= 0x03,
-    STATE_MEASUREMENT_IN_PROGRESS= 0x04,
-    STATE_MEASUREMENT_DONE= 0x04,
-    STATE_OVERHEATING= 0x05,
-
-} BatteryState;
+#include <stdio.h>
+#include "ti/driverlib/dl_timerg.h"
+#include "src/config.h"
 
 //Battery Discharge Safety Check
-typedef enum{
-    STATE_OK= 0x00,
-    STATE_SOV= 0x01,
-    STATE_HOV= 0x02,
-    STATE_OVERTEMPERATURE= 0x03,
-}DischargeSafetyCondition;
+typedef enum: uint8_t{
+    SLOT_STATE_OK= 0x00,
+    SLOT_STATE_SOV= 0x01,
+    SLOT_ERR_HOV= (0x02 | 0x80),
 
+    SLOT_ERR_OVERTEMPERATURE= (0x03 | 0x80), // first bit indicates complete error
 
-//Battery Structure
+    // Control error states
+    SLOT_WARN_LOWER_DAC_NOT_POSSIBLE=0x10,
+    SLOT_WARN_HIGHER_DAC_NOT_POSSIBLE=0x11,
+    SLOT_WARN_DAC_INVALID_VALUE=0x12,
+    SLOT_WARN_LOWER_PWM_NOT_POSSIBLE=0x13,
+    SLOT_WARN_HIGHER_PWM_NOT_POSSIBLE=0x14,
+
+    // I2C Slave Error states
+    SLOT_ERR_NO_DAC =  (0x20 | 0x80),
+    SLOT_ERR_NO_ADC1 = (0x21 | 0x80),
+    SLOT_ERR_NO_ADC2 = (0x22 | 0x80),
+    SLOT_ERR_NO_ADC3 = (0x23 | 0x80),
+    SLOT_ERR_NO_ADC4 = (0x24 | 0x80),
+    SLOT_ERR_CONFIGBYTE = (0x25 | 0x80),
+    SLOT_ERR_DAC_WRITE_FAILED= (0x26 | 0x80)
+} SlotState;
 
 typedef struct{
-    int16_t current;
     uint16_t voltage;
+    int16_t current;
     uint16_t temperature;
-    uint8_t slot_id;
-} Battery;
+    SlotState state;
+} BatteryMeasurement;
+
+typedef struct {
+    // for future extension of error states (overtemp etc): add here
+    int16_t set_current;
+    BatteryMeasurement measurement;
+    uint16_t dac_value;
+    uint16_t pwm_value;
+    GPTIMER_Regs *timer;
+    SlotState *state;
+    int16_t high_side_voltage;
+    uint8_t adc_addr;
+
+} BatterySlot;
 
 //global battery array declaration: extending visiblity of the variable to multiple source files: variable declaration
-extern Battery batteries[NUM_SLOTS];
+extern BatterySlot battery_slots[NUM_SLOTS];
+
+typedef struct {
+    void (*init)();
+    void (*read_state)(uint8_t slot_id);
+    void (*adjust_current)(uint8_t slot_id);
+    void (*disable)(uint8_t slot_id);
+} BatterySlotManager;
+
+extern BatterySlotManager battery_slotmgr;
 
-void Battery_Init();
-void Battery_Discharge_SafetyCheck(uint8_t slot_id);
-void Battery_ReadState(uint8_t slot_id);
 #endif

+ 104 - 0
src/config.h

@@ -0,0 +1,104 @@
+// globals definition
+
+//------------------------
+// Configuration section
+
+// How many slots do we currently support?
+// use 1 for debugging, 4 for production
+#define NUM_SLOTS 4
+
+//Battery Tolerance
+// how much tolerance do we allow if we charge / discharge before we 
+// trigger the control loop to adjust the value
+#define BATTERY_CURRENT_THRESHOLD 5
+
+// Mainloop sleep time
+// Time to sleep between two mainloop intervals
+// We have a 32 MHz clock
+// debugging e.g. 32000000*5 -> 5s
+// production e.g. 320000 (10ms) (Validate that this is really the case!)
+// should be large for debugging, (e.g. )
+// small for production
+#define MAINLOOP_DELAY (3200)
+
+// i2c address for acting as target
+// (based on the GPIO 1 integer is added)
+#define I2C_TARGET_BASE_ADDRESS 0x48
+
+// PWM Initalization delay
+// in order to ensure they don't go in exactly the same frequency to
+// avoid EMV peaks
+#define PWM_INITIALIZATION_DELAY 100
+
+// PWM Define max CC period
+#define MAX_PWM_CYCLE 320
+
+//------------
+// Section for configuring debugging outputs
+//------------
+
+// printf ADC outputs
+#define DEBUG_ADC 1
+
+// printf DAC outputs
+#define DEBUG_DAC 1
+
+// printf control loop outputs
+#define DEBUG_CTRL 1
+
+// printf trace: put also the transition messages
+#define DEBUG_TRACE_CTRL 1
+
+// printf i2c errors
+#define DEBUG_I2C_ERR 1
+
+// printf i2c traffic (tx)
+//#define DEBUG_I2C_TX 1
+
+// printf target i2c interrupts (where the mcu is the i2c target)
+#define DEBUG_TARGET 1
+
+// debug temperature sensor
+//#define DEBUG_TEMPERATURE
+
+//------------
+// Section for configuring error tresholds
+//------------
+
+// soft overvoltage treshold before getting into the soft overvoltage state
+#define SOV_THRESHOLD_MV 6000
+
+// hard overvoltage treshold for getting into the hard overvoltage state (error)
+#define HOV_THRESHOLD_MV 8000
+
+// define the temperature error state
+#define OVERTEMPERATURE_TRESHOLD 43
+
+//------------
+// Section for configuring i2c master values
+//------------
+// dac address
+#define DAC_TARGET_ADDRESS 0x60
+
+// ADC base address
+// it is assumed the slots are ADC ADC_TARGET_BASE_ADDRESS slot 0,
+// other addresses follow the address table of the MCP3428
+#define ADC_TARGET_BASE_ADDRESS 0x68
+
+// ADC Measurement mode:
+// can be single shot or continuous
+// if used continuous, a matching delay cycles needs to be set in order to
+// ensure that the measurement is ready. (set the define to 0 if it should be one-shot)
+// (it could be the case that the channel is switched and wrong data is fetched)
+#define ADC_MEASUREMENT_IS_CONTINUOUS 1
+#define ADC_CONTINUOUS_DELAY_CYCLES_VOLTAGES (32000*10) // 32000 is 1ms (32MHz clock)
+#define ADC_CONTINUOUS_DELAY_CYCLES_SHUNT (32000*75)
+
+// Packet buffer sizes for RX and TX for the
+// controller mode only
+// (target for the other MCU is treated differently)
+#define I2C_TX_MAX_PACKET_SIZE 5
+#define I2C_RX_MAX_PACKET_SIZE 5
+
+// how many cycles do we wait until a tx message is completed?
+#define MAX_I2C_WAIT_RX 32000*10

+ 0 - 91
src/i2c_comm/mcu_slave_interface.c

@@ -1,91 +0,0 @@
-/*
-References:
-https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
-
-*/
-
-#include "mcu_slave_interface.h"
-#include "src/battery_data/battery.h"
-#include "ti/driverlib/dl_i2c.h"
-#include <stdio.h>
-#include <string.h>
-#include "src/peripherals/dac/dac.h"
-#include <inttypes.h>
-
-/*Function to Rx and Tx data from Target to Controller*/
-// The code has multiple i2c instances (multiple MCUs connected) from which we
-// need to select the right one, passing a pointer as an argument
-
-void mcu_i2c_handle(I2C_Regs *i2c) {
-  printf("MCU interrupt triggered\n");
-  uint8_t receivedCommand = DL_I2C_receiveTargetData(i2c);
-  printf("[SLAVE] Received Command: 0x%02X\n", receivedCommand);
-  uint8_t tx_buffer[8] = {0};
-  // changed to volatile variable, so that the compiler cannot optimize the
-  // variable out and is forced to do as told by the code
-  volatile uint8_t rx_buffer[8] = {0};
-  /*Handling GET commands with bitmasking*/
-  // GET command for ADC(Battery Measurement): Voltage, Current, Temperature
-  if ((receivedCommand & 0xF0) == 0x60) {
-    uint8_t slot = receivedCommand & 0x0F;
-    if (slot > NUM_SLOTS) {
-      DL_I2C_flushTargetTXFIFO(i2c);
-      return;
-    }
-    // Struct for voltage, current and temperature
-    BatteryMeasurementData battery_measure;
-    // Battery *battery= &batteries[slot];
-    //  take the updated battery measurement from the battery struct and store
-    //  it in the battery_measure struct
-    battery_measure.voltage = batteries[slot].voltage;
-    battery_measure.current = batteries[slot].current;
-    battery_measure.temperature = batteries[slot].temperature;
-    // Copying the memory block from battery_measure struct to tx_buffer:
-    memcpy(tx_buffer, &battery_measure, sizeof(BatteryMeasurementData));
-    DL_I2C_fillTargetTXFIFO(i2c, tx_buffer, sizeof(BatteryMeasurementData));
-    printf("Battery Measurement Sent to MCU. \n");
-    DL_I2C_flushTargetTXFIFO(i2c);
-  } else if (receivedCommand == CMD_SET_CURRENT) {
-    SetChargeDischargeCurrent set_current;
-    // Read incoming bytes from the Controller:
-    uint8_t rx_index = 0;
-    while (rx_index < sizeof(SetChargeDischargeCurrent)+1) {
-      // TODO: Need to have a workaround, currently the code is getting stuck on
-      // the first trigger and provides result on the second trigger
-      if (!DL_I2C_isTargetRXFIFOEmpty(i2c)) {
-        rx_buffer[rx_index] = DL_I2C_receiveTargetData(i2c);
-        rx_index++;
-      }
-    }
-    printf("index:%d\n", rx_index);
-    // Byte array received from the Controller will be typecasted to (const
-    // uint8_t *), treats the rx_buffer as an array of READ ONLY bytes because
-    // of the const
-    if (rx_index != sizeof(SetChargeDischargeCurrent)+1) {
-      printf("ERROR: Incomplete I2C Rx: received %d%zu bytes\n", rx_index,
-             sizeof(SetChargeDischargeCurrent)+1);
-      DL_I2C_flushTargetRXFIFO(i2c);
-      rx_index = 0;
-      return;
-    }
-    printf("size: %d", sizeof(SetChargeDischargeCurrent));
-    memcpy(&set_current, (const uint8_t *)rx_buffer+1,
-           sizeof(SetChargeDischargeCurrent));
-    uint8_t slot = set_current.slot_id;
-    int16_t current = set_current.current;
-    printf("Slot id: %d, Current: %" SCNd16 "\n", slot, current);
-    if (current >= 0) {
-      DAC_SingleWrite(slot, current);
-    } else if (current < 0) {
-        
-        DL_TimerG_startCounter(PWM_0_INST);
-        DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*current, DL_TIMER_CC_0_INDEX); // update ccr0 value
-        //DL_TimerG_setCaptureCompareValue(PWM_0_INST, 1000, DL_TIMER_CC_1_INDEX); 
-
-    } else {
-      // do nothing, charge or discharge
-      printf("state is idle");
-    }
-
-  }
-}

+ 0 - 31
src/i2c_comm/mcu_slave_interface.h

@@ -1,31 +0,0 @@
-//This file is an interface for I2C communication between MSPM0G3507 (Controller) and MSPM0L1304 (Target)
-
-#ifndef MCU_SLAVE_INTERACE_H_
-#include <stdint.h>
-#include "ti/driverlib/dl_i2c.h"
-#include "ti_msp_dl_config.h"
-
-// Handles I2C command coming into Target MCU:
-
-typedef enum{
-    CMD_SET_CURRENT= 0x05,
-    CMD_GET_MEASUREMENT= 0x06, 
-    CMD_GET_BATTERY_STATE= 0x07, 
-    CMD_SET_HOV_CLEAR= 0x08
-}mcu_I2C_command;
-
-//Command structures:
-typedef struct __attribute__((packed)) {
-    uint8_t slot_id;
-    int16_t current;
-    
-}SetChargeDischargeCurrent;
-
-typedef struct __attribute__((packed)){
-    uint16_t voltage;
-    int16_t current;
-    uint16_t temperature;
-}BatteryMeasurementData;
-
-void mcu_i2c_handle(I2C_Regs *i2c);
-#endif

+ 144 - 0
src/interfaces/i2c_controller.c

@@ -0,0 +1,144 @@
+/*
+ * This file implements Hardware Abstraction Layer (HAL) to make the I2C
+ * communication of MSPM0 SDK compatible with ADC (MCP3426/7/8) and DAC
+ * (MCP34728)
+ */
+#include "src/interfaces/i2c_controller.h"
+#include "ti/driverlib/dl_i2c.h"
+#include "ti_msp_dl_config.h"
+#include <stdio.h>
+
+/*
+static function is for implementing Data Hiding, access to the static function
+is restricted to the file where they are declared const keyword for
+'i2c_addr' and 'Data_length' makes the variable immutable. const uint8_t *
+const Data: means the pointer to the variable and the value of Data is immutable
+*/
+
+I2CRxPackage controllerRxPackage;
+I2CTxPackage controllerTxPackage;
+
+static bool msp_i2c_write(uint8_t const i2c_addr) {
+    // Flush any stale data in TX FIFO:
+    DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
+
+    // **Check if the I2C bus is stuck before WRITE
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) &
+        DL_I2C_CONTROLLER_STATUS_ERROR) {
+#ifdef DEBUG_I2C_ERR
+        printf("I2C Communication: Bus is stuck!\n");
+#endif
+        DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+        return false; 
+    }
+    
+    // **Wait for I2C Bus to be Free**
+    uint32_t n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n");
+        DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+        return false;
+    }
+
+    // **Start I2C Write Transaction**
+    DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr,
+                                  DL_I2C_CONTROLLER_DIRECTION_TX, controllerTxPackage.len);
+
+    // **Load Configuration Byte into TX FIFO**
+    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, controllerTxPackage.packet, controllerTxPackage.len);
+#ifdef DEBUG_I2C_TX
+    for (uint8_t i = 0; i < controllerTxPackage.len; i++) {
+        printf("Sending 0x%02X\n", controllerTxPackage.packet[i]);
+    }
+#endif
+
+    n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready after transmit data\n");
+        DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+        return false;
+    }
+    
+    // **Check if the target address is incorrect
+    
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ADDR_ACK) {
+#ifdef DEBUG_I2C_ERR
+        printf("I2C Write Error: Target Address not acknowledged!\n");
+#endif
+      return false;
+    }
+
+    // **Check for any WRITE error
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
+#ifdef DEBUG_I2C_ERR
+        printf("I2C Write Error: Bus error after sending data.\n");
+#endif
+        return false;
+    }
+
+    return true;
+}
+
+static bool msp_i2c_read(uint8_t const i2c_addr) {
+
+  
+    // Flush any stale data in TX FIFO:
+    DL_I2C_flushControllerRXFIFO(I2C_controller_INST);
+    
+    uint32_t n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n");
+    }
+
+    DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr,
+                                    DL_I2C_CONTROLLER_DIRECTION_RX, controllerRxPackage.len);
+
+    n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready after transmit start\n");
+    }
+        
+    DL_I2C_enableInterrupt(I2C_controller_INST,
+                            DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
+    
+    
+    return true;
+}
+
+/**
+ * this function discovers on the i2c bus the devices from the address
+ * to ensure all relevant bus participants are present
+ */
+ bool i2c_discover(uint8_t i2c_addr) {
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) {
+        DL_I2C_disableController(I2C_controller_INST);  // Disable I2C
+        DL_I2C_enableController(I2C_controller_INST);   // Re-enable I2C
+    }
+#ifdef DEBUG_I2C_TX
+    printf("Scanning 0x%02X\n", i2c_addr);
+#endif
+    DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+    delay_cycles(5000);
+    uint32_t i2c_status = DL_I2C_getControllerStatus(I2C_controller_INST);
+    bool found = !(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR);
+    DL_I2C_disableController(I2C_controller_INST);
+    DL_I2C_enableController(I2C_controller_INST);
+    return found;
+}
+
+I2C_Interface i2c_hal = {
+    .write = msp_i2c_write,
+    .read = msp_i2c_read,
+};

+ 4 - 5
src/interfaces/i2c_controller_interface.h → src/interfaces/i2c_controller.h

@@ -4,7 +4,7 @@
 * Our current functions in ADC and DAC are tightly coupled with I2C communication. 
 * Need a communication mechanism to isolate the flow of the ADC function from Asynchronous calls.
 * Decision:
-* i2c_controller_interface is a header file which defines what the I2C peripheral does:
+* i2c_controller is a header file which defines what the I2C peripheral does:
 * - i2c READ
 * - i2c WRITE
 * - i2c start controller transfer
@@ -24,10 +24,7 @@ Reference:
 
 #include <stdint.h>
 #include <stdbool.h>
-
-//Maximum packet sizes
-#define I2C_TX_MAX_PACKET_SIZE (4)  
-#define I2C_RX_MAX_PACKET_SIZE (4)  
+#include "src/config.h"
 
 typedef struct {
     volatile bool complete;
@@ -46,6 +43,8 @@ typedef struct {
 } I2CTxPackage;
 extern I2CTxPackage controllerTxPackage;
 
+bool i2c_discover(uint8_t i2c_addr);
+
 /*
 * Since C does not allows to add functions in typedef struct, however a function pointer can be included in Structure in C. This interface provides a standard features of i2c_hal
 */

+ 0 - 105
src/interfaces/i2c_hal.c

@@ -1,105 +0,0 @@
-/*
- * This file implements Hardware Abstraction Layer (HAL) to make the I2C
- * communication of MSPM0 SDK compatible with ADC (MCP3426/7/8) and DAC
- * (MCP34728)
- */
-#include "src/interfaces/i2c_controller_interface.h"
-#include "ti/driverlib/dl_i2c.h"
-#include "ti_msp_dl_config.h"
-#include <stdio.h>
-
-volatile bool gRxComplete;
-volatile bool gTxComplete;
-uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE];
-uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];
-uint8_t gTxADClen, gTxADCcount;
-uint8_t gRxADClen, gRxADCcount;
-
-/*
-static function is for implementing Data Hiding, access to the static function
-is restricted to the file where they are declared const keyword for
-'TARGET_ADDRESS' and 'Data_length' makes the variable immutable. const uint8_t *
-const Data: means the pointer to the variable and the value of Data is immutable
-*/
-
-I2CRxPackage controllerRxPackage;
-I2CTxPackage controllerTxPackage;
-
-static bool msp_i2c_write(uint8_t const TARGET_ADDRESS) {
-  // Flush any stale data in TX FIFO:
-  DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
-
-  // **Check if the I2C bus is stuck before WRITE
-  if (DL_I2C_getControllerStatus(I2C_controller_INST) &
-      DL_I2C_CONTROLLER_STATUS_ERROR) {
-    printf("I2C Communication: Bus is stuck!\n");
-    DL_I2C_resetControllerTransfer(I2C_controller_INST); 
-    return false; 
-  }
-  
-  // **Wait for I2C Bus to be Free**
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-
-  // **Start I2C Write Transaction**
-  DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
-                                 DL_I2C_CONTROLLER_DIRECTION_TX, controllerTxPackage.len);
-
-  // **Load Configuration Byte into TX FIFO**
-  DL_I2C_fillControllerTXFIFO(I2C_controller_INST, controllerTxPackage.packet, controllerTxPackage.len);
-  for (uint8_t i = 0; i < controllerTxPackage.len; i++) {
-      printf("Sending 0x%02X\n", controllerTxPackage.packet[i]);
-  }
-
-  // ** Wait for the I2C Bus to be FREE **
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-  
-  // **Check if the target address is incorrect
-  
-  if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ADDR_ACK) {
-    printf("I2C Write Error: Target Address not acknowledged!\n");
-    return false;
-  }
-  
-  // Debug for I2C WRITE:
-  //printf("HAL Write: Address=0x%02X, Data Length=%d\n", TARGET_ADDRESS, Data_length);
-
-
-  // **Check for any WRITE error
-  if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
-    printf("I2C Write Error: Bus error after sending data.\n");
-    return false;
-  }
-
-  return true;
-}
-
-static bool msp_i2c_read(uint8_t const TARGET_ADDRESS) {
-
-  
- // Flush any stale data in TX FIFO:
-  DL_I2C_flushControllerRXFIFO(I2C_controller_INST);
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-  DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
-                                 DL_I2C_CONTROLLER_DIRECTION_RX, controllerRxPackage.len);
-
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-    
-  DL_I2C_enableInterrupt(I2C_controller_INST,
-                         DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
-  
-  
-  return true;
-}
-
-I2C_Interface i2c_hal = {
-    .write = msp_i2c_write,
-    .read = msp_i2c_read,
-};

+ 104 - 0
src/interfaces/i2c_target.c

@@ -0,0 +1,104 @@
+/*
+References:
+https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
+*/
+
+#include "i2c_target.h"
+#include "src/battery_data/battery.h"
+#include "ti/driverlib/dl_i2c.h"
+#include <stdio.h>
+#include <string.h>
+#include "src/peripherals/dac/dac.h"
+#include <inttypes.h>
+#include "src/config.h"
+#include "ti_msp_dl_config.h"
+#include "src/peripherals/temp/tmp1075.h"
+
+/**
+ * Dynamic addressing function
+ * 1. set resistor to pullup
+ * 2. measure gpio:
+ *   is it up, set the address +0, else set it +1
+ * 3. disable the pullup again, so there is no current wasted
+ */
+void initialize_target_address() {
+    uint8_t add = 0;
+    if (DL_GPIO_readPins(GPIOS_PORT, GPIOS_ADDR_PIN)) {
+        add = 1;
+        addr_offset = 4;
+    }
+    DL_I2C_setTargetOwnAddress(I2C_target_INST, I2C_TARGET_BASE_ADDRESS+add);
+    DL_I2C_enableTargetOwnAddress(I2C_target_INST);
+}
+
+/*Function to Rx and Tx data from Target to Controller*/
+// The code has multiple i2c instances (multiple MCUs connected) from which we
+// need to select the right one, passing a pointer as an argument
+
+int8_t mcu_i2c_handle(I2C_Regs *i2c) {
+    if (DL_I2C_isTargetRXFIFOEmpty(i2c)) {
+      return -1;
+    }
+        
+    uint8_t receivedByte = DL_I2C_receiveTargetData(i2c);
+    uint8_t receivedCommand = (receivedByte & 0x0F);
+    uint8_t slot = ((receivedByte & 0xF0) >> 4);
+
+    if (receivedCommand == CMD_GET_MEASUREMENT) {
+        DL_I2C_flushTargetTXFIFO(i2c);
+        DL_I2C_fillTargetTXFIFO(i2c, (uint8_t *)&battery_slots[slot].measurement, 8);
+    } else if (receivedCommand == CMD_SET_CURRENT) {
+        return slot;
+    } else if (receivedCommand == CMD_CLEAR_ERR) {
+        if (slot > NUM_SLOTS) {
+            DL_I2C_flushTargetTXFIFO(i2c);
+            return -1;
+        }
+        *battery_slots[slot].state = SLOT_STATE_OK;
+    }
+    DL_I2C_flushTargetRXFIFO(i2c);
+    return -1;
+}
+
+void mcu_i2c_handle_read(I2C_Regs *i2c, uint8_t slot) {
+    // Read incoming bytes from the Controller:
+        uint8_t rx_index = 0;
+        uint8_t rx_buffer[2] = {0x00, 0x00};
+        while (rx_index < 2) {
+            // TODO: Need to have a workaround, currently the code is getting stuck on
+            // the first trigger and provides result on the second trigger
+            if (!DL_I2C_isTargetRXFIFOEmpty(i2c)) {
+                rx_buffer[rx_index] = DL_I2C_receiveTargetData(i2c);
+                rx_index++;
+            }
+        }
+        if (rx_index != 2) {
+#ifdef DEBUG_TARGET
+            printf("ERROR: Incomplete I2C Rx: received %d bytes\n", rx_index);
+#endif
+            DL_I2C_flushTargetRXFIFO(i2c);
+            rx_index = 0;
+            return;
+        }
+        battery_slots[slot].set_current = *((int16_t*)(&rx_buffer[0]));
+        
+#ifdef DEBUG_TARGET
+        printf("Slot id: %d, Current: %d mA (Bytes 0x%02X 0x%02X)\n", slot, battery_slots[slot].set_current, rx_buffer[0], rx_buffer[1]);
+#endif
+        /*
+        // This code is for debugging:
+        // you can shoot directly code to the DAC / PWM for debugging
+        if (battery_slots[slot].set_current >= 0) {
+            DAC_SingleWrite(slot, battery_slots[slot].set_current);
+        } else if (battery_slots[slot].set_current < 0) {
+            DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*battery_slots[slot].set_current, DL_TIMER_CC_1_INDEX);
+
+        } else {
+            // do nothing, charge or discharge
+#ifdef DEBUG_TARGET
+            printf("state is idle");
+#else
+            ;
+#endif
+        } */
+}

+ 20 - 0
src/interfaces/i2c_target.h

@@ -0,0 +1,20 @@
+//This file is an interface for I2C communication between MSPM0G3507 (Controller) and MSPM0L1304 (Target)
+
+#ifndef MCU_SLAVE_INTERACE_H_
+#include <stdint.h>
+#include "ti/driverlib/dl_i2c.h"
+#include "ti_msp_dl_config.h"
+
+// Handles I2C command coming into Target MCU:
+
+typedef enum{
+    CMD_SET_CURRENT= 0x05,
+    CMD_GET_MEASUREMENT= 0x06, 
+    CMD_CLEAR_ERR= 0x07
+}mcu_I2C_command;
+
+void initialize_target_address();
+
+int8_t mcu_i2c_handle(I2C_Regs *i2c);
+void mcu_i2c_handle_read(I2C_Regs *i2c, uint8_t slot);
+#endif

+ 36 - 35
src/peripherals/adc/adc.c

@@ -3,28 +3,53 @@
 #include <stdint.h>
 #include <stdio.h>
 #include "src/peripherals/adc/adc_interface.h"
-#include "src/interfaces/i2c_controller_interface.h"
+#include "src/interfaces/i2c_controller.h"
+#include "src/config.h"
 
 
 //static ADC_Params adc_params;
 static ADC_MeasurementState adc_state = ADC_STATE_CONFIGURE;
 
 
-void updateADCReading_multichannel(uint8_t slot, uint8_t channel) {
+uint16_t read_adc_channel(uint8_t slot, uint8_t channel) {
   //printf("Slot: %d, Channel: %d\n", slot, channel);
   ADC_Params adc_params= {0}; 
+  uint16_t adc_voltage = 0;
   while (adc_state != ADC_STATE_DONE) {
     switch (adc_state) {
         
         case ADC_STATE_CONFIGURE:
             adc_params.channel = channel;
-            adc_params.resolution = 12;
-            //adc_params.continuous = 1;
-            adc_params.gain = 1;
+            adc_params.continuous = ADC_MEASUREMENT_IS_CONTINUOUS;
+            if (channel == 0 || channel == 3) {
+                // voltage measurement
+                // -> we can measure directly
+                adc_params.gain = 1;
+                adc_params.resolution = 12;
+                adc_params.factor = 1;
+            } else {
+                // current measurement
+                // -> maximum gain, max resolution
+                //adc_params.gain = 8;
+                //adc_params.resolution = 16;
+                adc_params.factor = 1000; // get microvolts
+            }
             //printf("Config: Memory address of batteries: %p\n", &batteries[0]);
-            adc_hal.configure(slot, &adc_params);
-            //adc_state = ADC_STATE_WAIT;
-            adc_state = ADC_STATE_READ;
+            if (!adc_hal.configure(slot, &adc_params)) {
+                return 0xffff;
+            }
+            if (adc_params.continuous != 1) {
+                // in one shot mode we wait first to get the result
+                adc_state = ADC_STATE_WAIT;
+            } else {
+                // in continuous mode we can directly read
+                adc_state = ADC_STATE_READ;
+                if (adc_params.resolution == 16) {
+                    delay_cycles(ADC_CONTINUOUS_DELAY_CYCLES_SHUNT);
+                } else {
+                    delay_cycles(ADC_CONTINUOUS_DELAY_CYCLES_VOLTAGES);
+                }
+            }
             break;
 
         case ADC_STATE_WAIT:
@@ -34,33 +59,8 @@ void updateADCReading_multichannel(uint8_t slot, uint8_t channel) {
             break;
 
         case ADC_STATE_READ:
-            if (channel == 0) {
-
-                int16_t raw_adc_voltage = adc_hal.read_raw(slot, &adc_params);
-                batteries[slot].voltage =
-                    adc_hal.convert_voltage(raw_adc_voltage, &adc_params); 
-                adc_state = ADC_STATE_DONE;
-                printf("[ADC] Battery Voltage in slot %d is %d mV.\n", slot, batteries[slot].voltage);
-                //printf("voltage: Memory address of batteries: %p\n", &batteries[0].voltage);
-
-            } else if (channel == 1) {
-
-                int16_t raw_adc_current = adc_hal.read_raw(slot, &adc_params);
-                batteries[slot].current =
-                    adc_hal.convert_current(raw_adc_current, &adc_params);
-                adc_state = ADC_STATE_DONE;
-                printf("[ADC] Battery Current in slot %d is %d mA.\n", slot, batteries[slot].current);
-                //printf("current: Memory address of batteries: %p\n", &batteries[0]);
-            } else if (channel == 2) {
-
-                int16_t raw_adc_voltage = adc_hal.read_raw(slot, &adc_params);
-                batteries[slot].voltage =
-                    adc_hal.convert_voltage(raw_adc_voltage, &adc_params); 
-                adc_state = ADC_STATE_DONE;
-                printf("[ADC] Ch3 Voltage in slot %d is %d mV.\n", slot, batteries[slot].voltage);
-                //printf("voltage: Memory address of batteries: %p\n", &batteries[0].voltage);
-
-            }
+            adc_voltage = adc_hal.read_voltage(slot, &adc_params);
+            adc_state = ADC_STATE_DONE;
             break;
         default:
             channel = 0;
@@ -70,4 +70,5 @@ void updateADCReading_multichannel(uint8_t slot, uint8_t channel) {
   }
 
   adc_state = ADC_STATE_CONFIGURE;
+  return adc_voltage;
 }

+ 1 - 3
src/peripherals/adc/adc.h

@@ -12,8 +12,6 @@ typedef enum{
     ADC_STATE_DONE
 }ADC_MeasurementState;
 
-
-
-void updateADCReading_multichannel(uint8_t slot, uint8_t channel); //belongs to battery module
+uint16_t read_adc_channel(uint8_t slot, uint8_t channel); //belongs to battery module
 
 #endif

+ 132 - 137
src/peripherals/adc/adc_hal.c

@@ -49,10 +49,12 @@ D15.
 */
 
 
-#include "src/interfaces/i2c_controller_interface.h"
+#include "src/interfaces/i2c_controller.h"
 #include "src/peripherals/adc/adc_interface.h"
 #include "ti_msp_dl_config.h"
 #include <stdio.h>
+#include "src/battery_data/battery.h"
+#include "src/config.h"
 
 /*
 * Creating Configuartion Register as mentioned in the datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/22226a.pdf
@@ -61,72 +63,95 @@ D15.
 */
 static uint8_t construct_config_byte(ADC_Params *params) {
 
-  uint8_t config = 0;
-  
-  config |= ((params->channel) << 5); // Channel Selection (Bits 6-5)
-  
-
-  config |= (1 << 4); // Continous mode
-  //config |= (1 << 7); // One-Shot Mode: enable measurement (set read/not ready byte)
-  
-  
-  switch (params->resolution) {
+    uint8_t config = 0;
+    
+    config |= ((params->channel) << 5); // Channel Selection (Bits 6-5)
+    
+    if (params->continuous == 1) {
+        config |= (1 << 4); // Continous mode
+    } else {
+        // One-Shot mode
+        // Bit set to zero, BUT the Ready bit needs to be set to start meausrement
+        // (read/not write bit)
+        config |= (1 << 7);
+    }
     
-    case 12:
-        config |= (0b00 << 2);
-        break;
-    case 14:
-        config |= (0b01 << 2);
-        break;
-    case 16:
-        config |= (0b10 << 2);
-        break;
-    default:
-        //printf("ERROR: Invalid Resolution!\n");
-        return 0;
-  }
-   
-  switch (params->gain) {
+    switch (params->resolution) {
+        
+        case 12:
+            config |= (0b00 << 2);
+            break;
+        case 14:
+            config |= (0b01 << 2);
+            break;
+        case 16:
+            config |= (0b10 << 2);
+            break;
+        default:
+            //printf("ERROR: Invalid Resolution!\n");
+            return 0;
+    }
     
-    case 1:
-        config |= (0b00);
-        break;
-    case 2:
-        config |= (0b01);
-        break;
-    case 4:
-        config |= (0b10);
-        break;
-    default:
-        //printf("ERROR: Invalid Gain!\n");
-        return 0;
-  }
-
-  return config;
+    switch (params->gain) {
+        
+        case 1:
+            config |= (0b00);
+            break;
+        case 2:
+            config |= (0b01);
+            break;
+        case 4:
+            config |= (0b10);
+            break;
+        case 8:
+            config |= (0b11);
+            break;
+        default:
+            //printf("ERROR: Invalid Gain!\n");
+            return 0;
+    }
+
+    return config;
 }
 
 /* Tansmit Data from MCU to ADC:  Function to SET configuration to ADC over
  * I2C*/
 
 static bool adc_configure(uint8_t slot_id, ADC_Params *params) {
-  controllerTxPackage.packet[0] = construct_config_byte(params);
-  printf("Config Byte: 0x%02X\n", controllerTxPackage.packet[0]);
-  // Wait for I2C Bus to be Free**
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-  if(controllerTxPackage.packet[0] == 0xFF){
-    printf("[ADC] Unable to send config bytes\n");
-    return false;
-  } 
-  // Prepare TX Buffer
-  controllerTxPackage.len = 1;
-  controllerTxPackage.count = 0;
-  controllerTxPackage.complete = false;
-  i2c_hal.write(ADC_TARGET_BASE_ADDRESS);
-  
-  while(!controllerTxPackage.complete);
-  return true;
+    controllerTxPackage.packet[0] = construct_config_byte(params);
+
+    // Wait for I2C Bus to be Free**
+    uint32_t n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready on config byte\n");
+    }
+    if(controllerTxPackage.packet[0] == 0xFF){
+        // this clause can only happen if the internal memory management is messed up?!
+        // the config function should take care that this is never the case
+#ifdef DEBUG_ADC
+        printf("[ADC] Unable to send config bytes\n");
+#endif
+        *battery_slots[slot_id].state = SLOT_ERR_CONFIGBYTE;
+        return false;
+    } 
+    // Prepare TX Buffer
+    controllerTxPackage.len = 1;
+    controllerTxPackage.count = 0;
+    controllerTxPackage.complete = false;
+    i2c_hal.write(battery_slots[slot_id].adc_addr);
+    
+    n_cycles = 0;
+    while(!controllerTxPackage.complete && n_cycles++ < MAX_I2C_WAIT_RX);
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+#ifdef DEBUG_ADC
+        printf("[ADC] No Response to the config byte!\n");
+#endif
+        return false;
+    }
+    return true;
 }
 
 
@@ -142,93 +167,63 @@ Conversion mode, writing this bit to “1” initiates a new conversion.
 */
 
 static bool adc_is_ready(uint8_t slot_id, ADC_Params *params) {
-  uint8_t adc_address = ADC_TARGET_BASE_ADDRESS + slot_id;
-  controllerRxPackage.len = 3;
-  controllerRxPackage.count = 0;
-  controllerRxPackage.complete = false;
-
-  i2c_hal.read(adc_address);
-  //i2c_hal.read(ADC_TARGET_BASE_ADDRESS + slot_id, 3);
-  // Ready bit is bit 7
-  while(!controllerRxPackage.complete);
-  uint8_t config_adc_byte = controllerRxPackage.packet[2];
-  bool ready = (config_adc_byte & 0x80) == 1;
-  printf("Bytes: 0x%02X 0x%02X 0x%02X (%d %d %d)\n", controllerRxPackage.packet[0], controllerRxPackage.packet[1],  controllerRxPackage.packet[2], controllerRxPackage.packet[0], controllerRxPackage.packet[1],  controllerRxPackage.packet[2]);
-  printf("ADC Ready:: gRxADClen: %d, gRxADCcount: %d ready? %d\n", controllerRxPackage.len, controllerRxPackage.count, ready);
-  return ready;
+    uint8_t adc_address = battery_slots[slot_id].adc_addr;
+    controllerRxPackage.len = 3;
+    controllerRxPackage.count = 0;
+    controllerRxPackage.complete = false;
+
+    i2c_hal.read(adc_address);
+    // Ready bit is bit 7
+    while(!controllerRxPackage.complete);
+    uint8_t config_adc_byte = controllerRxPackage.packet[2];
+    bool ready = (config_adc_byte & 0x80) == 1;
+    return ready;
 }
 
 
 static int16_t read_adc_raw_data(uint8_t slot_id, ADC_Params *params) {
 
-  // Buffer for ADC data (MSB, LSB, Config Byte)
-  int16_t raw_adc = 0;
-
-  controllerRxPackage.len = 3;
-  controllerRxPackage.count = 0;
-  controllerRxPackage.complete = false;
-  
-  i2c_hal.read(ADC_TARGET_BASE_ADDRESS + slot_id);
-  while(!controllerRxPackage.complete);
-  printf("ADC Read:: gRxADClen: %d, gRxADCcount: %d\n", controllerRxPackage.len, controllerRxPackage.count);
-  printf("Bytes: 0x%02X 0x%02X 0x%02X (%d %d %d)\n", controllerRxPackage.packet[0], controllerRxPackage.packet[1],  controllerRxPackage.packet[2], controllerRxPackage.packet[0], controllerRxPackage.packet[1],  controllerRxPackage.packet[2]);
-  uint8_t msb = controllerRxPackage.packet[0];
-  uint8_t lsb = controllerRxPackage.packet[1];
-  uint8_t config_adc_byte = controllerRxPackage.packet[2];
-
-  if (params->resolution == 12) {
-    raw_adc = ((msb & 0b00001111) << 8) | lsb;
-    if (raw_adc > 2047)
-      raw_adc -= 4096;
-  }
-  printf("MSB: 0x%02X (%d)\n", msb, msb);
-  printf("LSB: 0x%02X (%d)\n", lsb, lsb);
-  printf("Config Byte response: 0x%02X \n", config_adc_byte);
-  return raw_adc;
-}
+    // Buffer for ADC data (MSB, LSB, Config Byte)
+    uint32_t raw_adc = 0;
 
-/* Function to Convert ADC Reading to Voltage */
-static uint16_t adc_voltage(int16_t adc_value, ADC_Params *params) {
-  uint16_t measured_voltage = 0;
-  uint16_t LSB = 0;
-  uint32_t max_adc_value = 1;
-
-  switch (params->resolution) {
-  case 12: // 12-bit
-    max_adc_value = 4095;
-    break;
-  case 14: // 14-bit
-    max_adc_value = 16383;
-    break;
-  case 16: // 16-bit
-    max_adc_value = 65535;
-    break;
-  default:
-    //printf("Error: Unknown ADC Resolution!\n");
-    return 0;
-  }
-  measured_voltage = (((uint32_t)adc_value) * 2.7);
-  //printf("Measured ADC voltage: %d\n", measured_voltage);
-  return (uint16_t)measured_voltage;
-}
-
-/* Function to Convert ADC Reading to Voltage */
-uint16_t adc_current(int16_t adc_value, ADC_Params *params) {
-  int16_t current_mA = 0;
-  // Convert ADC value to voltage across shunt resistor:
-  uint16_t voltage_mV = adc_voltage(adc_value, params);
-  uint8_t gain_multiplier = (1 << (params->gain - 1));
-  // Convert voltage drop across shunt resistor to current
-  current_mA = (adc_value) * (10 * gain_multiplier);
-  //printf("[ADC] Battery current is %u mA.\n", current_mA);
-  return (int16_t)current_mA;
+    controllerRxPackage.len = 3;
+    controllerRxPackage.count = 0;
+    controllerRxPackage.complete = false;
+    
+    i2c_hal.read(battery_slots[slot_id].adc_addr);
+    uint32_t n_cycles = 0;
+    while(!controllerRxPackage.complete && n_cycles++ < MAX_I2C_WAIT_RX);
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        return 0xffff;
+    }
+    uint8_t msb = controllerRxPackage.packet[0];
+    uint8_t lsb = controllerRxPackage.packet[1];
+    uint8_t config_adc_byte = controllerRxPackage.packet[2];
+
+    uint32_t max_adc_val = 0;
+
+    switch (params->resolution) {
+        case 12: // 12-bit
+            raw_adc = ((msb & 0b00001111) << 8) | lsb;
+            max_adc_val = 4096;
+            break;
+        case 14: // 14-bit
+            raw_adc = ((msb & 0b00111111) << 8) | lsb;
+            max_adc_val = 16384;
+            break;
+        case 16: // 16-bit
+            raw_adc = ((msb & 0b11111111) << 8) | lsb;
+            max_adc_val = 65536;
+            break;
+        default:
+            //printf("Error: Unknown ADC Resolution!\n");
+            break;
+    }
+    return raw_adc * params->factor * 2048 / (max_adc_val/2) / params->gain;
 }
 
-
 ADC_Interface adc_hal= {
     .configure= adc_configure,
-    .read_raw= read_adc_raw_data,
+    .read_voltage = read_adc_raw_data,
     .is_ready= adc_is_ready,
-    .convert_voltage= adc_voltage,
-    .convert_current= adc_current
 };

+ 3 - 6
src/peripherals/adc/adc_interface.h

@@ -4,24 +4,21 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-#define ADC_TARGET_BASE_ADDRESS (0x68)
 #define ADC_VREF_MV (2048)
 
 typedef struct {
     uint8_t channel;
     uint8_t resolution;
-    //bool continuous;
+    bool continuous;
     uint8_t gain;
+    uint16_t factor;
 } ADC_Params;
 
 // 14.04: added pointer for ADC_Params
 typedef struct {
     bool (*configure)(uint8_t slot_id, ADC_Params *params);
+    int16_t (*read_voltage)(uint8_t slot_id, ADC_Params *params);
     bool (*is_ready)(uint8_t slot_id, ADC_Params *params);
-    int16_t (*read_raw)(uint8_t slot_id, ADC_Params *params);
-    uint16_t (*convert_voltage)(int16_t raw, ADC_Params *params);
-    uint16_t (*convert_current)(int16_t raw, ADC_Params *params);
-    
 } ADC_Interface;
 
 extern ADC_Interface adc_hal;

+ 22 - 47
src/peripherals/dac/dac.c

@@ -1,58 +1,33 @@
 #include "dac.h"
-#include "src/interfaces/i2c_controller_interface.h"
+#include "src/interfaces/i2c_controller.h"
 #include "ti/driverlib/dl_i2c.h"
 #include "ti_msp_dl_config.h"
+#include "src/battery_data/battery.h"
 #include <stdint.h>
 #include <stdio.h>
-
-
-// The device updates all DAC analog output(vout) at the same time
-
-void DAC_UpdateOutput() {
-  uint8_t general_call_command = 0x08; // General Call Update Command
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-
-  // Start I2C transaction
-  DL_I2C_startControllerTransfer(I2C_controller_INST, 0x00,
-                                 DL_I2C_CONTROLLER_DIRECTION_TX, 1);
-
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-
-  DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &general_call_command, 1);
-
-  //printf("DAC Outputs Updated via General Call Software Update!\n");
-}
-
+#include "src/config.h"
 
 bool DAC_SingleWrite(uint8_t slot, uint16_t channel_value) {
-  if(channel_value > 4095){
-    printf("DAC Error: channel_value out of range. Must be between 0 and 4095\n");
-    return false;
-  }
-  controllerTxPackage.len = 3;
-  controllerTxPackage.packet[0] = 0x58; //0x58 for Channel 0; 0x5A for Channel 1
-  controllerTxPackage.packet[1] = (0x10) | ((channel_value >> 8) & 0x0F);
-  controllerTxPackage.packet[2] = (channel_value & 0xFF);
-
-
-  // Log data being sent
-  printf("Sending to DAC: 0x%02X 0x%02X 0x%02X\n",
-           controllerTxPackage.packet[0],
-           controllerTxPackage.packet[1],
-           controllerTxPackage.packet[2]);
-
-  // Write data to DAC
-  if (!i2c_hal.write(DAC_TARGET_ADDRESS)) {
+    if(channel_value > MAX_DAC_VALUE) {
+#ifdef DEBUG_DAC
+        printf("DAC Error: channel_value out of range. Must be between 0 and %d\n", MAX_DAC_VALUE);
+#endif
+        *battery_slots[slot].state = SLOT_WARN_DAC_INVALID_VALUE;
+        return false;
+    }
+    controllerTxPackage.len = 3;
+    controllerTxPackage.packet[0] = (0b01000000 | slot << 1);
+    controllerTxPackage.packet[1] = (0x10) | ((channel_value >> 8) & 0x0F);
+    controllerTxPackage.packet[2] = (channel_value & 0xFF);
+
+    // Write data to DAC
+    if (!i2c_hal.write(DAC_TARGET_ADDRESS)) {
+#ifdef DEBUG_DAC
         printf("I2C DAC Write Error: Failed to write to DAC.\n");
+#endif
+        *battery_slots[slot].state = SLOT_ERR_DAC_WRITE_FAILED;
         return false;
     }
 
-  DAC_UpdateOutput();
-
-  return true;
-
-}
+    return true;
+}

+ 3 - 1
src/peripherals/dac/dac.h

@@ -1,10 +1,12 @@
 #ifndef DAC_H_
+#define DAC_H_
 #include "ti/driverlib/dl_i2c.h"
 #include "ti_msp_dl_config.h"
 #include <stdbool.h>
+#include "src/config.h"
 
-#define DAC_TARGET_ADDRESS (0x60)
 #define DAC_VREF_MV 2048
+#define MAX_DAC_VALUE 4095
 
 bool DAC_SingleWrite(uint8_t slot, uint16_t channel_value);
 

+ 40 - 0
src/peripherals/temp/tmp1075.c

@@ -0,0 +1,40 @@
+
+#include "src/peripherals/temp/tmp1075.h"
+
+#include "src/interfaces/i2c_controller.h"
+
+#include <stdio.h>
+
+/**
+ * Read Temperature
+ * of a former initalized TMP1075 sensor
+ */
+
+volatile uint8_t addr_offset = 0;
+
+uint16_t read_temperature(uint8_t slot) {
+
+    // Prepare TX Buffer
+    controllerTxPackage.len = 1;
+    controllerTxPackage.count = 0;
+    controllerTxPackage.complete = false;
+    controllerTxPackage.packet[0] = 0x00;
+    i2c_hal.write(TMP1075_BASE_ADDRESS + slot + addr_offset);
+
+    controllerRxPackage.len = 3;
+    controllerRxPackage.count = 0;
+    controllerRxPackage.complete = false;
+    i2c_hal.read(TMP1075_BASE_ADDRESS + slot + addr_offset);
+
+    while(!controllerRxPackage.complete);
+    uint16_t byte1 = controllerRxPackage.packet[0];
+    uint8_t byte2 = controllerRxPackage.packet[1];
+    
+    uint16_t temp = ((byte1 << 4) | (byte2 >> 4)) * 62.5;
+
+#ifdef DEBUG_TEMPERATURE
+    printf("Temperatur von slot %d: 0x%02X 0x%02X -> %d \n", slot, byte1, byte2, temp);
+#endif
+
+    return temp;
+}

+ 12 - 0
src/peripherals/temp/tmp1075.h

@@ -0,0 +1,12 @@
+#ifndef TMP1075_H_
+#define TMP1075_H_
+
+#include <stdint.h>
+
+#define TMP1075_BASE_ADDRESS 0x48
+
+uint16_t read_temperature(uint8_t slot);
+
+extern volatile uint8_t addr_offset;
+
+#endif

+ 59 - 0
test-mcu.py

@@ -0,0 +1,59 @@
+from smbus2 import SMBus, i2c_msg
+import struct
+import time
+
+# Beispiel: I2C-Adresse des Geräts
+DEVICE_ADDRESS = 0x48  # z.B. EEPROM oder Sensoradresse
+I2C_BUS = 1            # I2C-1 ist meist Standard beim Raspberry Pi
+
+slot = input("Slot id (default: 0): ")
+if slot == "": slot = 0
+else: slot = int(slot)
+
+def read_status(bus):
+    data_to_write = [(0x06 | slot << 4)]
+
+    write = i2c_msg.write(DEVICE_ADDRESS, data_to_write)
+    bus.i2c_rdwr(write)
+
+    # Lesen von 3 Bytes roher Binärdaten
+    read = i2c_msg.read(DEVICE_ADDRESS, 8)
+    bus.i2c_rdwr(read)
+    data_read = bytes(read)
+    print("data:", data_read.hex())
+
+    data = struct.unpack("<HhHH", data_read)
+
+    # data[0] is voltage in mV
+    print(f"Spannung: {data[0]/1000:.2f}V, Strom: {data[1]}mA, Temperatur: {data[2]}°C, Error: 0x{data[3]:02X}")
+
+with SMBus(I2C_BUS) as bus:
+    # Schreiben von Rohdaten
+
+    while True:
+        
+        print("Mögliche Aktionen:")
+        print("  r <n>     n Zyklen lesen")
+        print("  w <i>     i mA Strom positiv: laden (DAC), negativ entladen: (PWM)")
+        act = input("nächste Aktion: ")
+        if act[0] == "r":
+            n = int(act.split(" ")[1])
+            for i in range(n):
+                time.sleep(1)
+                try:
+                    read_status(bus)
+                except:
+                    print("Bus error.")
+        elif act[0] == "w":
+            i = int(act.split(" ")[1])
+            # 5 is the command for setting the current
+            byte_str = struct.pack("<Bh", (5 + (slot << 4)), int(i))
+            print("Sending bytes", byte_str.hex())
+
+            write = i2c_msg.write(DEVICE_ADDRESS, list(byte_str))
+            bus.i2c_rdwr(write)
+
+
+        else:
+            "Ungültiges Kommando."
+        

Vissa filer visades inte eftersom för många filer har ändrats