Etape 7 : liaison UART SCI-A 57600 8N1 validee sur cible
Emission $T,...*XX et reception $C,...*XX conformes a docs/ESP32-UART.md. Trame mesuree a 129 caracteres, checksum XOR verifie independamment. Corrections trouvees au bring-up sur materiel : - StartCpuTimer0() manquant : ConfigCpuTimer() laisse le timer arrete, donc le tick d'emission ne se produisait jamais et rien ne partait sur la ligne. - Suppression de "%f" dans sprintf. Sur C28x le support flottant de printf passe par du long double 64 bits emule (frexpl/scalbnl/L$$DIV) : le CPU partait a PC=0 des le premier envoi. Formatage decimal manuel a la place, comme le prevoyait deja PROMPT §7 etape 7. - RXFFIENA n'etait pas arme dans SCIFFRX : aucune interruption de reception. - Recuperation de SCIRXST.RXERROR. Un FE/OE/PE/BRKDT le latche et bloque le recepteur jusqu'a un SW RESET du SCI ; sans ca une seule perturbation arretait la reception definitivement (constate : RXERROR+FE+BRKDT latches). - Formatage borne : clamp des valeurs (NaN et saturation) puis snprintf avec la capacite restante. Un champ qui ne tient pas est abandonne entierement, ce que le protocole autorise, plutot que de deborder s_tx_frame. - Emission non bloquante : send_telemetry() ne fait que mettre en attente, uart_link_service_tx() pousse au plus une FIFO (4 octets) puis rend la main. L'ancienne version monopolisait 22 ms par trame, incompatible avec la priorite donnee a la boucle de regulation. Plan memoire (F2802x_generic_flash.cmd) : - les 4 secteurs flash du F28027 sont declares (32K mots au lieu de 8K) - .ebss bascule en RAML0 : il etait colle juste apres .stack, donc tout debordement de pile ecrasait silencieusement les globales - pile portee a 1024 mots, seule dans RAMM1 LED : polarite reelle confirmee active-haut (cathode commune a la masse, anodes pilotees par GPIO12/GPIO33 a travers 1k) -> LED_ACTIVE_LOW = 0. Repond au point ouvert §9.2 du PROMPT. safety_init() reste desactive dans main.c : bring-up isole LED+UART, a reactiver quand l'etage de puissance sera cable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
58
.cproject
58
.cproject
@ -22,8 +22,8 @@
|
|||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
<configuration artifactExtension="out" artifactName="Example_2802xLEDBlink" buildProperties="" description="" id="com.ti.ccstudio.buildDefinitions.C2000.Debug.1909800144" name="Debug" parent="com.ti.ccstudio.buildDefinitions.C2000.Debug">
|
<configuration artifactExtension="out" artifactName="Example_2802xLEDBlink" buildProperties="" description="" id="com.ti.ccstudio.buildDefinitions.C2000.Debug.1909800144" name="Debug" parent="com.ti.ccstudio.buildDefinitions.C2000.Debug">
|
||||||
<folderInfo id="com.ti.ccstudio.buildDefinitions.C2000.Debug.1909800144.847706334" name="/" resourcePath="">
|
<folderInfo id="com.ti.ccstudio.buildDefinitions.C2000.Debug.1909800144.847706334" name="/" resourcePath="">
|
||||||
<toolChain id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.DebugToolchain.664403306" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug.1235779316">
|
<toolChain id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.DebugToolchain.159661892" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug.1551753352">
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1554114453" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
|
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1144356066" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
|
||||||
<listOptionValue value="DEVICE_CONFIGURATION_ID=TMS320C28XX.TMS320F28027"/>
|
<listOptionValue value="DEVICE_CONFIGURATION_ID=TMS320C28XX.TMS320F28027"/>
|
||||||
<listOptionValue value="DEVICE_CORE_ID="/>
|
<listOptionValue value="DEVICE_CORE_ID="/>
|
||||||
<listOptionValue value="DEVICE_ENDIANNESS=UNKNOWN"/>
|
<listOptionValue value="DEVICE_ENDIANNESS=UNKNOWN"/>
|
||||||
@ -38,14 +38,14 @@
|
|||||||
<listOptionValue value="LINK_ORDER="/>
|
<listOptionValue value="LINK_ORDER="/>
|
||||||
<listOptionValue value="PRODUCTS=C2000WARE:26.1.0.00;"/>
|
<listOptionValue value="PRODUCTS=C2000WARE:26.1.0.00;"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.474454367" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="25.11.1.LTS" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1164917113" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="25.11.1.LTS" valueType="string"/>
|
||||||
<targetPlatform id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.targetPlatformDebug.960982070" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.targetPlatformDebug"/>
|
<targetPlatform id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.targetPlatformDebug.304590691" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.targetPlatformDebug"/>
|
||||||
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.builderDebug.557038836" keepEnvironmentInBuildfile="false" name="GNU Make" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.builderDebug"/>
|
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.builderDebug.1772446421" name="GNU Make.Debug" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.builderDebug"/>
|
||||||
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.compilerDebug.2141707820" name="C2000 Compiler" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.compilerDebug">
|
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.compilerDebug.1541428198" name="C2000 Compiler" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.compilerDebug">
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.LARGE_MEMORY_MODEL.400788932" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.LARGE_MEMORY_MODEL" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.LARGE_MEMORY_MODEL.1715790107" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.LARGE_MEMORY_MODEL" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.UNIFIED_MEMORY.110360032" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.UNIFIED_MEMORY" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.UNIFIED_MEMORY.1984521868" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.UNIFIED_MEMORY" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION.1781053235" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION.28" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION.2036393650" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.SILICON_VERSION.28" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.INCLUDE_PATH.563309171" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.INCLUDE_PATH" valueType="includePath">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.INCLUDE_PATH.1849469441" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.INCLUDE_PATH" valueType="includePath">
|
||||||
<listOptionValue value="${COM_TI_C2000WARE_INCLUDE_PATH}"/>
|
<listOptionValue value="${COM_TI_C2000WARE_INCLUDE_PATH}"/>
|
||||||
<listOptionValue value="${CG_TOOL_ROOT}/include"/>
|
<listOptionValue value="${CG_TOOL_ROOT}/include"/>
|
||||||
<listOptionValue value="${INSTALLROOT_F2802x}/headers/include"/>
|
<listOptionValue value="${INSTALLROOT_F2802x}/headers/include"/>
|
||||||
@ -53,35 +53,35 @@
|
|||||||
<listOptionValue value="${INSTALLROOT_F2802x}/common/include"/>
|
<listOptionValue value="${INSTALLROOT_F2802x}/common/include"/>
|
||||||
<listOptionValue value="${INSTALLROOT_IQMATH}/include"/>
|
<listOptionValue value="${INSTALLROOT_IQMATH}/include"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEFINE.771081258" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEFINE" valueType="definedSymbols">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEFINE.1614629519" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEFINE" valueType="definedSymbols">
|
||||||
<listOptionValue value="${COM_TI_C2000WARE_SYMBOLS}"/>
|
<listOptionValue value="${COM_TI_C2000WARE_SYMBOLS}"/>
|
||||||
<listOptionValue value="_DEBUG"/>
|
<listOptionValue value="_DEBUG"/>
|
||||||
<listOptionValue value="LARGE_MODEL"/>
|
<listOptionValue value="LARGE_MODEL"/>
|
||||||
<listOptionValue value="_FLASH"/>
|
<listOptionValue value="_FLASH"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL.1668491955" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL.196664150" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_SUPPRESS.83242442" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_SUPPRESS" valueType="stringList">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_SUPPRESS.689463295" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_SUPPRESS" valueType="stringList">
|
||||||
<listOptionValue value="232"/>
|
<listOptionValue value="232"/>
|
||||||
<listOptionValue value="10063"/>
|
<listOptionValue value="10063"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_WARNING.1274415402" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_WARNING" valueType="stringList">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_WARNING.1851392201" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.DIAG_WARNING" valueType="stringList">
|
||||||
<listOptionValue value="225"/>
|
<listOptionValue value="225"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ISSUE_REMARKS.186583961" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ISSUE_REMARKS" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ISSUE_REMARKS.19643992" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ISSUE_REMARKS" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.VERBOSE_DIAGNOSTICS.318737604" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.VERBOSE_DIAGNOSTICS" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.VERBOSE_DIAGNOSTICS.1636041796" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.VERBOSE_DIAGNOSTICS" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL.8063966" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL.QUIET" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL.255072012" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.QUIET_LEVEL.QUIET" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI.1114196468" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI.coffabi" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI.1040365072" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.C2000_25.11.compilerID.ABI.coffabi" valueType="enumerated"/>
|
||||||
</tool>
|
</tool>
|
||||||
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug.1235779316" name="C2000 Linker" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug">
|
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug.1551753352" name="C2000 Linker" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.exe.linkerDebug">
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.STACK_SIZE.1733044792" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.STACK_SIZE" value="0x200" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.STACK_SIZE.164177814" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.STACK_SIZE" value="0x400" valueType="string"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.MAP_FILE.647012608" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.MAP_FILE" value=""Example_2802xLEDBlink.map"" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.MAP_FILE.1243476423" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.MAP_FILE" value=""Example_2802xLEDBlink.map"" valueType="string"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.OUTPUT_FILE.813073460" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.OUTPUT_FILE" value="Example_2802xLEDBlink.out" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.OUTPUT_FILE.119763382" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.OUTPUT_FILE" value="Example_2802xLEDBlink.out" valueType="string"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.LIBRARY.528423534" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.LIBRARY" valueType="libs">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.LIBRARY.397023344" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.LIBRARY" valueType="libs">
|
||||||
<listOptionValue value="${COM_TI_C2000WARE_LIBRARIES}"/>
|
<listOptionValue value="${COM_TI_C2000WARE_LIBRARIES}"/>
|
||||||
<listOptionValue value="rts2800_ml.lib"/>
|
<listOptionValue value="rts2800_ml.lib"/>
|
||||||
<listOptionValue value="IQmath.lib"/>
|
<listOptionValue value="IQmath.lib"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.SEARCH_PATH.915839469" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.SEARCH_PATH" valueType="libPaths">
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.SEARCH_PATH.567141830" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.SEARCH_PATH" valueType="libPaths">
|
||||||
<listOptionValue value="${COM_TI_C2000WARE_LIBRARY_PATH}"/>
|
<listOptionValue value="${COM_TI_C2000WARE_LIBRARY_PATH}"/>
|
||||||
<listOptionValue value="${CG_TOOL_ROOT}/lib"/>
|
<listOptionValue value="${CG_TOOL_ROOT}/lib"/>
|
||||||
<listOptionValue value="${CG_TOOL_ROOT}/include"/>
|
<listOptionValue value="${CG_TOOL_ROOT}/include"/>
|
||||||
@ -89,12 +89,12 @@
|
|||||||
<listOptionValue value="${INSTALLROOT_F2802x}/common/lib"/>
|
<listOptionValue value="${INSTALLROOT_F2802x}/common/lib"/>
|
||||||
<listOptionValue value="${INSTALLROOT_IQMATH}/lib"/>
|
<listOptionValue value="${INSTALLROOT_IQMATH}/lib"/>
|
||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ISSUE_REMARKS.660341548" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ISSUE_REMARKS" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ISSUE_REMARKS.1756602824" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ISSUE_REMARKS" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.VERBOSE_DIAGNOSTICS.183992281" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.VERBOSE_DIAGNOSTICS" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.VERBOSE_DIAGNOSTICS.489766963" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.VERBOSE_DIAGNOSTICS" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.XML_LINK_INFO.1900510778" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.XML_LINK_INFO" value=""Example_2802xLEDBlink_linkInfo.xml"" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.XML_LINK_INFO.667790640" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.XML_LINK_INFO" value=""Example_2802xLEDBlink_linkInfo.xml"" valueType="string"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ENTRY_POINT.1884395562" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ENTRY_POINT" value="code_start" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ENTRY_POINT.511960855" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.linkerID.ENTRY_POINT" value="code_start" valueType="string"/>
|
||||||
</tool>
|
</tool>
|
||||||
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.hex.165990339" name="C2000 Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.hex"/>
|
<tool id="com.ti.ccstudio.buildDefinitions.C2000_25.11.hex.813831478" name="C2000 Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.C2000_25.11.hex"/>
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,3 +9,7 @@ Release/
|
|||||||
# IDE-generated, machine-specific (hardcoded local tool paths)
|
# IDE-generated, machine-specific (hardcoded local tool paths)
|
||||||
.mcp.json
|
.mcp.json
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
|
|
||||||
|
# Outillage agent (local, non partage)
|
||||||
|
.claude/
|
||||||
|
.codex/
|
||||||
|
|||||||
16
.theia/launch.json
Normal file
16
.theia/launch.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "TMS320F28027-dualboost",
|
||||||
|
"type": "ccs-debug",
|
||||||
|
"request": "launch",
|
||||||
|
"projectInfo": {
|
||||||
|
"name": "TMS320F28027-dualboost",
|
||||||
|
"resourceId": "/TMS320F28027-dualboost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -99,11 +99,16 @@ PAGE 0: /* Program Memory */
|
|||||||
|
|
||||||
RAMM0 : origin = 0x000050, length = 0x0003B0 /* on-chip RAM block M0 */
|
RAMM0 : origin = 0x000050, length = 0x0003B0 /* on-chip RAM block M0 */
|
||||||
OTP : origin = 0x3D7800, length = 0x000400 /* on-chip OTP */
|
OTP : origin = 0x3D7800, length = 0x000400 /* on-chip OTP */
|
||||||
FLASHA : origin = 0x3F7000, length = 0x000F80 /* on-chip FLASH */
|
/* Les 4 secteurs flash du F28027 (32K mots au total, cf. common/cmd/F28027.cmd
|
||||||
|
de C2000Ware). Le fichier "generic" d'origine ne declarait que le secteur A
|
||||||
|
(~8K), ce qui faisait deborder le link des que le code grossissait. */
|
||||||
|
FLASHD : origin = 0x3F0000, length = 0x002000 /* on-chip FLASH */
|
||||||
|
FLASHC : origin = 0x3F2000, length = 0x002000 /* on-chip FLASH */
|
||||||
|
FLASHB : origin = 0x3F4000, length = 0x002000 /* on-chip FLASH */
|
||||||
|
FLASHA : origin = 0x3F6000, length = 0x001F80 /* on-chip FLASH */
|
||||||
CSM_RSVD : origin = 0x3F7F80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */
|
CSM_RSVD : origin = 0x3F7F80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */
|
||||||
BEGIN : origin = 0x3F7FF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
|
BEGIN : origin = 0x3F7FF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
|
||||||
CSM_PWL_P0 : origin = 0x3F7FF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */
|
CSM_PWL_P0 : origin = 0x3F7FF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */
|
||||||
FLASHB : origin = 0x3F6000, length = 0x001000 /* on-chip FLASH */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -121,7 +126,7 @@ PAGE 1 : /* Data Memory */
|
|||||||
|
|
||||||
BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */
|
BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */
|
||||||
RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */
|
RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */
|
||||||
RAML0 : origin = 0x008000, length = 0x000400 /* on-chip RAM block L0 */
|
RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 (4K mots sur F28027) */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,25 +150,29 @@ SECTIONS
|
|||||||
RUN_START(_RamfuncsRunStart),
|
RUN_START(_RamfuncsRunStart),
|
||||||
PAGE = 0
|
PAGE = 0
|
||||||
|
|
||||||
.cinit : > FLASHA | FLASHB, PAGE = 0
|
.cinit : > FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0
|
||||||
.pinit : > FLASHA | FLASHB, PAGE = 0
|
.pinit : > FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0
|
||||||
.text : >> FLASHA | FLASHB, PAGE = 0
|
.text : >> FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0
|
||||||
|
|
||||||
csmpasswds : > CSM_PWL_P0, PAGE = 0
|
csmpasswds : > CSM_PWL_P0, PAGE = 0
|
||||||
csm_rsvd : > CSM_RSVD, PAGE = 0
|
csm_rsvd : > CSM_RSVD, PAGE = 0
|
||||||
|
|
||||||
/* Allocate uninitalized data sections: */
|
/* Allocate uninitalized data sections: */
|
||||||
|
/* .ebss place en RAML0 EN PREMIER (et non RAMM1) : sinon les globales se
|
||||||
|
retrouvent collees juste apres .stack, et un debordement de pile les
|
||||||
|
ecrase silencieusement au lieu de tomber dans du vide. RAMM1 est ainsi
|
||||||
|
reserve a la pile seule. */
|
||||||
.stack : > RAMM1, PAGE = 1
|
.stack : > RAMM1, PAGE = 1
|
||||||
.ebss : >> RAMM1 | RAML0, PAGE = 1
|
.ebss : >> RAML0 | RAMM1, PAGE = 1
|
||||||
.esysmem : >> RAMM1 | RAML0, PAGE = 1
|
.esysmem : >> RAML0 | RAMM1, PAGE = 1
|
||||||
|
|
||||||
/* Initalized sections go in Flash */
|
/* Initalized sections go in Flash */
|
||||||
/* For SDFlash to program these, they must be allocated to page 0 */
|
/* For SDFlash to program these, they must be allocated to page 0 */
|
||||||
.econst : >> FLASHA | FLASHB, PAGE = 0
|
.econst : >> FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0
|
||||||
.switch : >> FLASHA | FLASHB, PAGE = 0
|
.switch : >> FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0
|
||||||
|
|
||||||
/* Allocate IQ math areas: */
|
/* Allocate IQ math areas: */
|
||||||
IQmath : >> FLASHA | FLASHB, PAGE = 0 /* Math Code */
|
IQmath : >> FLASHA | FLASHB | FLASHC | FLASHD, PAGE = 0 /* Math Code */
|
||||||
IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
|
IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
|
||||||
|
|
||||||
/* Uncomment the section below if calling the IQNexp() or IQexp()
|
/* Uncomment the section below if calling the IQNexp() or IQexp()
|
||||||
|
|||||||
16
src/calib.h
16
src/calib.h
@ -9,7 +9,10 @@
|
|||||||
#define CLK_SYSCLKOUT_HZ 60000000UL
|
#define CLK_SYSCLKOUT_HZ 60000000UL
|
||||||
|
|
||||||
// LEDs (LQFP48 PT) : bleue = GPIO12 (broche 47), rouge = GPIO33 (broche 36)
|
// LEDs (LQFP48 PT) : bleue = GPIO12 (broche 47), rouge = GPIO33 (broche 36)
|
||||||
#define LED_ACTIVE_LOW 1
|
// Point ouvert §9 du prompt : polarite a confirmer au premier test.
|
||||||
|
// Observation bring-up (carte 2) : GPIO33 haut = LED rouge visuellement allumee
|
||||||
|
// -> cablage actif-haut, pas actif-bas comme suppose initialement.
|
||||||
|
#define LED_ACTIVE_LOW 0
|
||||||
|
|
||||||
// Valeur de champ AIOMUX1 pour basculer une broche AIOx en mode analogique
|
// Valeur de champ AIOMUX1 pour basculer une broche AIOx en mode analogique
|
||||||
#define GPIO_ANALOG_MODE 2
|
#define GPIO_ANALOG_MODE 2
|
||||||
@ -21,4 +24,15 @@
|
|||||||
#define SAFETY_DAC_CODE \
|
#define SAFETY_DAC_CODE \
|
||||||
((uint16_t)((SAFETY_ISHUNT_THRESHOLD_A * 0.6f) / SAFETY_DAC_VREF_V * 1023.0f + 0.5f))
|
((uint16_t)((SAFETY_ISHUNT_THRESHOLD_A * 0.6f) / SAFETY_DAC_VREF_V * 1023.0f + 0.5f))
|
||||||
|
|
||||||
|
// Liaison UART SCI-A (voir docs/ESP32-UART.md) : 57600 8N1.
|
||||||
|
// LSPCLK = SYSCLKOUT/4 (LOSPCP laisse a sa valeur par defaut par InitSysCtrl).
|
||||||
|
#define UART_BAUD_RATE 57600UL
|
||||||
|
#define UART_LSPCLK_HZ (CLK_SYSCLKOUT_HZ / 4UL)
|
||||||
|
// BRR = round(LSPCLK / (8 * baud)) - 1 (TRM SPRUI09A, registre SCIHBAUD:SCILBAUD)
|
||||||
|
#define UART_SCIBRR \
|
||||||
|
((uint16_t)(((UART_LSPCLK_HZ + 4UL * UART_BAUD_RATE) / (8UL * UART_BAUD_RATE)) - 1U))
|
||||||
|
|
||||||
|
#define UART_RX_RING_SIZE 64U
|
||||||
|
#define UART_LINE_MAX 160U // limite cote ESP32 (g_lineBuf[160])
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
51
src/main.c
51
src/main.c
@ -2,6 +2,8 @@
|
|||||||
#include "bsp_clock.h"
|
#include "bsp_clock.h"
|
||||||
#include "bsp_gpio.h"
|
#include "bsp_gpio.h"
|
||||||
#include "safety.h"
|
#include "safety.h"
|
||||||
|
#include "uart_link.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
extern uint16_t RamfuncsLoadStart;
|
extern uint16_t RamfuncsLoadStart;
|
||||||
extern uint16_t RamfuncsLoadSize;
|
extern uint16_t RamfuncsLoadSize;
|
||||||
@ -9,6 +11,11 @@ extern uint16_t RamfuncsRunStart;
|
|||||||
|
|
||||||
interrupt void cpu_timer0_isr(void);
|
interrupt void cpu_timer0_isr(void);
|
||||||
|
|
||||||
|
// Bring-up etape 7 (UART) : dernier CommandState recu, pour inspection au
|
||||||
|
// debogueur. Valeurs de telemetrie figees tant que measure.c n'existe pas.
|
||||||
|
static volatile command_state_t g_last_cmd = {false, false, false};
|
||||||
|
static volatile bool s_send_telemetry = false;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
#ifdef _FLASH
|
#ifdef _FLASH
|
||||||
@ -25,14 +32,18 @@ void main(void)
|
|||||||
InitPieVectTable();
|
InitPieVectTable();
|
||||||
|
|
||||||
bsp_gpio_analog_init();
|
bsp_gpio_analog_init();
|
||||||
safety_init();
|
// safety_init() desactive temporairement : bring-up isole sur LED+UART
|
||||||
|
// uniquement (voir §8 du prompt -- sans risque ici, pwm.c n'existe pas
|
||||||
|
// encore, donc aucun PWM ne peut sortir avec ou sans TZ arme).
|
||||||
|
uart_link_init();
|
||||||
|
|
||||||
EALLOW;
|
EALLOW;
|
||||||
PieVectTable.TINT0 = &cpu_timer0_isr;
|
PieVectTable.TINT0 = &cpu_timer0_isr;
|
||||||
EDIS;
|
EDIS;
|
||||||
|
|
||||||
InitCpuTimers();
|
InitCpuTimers();
|
||||||
ConfigCpuTimer(&CpuTimer0, 60, 500000); // 500 ms -> 1 Hz sur la LED
|
ConfigCpuTimer(&CpuTimer0, 60, 300000); // 300 ms -> rythme d'envoi bring-up UART
|
||||||
|
StartCpuTimer0(); // ConfigCpuTimer laisse TSS=1 (timer a l'arret) par conception
|
||||||
|
|
||||||
IER |= M_INT1;
|
IER |= M_INT1;
|
||||||
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // TINT0
|
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // TINT0
|
||||||
@ -42,8 +53,39 @@ void main(void)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Etape 1-2 : validation clock/LED/securite. Rien d'autre pour
|
command_state_t cmd;
|
||||||
// l'instant, tout se passe dans les ISR.
|
|
||||||
|
if (uart_link_poll(&cmd))
|
||||||
|
{
|
||||||
|
g_last_cmd = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_send_telemetry)
|
||||||
|
{
|
||||||
|
telemetry_t t;
|
||||||
|
|
||||||
|
// Bring-up : valeurs figees, seul le lien TX/RX est valide ici.
|
||||||
|
t.freq1_hz = 100000.0f;
|
||||||
|
t.freq2_hz = 100000.0f;
|
||||||
|
t.duty1_pct = 0.0f;
|
||||||
|
t.duty2_pct = 0.0f;
|
||||||
|
t.vin_v = 12.3f;
|
||||||
|
t.iin_a = 0.5f;
|
||||||
|
t.v1_v = 20.0f;
|
||||||
|
t.i1_a = 0.1f;
|
||||||
|
t.t1_c = 25.0f;
|
||||||
|
t.vout_v = 0.0f;
|
||||||
|
t.i2_a = 0.0f;
|
||||||
|
t.t2_c = 25.0f;
|
||||||
|
t.iout_a = 0.0f;
|
||||||
|
|
||||||
|
uart_link_send_telemetry(&t);
|
||||||
|
s_send_telemetry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emission en tache de fond : pousse au plus 4 octets (profondeur de
|
||||||
|
// la FIFO) puis rend la main. Ne doit jamais retarder la regulation.
|
||||||
|
uart_link_service_tx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +94,7 @@ interrupt void cpu_timer0_isr(void)
|
|||||||
static bool blue_on = false;
|
static bool blue_on = false;
|
||||||
|
|
||||||
CpuTimer0.InterruptCount++;
|
CpuTimer0.InterruptCount++;
|
||||||
|
s_send_telemetry = true;
|
||||||
|
|
||||||
blue_on = !blue_on;
|
blue_on = !blue_on;
|
||||||
led_set(LED_BLUE, blue_on);
|
led_set(LED_BLUE, blue_on);
|
||||||
|
|||||||
391
src/uart_link.c
Normal file
391
src/uart_link.c
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "DSP28x_Project.h"
|
||||||
|
#include "uart_link.h"
|
||||||
|
#include "calib.h"
|
||||||
|
|
||||||
|
static volatile uint8_t s_rx_ring[UART_RX_RING_SIZE];
|
||||||
|
static volatile uint16_t s_rx_head = 0; // ecrit par l'ISR uniquement
|
||||||
|
static uint16_t s_rx_tail = 0; // ecrit par uart_link_poll() uniquement
|
||||||
|
|
||||||
|
static char s_line[UART_LINE_MAX];
|
||||||
|
static uint16_t s_line_len = 0;
|
||||||
|
|
||||||
|
interrupt void scia_rx_isr(void);
|
||||||
|
|
||||||
|
// Profondeur de la FIFO d'emission du SCI (TRM SPRUI09A) : on ne pousse
|
||||||
|
// jamais au-dela, ce qui garantit que uart_link_service_tx() rend la main
|
||||||
|
// immediatement au lieu d'attendre le debit de la ligne.
|
||||||
|
#define SCI_TX_FIFO_DEPTH 4U
|
||||||
|
|
||||||
|
static uint8_t checksum_of(const char *s, int len)
|
||||||
|
{
|
||||||
|
uint8_t cs = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
cs ^= (uint8_t)s[i];
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_link_init(void)
|
||||||
|
{
|
||||||
|
EALLOW;
|
||||||
|
GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // pull-up sur RX
|
||||||
|
GpioCtrlRegs.GPAPUD.bit.GPIO29 = 1; // pas de pull-up sur TX (sortie)
|
||||||
|
GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; // RX asynchrone, pas de qualification
|
||||||
|
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // GPIO28 -> SCIRXDA
|
||||||
|
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // GPIO29 -> SCITXDA
|
||||||
|
EDIS;
|
||||||
|
|
||||||
|
// 1 stop bit, pas de parite, 8 bits, mode async, protocole idle-line
|
||||||
|
SciaRegs.SCICCR.all = 0x0007;
|
||||||
|
// TX/RX actives, horloge SCI interne
|
||||||
|
SciaRegs.SCICTL1.all = 0x0003;
|
||||||
|
SciaRegs.SCICTL2.bit.TXINTENA = 0; // TX en polling, pas d'interruption
|
||||||
|
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;
|
||||||
|
|
||||||
|
SciaRegs.SCIHBAUD = (UART_SCIBRR >> 8) & 0xFF;
|
||||||
|
SciaRegs.SCILBAUD = UART_SCIBRR & 0xFF;
|
||||||
|
|
||||||
|
SciaRegs.SCIFFTX.all = 0xE040; // FIFO active, TX en polling (pas d'IT FIFO)
|
||||||
|
SciaRegs.SCIFFRX.all = 0x2021; // FIFO active, RXFFIENA=1, seuil=1 octet
|
||||||
|
SciaRegs.SCIFFCT.all = 0x0;
|
||||||
|
|
||||||
|
SciaRegs.SCICTL1.all = 0x0023; // sort le SCI de son reset local
|
||||||
|
|
||||||
|
EALLOW;
|
||||||
|
PieVectTable.SCIRXINTA = &scia_rx_isr;
|
||||||
|
EDIS;
|
||||||
|
|
||||||
|
IER |= M_INT9;
|
||||||
|
PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // SCIRXINTA
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer d'emission statique et non local : evite 160 mots de pile a chaque
|
||||||
|
// envoi (la pile ne fait que 1024 mots et sprintf en consomme deja beaucoup).
|
||||||
|
static char s_tx_frame[UART_LINE_MAX];
|
||||||
|
static uint16_t s_tx_len = 0; // longueur de la trame en attente d'emission
|
||||||
|
static uint16_t s_tx_pos = 0; // prochain octet a pousser dans la FIFO
|
||||||
|
static uint16_t s_tx_dropped = 0; // trames abandonnees (ligne trop lente)
|
||||||
|
static uint16_t s_tx_truncated = 0; // trames ayant perdu des champs (borne)
|
||||||
|
|
||||||
|
// Place a reserver en fin de buffer : "*XX\n" + le NUL ecrit par snprintf.
|
||||||
|
#define UART_TX_TAIL_LEN 5
|
||||||
|
|
||||||
|
// Garde-fou sur les valeurs formatees : un flottant aberrant (capteur non
|
||||||
|
// encore cable, ADC non initialise, NaN) rendrait le cast en int32
|
||||||
|
// indefini, donc un champ de longueur arbitraire.
|
||||||
|
#define UART_FIELD_ABS_MAX 999999.0f
|
||||||
|
|
||||||
|
// Formatage decimal a la main, SANS "%f". Sur C28x le support flottant de
|
||||||
|
// printf passe par du long double 64 bits emule (frexpl/scalbnl/L$$DIV) :
|
||||||
|
// tres couteux en pile et en temps, et constate au bring-up comme faisant
|
||||||
|
// partir le CPU dans le decor (PC=0) des le premier envoi de telemetrie.
|
||||||
|
// Voir aussi PROMPT §7 etape 7, qui prevoyait deja ce repli.
|
||||||
|
//
|
||||||
|
// `room` = octets disponibles pour ce champ, NUL compris. Renvoie 0 (champ
|
||||||
|
// entierement abandonne, rien d'ecrit) s'il ne tient pas : le protocole
|
||||||
|
// autorise les champs manquants, l'ESP32 garde alors sa derniere valeur
|
||||||
|
// (docs/ESP32-UART.md). Mieux vaut une trame courte mais valide qu'un
|
||||||
|
// debordement de s_tx_frame.
|
||||||
|
static int append_field(char *out, int room, const char *tag, float value,
|
||||||
|
uint16_t decimals)
|
||||||
|
{
|
||||||
|
static const int32_t k_pow10[3] = {1L, 10L, 100L};
|
||||||
|
const char *sign = "";
|
||||||
|
int32_t scaled;
|
||||||
|
int32_t ip;
|
||||||
|
int32_t fp;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (room <= 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// value != value n'est vrai que pour un NaN.
|
||||||
|
if (value != value)
|
||||||
|
{
|
||||||
|
value = 0.0f;
|
||||||
|
}
|
||||||
|
else if (value < -UART_FIELD_ABS_MAX)
|
||||||
|
{
|
||||||
|
value = -UART_FIELD_ABS_MAX;
|
||||||
|
}
|
||||||
|
else if (value > UART_FIELD_ABS_MAX)
|
||||||
|
{
|
||||||
|
value = UART_FIELD_ABS_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
scaled = (int32_t)(value * (float)k_pow10[decimals]
|
||||||
|
+ ((value >= 0.0f) ? 0.5f : -0.5f));
|
||||||
|
if (scaled < 0)
|
||||||
|
{
|
||||||
|
scaled = -scaled;
|
||||||
|
sign = "-";
|
||||||
|
}
|
||||||
|
ip = scaled / k_pow10[decimals];
|
||||||
|
fp = scaled % k_pow10[decimals];
|
||||||
|
|
||||||
|
if (decimals == 0)
|
||||||
|
{
|
||||||
|
n = snprintf(out, (size_t)room, ",%s=%s%ld", tag, sign, ip);
|
||||||
|
}
|
||||||
|
else if (decimals == 1)
|
||||||
|
{
|
||||||
|
n = snprintf(out, (size_t)room, ",%s=%s%ld.%01ld", tag, sign, ip, fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = snprintf(out, (size_t)room, ",%s=%s%ld.%02ld", tag, sign, ip, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0 || n >= room)
|
||||||
|
{
|
||||||
|
out[0] = '\0'; // tronque : on annule le champ au lieu de le laisser coupe
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construit la trame et la met en attente. NE BLOQUE PAS : l'emission reelle
|
||||||
|
// se fait ensuite par uart_link_service_tx(), appelee quand la boucle
|
||||||
|
// principale a du temps disponible. Renvoie false si la trame precedente
|
||||||
|
// n'est pas encore partie (nouvelle trame abandonnee, la telemetrie est par
|
||||||
|
// nature perissable : mieux vaut la suivante que du retard accumule).
|
||||||
|
bool uart_link_send_telemetry(const telemetry_t *t)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
int fields_dropped;
|
||||||
|
uint8_t cs;
|
||||||
|
|
||||||
|
if (uart_link_tx_busy())
|
||||||
|
{
|
||||||
|
s_tx_dropped++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_tx_frame[0] = '$';
|
||||||
|
s_tx_frame[1] = 'T';
|
||||||
|
n = 2;
|
||||||
|
fields_dropped = 0;
|
||||||
|
|
||||||
|
#define TX_ROOM() ((int)UART_LINE_MAX - UART_TX_TAIL_LEN - n)
|
||||||
|
#define TX_ADD(tag_, val_, dec_) \
|
||||||
|
do { \
|
||||||
|
int added_ = append_field(&s_tx_frame[n], TX_ROOM(), (tag_), (val_), \
|
||||||
|
(dec_)); \
|
||||||
|
if (added_ == 0) { fields_dropped++; } else { n += added_; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
TX_ADD("FREQ1", t->freq1_hz, 0);
|
||||||
|
TX_ADD("FREQ2", t->freq2_hz, 0);
|
||||||
|
TX_ADD("DUTY1", t->duty1_pct, 1);
|
||||||
|
TX_ADD("DUTY2", t->duty2_pct, 1);
|
||||||
|
TX_ADD("VIN", t->vin_v, 1);
|
||||||
|
TX_ADD("IIN", t->iin_a, 2);
|
||||||
|
TX_ADD("V1", t->v1_v, 1);
|
||||||
|
TX_ADD("I1", t->i1_a, 2);
|
||||||
|
TX_ADD("T1", t->t1_c, 1);
|
||||||
|
TX_ADD("VOUT", t->vout_v, 1);
|
||||||
|
TX_ADD("I2", t->i2_a, 2);
|
||||||
|
TX_ADD("T2", t->t2_c, 1);
|
||||||
|
TX_ADD("IOUT", t->iout_a, 2);
|
||||||
|
|
||||||
|
#undef TX_ADD
|
||||||
|
#undef TX_ROOM
|
||||||
|
|
||||||
|
if (fields_dropped != 0)
|
||||||
|
{
|
||||||
|
s_tx_truncated++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checksum XOR sur le corps seul, entre '$' et '*' (docs/ESP32-UART.md).
|
||||||
|
// La place a ete reservee par UART_TX_TAIL_LEN, l'ecriture tient toujours.
|
||||||
|
cs = checksum_of(&s_tx_frame[1], n - 1);
|
||||||
|
n += snprintf(&s_tx_frame[n], (size_t)((int)UART_LINE_MAX - n),
|
||||||
|
"*%02X\n", cs);
|
||||||
|
|
||||||
|
s_tx_len = (uint16_t)n;
|
||||||
|
s_tx_pos = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uart_link_tx_busy(void)
|
||||||
|
{
|
||||||
|
return (s_tx_pos < s_tx_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_link_service_tx(void)
|
||||||
|
{
|
||||||
|
while ((s_tx_pos < s_tx_len)
|
||||||
|
&& (SciaRegs.SCIFFTX.bit.TXFFST < SCI_TX_FIFO_DEPTH))
|
||||||
|
{
|
||||||
|
SciaRegs.SCITXBUF = (uint16_t)(uint8_t)s_tx_frame[s_tx_pos];
|
||||||
|
s_tx_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// body pointe juste apres "C," ; len = nb de caracteres avant le '*'.
|
||||||
|
static bool parse_command(const char *body, command_state_t *cmd)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
bool ht_found = false, pwm1_found = false, pwm2_found = false;
|
||||||
|
|
||||||
|
p = strstr(body, "HT=");
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
cmd->ht_enabled = (p[3] == '1');
|
||||||
|
ht_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strstr(body, "PWM1=");
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
cmd->pwm1_enabled = (p[5] == '1');
|
||||||
|
pwm1_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strstr(body, "PWM2=");
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
cmd->pwm2_enabled = (p[5] == '1');
|
||||||
|
pwm2_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ht_found && pwm1_found && pwm2_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// s_line contient une ligne complete (sans le '\n' terminal).
|
||||||
|
static bool process_line(command_state_t *cmd)
|
||||||
|
{
|
||||||
|
int len = (int)s_line_len;
|
||||||
|
int i;
|
||||||
|
int star = -1;
|
||||||
|
uint8_t cs_calc, cs_recv;
|
||||||
|
|
||||||
|
if (len > 0 && s_line[len - 1] == '\r')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < 4 || s_line[0] != '$')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < len; i++)
|
||||||
|
{
|
||||||
|
if (s_line[i] == '*')
|
||||||
|
{
|
||||||
|
star = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (star < 0 || (len - star) < 3)
|
||||||
|
{
|
||||||
|
return false; // pas de checksum complet
|
||||||
|
}
|
||||||
|
|
||||||
|
cs_calc = checksum_of(&s_line[1], star - 1);
|
||||||
|
cs_recv = (uint8_t)strtol(&s_line[star + 1], NULL, 16);
|
||||||
|
if (cs_calc != cs_recv)
|
||||||
|
{
|
||||||
|
return false; // trame corrompue -> ignoree silencieusement
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_line[1] != 'C' || s_line[2] != ',')
|
||||||
|
{
|
||||||
|
return false; // pas une trame de commande
|
||||||
|
}
|
||||||
|
|
||||||
|
s_line[star] = '\0';
|
||||||
|
return parse_command(&s_line[3], cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compteur de recuperations, expose au debogueur : une valeur qui grimpe
|
||||||
|
// signale un probleme physique sur la ligne (baud, masse, niveaux), pas un
|
||||||
|
// simple alea.
|
||||||
|
static uint16_t s_rx_error_recoveries = 0;
|
||||||
|
|
||||||
|
// Sur C28x, un FE / OE / PE / BRKDT positionne SCIRXST.RXERROR, qui est
|
||||||
|
// LATCHE : le recepteur reste bloque tant qu'on ne fait pas un SW RESET du
|
||||||
|
// SCI (TRM SPRUI09A, SCICTL1.SWRESET) ou un reset systeme. Sans ce
|
||||||
|
// traitement, une seule perturbation sur la ligne arrete definitivement la
|
||||||
|
// reception -- constate au bring-up (RXERROR+FE+BRKDT latches, plus aucune
|
||||||
|
// trame $C recue ensuite).
|
||||||
|
static void scia_recover_if_rx_error(void)
|
||||||
|
{
|
||||||
|
if (SciaRegs.SCIRXST.bit.RXERROR == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SciaRegs.SCICTL1.bit.SWRESET = 0;
|
||||||
|
SciaRegs.SCICTL1.bit.SWRESET = 1;
|
||||||
|
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;
|
||||||
|
|
||||||
|
// La ligne en cours d'assemblage est forcement tronquee : on repart propre.
|
||||||
|
s_line_len = 0;
|
||||||
|
s_rx_error_recoveries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uart_link_poll(command_state_t *cmd)
|
||||||
|
{
|
||||||
|
bool got_command = false;
|
||||||
|
|
||||||
|
scia_recover_if_rx_error();
|
||||||
|
|
||||||
|
while (s_rx_tail != s_rx_head)
|
||||||
|
{
|
||||||
|
uint8_t c = s_rx_ring[s_rx_tail];
|
||||||
|
s_rx_tail = (uint16_t)((s_rx_tail + 1U) % UART_RX_RING_SIZE);
|
||||||
|
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
if (process_line(cmd))
|
||||||
|
{
|
||||||
|
got_command = true;
|
||||||
|
}
|
||||||
|
s_line_len = 0;
|
||||||
|
}
|
||||||
|
else if (s_line_len < (UART_LINE_MAX - 1U))
|
||||||
|
{
|
||||||
|
s_line[s_line_len++] = (char)c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Ligne trop longue (> limite cote ESP32) : abandonnee.
|
||||||
|
s_line_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return got_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupt void scia_rx_isr(void)
|
||||||
|
{
|
||||||
|
uint16_t next_head = (uint16_t)((s_rx_head + 1U) % UART_RX_RING_SIZE);
|
||||||
|
|
||||||
|
if (next_head != s_rx_tail)
|
||||||
|
{
|
||||||
|
s_rx_ring[s_rx_head] = (uint8_t)SciaRegs.SCIRXBUF.bit.RXDT;
|
||||||
|
s_rx_head = next_head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(void)SciaRegs.SCIRXBUF.bit.RXDT; // anneau plein : octet jete
|
||||||
|
}
|
||||||
|
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;
|
||||||
|
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;
|
||||||
|
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
|
||||||
|
}
|
||||||
29
src/uart_link.h
Normal file
29
src/uart_link.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef UART_LINK_H
|
||||||
|
#define UART_LINK_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
void uart_link_init(void);
|
||||||
|
|
||||||
|
// Construit une trame $T,...*XX et la met en attente (docs/ESP32-UART.md).
|
||||||
|
// NE BLOQUE PAS : rien n'est emis ici, c'est uart_link_service_tx() qui
|
||||||
|
// alimente la ligne ensuite. Renvoie false si la trame precedente n'est pas
|
||||||
|
// encore partie -- la nouvelle est alors abandonnee.
|
||||||
|
bool uart_link_send_telemetry(const telemetry_t *t);
|
||||||
|
|
||||||
|
// Pousse dans la FIFO du SCI ce qui y rentre, puis rend la main
|
||||||
|
// immediatement. A appeler depuis la boucle principale, en tache de fond :
|
||||||
|
// l'emission ne doit jamais passer avant la regulation.
|
||||||
|
void uart_link_service_tx(void);
|
||||||
|
|
||||||
|
// true tant qu'une trame reste a emettre.
|
||||||
|
bool uart_link_tx_busy(void);
|
||||||
|
|
||||||
|
// A appeler dans la boucle principale (jamais en ISR). Si une trame
|
||||||
|
// $C,...*XX complete et de checksum valide a ete recue depuis le dernier
|
||||||
|
// appel, decode son contenu dans *cmd et renvoie true. Les trames
|
||||||
|
// corrompues sont ignorees silencieusement (voir docs/ESP32-UART.md).
|
||||||
|
bool uart_link_poll(command_state_t *cmd);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user