42 Commits 533a2cd5ae ... 0771f3f0d1

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

+ 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"
+    }
+}

Diff do ficheiro suprimidas por serem muito extensas
+ 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."
+        

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff