Initial commit for PSU

This commit is contained in:
Joshua Jeyaraj
2018-12-05 23:18:34 +05:30
parent 841129dda2
commit 0dc6f99c80
145 changed files with 27486 additions and 0 deletions

16
firmware/psu/.ccsproject Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?ccsproject version="1.0"?>
<projectOptions>
<ccsVersion value="8.1.0"/>
<deviceVariant value="Cortex M.TM4C1294NCPDT"/>
<deviceFamily value="TMS470"/>
<deviceEndianness value="little"/>
<codegenToolVersion value="18.1.2.LTS"/>
<isElfFormat value="true"/>
<rts value="libc.a"/>
<createSlaveProjects value=""/>
<templateProperties value="id=com_ti_rtsc_tirtostivac_example_148.projectspec.PSU,type=rtsc,products=com.ti.rtsc.TIRTOStivac,xdcToolsVersion=3_32_00_06_core,target=ti.targets.arm.elf.M4F,platform=ti.platforms.tiva:TM4C1294NCPDT,buildProfile=release,isHybrid=true,configuroOptions= --compileOptions &quot;${COMPILER_FLAGS} &quot;"/>
<origin value="C:\ti\tirtos_tivac_2_16_00_08\resources\ek_tm4C1294XLEvaluationKit\driverExamples\tiDriverExamples\i2CExamples\com_ti_rtsc_tirtostivac_example_148.projectspec"/>
<filesToOpen value=""/>
<isTargetManual value="true"/>
</projectOptions>

271
firmware/psu/.cproject Normal file
View File

@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule configRelations="2" moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.367607802">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.367607802" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.rtsc.xdctools.parsers.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" errorParsers="org.eclipse.rtsc.xdctools.parsers.ErrorParser;org.eclipse.cdt.core.GmakeErrorParser;com.ti.ccstudio.errorparser.CoffErrorParser;com.ti.ccstudio.errorparser.AsmErrorParser;com.ti.ccstudio.errorparser.LinkErrorParser" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.367607802" name="Debug" parent="com.ti.ccstudio.buildDefinitions.TMS470.Debug">
<folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.367607802." name="/" resourcePath="">
<toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.DebugToolchain.950654569" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerDebug.1052742121">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1857605006" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
<listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex M.TM4C1230E6PM"/>
<listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
<listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>
<listOptionValue builtIn="false" value="LINKER_COMMAND_FILE=tm4c1230e6pm.cmd"/>
<listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=libc.a"/>
<listOptionValue builtIn="false" value="XDC_VERSION=3.32.2.25_core"/>
<listOptionValue builtIn="false" value="INACTIVE_REPOS="/>
<listOptionValue builtIn="false" value="EXPANDED_REPOS="/>
<listOptionValue builtIn="false" value="PRODUCT_MACRO_IMPORTS={&quot;com.ti.rtsc.TIRTOStivac&quot;:[&quot;${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_LIBRARY_PATH}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_LIBRARIES}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_SYSCONFIG_MANIFEST}&quot;]}"/>
<listOptionValue builtIn="false" value="OUTPUT_TYPE=rtscApplication:executable"/>
<listOptionValue builtIn="false" value="CCS_MBS_VERSION=6.1.3"/>
<listOptionValue builtIn="false" value="PRODUCTS=com.ti.rtsc.TIRTOStivac:2.16.1.14;"/>
<listOptionValue builtIn="false" value="RTSC_MBS_VERSION=7.0.0"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1842092978" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="18.1.2.LTS" valueType="string"/>
<targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.targetPlatformDebug.408389259" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.targetPlatformDebug"/>
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.builderDebug.350368834" keepEnvironmentInBuildfile="false" name="GNU Make" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.builderDebug"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.compilerDebug.47682500" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.compilerDebug">
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION.1830390386" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION.7M4" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE.1620273713" name="Designate code state, 16-bit (thumb) or 32-bit (--code_state)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE.16" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI.1202618755" name="Application binary interface. (--abi)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI.eabi" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT.1063633263" name="Specify floating point support (--float_support)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT.FPv4SPD16" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GCC.1252346781" name="Enable support for GCC extensions (DEPRECATED) (--gcc)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GCC" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEFINE.669207335" name="Pre-define NAME (--define, -D)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEFINE" valueType="definedSymbols">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}"/>
<listOptionValue builtIn="false" value="DEBUG_LOGS"/>
<listOptionValue builtIn="false" value="ccs=&quot;ccs&quot;"/>
<listOptionValue builtIn="false" value="ccs"/>
<listOptionValue builtIn="false" value="TIVAWARE"/>
<listOptionValue builtIn="false" value="PART_TM4C1230E6PM"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.LITTLE_ENDIAN.1812243947" name="Little endian code [See 'General' page to edit] (--little_endian, -me)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.LITTLE_ENDIAN" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.INCLUDE_PATH.1675531016" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.INCLUDE_PATH" valueType="includePath">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src}"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/common}"/>
<listOptionValue builtIn="false" value="${PROJECT_ROOT}"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}}"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/bios_6_45_01_29/packages/ti/sysbios/posix"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/include"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL.1827123898" name="Debugging model" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.C_DIALECT.592686312" name="C Dialect" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.C_DIALECT" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.C_DIALECT.C99" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WARNING.1567388121" name="Treat diagnostic &lt;id&gt; as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WARNING" valueType="stringList">
<listOptionValue builtIn="false" value="225"/>
<listOptionValue builtIn="false" value="255"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP.24432476" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DISPLAY_ERROR_NUMBER.697873492" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS.1308351507" name="Place each function in a separate subsection (--gen_func_subsections, -ms)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS.on" valueType="enumerated"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__C_SRCS.1817216121" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__CPP_SRCS.1618143599" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM_SRCS.542009161" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM2_SRCS.41438759" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerDebug.1052742121" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.MAP_FILE.1575127121" name="Link information (map) listed into &lt;file&gt; (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.MAP_FILE" value="${ProjName}.map" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.STACK_SIZE.1217027644" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.STACK_SIZE" value="512" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.HEAP_SIZE.1549671163" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.HEAP_SIZE" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.OUTPUT_FILE.878809127" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.OUTPUT_FILE" value="${ProjName}.out" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.LIBRARY.456326683" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.LIBRARY" valueType="libs">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_LIBRARIES}"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/grlib/ccs/Debug/grlib.lib"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/usblib/ccs/Debug/usblib.lib"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/driverlib/ccs/Debug/driverlib.lib"/>
<listOptionValue builtIn="false" value="libc.a"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.SEARCH_PATH.663360582" name="Add &lt;dir&gt; to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.SEARCH_PATH" valueType="libPaths">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_LIBRARY_PATH}"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/lib"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/include"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP.74252680" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DISPLAY_ERROR_NUMBER.1083856529" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.XML_LINK_INFO.465852269" name="Detailed link information data-base into &lt;file&gt; (--xml_link_info, -xml_link_info)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.XML_LINK_INFO" value="${ProjName}_linkInfo.xml" valueType="string"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD_SRCS.1922631864" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD2_SRCS.1025144518" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD2_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__GEN_CMDS.1439916981" name="Generated Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__GEN_CMDS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.hex.1667869038" name="ARM Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.hex"/>
<tool id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.960794617" name="XDCtools" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool">
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH.1295857287" name="Package repositories (--xdcpath)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH" valueType="stringList">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_REPOS}"/>
<listOptionValue builtIn="false" value="C:\ti\ccsv8\ccs_base"/>
</option>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET.2044191652" name="Target (-t)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET" value="ti.targets.arm.elf.M4F" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM.1633730618" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM" value="ti.platforms.tiva:TM4C1230E6PM" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW.1929240797" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW" value="ti.platforms.tiva:TM4C1230E6PM" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE.1231662762" name="Build-profile (-r)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE" value="debug" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR.1891318288" name="Compiler tools directory (-c)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR" value="${CG_TOOL_ROOT}" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.COMPILE_OPTIONS.433569281" name="Additional compiler options (--compileOptions)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.COMPILE_OPTIONS" value="&quot;${COMPILER_FLAGS} &quot;" valueType="string"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1674095127">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1674095127" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.rtsc.xdctools.parsers.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" errorParsers="org.eclipse.rtsc.xdctools.parsers.ErrorParser;org.eclipse.cdt.core.GmakeErrorParser;com.ti.ccstudio.errorparser.CoffErrorParser;com.ti.ccstudio.errorparser.AsmErrorParser;com.ti.ccstudio.errorparser.LinkErrorParser" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1674095127" name="Release" parent="com.ti.ccstudio.buildDefinitions.TMS470.Release">
<folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1674095127." name="/" resourcePath="">
<toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.ReleaseToolchain.1941987735" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.ReleaseToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerRelease.419726953">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1143427461" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
<listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex M.TM4C1294NCPDT"/>
<listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
<listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>
<listOptionValue builtIn="false" value="CCS_MBS_VERSION=6.1.3"/>
<listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=libc.a"/>
<listOptionValue builtIn="false" value="RTSC_MBS_VERSION=7.0.0"/>
<listOptionValue builtIn="false" value="XDC_VERSION=3.32.0.06_core"/>
<listOptionValue builtIn="false" value="OUTPUT_TYPE=rtscApplication:executable"/>
<listOptionValue builtIn="false" value="PRODUCTS=com.ti.rtsc.TIRTOStivac:2.16.0.08;"/>
<listOptionValue builtIn="false" value="PRODUCT_MACRO_IMPORTS={&quot;com.ti.rtsc.TIRTOStivac&quot;:[&quot;${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_LIBRARY_PATH}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_LIBRARIES}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}&quot;,&quot;${COM_TI_RTSC_TIRTOSTIVAC_SYSCONFIG_MANIFEST}&quot;]}"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.938535830" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="18.1.2.LTS" valueType="string"/>
<targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.targetPlatformRelease.1753704672" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.targetPlatformRelease"/>
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.builderRelease.1470900567" keepEnvironmentInBuildfile="false" name="GNU Make" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.builderRelease"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.compilerRelease.1573078828" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.compilerRelease">
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION.802345926" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.SILICON_VERSION.7M4" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE.757217625" name="Designate code state, 16-bit (thumb) or 32-bit (--code_state)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.CODE_STATE.16" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI.1593681067" name="Application binary interface. (--abi)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.ABI.eabi" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT.331367973" name="Specify floating point support (--float_support)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.FLOAT_SUPPORT.FPv4SPD16" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GCC.574617752" name="Enable support for GCC extensions (DEPRECATED) (--gcc)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GCC" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEFINE.950007760" name="Pre-define NAME (--define, -D)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEFINE" valueType="definedSymbols">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}"/>
<listOptionValue builtIn="false" value="ccs=&quot;ccs&quot;"/>
<listOptionValue builtIn="false" value="PART_TM4C1294NCPDT"/>
<listOptionValue builtIn="false" value="ccs"/>
<listOptionValue builtIn="false" value="TIVAWARE"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WARNING.1597056491" name="Treat diagnostic &lt;id&gt; as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WARNING" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="225"/>
<listOptionValue builtIn="false" value="255"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DISPLAY_ERROR_NUMBER.10672880" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DISPLAY_ERROR_NUMBER" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP.1029145872" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.INCLUDE_PATH.2137945793" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.INCLUDE_PATH" valueType="includePath">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}"/>
<listOptionValue builtIn="false" value="${PROJECT_ROOT}"/>
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}}"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/bios_6_45_01_29/packages/ti/sysbios/posix"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/include"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.LITTLE_ENDIAN.2026697233" name="Little endian code [See 'General' page to edit] (--little_endian, -me)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.LITTLE_ENDIAN" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL.763882803" name="Debugging model" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS.185136756" name="Place each function in a separate subsection (--gen_func_subsections, -ms)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compilerID.GEN_FUNC_SUBSECTIONS.on" valueType="enumerated"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__C_SRCS.1840690492" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__CPP_SRCS.482076289" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM_SRCS.1495589712" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM2_SRCS.2115971040" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerRelease.419726953" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exe.linkerRelease">
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.MAP_FILE.412429120" name="Link information (map) listed into &lt;file&gt; (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.MAP_FILE" useByScannerDiscovery="false" value="${ProjName}.map" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.STACK_SIZE.320942580" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.STACK_SIZE" useByScannerDiscovery="false" value="512" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.HEAP_SIZE.1155896198" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.HEAP_SIZE" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.OUTPUT_FILE.213029085" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.OUTPUT_FILE" useByScannerDiscovery="false" value="${ProjName}.out" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.XML_LINK_INFO.2024278211" name="Detailed link information data-base into &lt;file&gt; (--xml_link_info, -xml_link_info)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.XML_LINK_INFO" useByScannerDiscovery="false" value="${ProjName}_linkInfo.xml" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DISPLAY_ERROR_NUMBER.690478376" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DISPLAY_ERROR_NUMBER" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP.2084859007" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.SEARCH_PATH.625525083" name="Add &lt;dir&gt; to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.SEARCH_PATH" valueType="libPaths">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_LIBRARY_PATH}"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/lib"/>
<listOptionValue builtIn="false" value="${CG_TOOL_ROOT}/include"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.LIBRARY.1601053686" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.linkerID.LIBRARY" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_LIBRARIES}"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/grlib/ccs/Debug/grlib.lib"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/usblib/ccs/Debug/usblib.lib"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.1.71b/driverlib/ccs/Debug/driverlib.lib"/>
<listOptionValue builtIn="false" value="libc.a"/>
</option>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD_SRCS.1978760983" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD2_SRCS.7949482" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__CMD2_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__GEN_CMDS.740786223" name="Generated Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.exeLinker.inputType__GEN_CMDS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_18.1.hex.629361897" name="ARM Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_18.1.hex"/>
<tool id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.77266496" name="XDCtools" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool">
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR.213585987" name="Compiler tools directory (-c)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR" value="${CG_TOOL_ROOT}" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET.1736185338" name="Target (-t)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET" value="ti.targets.arm.elf.M4F" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM.1594485937" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM" value="ti.platforms.tiva:TM4C1294NCPDT" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW.524231227" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW" value="ti.platforms.tiva:TM4C1294NCPDT" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE.1588737548" name="Build-profile (-r)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE" value="release" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH.270802450" name="Package repositories (--xdcpath)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH" valueType="stringList">
<listOptionValue builtIn="false" value="${COM_TI_RTSC_TIRTOSTIVAC_REPOS}"/>
</option>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.COMPILE_OPTIONS.1655560542" name="Additional compiler options (--compileOptions)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.COMPILE_OPTIONS" useByScannerDiscovery="false" value="&quot;${COMPILER_FLAGS} &quot;" valueType="string"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="src|tm4c1230e6pm.cmd" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/utils"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/sysbios"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/subsystem"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/registry"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/post"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/interfaces"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/helpers"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/drivers"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/devices/ocmp_wrappers"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/devices/i2c"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/comm"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src/devices/uart"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping">
<project-mappings>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.asmSource" language="com.ti.ccstudio.core.TIASMLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cHeader" language="com.ti.ccstudio.core.TIGCCLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cSource" language="com.ti.ccstudio.core.TIGCCLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxHeader" language="com.ti.ccstudio.core.TIGPPLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxSource" language="com.ti.ccstudio.core.TIGPPLanguage"/>
</project-mappings>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="PSU.com.ti.ccstudio.buildDefinitions.TMS470.ProjectType.1438298244" name="TMS470" projectType="com.ti.ccstudio.buildDefinitions.TMS470.ProjectType"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/PSU"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/PSU"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="scannerConfiguration"/>
</cproject>

11
firmware/psu/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
/Debug/
/Release/
/src/sysbios/
/src/makefile.libs
.xdchelp
/.config/
/.launches
# NOTE: this should only be ignored when "Manage the project's
# target-configuration automatically" is selected in Properties->CCS General
/targetConfigs/

28
firmware/psu/.project Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>PSU</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.rtsc.xdctools.buildDefinitions.XDC.xdcNature</nature>
<nature>com.ti.ccstudio.core.ccsNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,4 @@
ccsVersionValidationPolicy=warning
compilerVersionValidationPolicy=flexible
eclipse.preferences.version=1
productVersionsValidationPolicy=flexible

View File

@@ -0,0 +1,3 @@
eclipse.preferences.version=1
inEditor=false
onBuild=false

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker

View File

@@ -0,0 +1,46 @@
eclipse.preferences.version=1
encoding//Debug/makefile=UTF-8
encoding//Debug/objects.mk=UTF-8
encoding//Debug/platform/oc-sdr/cfg/subdir_rules.mk=UTF-8
encoding//Debug/platform/oc-sdr/cfg/subdir_vars.mk=UTF-8
encoding//Debug/platform/oc-sdr/schema/subdir_rules.mk=UTF-8
encoding//Debug/platform/oc-sdr/schema/subdir_vars.mk=UTF-8
encoding//Debug/sources.mk=UTF-8
encoding//Debug/src/Devices/i2c/subdir_rules.mk=UTF-8
encoding//Debug/src/Devices/i2c/subdir_vars.mk=UTF-8
encoding//Debug/src/Devices/ocmp_wrappers/subdir_rules.mk=UTF-8
encoding//Debug/src/Devices/ocmp_wrappers/subdir_vars.mk=UTF-8
encoding//Debug/src/Devices/subdir_rules.mk=UTF-8
encoding//Debug/src/Devices/subdir_vars.mk=UTF-8
encoding//Debug/src/Devices/uart/subdir_rules.mk=UTF-8
encoding//Debug/src/Devices/uart/subdir_vars.mk=UTF-8
encoding//Debug/src/comm/subdir_rules.mk=UTF-8
encoding//Debug/src/comm/subdir_vars.mk=UTF-8
encoding//Debug/src/devices/i2c/subdir_rules.mk=UTF-8
encoding//Debug/src/devices/i2c/subdir_vars.mk=UTF-8
encoding//Debug/src/devices/ocmp_wrappers/subdir_rules.mk=UTF-8
encoding//Debug/src/devices/ocmp_wrappers/subdir_vars.mk=UTF-8
encoding//Debug/src/devices/subdir_rules.mk=UTF-8
encoding//Debug/src/devices/subdir_vars.mk=UTF-8
encoding//Debug/src/devices/uart/subdir_rules.mk=UTF-8
encoding//Debug/src/devices/uart/subdir_vars.mk=UTF-8
encoding//Debug/src/drivers/subdir_rules.mk=UTF-8
encoding//Debug/src/drivers/subdir_vars.mk=UTF-8
encoding//Debug/src/helpers/subdir_rules.mk=UTF-8
encoding//Debug/src/helpers/subdir_vars.mk=UTF-8
encoding//Debug/src/interfaces/UART/subdir_rules.mk=UTF-8
encoding//Debug/src/interfaces/UART/subdir_vars.mk=UTF-8
encoding//Debug/src/post/subdir_rules.mk=UTF-8
encoding//Debug/src/post/subdir_vars.mk=UTF-8
encoding//Debug/src/registry/subdir_rules.mk=UTF-8
encoding//Debug/src/registry/subdir_vars.mk=UTF-8
encoding//Debug/src/subdir_rules.mk=UTF-8
encoding//Debug/src/subdir_vars.mk=UTF-8
encoding//Debug/src/subsystem/power/subdir_rules.mk=UTF-8
encoding//Debug/src/subsystem/power/subdir_vars.mk=UTF-8
encoding//Debug/src/sysbios/subdir_rules.mk=UTF-8
encoding//Debug/src/sysbios/subdir_vars.mk=UTF-8
encoding//Debug/src/utils/subdir_rules.mk=UTF-8
encoding//Debug/src/utils/subdir_vars.mk=UTF-8
encoding//Debug/subdir_rules.mk=UTF-8
encoding//Debug/subdir_vars.mk=UTF-8

View File

@@ -0,0 +1,151 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _SYS_CFG_FRAMEWORK_H
#define _SYS_CFG_FRAMEWORK_H
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/post_frame.h" /* Just for post code */
#include <stdbool.h>
#include <stdlib.h>
#define POST_ENABLED 0
#define POST_DISABLED 1
/* For enabling schema sharing between host and firmware we need to import the
* factory config and driver config to schema.c as weak attribute from
* OC_CONNECT1.C. This helps host compilation as it doesn't need to know symbol definition for the configs
* and schema sharing can be achived with limited common files.
*/
#define SCHEMA_IMPORT extern __attribute__((weak))
/* DriverStruct acts as a generic datatype.
* In schema we are more intreseted in the address of structure so we use this datatype DriverStruct
* to avoid the include header for the devices in the system.
*/
typedef char DriverStruct;
/* TODO: move these to common header file */
typedef enum DataType {
TYPE_NULL = 0, /* No data is passed (used for simple GPIO-based alerts) */
TYPE_INT8,
TYPE_UINT8,
TYPE_INT16,
TYPE_UINT16,
TYPE_INT32,
TYPE_UINT32,
TYPE_INT64,
TYPE_UINT64,
TYPE_STR,
TYPE_BOOL,
TYPE_ENUM,
COUNT_TYPE,
} DataType;
typedef struct Enum_Map {
int value;
const char *name;
} Enum_Map;
typedef struct Parameter {
const char *name;
DataType type;
union {
Enum_Map *values;
size_t size;
};
} Parameter;
typedef bool (*CB_Command) (void *driver, void *params);
typedef struct Command {
const char *name;
const Parameter *parameters;
const CB_Command cb_cmd;
} Command;
typedef bool (*CB_POST) (void **params);
typedef struct Post {
const char *name;
const CB_POST cb_postCmd;
}Post;
// To avoid the awkward situation of not knowing how much to allocate for the return value (think
// string returns), we instead rely on the 'get' and 'set' functions to allocate and return a
// pointer to the value it wants to return via OCMP
typedef bool (*StatusGet_Cb) (void *driver, unsigned int param_id,
void *return_buf);
typedef bool (*ConfigGet_Cb) (void *driver, unsigned int param_id,
void *return_buf);
typedef bool (*ConfigSet_Cb) (void *driver, unsigned int param_id,
const void *data);
typedef ePostCode (*CB_Probe) (void *driver, POSTData* postData);
typedef ePostCode (*CB_Init) (void *driver, const void *config,
const void *alert_token);
typedef bool (*ssHook_Cb) (void *driver, void *return_buf);
typedef struct Driver_fxnTable {
// TODO: These callbacks are a bit rough. They'll get the job done, but we should revisit other
// options (per-parameter callbacks for example)
StatusGet_Cb cb_get_status;
ConfigGet_Cb cb_get_config;
ConfigSet_Cb cb_set_config;
CB_Probe cb_probe;
CB_Init cb_init;
} Driver_fxnTable;
typedef struct Driver {
const char *name;
const Parameter *status;
const Parameter *config;
const Parameter *alerts;
const Parameter *argList;
const Command *commands;
const Driver_fxnTable* fxnTable;
const Post *post;
bool payload_fmt_union; /* TODO: hack to account for OBC/Testmodule payload
being packed as a union instead of a struct */
} Driver;
typedef struct SSHookSet {
ssHook_Cb preInitFxn ;/* Function will run before post is executed */
ssHook_Cb postInitFxn; /* Function will run after post is executed */
}SSHookSet;
typedef void (*Component_InitCb) (void);
typedef struct Component {
const char *name;
const struct Component *components;
const Driver *driver;
void *driver_cfg; // TODO: this could be turned into a standard polymorphism struct to hold the
// driver, hw config & driver object data (like we did for GPIO)
const void *factory_config; /* Factory defaults for the device */
const Command *commands; /* TODO: super gross hack to fit into current CLI */
const SSHookSet *ssHookSet;
bool postDisabled; //Flag for POST execution.
void *ss;
} Component;
/* TODO: consider moving struct into c file - only need pointer externally */
typedef struct AlertData {
OCMPSubsystem subsystem;
uint8_t componentId;
uint8_t deviceId;
} AlertData;
void OCMP_GenerateAlert(const AlertData *alert_data,
unsigned int alert_id,
const void *data);
#endif /* _SYS_CFG_FRAMEWORK_H */

View File

@@ -0,0 +1,237 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef __OC_CONNECT1_H
#define __OC_CONNECT1_H
#ifdef __cplusplus
extern "C" {
#endif
#define OC_PMIC_ENABLE (1)
#define OC_PMIC_DISABLE (0)
#define OC_SDR_ENABLE (1)
#define OC_SDR_DISABLE (0)
#define OC_SDR_FE_IO_ENABLE (1)
#define OC_SDR_FE_IO_DISABLE (0)
#define OC_FE_ENABLE (1)
#define OC_FE_DISABLE (0)
#define OC_PWR_LION_BATT (1)
#define OC_PWR_LEAD_BATT (0)
#define OC_PWR_PSE_RESET_STATE (1)
#define OC_PWR_PSE_ON_STATE (0)
#define OC_GBC_PROC_ENABLE (1)
#define OC_GBC_PROC_RESET (0)
#define OC_SYNC_IOEXP_ENABLE (1)
#define OC_SYNC_IOEXP_RESET (0)
#define OC_HCI_LED_ENABLE (1)
#define OC_HCI_LED_DISABLE (0)
#define OC_ETH_SW_ENABLE (1)
#define OC_ETH_SW_DISABLE (0)
#define CAT24C256 { .page_size = 64, .mem_size = (256 / 8) }
/* GBC IO expander Slave address */
#define BIGBROTHER_IOEXP0_ADDRESS 0x71
#define BIGBROTHER_IOEXP1_ADDRESS 0x70
/* SYNC IO expander Slave address */
#define SYNC_IO_DEVICE_ADDR 0x71
/* SDR IO expander Slave address */
#define SDR_FX3_IOEXP_ADDRESS 0x1E
/* RFFE IO expander Slave address */
#define RFFE_CHANNEL1_IO_TX_ATTEN_ADDR 0x18
#define RFFE_CHANNEL1_IO_RX_ATTEN_ADDR 0x1A
#define RFFE_CHANNEL2_IO_TX_ATTEN_ADDR 0x1C
#define RFFE_CHANNEL2_IO_RX_ATTEN_ADDR 0x1D
#define RFFE_IO_REVPOWER_ALERT_ADDR 0x1B
/*!
* @def OC_CONNECT1_EMACName
* @brief Enum of EMAC names on the OC_CONNECT1 board
*/
typedef enum OC_CONNECT1_EMACName {
OC_CONNECT1_EMAC0 = 0,
OC_CONNECT1_EMACCOUNT
} OC_CONNECT1_EMACName;
/*!
* @def OC_CONNECT1_GPIOName
* @brief Enum of GPIO names on the OC_CONNECT1 board
*/
typedef enum OC_EC_PORTGroupName {
PA = 1,
PB,
PC,
PD,
PE,
PF,
PG
}OC_EC_PORTGroupName;
typedef enum OC_CONNECT1_GPIOName {
//PA
OC_EC_PSE_INT = 0,
OC_EC_nPSE_RESET,
OC_EC_WD_INPUT,
OC_EC_ENABLE_OC_INPUT,
OC_EC_POWER_OFF,
OC_EC_NOC_PA5,
OC_EC_CS_I2C1_SCLK,
OC_EC_CS_I2C1_SDA,
//PB
OC_EC_DISABLE_DC_INPUT = 8,
OC_EC_IOEXP_INT,
OC_EC_CS_I2C0_SCLK,
OC_EC_CS_I2C0_SDA,
OC_EC_ENABLE_PASSIVE_POE,
OC_EC_CS_ALERT_24V_20V,
OC_EC_TEMP_I2C5_SCL,
OC_EC_TEMP_I2C5_SDA,
//PC
OC_EC_JTAG_TCK = 16,
OC_EC_JTAG_TMS,
OC_EC_JTAG_TDI,
OC_EC_JTAG_TDO,
OC_EC_UART_RX,
OC_EC_EN_INT_BATT_PWR,
OC_EC_DC_INPUT_FAULT,
OC_EC_UART_TX,
//PD
OC_EC_CS_ALERT = 24,
OC_EC_DC_IN_PRESENT,
OC_EC_CS_ALERT_12V_GBC,
OC_EC_CS_ALERT_12V_BB,
OC_EC_CS_ALERT_12V_FE,
OC_EC_PGOOD_5V0,
OC_EC_PGOOD_12V0,
OC_NOC_PD7,
//PE
OC_EC_IVINMON = 32,
OC_EC_ISMON,//OC_CONNECT1_GBC_TEMP_ALERT2,
OC_EC_CHARGER_ALERT,
OC_EC_PGOOD_BOOST_CONV_BATT,
OC_EC_CHARGER_I2C2_SCL,
OC_EC_CHARGER_I2C2_SDA,
//PF
OC_EC_TIVA_GPIO1 = 40,
OC_EC_TIVA_GPIO2,
OC_EC_BUZZER_ON,
OC_EC_PD_T2P,
OC_EC_TEMP_EVENT,
//PG
OC_EC_PB_PSE_I2C3_SCL = 48,
OC_EC_PB_PSE_I2C3_SDA,
OC_EC_CS_I2C4_SCL,
OC_EC_CS_I2C4_SDA,
OC_EC_OC_IN_PRESENT,
OC_EC_POE_IN_PRESENT,
OC_EC_GPIOCOUNT
} OC_CONNECT1_GPIOName;
/*!
* @def OC_CONNECT1_I2CName
* @brief Enum of I2C names on the OC_CONNECT1 board
*/
typedef enum OC_CONNECT1_I2CName {
OC_CONNECT1_I2C0 = 0,
OC_CONNECT1_I2C1,
OC_CONNECT1_I2C2,
OC_CONNECT1_I2C3,
OC_CONNECT1_I2C4,
OC_CONNECT1_I2C5,
OC_CONNECT1_I2CCOUNT
} OC_CONNECT1_I2CName;
/*!
* @def OC_CONNECT1_UARTName
* @brief Enum of UARTs on the OC_CONNECT1 board
*/
typedef enum OC_CONNECT1_UARTName {
OC_CONNECT1_UART3,
OC_CONNECT1_UART4,
OC_CONNECT1_UARTCOUNT
} OC_CONNECT1_UARTName;
/*
* @def OC_CONNECT1_WatchdogName
* @brief Enum of Watchdogs on the OC_CONNECT1 board
*/
typedef enum OC_CONNECT1_WatchdogName {
OC_CONNECT1_WATCHDOG0 = 0,
OC_CONNECT1_WATCHDOGCOUNT
} OC_CONNECT1_WatchdogName;
/*!
* @brief Initialize the general board specific settings
*
* This function initializes the general board specific settings.
* This includes:
* - Enable clock sources for peripherals
*/
void OC_CONNECT1_initGeneral(void);
/*!
* @brief Initialize board specific EMAC settings
*
* This function initializes the board specific EMAC settings and
* then calls the EMAC_init API to initialize the EMAC module.
*
* The EMAC address is programmed as part of this call.
*
*/
void OC_CONNECT1_initEMAC(void);
/*!
* @brief Initialize board specific GPIO settings
*
* This function initializes the board specific GPIO settings and
* then calls the GPIO_init API to initialize the GPIO module.
*
* The GPIOs controlled by the GPIO module are determined by the GPIO_PinConfig
* variable.
*/
void OC_CONNECT1_initGPIO(void);
/*!
* @brief Initialize board specific I2C settings
*
* This function initializes the board specific I2C settings and then calls
* the I2C_init API to initialize the I2C module.
*
* The I2C peripherals controlled by the I2C module are determined by the
* I2C_config variable.
*/
void OC_CONNECT1_initI2C(void);
/*!
* @brief Initialize board specific UART settings
*
* This function initializes the board specific UART settings and then calls
* the UART_init API to initialize the UART module.
*
* The UART peripherals controlled by the UART module are determined by the
* UART_config variable.
*/
void OC_CONNECT1_initUART(void);
/*!
* @brief Initialize board specific Watchdog settings
*
* This function initializes the board specific Watchdog settings and then
* calls the Watchdog_init API to initialize the Watchdog module.
*
* The Watchdog peripherals controlled by the Watchdog module are determined
* by the Watchdog_config variable.
*/
void OC_CONNECT1_initWatchdog(void);
#ifdef __cplusplus
}
#endif
#endif /* __OC_CONNECT1_H */

View File

@@ -0,0 +1,166 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef OCMP_FRAME_H_
#define OCMP_FRAME_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include <stdint.h>
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
/* Start Of Frame & Message Lengths */
#define OCMP_MSG_SOF 0x55
#define OCMP_FRAME_TOTAL_LENGTH 64
#define OCMP_FRAME_HEADER_LENGTH 17
#define OCMP_FRAME_MSG_LENGTH (OCMP_FRAME_TOTAL_LENGTH - OCMP_FRAME_HEADER_LENGTH)
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
typedef enum {
OC_SS_BB = -1, //Hack around the fact that IPC reuses OCMP to allow us
// to split BB (internal) and SYS (CLI) message handling
OC_SS_PWR = 0,
// OC_SS_PWRBMS,
OC_SS_PWRDEBUG,
OC_SS_MAX_LIMIT,//TODO:REV C Change
} OCMPSubsystem;
typedef enum {
OCMP_COMM_IFACE_UART = 1, // Uart - 1
OCMP_COMM_IFACE_ETHERNET, // Ethernet - 2
OCMP_COMM_IFACE_SBD, // SBD(Satellite) - 3
OCMP_COMM_IFACE_USB // Usb - 4
} OCMPInterface;
/*
* OCMPMsgType - msg type specifies what is the communication all about.
* It can be Configuration, Status, Alert, Command, Watchdog, Debug
* OCMPMsgType 1 byte message.
* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* || 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 ||
* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|| Message Type ||
* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/
typedef enum {
OCMP_MSG_TYPE_CONFIG = 1,
OCMP_MSG_TYPE_STATUS,
OCMP_MSG_TYPE_ALERT,
OCMP_MSG_TYPE_COMMAND,
OCMP_MSG_TYPE_WATCHDOG,
OCMP_MSG_TYPE_DEBUG,
OCMP_MSG_TYPE_EVENTINFO,
OCMP_MSG_TYPE_ITCMSG,
OCMP_MSG_TYPE_POST,
} OCMPMsgType;
/*
* OCMPActionType - It is about setting something or getting or Reply back.
*/
typedef enum {
OCMP_AXN_TYPE_GET = 1,
OCMP_AXN_TYPE_SET,
OCMP_AXN_TYPE_REPLY,
OCMP_AXN_TYPE_ACTIVE,
OCMP_AXN_TYPE_CLEAR,
OCMP_AXN_TYPE_RESET,
OCMP_AXN_TYPE_ENABLE,
OCMP_AXN_TYPE_DISABLE,
OCMP_AXN_REG_READ,
OCMP_AXN_REG_WRITE,
OCMP_AXN_TYPE_ECHO,
/* TODO: Really shouldn't be generic commands, but keeping here for now
* because refactoring would be too painful just to test the CLI
*/
OCMP_AXN_DIS_NETWORK,
OCMP_AXN_CONN_NETWORK,
OCMP_AXN_SEND_SMS,
OCMP_AXN_DIAL_NUMBER,
OCMP_AXN_ANSWER,
OCMP_AXN_HANGUP,
OCMP_NUM_ACTIONS
} OCMPActionType;
typedef enum {
OCMP_SENSOR_EVENT = 1,
OCMP_TEMP_EVENT,
OCMP_CURRENT_EVENT,
OCMP_REV_POWER_EVENT,
OCMP_BATT_EVENT,
OCMP_PSE_EVENT,
OCMP_PD_EVENT,
OCMP_ETH_EVENT,
OCMP_GPS_EVENT
} OCMPEvents;
/*
* eOCMPDebugOperation - This forms the complete debug message frame for
* communication with EC from External entity (e.g. AP over UART, Ethernet
* or SBD)
*/
typedef enum {
OCMP_DEBUG_READ = 1,
OCMP_DEBUG_WRITE
} eOCMPDebugOperation;
/* TODO::This OCWARE_HOST has to be removed with OCMP cleanUp*/
#ifndef OCWARE_HOST
#define OC_SS OCMPSubsystem
#define OC_MSG_TYP OCMPMsgType
#define OC_AXN_TYP OCMPActionType
#else
#define OC_SS uint8_t
#define OC_MSG_TYP uint8_t
#define OC_AXN_TYP uint8_t
#define OC_IFACE_TYP uint8_t
#endif
/*
* Header is the field which will be containing SOF, Framelen,
* Source Interface, Sequence number, and timestamp.
*/
typedef struct __attribute__((packed, aligned(1))) {
uint8_t ocmpSof; // SOF - It must be 0x55
uint8_t ocmpFrameLen; // Framelen - tells about the configuration size ONLY.
OCMPInterface ocmpInterface; // Interface - UART/Ethernet/SBD
uint32_t ocmpSeqNumber; // SeqNo - Don't know!!!
uint32_t ocmpTimestamp; // Timestamp - When AP sent the command?
} OCMPHeader;
/*
* This is the Message structure for Subsystem level information
*/
typedef struct __attribute__((packed, aligned(1))) {
OC_SS subsystem; // RF/GPP/BMS/Watchdog etc..
uint8_t componentID; // Compononent ID. Different for different subsystem.
OCMPMsgType msgtype; // Msg type is Config/Status/Alert/Command/Watchdog/Debug
uint8_t action; // Action is - Get/Set/Reply.
uint16_t parameters; // List of Parameters to be set or get.
#ifndef OCWARE_HOST
uint8_t ocmp_data[]; // The data payload.
#else
int8_t* info;
#endif
} OCMPMessage;
/*
* OCMPMessageFrame - This forms the complete message frame for communication
* with EC from External entity (e.g. AP over UART, Ethernet or SBD)
*/
typedef struct __attribute__((packed, aligned(1))) {
OCMPHeader header;
OCMPMessage message;
} OCMPMessageFrame;
#endif /* OCMP_FRAME_H_ */

View File

@@ -0,0 +1,43 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef POST_FRAME_H_
#define POST_FRAME_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include <stdint.h>
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
typedef enum {
POST_DEV_NOSTATUS = 0,
POST_DEV_MISSING,
POST_DEV_ID_MISMATCH,
POST_DEV_FOUND,
POST_DEV_CFG_DONE,
POST_DEV_NO_CFG_REQ,
POST_DEV_CFG_FAIL,
POST_DEV_FAULTY,
POST_DEV_CRITICAL_FAULT,
POST_DEV_NO_DRIVER_EXIST,
} ePostCode;
typedef struct __attribute__((packed, aligned(1))) {
uint8_t subsystem;
uint8_t devSno;
uint8_t i2cBus;
uint8_t devAddr;
uint16_t devId;
uint16_t manId;
uint8_t status;
} POSTData;
#endif /* POST_FRAME_H_ */

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef OCMP_I2C_H_
#define OCMP_I2C_H_
#include "common/inc/global/Framework.h"
SCHEMA_IMPORT bool i2c_read(void *driver, void *data);
SCHEMA_IMPORT bool i2c_write(void *driver, void *data);
static const Driver OC_I2C = {
.name = "OC_I2C",
.argList = (Parameter[]){
{ .name = "slave_address", .type = TYPE_UINT8 },
{ .name = "no_of_bytes", .type = TYPE_UINT8 },
{ .name = "reg_address", .type = TYPE_UINT8 },
{ .name = "reg_values", .type = TYPE_UINT16 },
{}
},
.commands = (Command[]){
{
.name = "get",
.cb_cmd = i2c_read,
},
{
.name = "set",
.cb_cmd = i2c_write,
},
{}
},
};
#endif /* INC_DEVICES_OCMP_WRAPPERS_OCMP_I2C_H_ */

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef OCMP_OCGPIO_H_
#define OCMP_OCGPIO_H_
#include "common/inc/global/Framework.h"
SCHEMA_IMPORT bool ocgpio_get(void *driver, void *data);
SCHEMA_IMPORT bool ocgpio_set(void *driver, void *data);
SCHEMA_IMPORT const Driver_fxnTable DEBUG_OCGPIO_fxnTable;
static const Driver OC_GPIO = {
.name = "OC_GPIO",
.argList = (Parameter[]){
{ .name = "pin", .type = TYPE_UINT8 },
{ .name = "value", .type = TYPE_UINT8 },
{}
},
.commands = (Command[]){
{
.name = "get",
.cb_cmd = ocgpio_get,
},
{
.name = "set",
.cb_cmd = ocgpio_set,
},
{}
},
.fxnTable = &DEBUG_OCGPIO_fxnTable,
};
#endif /* OCMP_OCGPIO_H_ */

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INC_DEVICES_OCMP_EEPROM_H_
#define INC_DEVICES_OCMP_EEPROM_H_
#include "common/inc/global/Framework.h"
SCHEMA_IMPORT const Driver_fxnTable CAT24C04_psu_sid_fxnTable;
SCHEMA_IMPORT const Driver_fxnTable CAT24C04_psu_inv_fxnTable;
static const Driver CAT24C04_psu_sid = {
.name = "EEPROM",
.status = (Parameter[]){
{ .name = "ocserialinfo", .type = TYPE_STR, .size = 21 },
{ .name = "gbcboardinfo", .type = TYPE_STR, .size = 21 },
},
.fxnTable = &CAT24C04_psu_sid_fxnTable,
};
static const Driver CAT24C04_psu_inv = {
.name = "Inventory",
.fxnTable = &CAT24C04_psu_inv_fxnTable,
};
#endif /* INC_DEVICES_OCMP_EEPROM_H_ */

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCMP_INA226_H
#define _OCMP_INA226_H
#include "common/inc/global/Framework.h"
typedef struct INA226_Config {
uint16_t current_lim;
} INA226_Config;
SCHEMA_IMPORT const Driver_fxnTable INA226_fxnTable;
static const Driver INA226 = {
.name = "INA226",
.status = (Parameter[]){
{ .name = "busvoltage", .type = TYPE_UINT16 },
{ .name = "shuntvoltage", .type = TYPE_UINT16 },
{ .name = "current", .type = TYPE_UINT16 },
{ .name = "power", .type = TYPE_UINT16 },
{}
},
.config = (Parameter[]){
{ .name = "currlimit", .type = TYPE_UINT16 },
{}
},
.alerts = (Parameter[]){
{ .name = "Overcurrent", .type = TYPE_UINT16 },
{}
},
.fxnTable = &INA226_fxnTable,
};
#endif /* _OCMP_INA226_H */

View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCMP_LTC4015_H
#define _OCMP_LTC4015_H
#include "common/inc/global/Framework.h"
typedef struct LTC4015_Config {
int16_t batteryVoltageLow;
int16_t batteryVoltageHigh;
int16_t batteryCurrentLow;
int16_t inputVoltageLow;
int16_t inputCurrentHigh;
uint16_t inputCurrentLimit;
uint16_t icharge;
uint16_t vcharge;
} LTC4015_Config;
SCHEMA_IMPORT const Driver_fxnTable LTC4015_fxnTable;
static const Driver LTC4015 = {
.name = "LTC4015",
.status = (Parameter[]){
{ .name = "batteryVoltage", .type = TYPE_INT16 },
{ .name = "batteryCurrent", .type = TYPE_INT16 },
{ .name = "systemVoltage", .type = TYPE_INT16 },
{ .name = "inputVoltage", .type = TYPE_INT16 },
{ .name = "inputCurrent", .type = TYPE_INT16 },
{ .name = "dieTemperature", .type = TYPE_INT16 },
{ .name = "ichargeDAC", .type = TYPE_INT16 },
{}
},
.config = (Parameter[]){
{ .name = "batteryVoltageLow", .type = TYPE_INT16 },
{ .name = "batteryVoltageHigh", .type = TYPE_INT16 },
{ .name = "batteryCurrentLow", .type = TYPE_INT16 },
{ .name = "inputVoltageLow", .type = TYPE_INT16 },
{ .name = "inputCurrentHigh", .type = TYPE_INT16 },
{ .name = "inputCurrentLimit", .type = TYPE_UINT16 },
{ .name = "icharge", .type = TYPE_UINT16 },
{ .name = "vcharge", .type = TYPE_UINT16 },
{ .name = "dieTemperature", .type = TYPE_INT16 },
{}
},
.alerts = (Parameter[]){
{ .name = "BVL", .type = TYPE_INT16 },
{ .name = "BVH", .type = TYPE_INT16 },
{ .name = "BCL", .type = TYPE_INT16 },
{ .name = "IVL", .type = TYPE_INT16 },
{ .name = "ICH", .type = TYPE_INT16 },
{ .name = "DTH", .type = TYPE_INT16 },
{}
},
.fxnTable = &LTC4015_fxnTable,
};
#endif /* _OCMP_LTC4015_H */

View File

@@ -0,0 +1,69 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCMP_LTC4274_H_
#define _OCMP_LTC4274_H_
#include "common/inc/global/Framework.h"
typedef union LTC4274_Config {
struct {
int8_t operatingMode;
int8_t detectEnable;
int8_t interruptMask;
bool interruptEnable;
int8_t pseHpEnable;
};
} LTC4274_Config;
#ifdef UT_FRAMEWORK
extern const Driver_fxnTable LTC4274_fxnTable;
#else
SCHEMA_IMPORT const Driver_fxnTable LTC4274_fxnTable;
#endif
SCHEMA_IMPORT bool LTC4274_reset(void *driver, void *params);
static const Driver LTC4274 = {
.name = "PSE",
.status = (Parameter[]){
{ .name = "detection", .type = TYPE_UINT16 },
{ .name = "class", .type = TYPE_UINT16 },
{ .name = "powerGood", .type = TYPE_UINT16 },
{}
},
.config = (Parameter[]){
{ .name = "operatingMode", .type = TYPE_UINT16 },
{ .name = "detectEnable", .type = TYPE_UINT16 },
{ .name = "interruptMask", .type = TYPE_UINT16 },
{ .name = "interruptEnable", .type = TYPE_UINT16 },
{ .name = "enableHighpower", .type = TYPE_UINT16 },
{}
},
.alerts = (Parameter[]){
{ .name = "NoAlert", .type = TYPE_UINT8 },
{ .name = "PowerEnable", .type = TYPE_UINT8 },
{ .name = "PowerGood", .type = TYPE_UINT8 },
{ .name = "DiconnectAlert", .type = TYPE_UINT8 },
{ .name = "DetectionAlert", .type = TYPE_UINT8 },
{ .name = "ClassAlert", .type = TYPE_UINT8 },
{ .name = "TCUTAler", .type = TYPE_UINT8 },
{ .name = "TStartAlert", .type = TYPE_UINT8 },
{ .name = "SupplyAlert", .type = TYPE_UINT8 },
{}
},
.commands = (Command[]){
{
.name = "reset",
.cb_cmd = LTC4274_reset,
},
{}
},
.fxnTable = &LTC4274_fxnTable,
};
#endif /* _OCMP_LTC4274_H_ */

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef COMMON_INC_OCMP_WRAPPERS_OCMP_LTC4295_H_
#define COMMON_INC_OCMP_WRAPPERS_OCMP_LTC4295_H_
#include "common/inc/global/Framework.h"
SCHEMA_IMPORT const Driver_fxnTable LTC4295_fxnTable;
static const Driver LTC4295 = {
.name = "LTC4295",
.status = (Parameter[]){
{ .name = "class", .type = TYPE_ENUM },
{ .name = "powerGoodState", .type = TYPE_ENUM },
{}
},
.alerts = (Parameter[]){
{ .name = "INCOMPATIBLE", .type = TYPE_ENUM },
{ .name = "DISCONNECT", .type = TYPE_ENUM },
{ .name = "CONNECT", .type = TYPE_ENUM },
{}
},
.fxnTable = &LTC4295_fxnTable,
};
#endif /* COMMON_INC_OCMP_WRAPPERS_OCMP_LTC4295_H_ */

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCMP_POWERSOURCE_H_
#define _OCMP_POWERSOURCE_H_
#include "common/inc/global/Framework.h"
SCHEMA_IMPORT bool PWR_post_get_results(void **getpostResult);
SCHEMA_IMPORT bool PWR_post_enable(void **postActivate);
SCHEMA_IMPORT const Driver_fxnTable PWRSRC_fxnTable;
static const Driver PWRSRC = {
.name = "powerSource",
.status =
(Parameter[]){
{ .name = "extPowerAvailability", .type = TYPE_UINT8 },
{ .name = "extPowerAccessebility", .type = TYPE_UINT8 },
{ .name = "poeAvailability", .type = TYPE_UINT8 },
{ .name = "poeAccessebility", .type = TYPE_UINT8 },
{ .name = "battAvailability", .type = TYPE_UINT8 },
{ .name = "battAccessebility", .type = TYPE_UINT8 },
{}
},
.config = (Parameter[]){
{}
},
.alerts = (Parameter[]){
{}
},
.post = (Post[]){
{
.name = "results",
.cb_postCmd = PWR_post_get_results,
},
{
.name = "enable",
.cb_postCmd = PWR_post_enable,
},
{}
},
.fxnTable = &PWRSRC_fxnTable,
};
#endif /* _OCMP_POWERSOURCE_H_ */

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCMP_SE98A_H
#define _OCMP_SE98A_H
#include "common/inc/global/Framework.h"
typedef union SE98A_Config {
struct {
int8_t lowlimit;
int8_t highlimit;
int8_t critlimit;
};
int8_t limits[3];
} SE98A_Config;
SCHEMA_IMPORT const Driver_fxnTable SE98_fxnTable;
static const Driver SE98A = {
.name = "SE98A",
.status = (Parameter[]){
{ .name = "temperature", .type = TYPE_UINT8 },
{}
},
.config = (Parameter[]){
{ .name = "lowlimit", .type = TYPE_INT8 },
{ .name = "highlimit", .type = TYPE_UINT8 },
{ .name = "critlimit", .type = TYPE_UINT8 },
{}
},
.alerts = (Parameter[]){
{ .name = "BAW", .type = TYPE_UINT8 },
{ .name = "AAW", .type = TYPE_UINT8 },
{ .name = "ACW", .type = TYPE_UINT8 },
{}
},
.fxnTable = &SE98_fxnTable,
};
#endif /* _OCMP_SE98A_H */

View File

@@ -0,0 +1,35 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef BIGBROTHER_H_
#define BIGBROTHER_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/common/global_header.h"
#include "inc/utils/util.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define BIGBROTHER_TASK_PRIORITY 5
#define BIGBROTHER_TASK_STACK_SIZE 2048
/* Semaphore and Queue Handles for Big Brother */
extern Semaphore_Handle semBigBrotherMsg;
extern Queue_Handle bigBrotherRxMsgQueue;
extern Queue_Handle bigBrotherTxMsgQueue;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
void bigbrother_createtask(void);
#endif /* BIGBROTHER_H_ */

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INC_COMMON_BYTEORDER_H_
#define INC_COMMON_BYTEORDER_H_
/* Detect endianness if using TI compiler */
#ifndef __BYTE_ORDER__
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_BIG_ENDIAN__ 4321
#ifdef __little_endian__
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#else
#ifdef __big_endian__
#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
#else
#error Unable to detect byte order!
#endif
#endif
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
/* Little endian host functions here */
#define htobe16(a) ( (((a)>>8)&0xff) + (((a)<<8)&0xff00) )
#define betoh16(a) htobe16(a)
#define htobe32(a) ((((a) & 0xff000000) >> 24) | (((a) & 0x00ff0000) >> 8) | \
(((a) & 0x0000ff00) << 8) | (((a) & 0x000000ff) << 24) )
#define betoh32(a) htobe32(a)
#define htole16(a) a; // Host is a little endian.
#define letoh16(a) htole16(a)
#else
/* Big endian host functions here */
#define htole16(a) ( (((a)>>8)&0xff) + (((a)<<8)&0xff00) )
#define letoh16(a) htobe16(a)
#define htole32(a) ((((a) & 0xff000000) >> 24) | (((a) & 0x00ff0000) >> 8) | \
(((a) & 0x0000ff00) << 8) | (((a) & 0x000000ff) << 24) )
#define letoh32(a) htobe32(a)
#define htobe16(a) a; // Host is a little endian.
#define betoh16(a) htole16(a)
#endif
#endif /* INC_COMMON_BYTEORDER_H_ */

View File

@@ -0,0 +1,74 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef GLOBAL_HEADER_H_
#define GLOBAL_HEADER_H_
#define _FW_REV_MAJOR_ 0
#define _FW_REV_MINOR_ 4
#define _FW_REV_BUGFIX_ 0
#define _FW_REV_TAG_ __COMMIT_HASH__
/* xdc/runtime/System.h is poorly written so this must be included first */
#include <stdbool.h>
/* XDCtools Header files */
#include <xdc/runtime/System.h> /* For System_printf */
#if 1
#define DEBUG(...) {System_printf(__VA_ARGS__); System_flush();}
#define LOGGER(...) {System_printf(__VA_ARGS__); System_flush();}
#define LOGGER_WARNING(...) {System_printf(__VA_ARGS__); System_flush();}
#define LOGGER_ERROR(...) {System_printf(__VA_ARGS__); System_flush();}
#ifdef DEBUG_LOGS
#define LOGGER_DEBUG(...) {System_printf(__VA_ARGS__); System_flush();}
#define NOP_DELAY() { uint32_t delay =7000000;\
while (delay--) \
;\
}
#else
#define LOGGER_DEBUG(...)
#define NOP_DELAY()
#endif
#else
#define DEBUG(...) //
#define LOGGER(...) //
#define LOGGER_WARNING(...) //
#define LOGGER_ERROR(...) //
#ifdef DEBUG_LOGS
#define LOGGER_DEBUG(...) //
#endif
#define NOP_DELAY() { uint32_t delay =7000000;\
while (delay--) \
;\
}
#endif
#define RET_OK 0
#define RET_NOT_OK 1
typedef enum {
RETURN_OK = 0x00,
RETURN_NOTOK = 0x01,
RETURN_OCMP_INVALID_SS_TYPE = 0x02,
RETURN_OCMP_INVALID_MSG_TYPE = 0x03,
RETURN_OCMP_INVALID_COMP_TYPE = 0x04,
RETURN_OCMP_INVALID_AXN_TYPE = 0x05,
RETURN_OCMP_INVALID_PARAM_INFO = 0x06,
RETURN_OCMP_INVALID_CMD_INFO = 0x07,
RETURN_OCMP_INVALID_IFACE_TYPE = 0x08,
RETURN_DEV_VALUE_TOO_LOW = 0x09,
RETURN_DEV_VALUE_TOO_HIGH = 0x0A,
RETURN_DEV_I2C_BUS_FAILURE = 0x0B,
RETURN_SS_NOT_READY = 0x0C,
RETURN_SS_NOT_RESET_STATE = 0x0D
} ReturnStatus;
#endif /* GLOBAL_HEADER_H_ */

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef I2CBUS_H_
#define I2CBUS_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/common/global_header.h"
#include <ti/drivers/I2C.h>
/*****************************************************************************
* STRUCT DEFINITIONS
*****************************************************************************/
typedef struct I2C_Dev {
unsigned int bus;
uint8_t slave_addr;
} I2C_Dev;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
I2C_Handle i2c_open_bus(unsigned int index);
/* Wrapper to ease migration */
#define i2c_get_handle i2c_open_bus
void i2c_close_bus(I2C_Handle* i2cHandle);
ReturnStatus i2c_reg_write( I2C_Handle i2cHandle,
uint8_t deviceAddress,
uint8_t regAddress,
uint16_t value,
uint8_t numofBytes);
ReturnStatus i2c_reg_read( I2C_Handle i2cHandle,
uint8_t deviceAddress,
uint8_t regAddress,
uint16_t *value,
uint8_t numofBytes);
#endif /* I2CBUS_H_ */

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef POST_H_
#define POST_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/post_frame.h"
#include "inc/common/global_header.h"
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define POST_RECORDS 55
#define OC_POST_TASKPRIORITY 3
#define POST_TASK_STACK_SIZE 2048
/*****************************************************************************
* HANDLE DECLARATIONS
*****************************************************************************/
extern Semaphore_Handle semPOSTMsg;
extern Queue_Handle postRxMsgQueue;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
void post_createtask(void);
#endif /* POST_H_ */

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INC_COMMON_POST_UTIL_H_
#define INC_COMMON_POST_UTIL_H_
#include "common/inc/global/Framework.h"
#include "inc/common/post.h"
ReturnStatus _execPost(OCMPMessageFrame *pMsg,
unsigned int subsystem_id);
#endif /* INC_COMMON_POST_UTIL_H_ */

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef SYSTEM_STATES_H_
#define SYSTEM_STATES_H_
/*****************************************************************************
* ENUM DEFINITIONS
*****************************************************************************/
typedef enum {
SS_STATE_PWRON = 1,
SS_STATE_INIT,
SS_STATE_CFG,
SS_STATE_RDY,
SS_STATE_ACTIVE,
SS_STATE_FAULTY,
SS_STATE_RESET,
SS_STATE_SHUTDOWN
} eSubSystemStates;
typedef enum {
OC_STATE_PWRON = 1,
OC_STATE_POST,
OC_STATE_RDY,
OC_STATE_CONFIGURED,
OC_STATE_RF_ACTIVE,
OC_STATE_FAULTY,
OC_STATE_DEGRADED,
OC_STATE_LOST_SYNC,
OC_STATE_UPGRADING,
OC_STATE_RF_FAILURE,
OC_STATE_ETH_FAILURE
} eOCSystemState;
#endif /* SYSTEM_STATES_H_ */

View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OC_GPIO_H_
#define _OC_GPIO_H_
#include "drivers/OcGpio.h"
typedef struct __attribute__ ((packed, aligned(1))) {
uint8_t pin;
uint8_t value;
}S_OCGPIO;
typedef struct S_OCGPIO_Cfg {
OcGpio_Port* port;
unsigned int group;
}S_OCGPIO_Cfg;
#endif /* _OC_GPIO_H_ */

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef OC_I2C_H_
#define OC_I2C_H_
#include <stdint.h>
typedef struct __attribute__ ((packed, aligned(1))){
uint8_t slaveAddress;
uint8_t number_of_bytes;
uint8_t reg_address;
uint16_t reg_value;
}S_OCI2C;
typedef struct S_I2C_Cfg {
unsigned int bus;
}S_I2C_Cfg;
#endif /* INC_DEVICES_OC_I2C_H_ */

View File

@@ -0,0 +1,92 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef EEPROM_H_
#define EEPROM_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/ocmp_frame.h" /* Temporary, just for OCMPSubsystem def */
#include "drivers/OcGpio.h"
#include "inc/common/i2cbus.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define OC_TEST_ADDRESS 0xFD0
#define OC_CONNECT1_SERIAL_INFO 0x01C6
#define OC_CONNECT1_SERIAL_SIZE 0x12
#define OC_GBC_BOARD_INFO 0x01AC
#define OC_GBC_BOARD_INFO_SIZE 0x12
#define OC_GBC_DEVICE_INFO 0x0100 /*TODO: Update offsets*/
#define OC_SDR_BOARD_INFO 0x01AC
#define OC_SDR_BOARD_INFO_SIZE 0x12
#define OC_SDR_DEVICE_INFO 0x0100 /*TODO: Update offsets*/
#define OC_RFFE_BOARD_INFO 0x01AC
#define OC_RFFE_BOARD_INFO_SIZE 0x11
#define OC_RFFE_DEVICE_INFO 0x0100 /*TODO: Update offsets*/
#define OC_DEVICE_INFO_SIZE 0x0A
/*****************************************************************************
* STRUCT DEFINITIONS
*****************************************************************************/
typedef struct EepromDev_Cfg {
/*!< EEPROM size in bytes */
size_t mem_size;
/*!< Page size (max bytes we can write in a single shot) */
size_t page_size;
} EepromDev_Cfg;
typedef struct Eeprom_Cfg {
I2C_Dev i2c_dev;
OcGpio_Pin *pin_wp;
EepromDev_Cfg type; /*!< Device specific config (page size, etc) */
OCMPSubsystem ss; /* TODO: The HW config need not know about the subsytem
to be fixed later */
} Eeprom_Cfg, *Eeprom_Handle;
typedef enum {
OC_STAT_SYS_SERIAL_ID = 0,
OC_STAT_SYS_GBC_BOARD_ID,
OC_STAT_SYS_STATE
} eOCStatusParamId;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
bool eeprom_init(Eeprom_Cfg *cfg);
ReturnStatus eeprom_read(Eeprom_Cfg *cfg,
uint16_t address,
void *buffer,
size_t size);
ReturnStatus eeprom_write(const Eeprom_Cfg *cfg,
uint16_t address,
const void *buffer,
size_t size);
ReturnStatus eeprom_disable_write(Eeprom_Cfg *cfg);
ReturnStatus eeprom_enable_write(Eeprom_Cfg *cfg);
ReturnStatus eeprom_read_oc_info(uint8_t * oc_serial);
ReturnStatus eeprom_read_board_info(const Eeprom_Cfg *cfg,
uint8_t * rom_info);
ReturnStatus eeprom_read_device_info_record(const Eeprom_Cfg *cfg,
uint8_t recordNo,
char * device_info);
ReturnStatus eeprom_write_device_info_record(Eeprom_Cfg *cfg,
uint8_t recordNo,
char * device_info);
#endif /* EEPROM_H_ */

View File

@@ -0,0 +1,93 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INA226_H_
#define INA226_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/post_frame.h"
#include "drivers/OcGpio.h"
#include "inc/common/i2cbus.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
/* Mask/Enable Register Bits */
#define INA_ALERT_EN_MASK 0xF800 /* Upper 5 bits are the enable bits */
#define INA_MSK_SOL (1 << 15) /* Shunt over-voltage */
#define INA_MSK_SUL (1 << 14) /* Shunt under-voltage */
#define INA_MSK_BOL (1 << 13) /* Bus over-voltage */
#define INA_MSK_BUL (1 << 12) /* Bus under-voltage */
#define INA_MSK_POL (1 << 11) /* Power over limit */
#define INA_MSK_CNVR (1 << 10) /* Conversion ready - enable alert when
* CVRF is set (ready for next conversion) */
#define INA_MSK_AFF (1 << 4) /* Alert Function Flag (caused by alert)
* In latch mode, cleared on mask read */
#define INA_MSK_CVRF (1 << 3) /* Conversion Ready Flag, cleared when
* writing to cfg reg or mask read */
#define INA_MSK_OVF (1 << 2) /* Math Overflow Flag (data may be invalid) */
#define INA_MSK_APOL (1 << 1) /* Alert Polarity (1 = invert, active high) */
#define INA_MSK_LEN (1 << 0) /* Alert Latch Enable
* 1 Latch (alert only cleared by read to msk)
* 0 Transparent (auto-clear on fault clear) */
#define INA_HYSTERESIS 30 /* 30mA TODO: need to make more robust, maybe percentage based */
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
typedef enum INA226_Event {
INA226_EVT_SOL = INA_MSK_SOL, /* Shunt over-voltage */
INA226_EVT_SUL = INA_MSK_SUL, /* Shunt under-voltage */
INA226_EVT_BOL = INA_MSK_BOL, /* Bus over-voltage */
INA226_EVT_BUL = INA_MSK_BUL, /* Bus under-voltage */
INA226_EVT_POL = INA_MSK_POL, /* Power over limit */
/* Meta Events */
INA226_EVT_COL, /* Current over limit - based on SOL */
INA226_EVT_CUL, /* Current under limit - based on SUL */
} INA226_Event;
typedef void (*INA226_CallbackFn) (INA226_Event evt, uint16_t value,
void *context);
typedef struct INA226_Cfg {
I2C_Dev dev;
OcGpio_Pin *pin_alert;
} INA226_Cfg;
typedef struct INA226_Obj {
INA226_CallbackFn alert_cb;
void *cb_context;
INA226_Event evt_to_monitor;
} INA226_Obj;
typedef struct INA226_Dev {
const INA226_Cfg cfg;
INA226_Obj obj;
} INA226_Dev;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
ReturnStatus ina226_readCurrentLim(INA226_Dev *dev, uint16_t* currLimit);
ReturnStatus ina226_setCurrentLim(INA226_Dev *dev, uint16_t currLimit);
ReturnStatus ina226_readBusVoltage(INA226_Dev *dev, uint16_t* busVoltValue);
ReturnStatus ina226_readShuntVoltage(INA226_Dev *dev,
uint16_t* shuntVoltValue);
ReturnStatus ina226_readCurrent(INA226_Dev *dev, uint16_t* currValue);
ReturnStatus ina226_readPower(INA226_Dev *dev, uint16_t* powValue);
ReturnStatus ina226_init(INA226_Dev *dev);
void ina226_setAlertHandler(INA226_Dev *dev, INA226_CallbackFn alert_cb,
void *cb_context);
ReturnStatus ina226_enableAlert(INA226_Dev *dev, INA226_Event evt);
ePostCode ina226_probe(INA226_Dev *dev, POSTData *postData);
#endif /* INA226_H_ */

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INT_BATTERY_H_
#define INT_BATTERY_H_
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define PWR_INT_BATT_RSNSB 30 //milli ohms
#define PWR_INT_BATT_RSNSI 7 //milli ohms
/* Config parameters for Internal battery charger */
#define PWR_INTBATT_UNDERVOLTAGE_VAL 9000 //milliVolts
#define PWR_INTBATT_OVERVOLTAGE_VAL 12600 //milliVolts
#define PWR_INTBATT_INPUTUNDERVOLATGE_VAL 16200 //milliVolts
#define PWR_INTBATT_INPUTOVERCURRENT_VAL 5000 //milliAmps
#define PWR_INTBATT_LOWBATTERYCURRENT_VAL 100 //milliAmps
#define PWR_INTBATT_INPUTCURRENTLIMIT_VAL 5570 //milliAmps
#endif /* INT_BATTERY_H_ */

View File

@@ -0,0 +1,199 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef LTC4015_H_
#define LTC4015_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/post_frame.h"
#include "drivers/OcGpio.h"
#include "inc/common/i2cbus.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
/* Mask/Enable Register Bits */
#define LTC4015_ALERT_EN_MASK 0xFFFF /* Bits 15-0 are the enable bits(except bit 14) */
#define LTC4015_MSK_MSRV (1 << 15) /* Measurement system results valid */
#define LTC4015_MSK_QCL (1 << 13) /* QCOUNT Low alert */
#define LTC4015_MSK_QCH (1 << 12) /* QCOUNT High alert */
#define LTC4015_MSK_BVL (1 << 11) /* Battery voltage Low alert */
#define LTC4015_MSK_BVH (1 << 10) /* Battery voltage High alert */
#define LTC4015_MSK_IVL (1 << 9) /* Input voltage Low alert */
#define LTC4015_MSK_IVH (1 << 8) /* Input voltage High alert */
#define LTC4015_MSK_SVL (1 << 7) /* System voltage Low alert */
#define LTC4015_MSK_SVH (1 << 6) /* System voltage High alert */
#define LTC4015_MSK_ICH (1 << 5) /* Input current High alert */
#define LTC4015_MSK_BCL (1 << 4) /* Battery current Low alert */
#define LTC4015_MSK_DTH (1 << 3) /* Die temperature High alert */
#define LTC4015_MSK_BSRH (1 << 2) /* BSR High alert */
#define LTC4015_MSK_NTCH (1 << 1) /* NTC ratio High alert */
#define LTC4015_MSK_NTCL (1 << 0) /* NTC ratio Low alert */
#define LTC4015_MSK_BMFA (1 << 1) /* Battery Missing Fault alert */
#define LTC4015_CHARGER_ENABLED (1 << 13)
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
/* Note: There are more chemistry settings that include fixed vs. programmable,
* however they don't matter as much as the overall chemistry grouping for
* selecting the correct conversion factors for the registers
*/
typedef enum LTC4015_Chem {
LTC4015_CHEM_LI_ION,
LTC4015_CHEM_LI_FE_PO4,
LTC4015_CHEM_LEAD_ACID,
} LTC4015_Chem;
typedef enum LTC4015_Event {
LTC4015_EVT_MSRV = LTC4015_MSK_MSRV, /* Measurement system results valid */
LTC4015_EVT_QCL = LTC4015_MSK_QCL, /* QCOUNT Low alert */
LTC4015_EVT_QCH = LTC4015_MSK_QCH, /* QCOUNT High alert */
LTC4015_EVT_BVL = LTC4015_MSK_BVL, /* Battery voltage Low alert */
LTC4015_EVT_BVH = LTC4015_MSK_BVH, /* Battery voltage High alert */
LTC4015_EVT_IVL = LTC4015_MSK_IVL, /* Input voltage Low alert */
LTC4015_EVT_IVH = LTC4015_MSK_IVH, /* Input voltage High alert */
LTC4015_EVT_SVL = LTC4015_MSK_SVL, /* System voltage Low alert */
LTC4015_EVT_SVH = LTC4015_MSK_SVH, /* System voltage High alert */
LTC4015_EVT_ICH = LTC4015_MSK_ICH, /* Input current High alert */
LTC4015_EVT_BCL = LTC4015_MSK_BCL, /* Battery current Low alert */
LTC4015_EVT_DTH = LTC4015_MSK_DTH, /* Die temperature High alert */
LTC4015_EVT_BSRH = LTC4015_MSK_BSRH, /* BSR High alert */
LTC4015_EVT_NTCL = LTC4015_MSK_NTCL, /* NTC ratio High alert */
LTC4015_EVT_NTCH = LTC4015_MSK_NTCH, /* NTC ratio Low alert */
LTC4015_EVT_BMFA = LTC4015_MSK_BMFA, /* Battery Missing Fault alert */
} LTC4015_Event;
typedef void (*LTC4015_CallbackFn) (LTC4015_Event evt, int16_t value,
void *context);
typedef struct LTC4015_HWCfg {
I2C_Dev i2c_dev;
/* TODO: this can be read from the IC itself */
LTC4015_Chem chem; /* Battery chemistry we're controlling (verified during init) */
uint8_t r_snsb; /* Value of SNSB resistor in milli-ohms */
uint8_t r_snsi; /* Value of SNSI resistor in milli-ohms */
/* TODO: this can be read from the IC itself */
uint8_t cellcount; /* Number of cells in battery */
OcGpio_Pin *pin_alert;
} LTC4015_HWCfg;
typedef struct LTC4015_Obj {
LTC4015_CallbackFn alert_cb;
void *cb_context;
} LTC4015_Obj;
typedef struct LTC4015_Dev {
LTC4015_HWCfg cfg;
LTC4015_Obj obj;
} LTC4015_Dev;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
ReturnStatus LTC4015_cfg_icharge(LTC4015_Dev *dev,
uint16_t max_chargeCurrent);
ReturnStatus LTC4015_get_cfg_icharge(LTC4015_Dev *dev,
uint16_t *max_chargeCurrent);
ReturnStatus LTC4015_cfg_vcharge(LTC4015_Dev *dev,
uint16_t charge_voltageLevel);
ReturnStatus LTC4015_get_cfg_vcharge(LTC4015_Dev *dev,
uint16_t *charge_voltageLevel);
ReturnStatus LTC4015_cfg_battery_voltage_low(LTC4015_Dev *dev,
int16_t underVoltage);
ReturnStatus LTC4015_get_cfg_battery_voltage_low(LTC4015_Dev *dev,
int16_t *underVolatage);
ReturnStatus LTC4015_cfg_battery_voltage_high(LTC4015_Dev *dev,
int16_t overVoltage);
ReturnStatus LTC4015_get_cfg_battery_voltage_high(LTC4015_Dev *dev,
int16_t *overVoltage);
ReturnStatus LTC4015_cfg_input_voltage_low(LTC4015_Dev *dev,
int16_t inputUnderVoltage);
ReturnStatus LTC4015_get_cfg_input_voltage_low(LTC4015_Dev *dev,
int16_t *inpUnderVoltage);
ReturnStatus LTC4015_cfg_input_current_high(LTC4015_Dev *dev,
int16_t inputOvercurrent);
ReturnStatus LTC4015_get_cfg_input_current_high(LTC4015_Dev *dev,
int16_t *inpOverCurrent);
ReturnStatus LTC4015_cfg_battery_current_low(LTC4015_Dev *dev,
int16_t lowbattCurrent);
ReturnStatus LTC4015_get_cfg_battery_current_low(LTC4015_Dev *dev,
int16_t *lowbattCurrent);
ReturnStatus LTC4015_cfg_die_temperature_high(LTC4015_Dev *dev,
int16_t dieTemp);
ReturnStatus LTC4015_get_cfg_die_temperature_high(LTC4015_Dev *dev,
int16_t *dieTemp);
ReturnStatus LTC4015_cfg_input_current_limit(LTC4015_Dev *dev,
uint16_t inputCurrentLimit);
ReturnStatus LTC4015_get_cfg_input_current_limit(LTC4015_Dev *dev,
uint16_t *currentLimit);
ReturnStatus LTC4015_get_die_temperature(LTC4015_Dev *dev,
int16_t *dieTemp);
ReturnStatus LTC4015_get_battery_current(LTC4015_Dev *dev,
int16_t *iBatt);
ReturnStatus LTC4015_get_input_current(LTC4015_Dev *dev,
int16_t *iIn);
ReturnStatus LTC4015_get_battery_voltage(LTC4015_Dev *dev,
int16_t *vbat);
ReturnStatus LTC4015_get_input_voltage(LTC4015_Dev *dev,
int16_t *vIn);
ReturnStatus LTC4015_get_system_voltage(LTC4015_Dev *dev,
int16_t *vSys);
ReturnStatus LTC4015_get_icharge_dac(LTC4015_Dev *dev,
int16_t *ichargeDac);
ReturnStatus LTC4015_get_bat_presence(LTC4015_Dev *dev,
bool *present);
ReturnStatus LTC4015_init(LTC4015_Dev *dev);
void LTC4015_setAlertHandler(LTC4015_Dev *dev, LTC4015_CallbackFn alert_cb,
void *cb_context);
ReturnStatus LTC4015_enableLimitAlerts(LTC4015_Dev *dev, uint16_t alert_mask);
ReturnStatus LTC4015_enableChargerStateAlerts(LTC4015_Dev *dev,
uint16_t alert_mask);
ePostCode LTC4015_probe(LTC4015_Dev *dev, POSTData *postData);
#endif /* LTC4015_H_ */

View File

@@ -0,0 +1,169 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef LTC4274_H_
#define LTC4274_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/post_frame.h"
#include "drivers/OcGpio.h"
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
#include <ti/sysbios/gates/GateMutex.h>
/* PSE Configuration */
#define LTC4274_INTERRUPT_MASK 0x00
#define LTC4274_OPERATING_MODE_SET 0x03
#define LTC4274_DETCET_CLASS_ENABLE 0x11
#define LTC4274_MISC_CONF 0xD1
/* PSE operating modes */
#define LTC4274_SHUTDOWN_MODE 0x00
#define LTC4274_MANUAL_MODE 0x01
#define LTC4274_SEMIAUTO_MODE 0x02
#define LTC4274_AUTO_MODE 0x03
#define LTC4274_INTERRUPT_ENABLE 0x80
#define LTC4274_DETECT_ENABLE 0x40
#define LTC4274_FAST_IV 0x20
#define LTC4274_MSD_MASK 0x01
#define LTC4274_HP_ENABLE 0x11
/* POE Device Info */
#define LTC4274_DEV_ID 0x0C
#define LTC4274_ADDRESS 0x2F
#define LTC4274_LTEPOE_90W 0x0E
#define LTC4274_DEVID(x) (x>>3)
#define LTC4274_PWRGD(x) ((x&0x10)>>4)
#define LTC4374_CLASS(x) ((x&0xF0)>>4) /*if MSB is set it specifies LTEPOE++ device*/
#define LTC4374_DETECT(x) ((x&0x07))
#define LTC4274_DETECTION_COMPLETE(x) (x&0x01)
#define LTC4274_CLASSIFICATION_COMPLETE(x) (x&0x10)
typedef enum LTC4274_Event {
LTC4274_EVT_SUPPLY = 1 << 8,
LTC4274_EVT_TSTART = 1 << 7,
LTC4274_EVT_TCUT = 1 << 6,
LTC4274_EVT_CLASS = 1 << 5,
LTC4274_EVT_DETECTION = 1 << 4,
LTC4274_EVT_DISCONNECT = 1 << 3,
LTC4274_EVT_POWERGOOD = 1 << 2,
LTC4274_EVT_POWER_ENABLE = 1 << 1,
LTC4274_EVT_NONE = 1 << 0,
} LTC4274_Event;
typedef enum {
LTC4274_POWERGOOD = 0,
LTC4274_POWERGOOD_NOTOK
} ePSEPowerState;
typedef enum {
LTC4274_DETECT_UNKOWN = 0,
LTC4274_SHORT_CIRCUIT,
LTC4274_CPD_HIGH,
LTC4274_RSIG_LOW,
LTC4274_SIGNATURE_GOOD,
LTC4274_RSIG_TOO_HIGH,
LTC4274_OPEN_CIRCUIT,
LTC4274_DETECT_ERROR
} ePSEDetection;
typedef enum {
LTC4274_CLASSTYPE_UNKOWN = 0x01,
LTC4274_CLASSTYPE_1,
LTC4274_CLASSTYPE_2,
LTC4274_CLASSTYPE_3,
LTC4274_CLASSTYPE_4,
LTC4274_CLASSTYPE_RESERVED,
LTC4274_CLASSTYPE_0,
LTC4274_OVERCURRENT,
LTC4274_LTEPOE_TYPE_52_7W =0x09,
LTC4274_LTEPOE_TYPE_70W =0x0a,
LTC4274_LTEPOE_TYPE_90W=0x0b,
LTC4274_LTEPOE_TYPE_38_7W=0xe,
LTC4274_LTEPOE_RESERVED,
LTC4274_CLASS_ERROR
} ePSEClassType;
typedef enum {
LTC4274_STATE_OK = 0,
LTC4274_STATE_NOTOK
} ePSEState;
typedef enum {
LTC4274_NO_ACTIVE_ALERT = 0x00,
LTC4274_POWER_ENABLE_ALERT = 0x01,
LTC4274_POWERGOOD_ALERT = 0x02,
LTC4274_DISCONNECT_ALERT = 0x04,
LTC4274_DETECTION_ALERT = 0x08,
LTC4274_CLASS_ALERT = 0x10,
LTC4274_TCUT_ALERT = 0x20,
LTC4274_TSTART_ALERT = 0x40,
LTC4274_SUPPLY_ALERT = 0x80
} ePSEAlert;
typedef void (*LTC4274_CallbackFn) (LTC4274_Event evt,
void *context);
typedef struct LTC4274_Cfg {
I2C_Dev i2c_dev;
OcGpio_Pin *pin_evt;
OcGpio_Pin reset_pin;
} LTC4274_Cfg;
typedef struct LTC4274_Obj {
LTC4274_CallbackFn alert_cb;
void *cb_context;
GateMutex_Handle mutex;
} LTC4274_Obj;
typedef struct LTC4274_Dev {
const LTC4274_Cfg cfg;
LTC4274_Obj obj;
} LTC4274_Dev;
ReturnStatus ltc4274_set_cfg_operation_mode(const I2C_Dev *i2c_dev, uint8_t operatingMode);
ReturnStatus ltc4274_get_operation_mode(const I2C_Dev *i2c_dev, uint8_t *operatingMode);
ReturnStatus ltc4274_set_cfg_detect_enable(const I2C_Dev *i2c_dev, uint8_t detectEnable);
ReturnStatus ltc4274_get_detect_enable(const I2C_Dev *i2c_dev, uint8_t *detectVal);
ReturnStatus ltc4274_set_interrupt_mask(const I2C_Dev *i2c_dev, uint8_t interruptMask);
ReturnStatus ltc4274_get_interrupt_mask(const I2C_Dev *i2c_dev, uint8_t *intrMask);
ReturnStatus ltc4274_cfg_interrupt_enable(const I2C_Dev *i2c_dev, bool enable);
ReturnStatus ltc4274_get_interrupt_enable(const I2C_Dev *i2c_dev, uint8_t *interruptEnable);
ReturnStatus ltc4274_set_cfg_pshp_feature(const I2C_Dev *i2c_dev, uint8_t hpEnable);
ReturnStatus ltc4274_get_pshp_feature(const I2C_Dev *i2c_dev, uint8_t *hpEnable);
ReturnStatus ltc4274_get_detection_status(const I2C_Dev *i2c_dev, ePSEDetection *pseDetect);
ReturnStatus ltc4274_get_class_status(const I2C_Dev *i2c_dev, ePSEClassType *pseClass);
ReturnStatus ltc4274_get_powergood_status(const I2C_Dev *i2c_dev, uint8_t *psePwrGood);
void ltc4274_set_alert_handler(LTC4274_Dev *dev, LTC4274_CallbackFn alert_cb, void *cb_context);
ReturnStatus ltc4274_clear_interrupt( const I2C_Dev *i2c_dev,
uint8_t *pwrEvent,
uint8_t *overCurrent,
uint8_t *supply);
ReturnStatus ltc4274_get_interrupt_status(const I2C_Dev *i2c_dev, uint8_t *val);
ReturnStatus ltc4274_debug_write(const I2C_Dev *i2c_dev,
uint8_t reg_address, uint8_t value);
ReturnStatus ltc4274_debug_read(const I2C_Dev *i2c_dev,
uint8_t reg_address, uint8_t *value);
void ltc4274_enable(LTC4274_Dev *dev, uint8_t enableVal);
ReturnStatus ltc4274_get_devid(const I2C_Dev *i2c_dev,
uint8_t *devID);
ReturnStatus ltc4274_detect(const I2C_Dev *i2c_dev,
uint8_t *detect, uint8_t *val);
ePostCode ltc4274_probe(const LTC4274_Dev *i2c_dev, POSTData *postData);
void ltc4274_init(LTC4274_Dev *dev);
void ltc4274_initPSEStateInfo();
void ltc4274_update_stateInfo(const I2C_Dev *i2c_dev);
ReturnStatus ltc4274_reset();
#endif /* LTC4274_H_ */

View File

@@ -0,0 +1,96 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef LTC4295_H_
#define LTC4295_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/post_frame.h"
#include "drivers/OcGpio.h"
#include "inc/common/global_header.h"
#include <ti/sysbios/gates/GateMutex.h>
typedef enum {
LTC4295_STATUS_CLASS = 0x00,
LTC4295_STATUS_POWERGOOD = 0x01,
}eltc4295StatusParamId;
typedef enum {
LTC4295_POWERGOOD = 0,
LTC4295_POWERGOOD_NOTOK
} ePDPowerState;
typedef enum {
LTC4295_CLASSTYPE_UNKOWN = 0,
LTC4295_CLASSTYPE_1,
LTC4295_CLASSTYPE_2,
LTC4295_CLASSTYPE_3,
LTC4295_CLASSTYPE_POEPP
} ePDClassType;
typedef enum {
LTC4295_STATE_OK = 0,
LTC4295_STATE_NOTOK
} ePDState;
typedef enum {
LTC4295_CONNECT_ALERT = 1,
LTC4295_DISCONNECT_ALERT,
LTC4295_INCOMPATIBLE_ALERT
} ePDAlert;
typedef enum {
LTC4295_CONNECT_EVT = 1 << 2, /* PD device Connected. */
LTC4295_DISCONNECT_EVT = 1 << 1, /* PD device removed. */
LTC4295_INCOMPATIBLE_EVT = 1 << 0, /* Incomaptible device */
} LTC4295_Event;
typedef struct __attribute__((packed, aligned(1))) {
uint8_t classStatus;
uint8_t powerGoodStatus;
}tPower_PDStatus;
typedef struct __attribute__((packed, aligned(1))) {
tPower_PDStatus pdStatus;
ePDState state;
ePDAlert pdalert;
}tPower_PDStatus_Info;
typedef struct LTC4295_Cfg {
OcGpio_Pin *pin_evt;
OcGpio_Pin *pin_detect;
} LTC4295_Cfg;
typedef void (*LTC4295_CallbackFn) (LTC4295_Event evt,
void *context);
typedef struct LTC4295_Obj {
LTC4295_CallbackFn alert_cb;
void *cb_context;
GateMutex_Handle mutex;
} LTC4295_Obj;
typedef struct LTC4295A_Dev {
const LTC4295_Cfg cfg;
LTC4295_Obj obj;
} LTC4295_Dev;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
void ltc4295_config(const LTC4295_Dev *dev);
ePostCode ltc4295_probe(const LTC4295_Dev *dev, POSTData *postData);
ReturnStatus ltc4295_init(LTC4295_Dev *dev);
void ltc4295_set_alert_handler(LTC4295_Dev *dev, LTC4295_CallbackFn alert_cb, void *cb_context);
ReturnStatus ltc4295_get_power_good(const LTC4295_Dev *dev, ePDPowerState *val);
ReturnStatus ltc4295_get_class(const LTC4295_Dev *dev, ePDClassType *val);
void ltc4295_update_status(const LTC4295_Dev *dev);
#endif /* LTC4295_H_ */

View File

@@ -0,0 +1,70 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef POWERSOURCE_H_
#define POWERSOURCE_H_
#include "common/inc/global/post_frame.h"
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/Framework.h"
#include "drivers/OcGpio.h"
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
#include <ti/sysbios/gates/GateMutex.h>
typedef enum {
PWR_SRC_EXT = 0,
PWR_SRC_POE,
PWR_SRC_LIION_BATT,
PWR_SRC_MAX
} ePowerSource;
typedef enum {
PWR_SRC_ACTIVE = 0, /* If source is primary source */
PWR_SRC_AVAILABLE, /* If source is available */
PWR_SRC_NON_AVAILABLE /* If source is not connected */
} ePowerSourceState;
typedef struct {
ePowerSource powerSource;
ePowerSourceState state;
} tPowerSource;
typedef struct PWRSRC_Cfg {
OcGpio_Pin pin_dc_present;
OcGpio_Pin pin_poe_prsnt_n;
OcGpio_Pin pin_int_bat_prsnt;
OcGpio_Pin pin_disable_dc_input;
OcGpio_Pin pin_dc_input_fault;
OcGpio_Pin pin_oc_input_present;
OcGpio_Pin pin_power_off;
} PWRSRC_Cfg;
typedef struct PWRSRC_Cfg_Obj {
GateMutex_Handle mutex;
} PWRSRC_Obj;
typedef struct PWRSRC_Dev {
const PWRSRC_Cfg cfg;
PWRSRC_Obj obj;
} PWRSRC_Dev;
typedef enum {
PWR_STAT_EXT_PWR_AVAILABILITY,
PWR_STAT_EXT_PWR_ACTIVE,
PWR_STAT_POE_AVAILABILITY,
PWR_STAT_POE_ACTIVE,
PWR_STAT_BATT_AVAILABILITY,
PWR_STAT_BATT_ACTIVE
} ePower_StatusParamId;
void pwr_source_init(void);
void pwr_get_source_info(PWRSRC_Dev *pwrSrcDev);
#endif /* POWERSOURCE_H_ */

View File

@@ -0,0 +1,116 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef SE98A_H_
#define SE98A_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "common/inc/global/post_frame.h"
#include "common/inc/global/Framework.h"
#include "drivers/OcGpio.h"
#include "inc/common/i2cbus.h"
#include <ti/sysbios/gates/GateMutex.h>
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
typedef enum SE98A_Event {
SE98A_EVT_ACT = 1 << 2, /* Above critical temp */
SE98A_EVT_AAW = 1 << 1, /* Above alarm window */
SE98A_EVT_BAW = 1 << 0, /* Below alarm window */
} SE98A_Event;
typedef enum
{
CONF_TEMP_SE98A_LOW_LIMIT_REG = 1,
CONF_TEMP_SE98A_HIGH_LIMIT_REG,
CONF_TEMP_SE98A_CRITICAL_LIMIT_REG
}eTempSensor_ConfigParamsId;
typedef void (*SE98A_CallbackFn) (SE98A_Event evt, int8_t temperature,
void *context);
typedef struct SE98A_Cfg {
I2C_Dev dev;
OcGpio_Pin *pin_evt;
} SE98A_Cfg;
typedef struct SE98A_Obj {
SE98A_CallbackFn alert_cb;
void *cb_context;
GateMutex_Handle mutex;
} SE98A_Obj;
typedef struct SE98A_Dev {
const SE98A_Cfg cfg;
SE98A_Obj obj;
} SE98A_Dev;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
/*! Initializes an SE98A device
* @param dev Pointer to the device struct containing hw config and object data
* @return RETURN_OK on success, error code on failure
*/
ReturnStatus se98a_init(SE98A_Dev *dev);
/*! Registers a callback function to process alerts from the sensor
* @param dev Device struct pointer
* @param alert_db Function to call when alert is triggered
* @param cb_context Pointer to pass to callback (optional)
*/
void se98a_set_alert_handler(SE98A_Dev *dev, SE98A_CallbackFn alert_cb,
void *cb_context);
/*! Enables the alert output pin on the SE98A
* @param dev Device struct pointer
* @return RETURN_OK on success, error code on failure
*/
ReturnStatus se98a_enable_alerts(SE98A_Dev *dev);
/* TODO: this is for legacy support for how subsystems currently perform
* POST (probe device, then init) - I propose that this should all be
* in a single function */
/*! Tests the SE98A device and verifies that the driver supports it
* @param dev Device struct pointer, Post data struct
* @return POST_DEV_FOUND on success, error code on failure
*/
ePostCode se98a_probe(SE98A_Dev *dev, POSTData *postData);
/*! Sets one of the 3 alert thresholds on the device
* @param dev Device struct pointer
* @param limitToConfig Which of the 3 limits to configure
* @param tempLimitValue The temperature to set the threshold to
* @return RETURN_OK on success, error code on failure
*/
ReturnStatus se98a_set_limit(SE98A_Dev *dev,
eTempSensor_ConfigParamsId limitToConfig,
int8_t tempLimitValue);
/*! Reads one of the 3 alert thresholds on the device
* @param dev Device struct pointer
* @param limitToConfig Which of the 3 limits to read
* @param tempLimitValue Outparam containing the returned threshold
* @return RETURN_OK on success, error code on failure
*/
ReturnStatus se98a_get_limit(SE98A_Dev *dev,
eTempSensor_ConfigParamsId limitToConfig,
int8_t* tempLimitValue);
/*! Reads the current temperature from the sensor
* @param dev Device struct pointer
* @param tempValue Outval containing the measured temperature
* @return RETURN_OK on success, error code on failure
*/
ReturnStatus se98a_read(SE98A_Dev *dev, int8_t *tempValue);
#endif /* SE98A_H_ */

View File

@@ -0,0 +1,141 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef SX1509_H_
#define SX1509_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
/* Oscillator frequency source */
#define SX1509_EXTERNAL_CLOCK 1
#define SX1509_INTERNAL_CLOCK_2MHZ 2
/* OSCIO pin function */
#define SX1509_CLOCK_OSC_IN 0
#define SX1509_CLOCK_OSC_OUT 1
/* IO pin definitions */
#define SX1509_IO_PIN_0 0x0001
#define SX1509_IO_PIN_1 0x0002
#define SX1509_IO_PIN_2 0x0004
#define SX1509_IO_PIN_3 0x0008
#define SX1509_IO_PIN_4 0x0010
#define SX1509_IO_PIN_5 0x0020
#define SX1509_IO_PIN_6 0x0040
#define SX1509_IO_PIN_7 0x0080
#define SX1509_IO_PIN_8 0x0001
#define SX1509_IO_PIN_9 0x0002
#define SX1509_IO_PIN_10 0x0004
#define SX1509_IO_PIN_11 0x0008
#define SX1509_IO_PIN_12 0x0010
#define SX1509_IO_PIN_13 0x0020
#define SX1509_IO_PIN_14 0x0040
#define SX1509_IO_PIN_15 0x0080
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
/* Enumeration of SX1509 register types */
typedef enum {
SX1509_REG_A = 0,
SX1509_REG_B,
SX1509_REG_AB
} sx1509RegType;
typedef enum {
SX1509_EDGE_SENSE_REG_LOW = 0,
SX1509_EDGE_SENSE_REG_HIGH,
SX1509_EDGE_SENSE_REG_LOW_HIGH
} sx1509EdgeSenseRegType;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
ReturnStatus ioexp_led_get_data(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t *regValue);
ReturnStatus ioexp_led_set_data(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t regValue1,
uint8_t regValue2);
ReturnStatus ioexp_led_set_on_time(const I2C_Dev *i2c_dev,
uint8_t index,
uint8_t tOnRegValue);
ReturnStatus ioexp_led_set_off_time(const I2C_Dev *i2c_dev,
uint8_t index,
uint8_t tOffRegValue);
ReturnStatus ioexp_led_software_reset(const I2C_Dev *i2c_dev);
ReturnStatus ioexp_led_config_inputbuffer(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t inputBuffRegValue1,
uint8_t inputBuffRegValue2);
ReturnStatus ioexp_led_config_pullup(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t pullUpRegValue1,
uint8_t pullUpRegValue2);
ReturnStatus ioexp_led_config_pulldown(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t pullDownRegValue1,
uint8_t pullDownRegValue2);
ReturnStatus ioexp_led_config_opendrain(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t openDrainRegValue1,
uint8_t openDrainRegValue2);
ReturnStatus ioexp_led_config_data_direction(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t directionRegValue1,
uint8_t directionRegValue2);
ReturnStatus ioexp_led_config_polarity(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t polarityRegValue1,
uint8_t polarityRegValue2);
ReturnStatus ioexp_led_config_clock(const I2C_Dev *i2c_dev,
uint8_t oscSource,
uint8_t oscPin);
ReturnStatus ioexp_led_config_misc(const I2C_Dev *i2c_dev,
uint8_t regValue);
ReturnStatus ioexp_led_enable_leddriver(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t ledEnableRegValue1,
uint8_t ledEnableRegValue2);
ReturnStatus ioexp_led_read_testregister_1(const I2C_Dev *i2c_dev,
uint8_t *regValue);
ReturnStatus ioexp_led_config_interrupt(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t interruptMaskRegValue1,
uint8_t interruptMaskRegValue2);
ReturnStatus ioexp_led_config_edge_sense_A(const I2C_Dev *i2c_dev,
sx1509EdgeSenseRegType regType,
uint8_t edgeSenseLowARegValue,
uint8_t edgeSenseHighARegValue);
ReturnStatus ioexp_led_config_edge_sense_A(const I2C_Dev *i2c_dev,
sx1509EdgeSenseRegType regType,
uint8_t edgeSenseLowBRegValue,
uint8_t edgeSenseHighBRegValue);
ReturnStatus ioexp_led_config_edge_sense_B(const I2C_Dev *i2c_dev,
sx1509EdgeSenseRegType regType,
uint8_t edgeSenseLowBRegValue,
uint8_t edgeSenseHighBRegValue);
ReturnStatus ioexp_led_config_debounce_time(const I2C_Dev *i2c_dev,
uint8_t debounceTime);
ReturnStatus ioexp_led_enable_debounce(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t debounceEnableRegValue1,
uint8_t debounceEnableRegValue2);
ReturnStatus ioexp_led_get_interrupt_source(const I2C_Dev *i2c_dev,
uint16_t *intPins);
ReturnStatus ioexp_led_clear_interrupt_source(const I2C_Dev *i2c_dev);
#endif /* SX1509_H_ */

View File

@@ -0,0 +1,53 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef UARTDMA_H_
#define UARTDMA_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/utils/util.h"
/*****************************************************************************
* MACROS DEFINITION
*****************************************************************************/
#define OCUARTDMA_TASK_PRIORITY 5
//#define OCUARTDMA_TASK_PRIORITY 7
#define OCUARTDMA_TASK_STACK_SIZE 1024
#define OCUARTDMATX_TASK_PRIORITY 7
#define OCUARTDMATX_TASK_STACK_SIZE 1024
#define UART_TXBUF_SIZE OCMP_FRAME_TOTAL_LENGTH
#define UART_RXBUF_SIZE OCMP_FRAME_TOTAL_LENGTH
/*****************************************************************************
* HANDLE DECLARATIONS
*****************************************************************************/
extern Semaphore_Handle semUARTTX;
extern Queue_Handle uartTxMsgQueue;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
void uDMAIntHandler(void);
void uDMAErrorHandler(void);
void UART4IntHandler(void);
void resetUARTDMA(void);
void ConfigureUART(void);
void InitUART4Transfer(void);
void dataTransfertoProc(char *buffer, int size);
void uartdma_init(void);
void uartDMAinterface_init(void);
void uartdma_tx_taskinit(void);
void uartdma_rx_createtask(void);
void uartdma_tx_createtask(void);
#endif /* UARTDMA_H_ */

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef HCI_H_
#define HCI_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "drivers/OcGpio.h"
#include "inc/subsystem/hci/hci_buzzer.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define HCI_TASK_PRIORITY 6
#define HCI_TASK_STACK_SIZE 1024
#define HCI_LED_TEMP_SENSOR_ADDR 0x1A
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
/* Subsystem config */
typedef struct Hci_Cfg {
HciBuzzer_Cfg buzzer;
} Hci_Cfg;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
bool HCI_Init(void *driver, void *return_buf);
#endif /* HCI_H_ */

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _HCI_BUZZER_H
#define _HCI_BUZZER_H
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "drivers/OcGpio.h"
#include "inc/common/global_header.h"
#include <stdint.h>
/*****************************************************************************
* STRUCT/ENUM DEFINITIONS
*****************************************************************************/
/* Subsystem config */
typedef struct HciBuzzer_Cfg {
OcGpio_Pin pin_en;
} HciBuzzer_Cfg;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
ReturnStatus HciBuzzer_init(void);
ReturnStatus hci_buzzer_beep(uint8_t buzzCount);
#endif /* _HCI_BUZZER_H */

View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef POWER_H_
#define POWER_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/devices/ltc4015.h"
#include "inc/devices/ltc4274.h"
#include "inc/devices/ltc4295.h"
#include "inc/devices/powerSource.h"
#include "inc/devices/se98a.h"
bool power_Init(void *driver, void *returnValue);
bool psuCore_pre_init(void *driver, void *returnValue);
#endif

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef WATCHDOG_H_
#define WATCHDOG_H_
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define WATCHDOG_TASK_STACK_SIZE 1024
#define WATCHDOG_TASK_PRIORITY 2
#endif /* WATCHDOG_H_ */

View File

@@ -0,0 +1,65 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef INC_UTILS_OCMP_UTIL_H_
#define INC_UTILS_OCMP_UTIL_H_
#include "common/inc/global/ocmp_frame.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/*****************************************************************************
** FUNCTION NAME : OCMP_mallocFrame
**
** DESCRIPTION : Allocates memory for OCMP packets.
**
** ARGUMENTS : length
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame * OCMP_mallocFrame(uint16_t len);
/*****************************************************************************
** FUNCTION NAME : create_ocmp_msg_frame
**
** DESCRIPTION : Create a OCMP message.
**
** ARGUMENTS : None
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame* create_ocmp_msg_frame(OCMPSubsystem subSystem,
OCMPMsgType msgtype,
OCMPActionType actionType,
uint8_t componentId,
uint16_t parameters,
uint8_t payloadSize);
/*****************************************************************************
** FUNCTION NAME : create_ocmp_alert_from_Evt
**
** DESCRIPTION : Create the OCMP Alert frame from the Event message.
**
** ARGUMENTS : OCMPMessageFrame to be used to create Alert,
** ComponentId,
** ParemeterID
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame* create_ocmp_alert_from_Evt(OCMPMessageFrame* ocmpEventMsg,
uint8_t componentId,
uint16_t parameters );
#endif /* INC_UTILS_OCMP_UTIL_H_ */

View File

@@ -0,0 +1,207 @@
/*******************************************************************************
Filename: util.h
Revised: $Date: 2015-07-07 13:30:52 -0700 (Tue, 07 Jul 2015) $
Revision: $Revision: 44319 $
Description: This file contains function declarations common to CC26xx
TIRTOS Applications.
Copyright 2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED <20>AS IS<49> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
#ifndef UTIL_H
#define UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Semaphore.h>
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
typedef struct
{
uint16_t event; // Event type.
uint8_t state; // Event state;
}appEvtHdr_t;
/*********************************************************************
* MACROS
*/
/*********************************************************************
* API FUNCTIONS
*/
/*********************************************************************
* @fn Util_constructClock
*
* @brief Initialize a TIRTOS Clock instance.
*
* @param pClock - pointer to clock instance structure.
* @param clockCB - callback function upon clock expiration.
* @param clockDuration - longevity of clock timer in milliseconds
* @param clockPeriod - duration of a periodic clock, used continuously
* after clockDuration expires.
* @param startFlag - TRUE to start immediately, FALSE to wait.
* @param arg - argument passed to callback function.
*
* @return Clock_Handle - a handle to the clock instance.
*/
Clock_Handle Util_constructClock(Clock_Struct *pClock,
Clock_FuncPtr clockCB,
uint32_t clockDuration,
uint32_t clockPeriod,
uint8_t startFlag,
UArg arg);
/*********************************************************************
* @fn Util_startClock
*
* @brief Start a clock.
*
* @param pClock - pointer to clock struct
*
* @return none
*/
void Util_startClock(Clock_Struct *pClock);
/*********************************************************************
* @fn Util_setClockTimeout
*
* @brief Restart a clock by changing the timeout.
*
* @param pClock - pointer to clock struct
* @param clockTimeout - longevity of clock timer in milliseconds
*
* @return none
*/
void Util_restartClock(Clock_Struct *pClock, uint32_t clockTimeout);
/*********************************************************************
* @fn Util_isActive
*
* @brief Determine if a clock is currently active.
*
* @param pClock - pointer to clock struct
*
* @return TRUE or FALSE
*/
bool Util_isActive(Clock_Struct *pClock);
/*********************************************************************
* @fn Util_stopClock
*
* @brief Stop a clock.
*
* @param pClock - pointer to clock struct
*
* @return none
*/
void Util_stopClock(Clock_Struct *pClock);
/*********************************************************************
* @fn Util_rescheduleClock
*
* @brief Reschedule a clock by changing the timeout and period values.
*
* @param pClock - pointer to clock struct
* @param clockPeriod - longevity of clock timer in milliseconds
* @return none
*/
void Util_rescheduleClock(Clock_Struct *pClock, uint32_t clockPeriod);
/*********************************************************************
* @fn Util_constructQueue
*
* @brief Initialize an RTOS queue to hold messages from profile to be
* processed.
*
* @param pQueue - pointer to queue instance structure.
*
* @return A queue handle.
*/
Queue_Handle Util_constructQueue(Queue_Struct *pQueue);
/*********************************************************************
* @fn Util_enqueueMsg
*
* @brief Creates a queue node and puts the node in RTOS queue.
*
* @param msgQueue - queue handle.
*
* @param sem - the thread's event processing semaphore that this queue is
* associated with.
*
* @param pMsg - pointer to message to be queued
*
* @return TRUE if message was queued, FALSE otherwise.
*/
uint8_t Util_enqueueMsg(Queue_Handle msgQueue, Semaphore_Handle sem, uint8_t *pMsg);
/*********************************************************************
* @fn Util_dequeueMsg
*
* @brief Dequeues the message from the RTOS queue.
*
* @param msgQueue - queue handle.
*
* @return pointer to dequeued message, NULL otherwise.
*/
uint8_t *Util_dequeueMsg(Queue_Handle msgQueue);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* UTIL_H */

View File

@@ -0,0 +1,24 @@
#File used to help "Clean Project" in CCS completely clean the kernel files
CFG_SRCDIR = ../src
ifneq (,$(findstring :,$(WINDIR)$(windir)$(COMSPEC)$(comspec)))
# if Windows, use copy to touch file dates
TOUCH = copy /b $(subst /,\,$@)+,, $(subst /,\,$@)
else
TOUCH = touch $@
endif
# include Config generated top-level makefile
-include $(CFG_SRCDIR)/makefile.libs
ifneq (clean,$(MAKECMDGOALS))
# ensure this file is reloaded when .cfg files change but after config runs
$(CFG_SRCDIR)/makefile.libs: $(GEN_OPTS) $(CFG_SRCS)
-@$(if $(wildcard $@),$(TOUCH),:)
endif
#add generated makefile to list of files to delete during a clean
GEN_MISC_FILES__QUOTED += "$(CFG_SRCDIR)/makefile.libs"
#add generated source dir to list of directories to delete during a clean
#GEN_MISC_DIRS__QTD += "$(CFG_SRCDIR)"

View File

@@ -0,0 +1,832 @@
/*******************************************************************************
Filename: OC_CONNECT1.c
Revised: $Date: 2015-06-02 11:18:40 -0700 (Tue, 02 Jun 2015) $
Revision: $Revision: 43957 $
Description: This file contains utility functions.
Copyright 2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED <20>AS IS<49> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include <inc/global/OC_CONNECT1.h>
#include <inc/hw_ints.h>
#include <inc/hw_memmap.h>
#include <inc/hw_types.h>
#include <inc/hw_gpio.h>
#include <stdint.h>
#include <stdbool.h>
#include <ti/sysbios/family/arm/m3/Hwi.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <driverlib/flash.h>
#include <driverlib/gpio.h>
#include <driverlib/i2c.h>
#include <driverlib/pin_map.h>
#include <driverlib/sysctl.h>
#include <driverlib/uart.h>
#include <driverlib/udma.h>
#ifndef TI_DRIVERS_UART_DMA
#define TI_DRIVERS_UART_DMA 0
#endif
#ifndef TI_EXAMPLES_PPP
#define TI_EXAMPLES_PPP 0
#else
/* prototype for NIMU init function */
extern int USBSerialPPP_NIMUInit();
#endif
#include <ti/drivers/uart/UARTTiva.h>
typedef enum DK_TM4C129X_UARTName {
DK_TM4C129X_UART0 = 0,
DK_TM4C129X_UART1,
DK_TM4C129X_UART2,
DK_TM4C129X_UART3,
DK_TM4C129X_UART4,
DK_TM4C129X_UARTCOUNT
} DK_TM4C129X_UARTName;
UARTTiva_Object uartTivaObjects[DK_TM4C129X_UARTCOUNT];
unsigned char uartTivaRingBuffer[DK_TM4C129X_UARTCOUNT][32];
const UARTTiva_HWAttrs uartTivaHWAttrs[DK_TM4C129X_UARTCOUNT] = {
{
.baseAddr = UART0_BASE,
.intNum = INT_UART0,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[0],
.ringBufSize = sizeof(uartTivaRingBuffer[0])
},
{
.baseAddr = UART1_BASE,
.intNum = INT_UART1,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[1],
.ringBufSize = sizeof(uartTivaRingBuffer[1])
},
{
.baseAddr = UART2_BASE,
.intNum = INT_UART2,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[2],
.ringBufSize = sizeof(uartTivaRingBuffer[2])
},
{
.baseAddr = UART4_BASE,
.intNum = INT_UART3,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[3],
.ringBufSize = sizeof(uartTivaRingBuffer[3])
},
{
.baseAddr = UART4_BASE,
.intNum = INT_UART4,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[4],
.ringBufSize = sizeof(uartTivaRingBuffer[4])
},
{
.baseAddr = UART5_BASE,
.intNum = INT_UART5,
.intPriority = (~0),
.flowControl = UART_FLOWCONTROL_NONE,
.ringBufPtr = uartTivaRingBuffer[5],
.ringBufSize = sizeof(uartTivaRingBuffer[5])
}
};
const UART_Config UART_config[] = {
{
.fxnTablePtr = &UARTTiva_fxnTable,
.object = &uartTivaObjects[0],
.hwAttrs = &uartTivaHWAttrs[0]
},
{
.fxnTablePtr = &UARTTiva_fxnTable,
.object = &uartTivaObjects[1],
.hwAttrs = &uartTivaHWAttrs[1]
},
{
.fxnTablePtr = &UARTTiva_fxnTable,
.object = &uartTivaObjects[2],
.hwAttrs = &uartTivaHWAttrs[2]
},
{
.fxnTablePtr = &UARTTiva_fxnTable,
.object = &uartTivaObjects[3],
.hwAttrs = &uartTivaHWAttrs[3]
},
{
.fxnTablePtr = &UARTTiva_fxnTable,
.object = &uartTivaObjects[4],
.hwAttrs = &uartTivaHWAttrs[4]
},
{NULL, NULL, NULL}
};
#include "common/inc/global/ocmp_frame.h"
#include "inc/common/global_header.h"
char input[64];
UART_Handle uart;
Void echoFxn(UArg arg0, UArg arg1)
{
// char input;
UART_Params uartParams;
const char echoPrompt[] = "\fEchoing characters:\r\n";
OC_CONNECT1_initUART();
/* Create a UART with data processing off. */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudRate = 115200;
uart = UART_open(DK_TM4C129X_UART4, &uartParams);
if (uart == NULL) {
System_abort("Error opening the UART");
}
// UART_write(uart, echoPrompt, sizeof(echoPrompt));
/* Loop forever echoing */
// input = '1';
while (1) {
UART_read(uart, &input, 64);
uint8_t * pWrite = NULL;
pWrite = (uint8_t *) malloc(
sizeof(OCMPMessageFrame) + OCMP_FRAME_MSG_LENGTH);
if (pWrite != NULL) {
memset(pWrite, '\0', 64);
memcpy(pWrite, input, 64);
#if 1
uint8_t i = 0;
LOGGER_DEBUG("UARTDMACTR:INFO:: UART RX BUFFER:\n");
for( i = 0; i < 64; i++)
{
LOGGER_DEBUG("0x%x ",pWrite[i]);
}
LOGGER_DEBUG("\n");
}
#endif
// UART_write(uart, &input, 1);
}
}
/*
* =============================== DMA ===============================
*/
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(dmaControlTable, 1024)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=1024
#elif defined(__GNUC__)
__attribute__ ((aligned (1024)))
#endif
static tDMAControlTable dmaControlTable[32];
static bool dmaInitialized = false;
/* Hwi_Struct used in the initDMA Hwi_construct call */
static Hwi_Struct dmaHwiStruct;
/* Hwi_Struct used in the usbBusFault Hwi_construct call */
static Hwi_Struct usbBusFaultHwiStruct;
/*
* ======== dmaErrorHwi ========
*/
static void dmaErrorHwi(UArg arg)
{
System_printf("DMA error code: %d\n", uDMAErrorStatusGet());
uDMAErrorStatusClear();
System_abort("DMA error!!");
}
/*
* ======== OC_CONNECT1_initDMA ========
*/
void OC_CONNECT1_initDMA(void)
{
Error_Block eb;
Hwi_Params hwiParams;
if (!dmaInitialized) {
Error_init(&eb);
Hwi_Params_init(&hwiParams);
Hwi_construct(&(dmaHwiStruct), INT_UDMAERR, dmaErrorHwi, &hwiParams,
&eb);
if (Error_check(&eb)) {
System_abort("Couldn't construct DMA error hwi");
}
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
uDMAEnable();
uDMAControlBaseSet(dmaControlTable);
dmaInitialized = true;
}
}
/*
* =============================== General ===============================
*/
/*
* ======== OC_CONNECT1_initGeneral ========
*/
void OC_CONNECT1_initGeneral(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
}
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(EMAC_config, ".const:EMAC_config")
#pragma DATA_SECTION(emacHWAttrs, ".const:emacHWAttrs")
#pragma DATA_SECTION(NIMUDeviceTable, ".data:NIMUDeviceTable")
#endif
#include <ti/drivers/EMAC.h>
#include <ti/drivers/emac/EMACSnow.h>
/*
* Required by the Networking Stack (NDK). This array must be NULL terminated.
* This can be removed if NDK is not used.
* Double curly braces are needed to avoid GCC bug #944572
* https://bugs.launchpad.net/gcc-linaro/+bug/944572
*/
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[2] = {
{
#if TI_EXAMPLES_PPP
/* Use PPP driver for PPP example only */
.init = USBSerialPPP_NIMUInit
#else
/* Default: use Ethernet driver */
.init = EMACSnow_NIMUInit
#endif
},
{ NULL }
};
EMACSnow_Object emacObjects[OC_CONNECT1_EMACCOUNT];
/*
* EMAC configuration structure
* Set user/company specific MAC octates. The following sets the address
* to ff-ff-ff-ff-ff-ff. Users need to change this to make the label on
* their boards.
*/
unsigned char macAddress[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
const EMACSnow_HWAttrs emacHWAttrs[OC_CONNECT1_EMACCOUNT] = {
[OC_CONNECT1_EMAC0] = {
.baseAddr = EMAC0_BASE,
// .intNum = INT_EMAC0,
.intPriority = (~0),
.macAddress = macAddress
}
};
const EMAC_Config EMAC_config[] = {
[OC_CONNECT1_EMAC0] = {
.fxnTablePtr = &EMACSnow_fxnTable,
.object = &emacObjects[OC_CONNECT1_EMAC0],
.hwAttrs = &emacHWAttrs[OC_CONNECT1_EMAC0]
},
{ NULL, NULL, NULL }
};
/*
* ======== OC_CONNECT1_initEMAC ========
*/
void OC_CONNECT1_initEMAC(void)
{
uint32_t ulUser0, ulUser1;
/* Get the MAC address */
FlashUserGet(&ulUser0, &ulUser1);
if ((ulUser0 != 0xffffffff) && (ulUser1 != 0xffffffff)) {
System_printf("Using MAC address in flash\n");
/*
* Convert the 24/24 split MAC address from NV ram into a 32/16 split
* MAC address needed to program the hardware registers, then program
* the MAC address into the Ethernet Controller registers.
*/
macAddress[0] = ((ulUser0 >> 0) & 0xff);
macAddress[1] = ((ulUser0 >> 8) & 0xff);
macAddress[2] = ((ulUser0 >> 16) & 0xff);
macAddress[3] = ((ulUser1 >> 0) & 0xff);
macAddress[4] = ((ulUser1 >> 8) & 0xff);
macAddress[5] = ((ulUser1 >> 16) & 0xff);
} else if (macAddress[0] == 0xff && macAddress[1] == 0xff
&& macAddress[2] == 0xff && macAddress[3] == 0xff
&& macAddress[4] == 0xff && macAddress[5] == 0xff) {
System_printf("Change the macAddress variable to valid Mac address");
}
// GPIOPinConfigure(GPIO_PF0_EN0LED0); /* OC_CONNECT1_USR_D3 */
// GPIOPinConfigure(GPIO_PF4_EN0LED1); /* OC_CONNECT1_USR_D4 */
// GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4);
/* Once EMAC_init is called, EMAC_config cannot be changed */
EMAC_init();
}
/*
* =============================== GPIO ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(GPIOTiva_config, ".const:GPIOTiva_config")
#endif
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOTiva.h>
extern GPIO_PinConfig gpioPinConfigs[];
/*
* Array of Pin configurations
* NOTE: The order of the pin configurations must coincide with what was
* defined in OC_CONNECT1.h
* NOTE: Pins not used for interrupts should be placed at the end of the
* array. Callback entries can be omitted from callbacks array to
* reduce memory usage.
*/
GPIO_PinConfig gpioPinConfigs[OC_EC_GPIOCOUNT] = {
[OC_EC_PSE_INT] =
GPIOTiva_PA_0 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING,
[OC_EC_nPSE_RESET] =
GPIOTiva_PA_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
[OC_EC_WD_INPUT] =
GPIOTiva_PA_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_HIGH,
[OC_EC_ENABLE_OC_INPUT] =
GPIOTiva_PA_3 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
[OC_EC_POWER_OFF] =
GPIOTiva_PA_4 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
[OC_EC_DISABLE_DC_INPUT] =
GPIOTiva_PB_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
[OC_EC_IOEXP_INT] =
GPIOTiva_PB_1 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING,
[OC_EC_ENABLE_PASSIVE_POE] =
GPIOTiva_PB_4 | GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW,
[OC_EC_CS_ALERT_24V_20V] =
GPIOTiva_PB_5 | GPIO_CFG_IN_PU ,
[OC_EC_EN_INT_BATT_PWR] =
GPIOTiva_PC_7 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_BOTH_EDGES,
[OC_EC_DC_INPUT_FAULT] =
GPIOTiva_PC_6 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_BOTH_EDGES,
[OC_EC_UART_TX] =
GPIOTiva_PC_5 | GPIO_CFG_OUTPUT,
[OC_EC_CS_ALERT] =
GPIOTiva_PD_0 | GPIO_CFG_INPUT ,
[OC_EC_DC_IN_PRESENT] =
GPIOTiva_PD_1 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_FALLING,
[OC_EC_CS_ALERT_12V_GBC] =
GPIOTiva_PD_2 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_FALLING,
[OC_EC_CS_ALERT_12V_BB] =
GPIOTiva_PD_3 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_BOTH_EDGES,
[OC_EC_CS_ALERT_12V_FE] =
GPIOTiva_PD_4 | GPIO_CFG_IN_PU ,
[OC_EC_PGOOD_5V0] =
GPIOTiva_PD_5 | GPIO_CFG_IN_NOPULL,
[OC_EC_PGOOD_12V0] =
GPIOTiva_PD_6 | GPIO_CFG_INPUT,
[OC_EC_IVINMON] =
GPIOTiva_PE_0 | GPIO_CFG_IN_NOPULL,
[OC_EC_ISMON] =
GPIOTiva_PE_1 | GPIO_CFG_IN_NOPULL,
[OC_EC_CHARGER_ALERT] =
GPIOTiva_PE_2 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_FALLING,
[OC_EC_PGOOD_BOOST_CONV_BATT] =
GPIOTiva_PE_3 | GPIO_CFG_IN_NOPULL ,
[OC_EC_TIVA_GPIO1] =
GPIOTiva_PF_0 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_BOTH_EDGES,
[OC_EC_TIVA_GPIO2] =
GPIOTiva_PF_1 | GPIO_CFG_IN_NOPULL | GPIO_CFG_IN_INT_FALLING,
[OC_EC_BUZZER_ON] =
GPIOTiva_PF_2 | GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW,
[OC_EC_PD_T2P] =
GPIOTiva_PF_3 | GPIO_CFG_INPUT ,
[OC_EC_TEMP_EVENT] =
GPIOTiva_PF_4 | GPIO_CFG_IN_NOPULL,
[OC_EC_OC_IN_PRESENT] =
GPIOTiva_PG_4 | GPIO_CFG_INPUT,
[OC_EC_POE_IN_PRESENT] =
GPIOTiva_PG_5 | GPIO_CFG_INPUT,
};
/*
* Array of callback function pointers
* NOTE: The order of the pin configurations must coincide with what was
* defined in OC_CONNECT1.h
* NOTE: Pins not used for interrupts can be omitted from callbacks array to
* reduce memory usage (if placed at end of gpioPinConfigs array).
* We have lots of RAM right now, so just set it to full size of
* GPIO array
*/
GPIO_CallbackFxn gpioCallbackFunctions[OC_EC_GPIOCOUNT] = { };
/* The device-specific GPIO_config structure */
const GPIOTiva_Config GPIOTiva_config = {
.pinConfigs = (GPIO_PinConfig *) gpioPinConfigs,
.callbacks = (GPIO_CallbackFxn *) gpioCallbackFunctions,
.numberOfPinConfigs = sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
.numberOfCallbacks = sizeof(gpioCallbackFunctions) /
sizeof(GPIO_CallbackFxn),
.intPriority = (~0)
};
/* Below is a sample system config demonstrating how we can configure our
* subsystems. It will effectively replace board.h. I've kept the header
* includes here since I'm thinking we'll want to move this out at some point
*/
#include "common/inc/global/ocmp_frame.h"
#include "drivers/GpioSX1509.h"
#include "drivers/GpioNative.h"
OcGpio_Port ec_io = {
.fn_table = &GpioNative_fnTable,
};
OcGpio_Port pwr_io = {
.fn_table = &GpioSX1509_fnTable,
.cfg = &(SX1509_Cfg) {
.i2c_dev = { OC_CONNECT1_I2C5, 0x3E },
// .pin_irq = &(OcGpio_Pin){ &ec_io, OC_EC_IOEXP_INT},
},
.object_data = &(SX1509_Obj){},
};
/*
* ======== OC_CONNECT1_initGPIO ========
*/
void OC_CONNECT1_initGPIO(void)
{
/* Initialize peripheral and pins */
GPIO_init();
GpioNative_init();
}
/*
* =============================== I2C ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(I2C_config, ".const:I2C_config")
#pragma DATA_SECTION(i2cTivaHWAttrs, ".const:i2cTivaHWAttrs")
#endif
#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CTiva.h>
I2CTiva_Object i2cTivaObjects[OC_CONNECT1_I2CCOUNT];
const I2CTiva_HWAttrs i2cTivaHWAttrs[OC_CONNECT1_I2CCOUNT] = {
[OC_CONNECT1_I2C0] = {
.baseAddr = I2C0_BASE,
.intNum = INT_I2C0,
.intPriority = (~0)
},
[OC_CONNECT1_I2C1] = {
.baseAddr = I2C1_BASE,
.intNum = INT_I2C1,
.intPriority = (~0)
},
[OC_CONNECT1_I2C2] = {
.baseAddr = I2C2_BASE,
.intNum = INT_I2C2,
.intPriority = (~0)
},
[OC_CONNECT1_I2C3] = {
.baseAddr = I2C3_BASE,
.intNum = INT_I2C3,
.intPriority = (~0)
},
[OC_CONNECT1_I2C4] = {
.baseAddr = I2C4_BASE,
.intNum = INT_I2C4,
.intPriority = (~0)
},
[OC_CONNECT1_I2C5] = {
.baseAddr = I2C5_BASE,
.intNum = INT_I2C5,
.intPriority = (~0)
},
};
const I2C_Config I2C_config[] = {
[OC_CONNECT1_I2C0] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C0],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C0]
},
[OC_CONNECT1_I2C1] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C1],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C1]
},
[OC_CONNECT1_I2C2] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C2],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C2]
},
[OC_CONNECT1_I2C3] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C3],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C3]
},
[OC_CONNECT1_I2C4] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C4],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C4]
},
[OC_CONNECT1_I2C5] = {
.fxnTablePtr = &I2CTiva_fxnTable,
.object = &i2cTivaObjects[OC_CONNECT1_I2C5],
.hwAttrs = &i2cTivaHWAttrs[OC_CONNECT1_I2C5]
},
{ NULL, NULL, NULL }
};
/*
* ======== OC_CONNECT1_initI2C ========
*/
void OC_CONNECT1_initI2C(void)
{
//Remove I2C0 PWR2
/* I2C0 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
/* I2C1 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PA6_I2C1SCL);
GPIOPinConfigure(GPIO_PA7_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
/* I2C2 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PE4_I2C2SCL);
GPIOPinConfigure(GPIO_PE5_I2C2SDA);
GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4);
GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5);
/* I2C3 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PG0_I2C3SCL);
GPIOPinConfigure(GPIO_PG1_I2C3SDA);
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
/* I2C4 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C4);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PG2_I2C4SCL);
GPIOPinConfigure(GPIO_PG3_I2C4SDA);
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_2);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_3);
/* I2C5 Init */
/* Enable the peripheral */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C5);
/* Configure the appropriate pins to be I2C instead of GPIO. */
GPIOPinConfigure(GPIO_PB6_I2C5SCL);
GPIOPinConfigure(GPIO_PB7_I2C5SDA);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_7);
I2C_init();
}
/*
* =============================== UART ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(UART_config, ".const:UART_config")
#pragma DATA_SECTION(uartTivaHWAttrs, ".const:uartTivaHWAttrs")
#endif
#include <ti/drivers/UART.h>
/* ======== OC_CONNECT1_initUART ========
*/
void OC_CONNECT1_initUART(void)
{
// UART For external communication
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
// SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
// GPIOPinConfigure(GPIO_PC4_U1RX);
// GPIOPinConfigure(GPIO_PC5_U1TX);
// GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
/* Initialize the UART driver */
#if TI_DRIVERS_UART_DMA
OC_CONNECT1_initDMA();
#endif
UART_init();
}
/*
* =============================== USB ===============================
*/
/*
* ======== OC_CONNECT1_usbBusFaultHwi ========
*/
#if 0
static void OC_CONNECT1_usbBusFaultHwi(UArg arg)
{
/*
* This function should be modified to appropriately manage handle
* a USB bus fault.
*/
System_printf("USB bus fault detected.");
Hwi_clearInterrupt(INT_GPIOQ4);
System_abort("USB error!!");
}
/*
* ======== OC_CONNECT1_initUSB ========
* This function just turns on the USB
*/
void OC_CONNECT1_initUSB(OC_CONNECT1_USBMode usbMode)
{
//PWR2
Error_Block eb;
Hwi_Params hwiParams;
/* Enable the USB peripheral and PLL */
SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
SysCtlUSBPLLEnable();
/* Setup pins for USB operation */
GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
/* Additional configurations for Host mode */
if (usbMode == OC_CONNECT1_USBHOST) {
/* Configure the pins needed */
HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xff;
GPIOPinConfigure(GPIO_PD6_USB0EPEN);
GPIOPinTypeUSBDigital(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);
/*
* USB bus fault is routed to pin PQ4. We create a Hwi to allow us
* to detect power faults and recover gracefully or terminate the
* program. PQ4 is active low; set the pin as input with a weak
* pull-up.
*/
GPIOPadConfigSet(GPIO_PORTQ_BASE, GPIO_PIN_4,
GPIO_STRENGTH_2MA,
GPIO_PIN_TYPE_STD_WPU);
GPIOIntTypeSet(GPIO_PORTQ_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
GPIOIntClear(GPIO_PORTQ_BASE, GPIO_PIN_4);
/* Create a Hwi for PQ4 pin. */
Error_init(&eb);
Hwi_Params_init(&hwiParams);
Hwi_construct(&(usbBusFaultHwiStruct), INT_GPIOQ4,
OC_CONNECT1_usbBusFaultHwi, &hwiParams, &eb);
if (Error_check(&eb)) {
System_abort("Couldn't construct USB bus fault hwi");
}
}
}
#endif
/*
* =============================== Watchdog ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(Watchdog_config, ".const:Watchdog_config")
#pragma DATA_SECTION(watchdogTivaHWAttrs, ".const:watchdogTivaHWAttrs")
#endif
#include <ti/drivers/Watchdog.h>
#include <ti/drivers/watchdog/WatchdogTiva.h>
WatchdogTiva_Object watchdogTivaObjects[OC_CONNECT1_WATCHDOGCOUNT];
const WatchdogTiva_HWAttrs watchdogTivaHWAttrs[OC_CONNECT1_WATCHDOGCOUNT] = {
[OC_CONNECT1_WATCHDOG0] = {
.baseAddr = WATCHDOG0_BASE,
.intNum = INT_WATCHDOG,
.intPriority = (~0),
.reloadValue = 80000000 // 1 second period at default CPU clock freq
},
};
const Watchdog_Config Watchdog_config[] = {
[OC_CONNECT1_WATCHDOG0] = {
.fxnTablePtr = &WatchdogTiva_fxnTable,
.object = &watchdogTivaObjects[OC_CONNECT1_WATCHDOG0],
.hwAttrs = &watchdogTivaHWAttrs[OC_CONNECT1_WATCHDOG0]
},
{ NULL, NULL, NULL },
};
/*
* ======== OC_CONNECT1_initWatchdog ========
*
* NOTE: To use the other watchdog timer with base address WATCHDOG1_BASE,
* an additional function call may need be made to enable PIOSC. Enabling
* WDOG1 does not do this. Enabling another peripheral that uses PIOSC
* such as ADC0 or SSI0, however, will do so. Example:
*
* SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
* SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG1);
*
* See the following forum post for more information:
* http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471/p/176487/654390.aspx#654390
*/
void OC_CONNECT1_initWatchdog(void)
{
/* Enable peripherals used by Watchdog */
SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG0);
Watchdog_init();
}

View File

@@ -0,0 +1,422 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/OC_CONNECT1.h"
#include "common/inc/ocmp_wrappers/ocmp_debugi2c.h"
#include "common/inc/ocmp_wrappers/ocmp_ina226.h"
#include "common/inc/ocmp_wrappers/ocmp_ltc4015.h"
#include "common/inc/ocmp_wrappers/ocmp_ltc4274.h"
#include "common/inc/ocmp_wrappers/ocmp_se98a.h"
#include "drivers/GpioSX1509.h"
#include "inc/devices/debug_ocgpio.h"
#include "inc/devices/debug_oci2c.h"
#include "inc/devices/eeprom.h"
#include "inc/devices/ina226.h"
#include "inc/devices/int_battery.h"
#include "inc/subsystem/hci/hci.h"
#include "inc/subsystem/power/power.h"
#include <stdint.h>
#include <stdbool.h>
SCHEMA_IMPORT OcGpio_Port ec_io;
SCHEMA_IMPORT OcGpio_Port pwr_io;
SCHEMA_IMPORT const Driver_fxnTable LTC4274_fxnTable;
/*****************************************************************************
* EEPROM CONFIG
*****************************************************************************/
Eeprom_Cfg eeprom_psu_sid = {
.i2c_dev = { OC_CONNECT1_I2C0, 0x56 },
// .pin_wp = &pin_s_id_eeprom_wp,
.type = CAT24C256,
// .ss = OC_SS_SYS,
};
Eeprom_Cfg eeprom_psu_inv = {
.i2c_dev = { OC_CONNECT1_I2C5, 0x56 },
// .pin_wp = &pin_inven_eeprom_wp,
.type = CAT24C256,
// .ss = OC_SS_SYS,
};
/*****************************************************************************
* SYSTEM CONFIG
*****************************************************************************/
/* Power SubSystem Config */
//Lithium ion battery charge controller.
LTC4015_Dev psu_pwr_int_bat_charger = {
.cfg = {
.i2c_dev = {
.bus = OC_CONNECT1_I2C2,
.slave_addr = 0x68, /* LTC4015 I2C address in 7-bit format */
},
.chem = LTC4015_CHEM_LI_ION,
.r_snsb = PWR_INT_BATT_RSNSB,
.r_snsi = PWR_INT_BATT_RSNSI,
.cellcount = 3,
.pin_alert = &(OcGpio_Pin){ &ec_io, OC_EC_CHARGER_ALERT},
},
.obj = {},
};
INA226_Dev pwr_bat_ps_12v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C3,
.slave_addr = 0x58,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_1v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C4,
.slave_addr = 0x45,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_3v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C4,
.slave_addr = 0x44,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_5v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C4,
.slave_addr = 0x41,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_12v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C1,
.slave_addr = 0x41,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_24v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C1,
.slave_addr = 0x45,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_fe_ps_28v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C4,
.slave_addr = 0x40,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_gbc_ps_12v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C1,
.slave_addr = 0x44,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_gen_ps_12v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C2,
.slave_addr = 0x41,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_gen_ps_24v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C2,
.slave_addr = 0x44,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
INA226_Dev psu_bb_ps_12v = {
/* 12V Power Sensor */
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C1,
.slave_addr = 0x40,
},
.pin_alert = &(OcGpio_Pin){ &ec_io,
OC_EC_CHARGER_ALERT },
},
};
//Power Source Equipment
LTC4274_Dev psu_pwr_pse = {
.cfg = {
.i2c_dev = {
.bus = OC_CONNECT1_I2C3,
.slave_addr = 0x2F, /* LTC4274 I2C address in 7-bit format */
},
.pin_evt = &(OcGpio_Pin){ &ec_io,
OC_EC_PSE_INT },
.reset_pin ={ &ec_io, OC_EC_nPSE_RESET},
},
.obj = {},
};
//Power Device
LTC4295_Dev psu_pwr_pd = {
.cfg = {
//TODO: find the powergood pin
.pin_evt = &(OcGpio_Pin){ &ec_io,
OC_EC_POE_IN_PRESENT},
.pin_detect = &(OcGpio_Pin){ &ec_io,
OC_EC_PD_T2P},
},
.obj = {},
};
//Power Source
PWRSRC_Dev psu_pwr_powerSource = { /*Added as a place holder for now.*/
.cfg = {
/* DC_POWER_PRESENT */
.pin_dc_present = { &ec_io, OC_EC_DC_IN_PRESENT},
/* POE_PRSNT_N */
.pin_poe_prsnt_n = { &ec_io, OC_EC_POE_IN_PRESENT},
/* INT_BAT_PRSNT */
.pin_int_bat_prsnt = { &ec_io, OC_EC_EN_INT_BATT_PWR},
.pin_disable_dc_input = { &ec_io, OC_EC_DISABLE_DC_INPUT},
.pin_dc_input_fault = { &ec_io, OC_EC_DC_INPUT_FAULT},
.pin_oc_input_present = { &ec_io, OC_EC_OC_IN_PRESENT},
.pin_power_off = { &ec_io, OC_EC_POWER_OFF},
},
.obj = {},
};
OcGpio_Pin pin_tempsen_evt1 = { &ec_io, OC_EC_TEMP_EVENT };
SE98A_Dev psu_sensor_ts1 = {
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C5,
.slave_addr = 0x18
},
.pin_evt = &pin_tempsen_evt1,
},
.obj = {},
};
SE98A_Dev psu_sensor_ts2 = {
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C5,
.slave_addr = 0x19,
},
.pin_evt = &pin_tempsen_evt1,
},
.obj = {},
};
SE98A_Dev psu_sensor_ts3 = {
.cfg = {
.dev = {
.bus = OC_CONNECT1_I2C5,
.slave_addr = 0x1A,
},
.pin_evt = &pin_tempsen_evt1,
},
.obj = {},
};
/* HCI SubSystem Config */
// Buzzer
HciBuzzer_Cfg psu_hci_buzzer = {
//.pin_en = { &, 10, OCGPIO_CFG_OUT_OD_NOPULL },
};
/* Debug Subsystem Config.*/
//I2C Bus
S_I2C_Cfg debug_I2C0 = {
.bus = OC_CONNECT1_I2C0,
};
S_I2C_Cfg debug_I2C1 = {
.bus = OC_CONNECT1_I2C1,
};
S_I2C_Cfg debug_I2C2 = {
.bus = OC_CONNECT1_I2C2,
};
S_I2C_Cfg debug_I2C3 = {
.bus = OC_CONNECT1_I2C3,
};
S_I2C_Cfg debug_I2C4 = {
.bus = OC_CONNECT1_I2C4,
};
S_I2C_Cfg debug_I2C5 = {
.bus = OC_CONNECT1_I2C5,
};
//Native GPIO
S_OCGPIO_Cfg debug_psu_gpio_pa = {
.port = &ec_io,
.group = PA,
};
S_OCGPIO_Cfg debug_psu_gpio_pb = {
.port = &ec_io,
.group = PB,
};
S_OCGPIO_Cfg debug_psu_gpio_pc = {
.port = &ec_io,
.group = PC,
};
S_OCGPIO_Cfg debug_psu_gpio_pd = {
.port = &ec_io,
.group = PD,
};
S_OCGPIO_Cfg debug_psu_gpio_pe = {
.port = &ec_io,
.group = PE,
};
S_OCGPIO_Cfg debug_psu_gpio_pf = {
.port = &ec_io,
.group = PF,
};
S_OCGPIO_Cfg debug_psu_gpio_pg = {
.port = &ec_io,
.group = PG,
};
// IO EXPANDERS
S_OCGPIO_Cfg debug_psu_ioexpander = {
.port = &pwr_io,
};
/* Factory Configuration for the Devices*/
//Power Factory Config.
const SE98A_Config fact_bc_se98a = {
.lowlimit = -20,
.highlimit = 75,
.critlimit = 80,
};
const LTC4015_Config fact_lithiumIon_cfg = {
.batteryVoltageLow = 9500,
.batteryVoltageHigh = 12600,
.batteryCurrentLow = 100,
.inputVoltageLow = 16200,
.inputCurrentHigh = 5000,
.inputCurrentLimit = 5570,
};
const LTC4274_Config fact_ltc4274_cfg = {
.operatingMode = LTC4274_AUTO_MODE,
.detectEnable = LTC4274_DETECT_ENABLE,
.interruptMask = LTC4274_INTERRUPT_MASK,
.interruptEnable = true,
.pseHpEnable = LTC4274_HP_ENABLE,
};
//BMS factory config.
const SE98A_Config fact_ec_se98a_cfg = {
.lowlimit = -20,
.highlimit = 75,
.critlimit = 80,
};
const INA226_Config fact_lion_12v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_fe_1v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_fe_3v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_fe_5v_ps_cfg = {
.current_lim = 1500,
};
const INA226_Config fact_fe_12v_ps_cfg = {
.current_lim = 2000,
};
const INA226_Config fact_fe_24v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_fe_28v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_psu_12v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_gen_12v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_gen_24v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_bb_12v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_ec_12v_ps_cfg = {
.current_lim = 1000,
};
const INA226_Config fact_ec_3v_ps_cfg = {
.current_lim = 1000,
};

View File

@@ -0,0 +1,369 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/Framework.h"
#include "common/inc/ocmp_wrappers/ocmp_debugocgpio.h"
#include "common/inc/ocmp_wrappers/ocmp_debugi2c.h"
#include "common/inc/ocmp_wrappers/ocmp_eeprom_cat24c04.h"
#include "common/inc/ocmp_wrappers/ocmp_ina226.h"
#include "common/inc/ocmp_wrappers/ocmp_ltc4015.h"
#include "common/inc/ocmp_wrappers/ocmp_ltc4274.h"
#include "common/inc/ocmp_wrappers/ocmp_ltc4295.h"
#include "common/inc/ocmp_wrappers/ocmp_powersource.h"
#include "common/inc/ocmp_wrappers/ocmp_se98a.h"
#include "schema.h"
/* Power SubSystem Configs */
SCHEMA_IMPORT DriverStruct eeprom_psu_sid;
SCHEMA_IMPORT DriverStruct eeprom_psu_inv;
SCHEMA_IMPORT const DriverStruct fact_bb_12v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_bc_se98a;
SCHEMA_IMPORT const DriverStruct fact_fe_1v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_fe_3v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_fe_5v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_fe_12v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_fe_24v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_fe_28v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_gbc_12v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_gen_12v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_gen_24v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_lithiumIon_cfg;
SCHEMA_IMPORT const DriverStruct fact_lion_12v_ps_cfg;
SCHEMA_IMPORT const DriverStruct fact_ltc4274_cfg;
SCHEMA_IMPORT DriverStruct psu_bat_ps_12v;
SCHEMA_IMPORT DriverStruct psu_bb_ps_12v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_1v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_3v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_5v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_12v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_24v;
SCHEMA_IMPORT DriverStruct psu_fe_ps_28v;
SCHEMA_IMPORT DriverStruct psu_gbc_ps_12v;
SCHEMA_IMPORT DriverStruct psu_gbc_ps_24v;
SCHEMA_IMPORT DriverStruct psu_gen_ps_12v;
SCHEMA_IMPORT DriverStruct psu_gen_ps_24v;
SCHEMA_IMPORT DriverStruct psu_lead_acid_ts;
SCHEMA_IMPORT DriverStruct psu_pwr_int_bat_charger;
SCHEMA_IMPORT DriverStruct psu_pwr_pd;
SCHEMA_IMPORT DriverStruct psu_pwr_powerSource;
SCHEMA_IMPORT DriverStruct psu_pwr_pse;
SCHEMA_IMPORT DriverStruct psu_sensor_ts1;
SCHEMA_IMPORT DriverStruct psu_sensor_ts2;
SCHEMA_IMPORT DriverStruct psu_sensor_ts3;
/*Debug SubSystem Configs*/
SCHEMA_IMPORT DriverStruct debug_I2C0;
SCHEMA_IMPORT DriverStruct debug_I2C1;
SCHEMA_IMPORT DriverStruct debug_I2C2;
SCHEMA_IMPORT DriverStruct debug_I2C3;
SCHEMA_IMPORT DriverStruct debug_I2C4;
SCHEMA_IMPORT DriverStruct debug_I2C5;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pa;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pb;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pc;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pd;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pe;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pf;
SCHEMA_IMPORT DriverStruct debug_psu_gpio_pg;
SCHEMA_IMPORT DriverStruct debug_psu_ioexpander;
/* Functions */
SCHEMA_IMPORT bool psuCore_pre_init(void *driver, void *returnValue);
const Component sys_schema[] = {
{
.name = "psuCore",
.ssHookSet =
&(SSHookSet){
.preInitFxn = (ssHook_Cb)psuCore_pre_init,
},
.driver_cfg = &psu_pwr_powerSource,
.components = (Component[]){
{
.name = "comp_all",
.driver = &PWRSRC,
.driver_cfg = &psu_pwr_powerSource,
},
{
.name = "eeprom1",
.driver = &CAT24C04_psu_inv,
.driver_cfg = &eeprom_psu_sid,
},
{
.name = "eeprom2",
.driver = &CAT24C04_psu_inv,
.driver_cfg = &eeprom_psu_inv,
},
{
.name = "lion",
.components = (Component[]){
{
.name = "battery",
.driver = &LTC4015,
.driver_cfg = &psu_pwr_int_bat_charger,
.factory_config = &fact_lithiumIon_cfg,
},
{}
}
},
{
.name = "pse",
.driver = &LTC4274,
.driver_cfg = &psu_pwr_pse,
.factory_config = &fact_ltc4274_cfg,
},
{
.name = "pd",
.driver = &LTC4295,
.driver_cfg = &psu_pwr_pd,
},
{
.name = "sensors",
.components = (Component[]){
{
.name = "temp_sensor1",
.driver = &SE98A,
.driver_cfg = &psu_sensor_ts1,
.factory_config = &fact_bc_se98a,
},
{
.name = "temp_sensor2",
.driver = &SE98A,
.driver_cfg = &psu_sensor_ts2,
.factory_config = &fact_bc_se98a,
},
{
.name = "temp_sensor3",
.driver = &SE98A,
.driver_cfg = &psu_sensor_ts3,
.factory_config = &fact_bc_se98a,
},
{}
},
},
{}
},
},
{
.name = "psubms",
.components = (Component[]){
{
.name = "comp_all",
.postDisabled = POST_DISABLED,
},
{
.name = "debugI2C",
.postDisabled = POST_DISABLED,
.components = (Component[]){
{
.name = "comp_all",
.postDisabled = POST_DISABLED
},
{
.name = "bus0",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C0,
.postDisabled = POST_DISABLED
},
{
.name = "bus1",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C1,
.postDisabled = POST_DISABLED
},
{
.name = "bus2",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C2,
.postDisabled = POST_DISABLED
},
{
.name = "bus3",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C3,
.postDisabled = POST_DISABLED
},
{
.name = "bus4",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C4,
.postDisabled = POST_DISABLED
},
{
.name = "bus5",
.driver = &OC_I2C,
.driver_cfg = &debug_I2C5,
.postDisabled = POST_DISABLED
},
{}
},
},
{
.name = "debugGPIO",
.postDisabled = POST_DISABLED,
.components = (Component[]){
{
.name = "comp_all",
.postDisabled = POST_DISABLED,
},
{
.name = "PA",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pa,
.postDisabled = POST_DISABLED,
},
{
.name = "PB",
.driver = &OC_GPIO,
.driver_cfg =&debug_psu_gpio_pb,
.postDisabled = POST_DISABLED,
},
{
.name = "PC",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pc,
.postDisabled = POST_DISABLED,
},
{
.name = "PD",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pd,
.postDisabled = POST_DISABLED,
},
{
.name = "PE",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pe,
.postDisabled = POST_DISABLED,
},
{
.name = "PF",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pf,
.postDisabled = POST_DISABLED,
},
{
.name = "PG",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_gpio_pg,
.postDisabled = POST_DISABLED,
},
{}
},
},
{
.name = "debugIOexpander",
.postDisabled = POST_DISABLED,
.components = (Component[]){
{
.name = "comp_all",
.postDisabled = POST_DISABLED,
},
{
.name = "ioexpander",
.driver = &OC_GPIO,
.driver_cfg = &debug_psu_ioexpander,
},
{}
},
},
{
.name = "fe1",
.components = (Component[]){
{
.name = "current_sensor1",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_1v,
.factory_config = &fact_fe_1v_ps_cfg,
},
{
.name = "current_sensor2",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_3v,
.factory_config = &fact_fe_3v_ps_cfg,
},
{
.name = "current_sensor3",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_5v,
.factory_config = &fact_fe_5v_ps_cfg,
},
{}
}
},
{
.name = "fe2",
.components = (Component[]){
{
.name = "current_sensor4",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_12v,
.factory_config = &fact_fe_12v_ps_cfg,
},
{
.name = "current_sensor5",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_24v,
.factory_config = &fact_fe_24v_ps_cfg,
},
{
.name = "current_sensor6",
.driver = &INA226,
.driver_cfg = &psu_fe_ps_28v,
.factory_config = &fact_fe_28v_ps_cfg,
},
{}
},
},
{
.name = "gbc",
.components = (Component[]){
{
.name = "current_sensor1",
.driver = &INA226,
.driver_cfg = &psu_gbc_ps_12v,
.factory_config = &fact_gbc_12v_ps_cfg,
},
{
.name = "current_sensor2",
.driver = &INA226,
.driver_cfg = &psu_gen_ps_12v,
.factory_config = &fact_gen_12v_ps_cfg,
},
{
.name = "current_sensor3",
.driver = &INA226,
.driver_cfg = &psu_gen_ps_24v,
.factory_config = &fact_gen_24v_ps_cfg,
},
{}
},
},
{
.name = "bb",
.components = (Component[]){
{
.name = "current_sensor",
.driver = &INA226,
.driver_cfg = &psu_bb_ps_12v,
.factory_config = &fact_bb_12v_ps_cfg,
},
{}
},
},
{}
},
},
{}
};

View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _SCHEMA_H
#define _SCHEMA_H
#define SUBSYSTEM_COUNT OC_SS_MAX_LIMIT
#endif /* _SCHEMA_H */

557
firmware/psu/psu.cfg Normal file
View File

@@ -0,0 +1,557 @@
/*
* Copyright (c) 2015-2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* ================ Clock configuration ================ */
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
/*
* Default value is family dependent. For example, Linux systems often only
* support a minimum period of 10000 us and multiples of 10000 us.
* TI platforms have a default of 1000 us.
*/
Clock.tickPeriod = 1000;
/* ================ Defaults (module) configuration ================ */
var Defaults = xdc.useModule('xdc.runtime.Defaults');
/*
* A flag to allow module names to be loaded on the target. Module name
* strings are placed in the .const section for debugging purposes.
*
* Pick one:
* - true (default)
* Setting this parameter to true will include name strings in the .const
* section so that Errors and Asserts are easier to debug.
* - false
* Setting this parameter to false will reduce footprint in the .const
* section. As a result, Error and Assert messages will contain an
* "unknown module" prefix instead of the actual module name.
*/
Defaults.common$.namedModule = true;
//Defaults.common$.namedModule = false;
/* ================ Error configuration ================ */
var Error = xdc.useModule('xdc.runtime.Error');
/*
* This function is called to handle all raised errors, but unlike
* Error.raiseHook, this function is responsible for completely handling the
* error with an appropriately initialized Error_Block.
*
* Pick one:
* - Error.policyDefault (default)
* Calls Error.raiseHook with an initialized Error_Block structure and logs
* the error using the module's logger.
* - Error.policySpin
* Simple alternative that traps on a while(1) loop for minimized target
* footprint.
* Using Error.policySpin, the Error.raiseHook will NOT called.
*/
Error.policyFxn = Error.policyDefault;
//Error.policyFxn = Error.policySpin;
/*
* If Error.policyFxn is set to Error.policyDefault, this function is called
* whenever an error is raised by the Error module.
*
* Pick one:
* - Error.print (default)
* Errors are formatted and output via System_printf() for easier
* debugging.
* - null
* Errors are not formatted or logged. This option reduces code footprint.
* - non-null function
* Errors invoke custom user function. See the Error module documentation
* for more details.
*/
Error.raiseHook = Error.print;
//Error.raiseHook = null;
//Error.raiseHook = "&myErrorFxn";
/*
* If Error.policyFxn is set to Error.policyDefault, this option applies to the
* maximum number of times the Error.raiseHook function can be recursively
* invoked. This option limits the possibility of an infinite recursion that
* could lead to a stack overflow.
* The default value is 16.
*/
Error.maxDepth = 2;
/* ================ Hwi configuration ================ */
var halHwi = xdc.useModule('ti.sysbios.hal.Hwi');
var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
/*
* Checks for Hwi (system) stack overruns while in the Idle loop.
*
* Pick one:
* - true (default)
* Checks the top word for system stack overflows during the idle loop and
* raises an Error if one is detected.
* - false
* Disabling the runtime check improves runtime performance and yields a
* reduced flash footprint.
*/
halHwi.checkStackFlag = true;
//halHwi.checkStackFlag = false;
/*
* The following options alter the system's behavior when a hardware exception
* is detected.
*
* Pick one:
* - Hwi.enableException = true
* This option causes the default m3Hwi.excHandlerFunc function to fully
* decode an exception and dump the registers to the system console.
* This option raises errors in the Error module and displays the
* exception in ROV.
* - Hwi.enableException = false
* This option reduces code footprint by not decoding or printing the
* exception to the system console.
* It however still raises errors in the Error module and displays the
* exception in ROV.
* - Hwi.excHandlerFunc = null
* This is the most aggressive option for code footprint savings; but it
* can difficult to debug exceptions. It reduces flash footprint by
* plugging in a default while(1) trap when exception occur. This option
* does not raise an error with the Error module.
*/
m3Hwi.enableException = true;
//m3Hwi.enableException = false;
//m3Hwi.excHandlerFunc = null;
/*
* Enable hardware exception generation when dividing by zero.
*
* Pick one:
* - 0 (default)
* Disables hardware exceptions when dividing by zero
* - 1
* Enables hardware exceptions when dividing by zero
*/
m3Hwi.nvicCCR.DIV_0_TRP = 0;
//m3Hwi.nvicCCR.DIV_0_TRP = 1;
/*
* Enable hardware exception generation for invalid data alignment.
*
* Pick one:
* - 0 (default)
* Disables hardware exceptions for data alignment
* - 1
* Enables hardware exceptions for data alignment
*/
m3Hwi.nvicCCR.UNALIGN_TRP = 0;
//m3Hwi.nvicCCR.UNALIGN_TRP = 1;
/* ================ Idle configuration ================ */
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
/*
* The Idle module is used to specify a list of functions to be called when no
* other tasks are running in the system.
*
* Functions added here will be run continuously within the idle task.
*
* Function signature:
* Void func(Void);
*/
//Idle.addFunc("&myIdleFunc");
/* ================ Kernel (SYS/BIOS) configuration ================ */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
/*
* Enable asserts in the BIOS library.
*
* Pick one:
* - true (default)
* Enables asserts for debugging purposes.
* - false
* Disables asserts for a reduced code footprint and better performance.
*/
//BIOS.assertsEnabled = true;
BIOS.assertsEnabled = false;
/*
* Specify default heap size for BIOS.
*/
//BIOS.heapSize = 6144;
BIOS.heapSize = 8192;
//BIOS.heapSize = 9216;
//BIOS.heapSize = 102400
/*
* A flag to determine if xdc.runtime sources are to be included in a custom
* built BIOS library.
*
* Pick one:
* - false (default)
* The pre-built xdc.runtime library is provided by the respective target
* used to build the application.
* - true
* xdc.runtime library souces are to be included in the custom BIOS
* library. This option yields the most efficient library in both code
* footprint and runtime performance.
*/
BIOS.includeXdcRuntime = false;
//BIOS.includeXdcRuntime = true;
/*
* The SYS/BIOS runtime is provided in the form of a library that is linked
* with the application. Several forms of this library are provided with the
* SYS/BIOS product.
*
* Pick one:
* - BIOS.LibType_Custom
* Custom built library that is highly optimized for code footprint and
* runtime performance.
* - BIOS.LibType_Debug
* Custom built library that is non-optimized that can be used to
* single-step through APIs with a debugger.
*
*/
BIOS.libType = BIOS.LibType_Custom;
//BIOS.libType = BIOS.LibType_Debug;
/*
* Runtime instance creation enable flag.
*
* Pick one:
* - true (default)
* Allows Mod_create() and Mod_delete() to be called at runtime which
* requires a default heap for dynamic memory allocation.
* - false
* Reduces code footprint by disallowing Mod_create() and Mod_delete() to
* be called at runtime. Object instances are constructed via
* Mod_construct() and destructed via Mod_destruct().
*/
BIOS.runtimeCreatesEnabled = true;
//BIOS.runtimeCreatesEnabled = false;
/*
* Enable logs in the BIOS library.
*
* Pick one:
* - true (default)
* Enables logs for debugging purposes.
* - false
* Disables logging for reduced code footprint and improved runtime
* performance.
*/
//BIOS.logsEnabled = true;
BIOS.logsEnabled = false;
/* ================ Memory configuration ================ */
var Memory = xdc.useModule('xdc.runtime.Memory');
/*
* The Memory module itself simply provides a common interface for any
* variety of system and application specific memory management policies
* implemented by the IHeap modules(Ex. HeapMem, HeapBuf).
*/
/* ================ Program configuration ================ */
/*
* Program.stack is ignored with IAR. Use the project options in
* IAR Embedded Workbench to alter the system stack size.
*/
if (!Program.build.target.$name.match(/iar/)) {
/*
* Reducing the system stack size (used by ISRs and Swis) to reduce
* RAM usage.
*/
Program.stack = 768;
}
/*
* Enable Semihosting for GNU targets to print to CCS console
*/
if (Program.build.target.$name.match(/gnu/)) {
var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
}
/* ================ Semaphore configuration ================ */
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
/*
* Enables global support for Task priority pend queuing.
*
* Pick one:
* - true (default)
* This allows pending tasks to be serviced based on their task priority.
* - false
* Pending tasks are services based on first in, first out basis.
*
* When using BIOS in ROM:
* This option must be set to false.
*/
//Semaphore.supportsPriority = true;
Semaphore.supportsPriority = false;
/*
* Allows for the implicit posting of events through the semaphore,
* disable for additional code saving.
*
* Pick one:
* - true
* This allows the Semaphore module to post semaphores and events
* simultaneously.
* - false (default)
* Events must be explicitly posted to unblock tasks.
*
*/
//Semaphore.supportsEvents = true;
Semaphore.supportsEvents = false;
/* ================ Swi configuration ================ */
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
/*
* A software interrupt is an object that encapsulates a function to be
* executed and a priority. Software interrupts are prioritized, preempt tasks
* and are preempted by hardware interrupt service routines.
*
* This module is included to allow Swi's in a users' application.
*/
/* ================ System configuration ================ */
var System = xdc.useModule('xdc.runtime.System');
/*
* The Abort handler is called when the system exits abnormally.
*
* Pick one:
* - System.abortStd (default)
* Call the ANSI C Standard 'abort()' to terminate the application.
* - System.abortSpin
* A lightweight abort function that loops indefinitely in a while(1) trap
* function.
* - A custom abort handler
* A user-defined function. See the System module documentation for
* details.
*/
System.abortFxn = System.abortStd;
//System.abortFxn = System.abortSpin;
//System.abortFxn = "&myAbortSystem";
/*
* The Exit handler is called when the system exits normally.
*
* Pick one:
* - System.exitStd (default)
* Call the ANSI C Standard 'exit()' to terminate the application.
* - System.exitSpin
* A lightweight exit function that loops indefinitely in a while(1) trap
* function.
* - A custom exit function
* A user-defined function. See the System module documentation for
* details.
*/
System.exitFxn = System.exitStd;
//System.exitFxn = System.exitSpin;
//System.exitFxn = "&myExitSystem";
/*
* Minimize exit handler array in the System module. The System module includes
* an array of functions that are registered with System_atexit() which is
* called by System_exit(). The default value is 8.
*/
System.maxAtexitHandlers = 2;
/*
* The System.SupportProxy defines a low-level implementation of System
* functions such as System_printf(), System_flush(), etc.
*
* Pick one pair:
* - SysMin
* This module maintains an internal configurable circular buffer that
* stores the output until System_flush() is called.
* The size of the circular buffer is set via SysMin.bufSize.
* - SysCallback
* SysCallback allows for user-defined implementations for System APIs.
* The SysCallback support proxy has a smaller code footprint and can be
* used to supply custom System_printf services.
* The default SysCallback functions point to stub functions. See the
* SysCallback module's documentation.
*/
var SysMin = xdc.useModule('xdc.runtime.SysMin');
SysMin.bufSize = 128;
System.SupportProxy = SysMin;
//var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
//System.SupportProxy = SysCallback;
//SysCallback.abortFxn = "&myUserAbort";
//SysCallback.exitFxn = "&myUserExit";
//SysCallback.flushFxn = "&myUserFlush";
//SysCallback.putchFxn = "&myUserPutch";
//SysCallback.readyFxn = "&myUserReady";
/* ================ Task configuration ================ */
var Task = xdc.useModule('ti.sysbios.knl.Task');
/*
* Check task stacks for overflow conditions.
*
* Pick one:
* - true (default)
* Enables runtime checks for task stack overflow conditions during
* context switching ("from" and "to")
* - false
* Disables runtime checks for task stack overflow conditions.
*/
Task.checkStackFlag = true;
//Task.checkStackFlag = false;
/*
* Set the default task stack size when creating tasks.
*
* The default is dependent on the device being used. Reducing the default stack
* size yields greater memory savings.
*/
Task.defaultStackSize = 512;
/*
* Enables the idle task.
*
* Pick one:
* - true (default)
* Creates a task with priority of 0 which calls idle hook functions. This
* option must be set to true to gain power savings provided by the Power
* module.
* - false
* No idle task is created. This option consumes less memory as no
* additional default task stack is needed.
* To gain power savings by the Power module without having the idle task,
* add Idle.run as the Task.allBlockedFunc.
*/
Task.enableIdleTask = true;
//Task.enableIdleTask = false;
//Task.allBlockedFunc = Idle.run;
/*
* If Task.enableIdleTask is set to true, this option sets the idle task's
* stack size.
*
* Reducing the idle stack size yields greater memory savings.
*/
Task.idleTaskStackSize = 512;
/*
* Reduce the number of task priorities.
* The default is 16.
* Decreasing the number of task priorities yield memory savings.
*/
Task.numPriorities = 16;
/* ================ Text configuration ================ */
var Text = xdc.useModule('xdc.runtime.Text');
/*
* These strings are placed in the .const section. Setting this parameter to
* false will save space in the .const section. Error, Assert and Log messages
* will print raw ids and args instead of a formatted message.
*
* Pick one:
* - true (default)
* This option loads test string into the .const for easier debugging.
* - false
* This option reduces the .const footprint.
*/
Text.isLoaded = true;
//Text.isLoaded = false;
/* ================ Types configuration ================ */
var Types = xdc.useModule('xdc.runtime.Types');
/*
* This module defines basic constants and types used throughout the
* xdc.runtime package.
*/
/* ================ TI-RTOS middleware configuration ================ */
var mwConfig = xdc.useModule('ti.mw.Config');
/*
* Include TI-RTOS middleware libraries
*/
/* ================ TI-RTOS drivers' configuration ================ */
var driversConfig = xdc.useModule('ti.drivers.Config');
/*
* Include TI-RTOS drivers
*
* Pick one:
* - driversConfig.LibType_NonInstrumented (default)
* Use TI-RTOS drivers library optimized for footprint and performance
* without asserts or logs.
* - driversConfig.LibType_Instrumented
* Use TI-RTOS drivers library for debugging with asserts and logs enabled.
*/
driversConfig.libType = driversConfig.LibType_NonInstrumented;
//driversConfig.libType = driversConfig.LibType_Instrumented;
var Main = xdc.useModule('xdc.runtime.Main');
/*var m3Hwi0Params = new m3Hwi.Params();
m3Hwi0Params.instance.name = "m3Hwi0";
m3Hwi0Params.enableInt = false;
Program.global.m3Hwi0 = m3Hwi.create(76, "&UART4IntHandler", m3Hwi0Params);
/*
var m3Hwi1Params = new m3Hwi.Params();
m3Hwi1Params.instance.name = "m3Hwi1";
Program.global.m3Hwi1 = m3Hwi.create(60, "&uDMAIntHandler", m3Hwi1Params);
*/
/*var m3Hwi2Params = new m3Hwi.Params();
m3Hwi2Params.instance.name = "m3Hwi2";
m3Hwi2Params.enableInt = false;
Program.global.m3Hwi2 = m3Hwi.create(61, "&uDMAErrorHandler", m3Hwi2Params);
/* ================ Application Specific Instances ================ */

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="Texas Instruments XDS110 USB Debug Probe_0">
<instance XML_version="1.2" desc="Texas Instruments XDS110 USB Debug Probe_0" href="connections/TIXDS110_Connection.xml" id="Texas Instruments XDS110 USB Debug Probe_0" xml="TIXDS110_Connection.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="Texas Instruments XDS110 USB Debug Probe_0">
<instance XML_version="1.2" href="drivers/tixds510cs_dap.xml" id="drivers" xml="tixds510cs_dap.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cortexM.xml" id="drivers" xml="tixds510cortexM.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="Tiva TM4C1230E6PM_0" href="devices/tm4c1230e6pm.xml" id="Tiva TM4C1230E6PM_0" xml="tm4c1230e6pm.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

92
firmware/psu/src/Board.h Normal file
View File

@@ -0,0 +1,92 @@
/*******************************************************************************
Filename: Board.h
Revised: $Date: 2015-06-02 11:18:40 -0700 (Tue, 02 Jun 2015) $
Revision: $Revision: 43957 $
Description: This file contains utility functions.
Copyright 2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED <20>AS IS<49> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
#ifndef __BOARD_H
#define __BOARD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "common/inc/global/OC_CONNECT1.h"
#define Board_initEMAC OC_CONNECT1_initEMAC
#define Board_initGeneral OC_CONNECT1_initGeneral
#define Board_initGPIO OC_CONNECT1_initGPIO
#define Board_initI2C OC_CONNECT1_initI2C
#define Board_initUART OC_CONNECT1_initUART
#define Board_initUSB OC_CONNECT1_initUSB
#define Board_initWatchdog OC_CONNECT1_initWatchdog
#define Board_IOEXP_ALERT OC_EC_GBC_IOEXP71_ALERT
#define Board_ECINA_ALERT OC_EC_GBC_INA_ALERT
#define Board_APINA_ALERT OC_EC_GBC_AP_INA_ALERT
#define Board_SDRFPGA_TEMPINA_ALERT OC_EC_SDR_FPGA_TEMP_INA_ALERT
#define Board_SDR_INA_ALERT OC_EC_SDR_INA_ALERT
#define Board_RFFE_TEMP_INA_ALERT OC_EC_RFFE_TEMP_INA_ALERT
#define Board_SYNC_IOEXP_ALERT OC_EC_SYNC_IOEXP_ALERT
#define Board_LeadAcidAlert OC_EC_PWR_LACID_ALERT
#define Board_LithiumIonAlert OC_EC_PWR_LION_ALERT
#define Board_PSEALERT OC_EC_GBC_PSE_ALERT
#define Board_PD_PWRGDAlert OC_EC_PD_PWRGD_ALERT
#define Board_SOC_UART3_TX OC_EC_SOC_UART3_TX
#define Board_I2C0 OC_CONNECT1_I2C0
#define Board_I2C1 OC_CONNECT1_I2C1
#define Board_I2C2 OC_CONNECT1_I2C2
#define Board_I2C3 OC_CONNECT1_I2C3
#define Board_I2C4 OC_CONNECT1_I2C4
#define Board_I2C6 OC_CONNECT1_I2C6
#define Board_I2C7 OC_CONNECT1_I2C7
#define Board_I2C8 OC_CONNECT1_I2C8
#define Board_I2CCOUNT OC_CONNECT1_I2CCOUNT
#define Board_USBHOST OC_CONNECT1_USBHOST
#define Board_USBDEVICE OC_CONNECT1_USBDEVICE
// TODO: maybe rename to "UART_GSM" and stuff to be more abstracted from HW
#define Board_UART0 OC_CONNECT1_UART0
#define Board_UART3 OC_CONNECT1_UART3
#define Board_UART4 OC_CONNECT1_UART4
#define Board_UARTXR0 OC_CONNECT1_UARTXR0
#define Board_WATCHDOG0 OC_CONNECT1_WATCHDOG0
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H */

View File

@@ -0,0 +1,369 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "inc/common/bigbrother.h"
#include "Board.h"
#include "comm/gossiper.h"
#include "common/inc/global/ocmp_frame.h"
#include "drivers/OcGpio.h"
#include "inc/common/post.h"
#include "inc/common/system_states.h"
#include "inc/subsystem/hci/hci_buzzer.h"
#include "inc/utils/ocmp_util.h"
#include "registry/SSRegistry.h"
#include <ti/sysbios/BIOS.h>
#include <stdlib.h>
extern OcGpio_Port pwr_io;
extern OcGpio_Port ec_io;
OcGpio_Pin pin_24v = { &pwr_io, 3};
OcGpio_Pin pin_5v0 = { &pwr_io, 4};
OcGpio_Pin pin_3v3 = { &pwr_io, 5};
OcGpio_Pin pin_gbcv2_on = { &pwr_io, 6};
OcGpio_Pin pin_12v_bb = { &pwr_io, 7};
OcGpio_Pin pin_12v_fe = { &pwr_io, 8};
OcGpio_Pin pin_20v_fe = { &pwr_io, 9};
OcGpio_Pin pin_1v8 = { &pwr_io, 10};
/* Global Task Configuration Variables */
Task_Struct bigBrotherTask;
Char bigBrotherTaskStack[BIGBROTHER_TASK_STACK_SIZE];
eSubSystemStates oc_sys_state = SS_STATE_PWRON;
//*****************************************************************************
// HANDLES DEFINITION
//*****************************************************************************
/* Queue object */
/*
* Semaphore for the Big Brother task where it will be waiting on.
* Sub systems or Gossiper post this with respective queues filled in.
*/
Semaphore_Handle semBigBrotherMsg;
static Queue_Struct bigBrotherRxMsg;
static Queue_Struct bigBrotherTxMsg;
/*
* bigBrotherRxMsgQueue - Used by the gossiper to pass the frame once recived
* from Ethernet or UART and processed and needs to forward to bigBrother.
*/
Queue_Handle bigBrotherRxMsgQueue;
/*
* bigBrotherTxMsgQueue - Used by the BigBrother to pass the frame once
* underlying subsystem processed it (GPP/RF etc) and need to send back
* to Gosipper. This is the one all the subsystem will be listening only.
*/
Queue_Handle bigBrotherTxMsgQueue;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
static void bigbrother_taskfxn(UArg a0, UArg a1);
static void bigbrother_init(void);
static ReturnStatus bigbrother_process_rx_msg(uint8_t *pMsg);
static ReturnStatus bigbrother_process_tx_msg(uint8_t *pMsg);
extern void post_createtask(void);
static void bigborther_initiate_post(void);
extern void gossiper_createtask(void);
extern void usb_rx_createtask(void);
extern void usb_tx_createtask(void);
extern void uartdma_rx_createtask(void);
extern void uartdma_tx_createtask(void);
//extern void watchdog_create_task(void);;
/*****************************************************************************
** FUNCTION NAME : bb_sys_post_complete
**
** DESCRIPTION : Get POST results from EEPROM.
**
** ARGUMENTS : None
**
** RETURN TYPE : ReturnStatus
**
*****************************************************************************/
ReturnStatus bb_sys_post_complete()
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("BIGBROTHER:INFO::POST test is completed.\n");
static uint8_t count = 0;
if (count == 0) {
// Task_sleep(60000);
// TODO: Starting UART DMA Interface based on EBMP.
uartdma_rx_createtask(); // P - 07
uartdma_tx_createtask(); // P - 07
count++;
// uart_enable();
/* TODO: enable this back */
#if ENABLE_POWER
OcGpio_configure(&pin_24v,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_24v, 1);
OcGpio_configure(&pin_5v0,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_5v0, 1);
OcGpio_configure(&pin_3v3,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_3v3, 1);
OcGpio_configure(&pin_gbcv2_on,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_gbcv2_on, 1);
OcGpio_configure(&pin_12v_bb,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_12v_bb, 1);
OcGpio_configure(&pin_12v_fe,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_12v_fe, 1);
OcGpio_configure(&pin_20v_fe,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_20v_fe, 1);
OcGpio_configure(&pin_1v8,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_LOW);
OcGpio_write(&pin_1v8, 1);
#endif
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_process_tx_msg
**
** DESCRIPTION : Processes the big brother outgoing messages.
**
** ARGUMENTS : Pointer to BIGBROTHER_TXEvt_t structure
**
** RETURN TYPE : None
**
*****************************************************************************/
static ReturnStatus bigbrother_process_tx_msg(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("BIGBROTHER:INFO:: Processing Big Brother TX Message.\n");
if (pMsg != NULL) {
Util_enqueueMsg(gossiperTxMsgQueue, semGossiperMsg, (uint8_t*) pMsg);
} else {
LOGGER_ERROR("BIGBROTHER::ERROR::No Valid Pointer.\n");
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_process_rx_msg
**
** DESCRIPTION : Processes the big brother incoming messages.
**
** ARGUMENTS : Pointer to BIGBROTHER_RXEvt_t structure
**
** RETURN TYPE : None
**
*****************************************************************************/
static ReturnStatus bigbrother_process_rx_msg(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("BIGBROTHER:INFO:: Processing Big Brother RX Message.\n");
OCMPMessageFrame * pOCMPMessageFrame = (OCMPMessageFrame *) pMsg;
if (pOCMPMessageFrame != NULL) {
LOGGER_DEBUG("BIGBROTHER:INFO:: RX Msg recieved with Length: 0x%x,"
"Interface: 0x%x, Seq.No: 0x%x, TimeStamp: 0x%x.\n",
pOCMPMessageFrame->header.ocmpFrameLen,
pOCMPMessageFrame->header.ocmpInterface,
pOCMPMessageFrame->header.ocmpSeqNumber,
pOCMPMessageFrame->header.ocmpTimestamp);
// Forward this to respective subsystem.
if (!SSRegistry_sendMessage(pOCMPMessageFrame->message.subsystem,
pMsg)) {
LOGGER_ERROR("BIGBROTHER::ERROR::Subsystem %d doesn't exist\n",
pOCMPMessageFrame->message.subsystem);
free(pMsg);
}
} else {
LOGGER_ERROR("BIGBROTHER:ERROR:: No message recieved.\n");
free(pMsg);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : bigborther_initiate_post
**
** DESCRIPTION : Creates POST test task.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void bigborther_initiate_post(void)
{
LOGGER_DEBUG("BIGBROTHER:INFO::Creating task to perform POST.\n");
post_createtask();
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_ioexp_init
**
** DESCRIPTION : Initializes Io expander SX1509.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
OcGpio_Pin pin_v5_a_pgood = { &ec_io, OC_EC_PGOOD_5V0};
OcGpio_Pin pin_v12_a_pgood = { &ec_io, OC_EC_PGOOD_12V0};
ReturnStatus bigbrother_ioexp_init(void)
{
ReturnStatus status = RETURN_OK;
OcGpio_init(&pwr_io);
/* Initialize pins that aren't covered yet by a subsystem */
OcGpio_configure(&pin_v5_a_pgood, OCGPIO_CFG_INPUT);
OcGpio_configure(&pin_v12_a_pgood, OCGPIO_CFG_INPUT);
return status;
}
/*******************************************************************************
** FUNCTION NAME : bigborther_spwan_task
**
** DESCRIPTION : Application task start up point for open cellular.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
******************************************************************************/
static void bigborther_spwan_task(void)
{
/* Read OC UID EEPROM */
/* Check the list for possible devices connected. */
/* Launches other tasks */
// usb_rx_createtask(); // P - 05
// usb_tx_createtask(); // P - 04
gossiper_createtask(); // P - 06
// ebmp_create_task();
// watchdog_create_task();
/* Initialize subsystem interface to set up interfaces and launch
* subsystem tasks */
SSRegistry_init();
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_init
**
** DESCRIPTION : Initializes the Big Brother task.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void bigbrother_init(void)
{
/*Creating Semaphore for RX Message Queue*/
semBigBrotherMsg = Semaphore_create(0, NULL, NULL);
if (semBigBrotherMsg == NULL) {
LOGGER_ERROR("BIGBROTHER:ERROR::BIGBROTHER RX Semaphore creation failed.\n");
}
/*Creating RX Message Queue*/
bigBrotherRxMsgQueue = Util_constructQueue(&bigBrotherRxMsg);
LOGGER_DEBUG("BIGBROTHER:INFO::Constructing message Queue for 0x%x Big Brother RX Messages.\n",
bigBrotherRxMsgQueue);
/*Creating TX Message Queue*/
bigBrotherTxMsgQueue = Util_constructQueue(&bigBrotherTxMsg);
LOGGER_DEBUG("BIGBROTHER:INFO::Constructing message Queue for 0x%x Big Brother RX Messages.\n",
bigBrotherTxMsgQueue);
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_taskfxn
**
** DESCRIPTION : handles the system state and subsystem states.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void bigbrother_taskfxn(UArg a0, UArg a1)
{
bigbrother_init();
/* Initialize GPIO Expander SX1509 */
bigbrother_ioexp_init();
// hci_buzzer_beep(1);
//Create Tasks.
bigborther_spwan_task();
//Perform POST
bigborther_initiate_post();
while (true) {
if (Semaphore_pend(semBigBrotherMsg, BIOS_WAIT_FOREVER)) {
while (!Queue_empty(bigBrotherRxMsgQueue)) {
uint8_t *pWrite = (uint8_t *) Util_dequeueMsg(
bigBrotherRxMsgQueue);
if (pWrite) {
bigbrother_process_rx_msg(pWrite);
}
}
while (!Queue_empty(bigBrotherTxMsgQueue)) {
uint8_t *pWrite = (uint8_t *) Util_dequeueMsg(
bigBrotherTxMsgQueue);
if (pWrite) {
bigbrother_process_tx_msg(pWrite);
}
}
}
}
}
/*****************************************************************************
** FUNCTION NAME : bigbrother_createtask
**
** DESCRIPTION : Creates task for Big Brother task
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
void bigbrother_createtask(void)
{
//watchdog_pin();
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = bigBrotherTaskStack;
taskParams.stackSize = BIGBROTHER_TASK_STACK_SIZE;
taskParams.priority = BIGBROTHER_TASK_PRIORITY;
Task_construct(&bigBrotherTask, bigbrother_taskfxn, &taskParams, NULL);
LOGGER_DEBUG("BIGBROTHER:INFO::Creating a BigBrother task.\n");
}

View File

@@ -0,0 +1,248 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "comm/gossiper.h"
#include "common/inc/global/ocmp_frame.h"
#include "inc/common/bigbrother.h"
#include "inc/common/global_header.h"
#include "inc/interfaces/uartdma.h"
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
/*****************************************************************************
* HANDLES DEFINITION
*****************************************************************************/
// Semaphore on which USB will listen.
//extern Semaphore_Handle semUSBTX;
/*
* usbTxMsgQueue - Message queue of USB interface to read.
* Will be filled in by Gossiper.
*/
//extern Queue_Handle usbTxMsgQueue;
//extern Semaphore_Handle ethTxsem;
//extern Queue_Handle ethTxMsgQueue;
/* Config message Queue */
/*
* This is the semaphore posted by either Interface (UART/Ethernet) when it has
* recieved from external world or Bigbrother task once frame is processed and
* needs to be sent back.
*/
Semaphore_Handle semGossiperMsg;
// Queue object
static Queue_Struct gossiperRxMsg;
static Queue_Struct gossiperTxMsg;
/*
* gossiperRxMsgQueue - Queue used by the Interface to
* send data to Gossiper
*/
Queue_Handle gossiperRxMsgQueue;
/*
* gossiperTxMsgQueue - Queue used by the Big brother to
* forward data to Gossiper
*/
Queue_Handle gossiperTxMsgQueue;
/* Global Task Configuration Variables */
static Task_Struct gossiperTask;
static Char gossiperTaskStack[GOSSIPER_TASK_STACK_SIZE];
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
static void gossiper_init();
static void gossiper_taskfxn(UArg a0, UArg a1);
static ReturnStatus gossiper_process_rx_msg(uint8_t *pMsg);
static ReturnStatus gossiper_process_tx_msg(uint8_t *pMsg);
static ReturnStatus gossiper_uart_send_msg(uint8_t *pMsg);
/*****************************************************************************
** FUNCTION NAME : gossiper_createtask
**
** DESCRIPTION : Creates task for Gossiper
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
void gossiper_createtask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = gossiperTaskStack;
taskParams.stackSize = GOSSIPER_TASK_STACK_SIZE;
taskParams.priority = GOSSIPER_TASK_PRIORITY;
Task_construct(&gossiperTask, gossiper_taskfxn, &taskParams, NULL);
LOGGER_DEBUG("GOSSIPER:INFO::Creating a Gossiper task.\n");
}
/*****************************************************************************
** FUNCTION NAME : gossiper_init
**
** DESCRIPTION : Initializes the gossiper task.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void gossiper_init(void)
{
/*Creating Semaphore for RX Message Queue*/
semGossiperMsg = Semaphore_create(0, NULL, NULL);
if (semGossiperMsg == NULL) {
LOGGER_ERROR("GOSSIPER:ERROR::GOSSIPER RX Semaphore creation failed.\n");
}
/*Creating RX Message Queue*/
gossiperRxMsgQueue = Util_constructQueue(&gossiperRxMsg);
LOGGER_DEBUG("GOSSIPER:INFO::Constructing message Queue 0x%x for RX Gossiper Messages.\n",
gossiperRxMsgQueue);
/*Creating TX Message Queue*/
gossiperTxMsgQueue = Util_constructQueue(&gossiperTxMsg);
LOGGER_DEBUG("GOSSIPER:INFO::Constructing message Queue 0x%x for TX Gossiper Messages.\n",
gossiperTxMsgQueue);
}
/*****************************************************************************
** FUNCTION NAME : gossiper_taskfxn
**
** DESCRIPTION : Recieve and transmitts media depenedent messages.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void gossiper_taskfxn(UArg a0, UArg a1)
{
gossiper_init();
while (true) {
if (Semaphore_pend(semGossiperMsg, BIOS_WAIT_FOREVER)) {
/* Gossiper RX Messgaes */
while (!Queue_empty(gossiperRxMsgQueue)) {
uint8_t *pWrite = (uint8_t *) Util_dequeueMsg(
gossiperRxMsgQueue);
if (pWrite) {
gossiper_process_rx_msg(pWrite);
} else {
LOGGER_ERROR("GOSSIPER::ERROR:: No Valid Pointer.\n");
}
}
/* Gossiper TX Messgaes */
while (!Queue_empty(gossiperTxMsgQueue)) {
uint8_t *pWrite = (uint8_t *) Util_dequeueMsg(
gossiperTxMsgQueue);
if (pWrite) {
gossiper_process_tx_msg(pWrite);
} else {
LOGGER_ERROR("GOSSIPER::ERROR:: No Valid Pointer.\n");
}
}
}
}
}
/*****************************************************************************
** FUNCTION NAME : gossiper_process_rx_msg
**
** DESCRIPTION : Processes the RX Gossiper messages
**
** ARGUMENTS : Pointer to message structure
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
static ReturnStatus gossiper_process_rx_msg(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("GOSSIPER:INFO:: Processing Gossiper RX Message.\n");
OCMPMessageFrame * pOCMPMessageFrame = (OCMPMessageFrame *) pMsg;
if (pOCMPMessageFrame != NULL) {
LOGGER_DEBUG("GOSSIPER:INFO:: RX Msg recieved with Length: 0x%x, Interface: 0x%x, Seq.No: 0x%x, TimeStamp: 0x%x.\n",
pOCMPMessageFrame->header.ocmpFrameLen,
pOCMPMessageFrame->header.ocmpInterface,
pOCMPMessageFrame->header.ocmpSeqNumber,
pOCMPMessageFrame->header.ocmpTimestamp);
/*Update the Debug info required based on the debug jumper connected*/
//status = CheckDebugEnabled()
if (pOCMPMessageFrame->message.msgtype == OCMP_MSG_TYPE_DEBUG) {
#if 0
if (!IN_DEBUGMODE()) {
// If board is not set in debug mode then discard the message.
} else {
pOCMPMessageFrame->message.msgtype = UNSET_DEBUG_MODE(
pOCMPMessageFrame->message.msgtype);
}
#endif
}
Util_enqueueMsg(bigBrotherRxMsgQueue, semBigBrotherMsg, (uint8_t*) pMsg);
} else {
LOGGER_ERROR("GOSSIPER:ERROR:: Not valid pointer.\n");
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : gossiper_process_tx_msg
**
** DESCRIPTION : Processes the Gossiper TX Messages
**
** ARGUMENTS : Pointer to message structure
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
static ReturnStatus gossiper_process_tx_msg(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("GOSSIPER:INFO:: Processing Gossiper TX Message.\n");
OCMPMessageFrame * pOCMPMessageFrame = (OCMPMessageFrame *) pMsg;
if (pOCMPMessageFrame != NULL) {
status = gossiper_uart_send_msg(pMsg);
} else {
LOGGER_ERROR("BIGBROTHER:ERROR:: Not valid pointer.\n");
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : gossiper_uart_send_msg
**
** DESCRIPTION : transmitt TX Messages to UART
**
** ARGUMENTS : Pointer to message
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
static ReturnStatus gossiper_uart_send_msg(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
LOGGER_DEBUG("GOSSIPER:INFO:: Forwarding TX message to the UART Interface.\n");
if (pMsg != NULL) {
Util_enqueueMsg(uartTxMsgQueue, semUARTTX, (uint8_t*) pMsg);
} else {
LOGGER_ERROR("GOSSIPER::ERROR::No Valid Pointer.\n");
}
return status;
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef GOSSIPER_H_
#define GOSSIPER_H_
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/utils/util.h"
/*****************************************************************************
* MACRO DEFINITIONS
*****************************************************************************/
#define GOSSIPER_TASK_PRIORITY 6
#define GOSSIPER_TASK_STACK_SIZE 2048
#define SET_DEBEUG_MODE(debugMode) ((debugMode | 0x00))
#define UNSET_DEBUG_MODE(debugMode) ((debugMode & 0x0f))
/*****************************************************************************
* HANDLE DEFINITIONS
*****************************************************************************/
/* Semaphore and Queue Handles for Gossiper */
extern Semaphore_Handle semGossiperMsg;
extern Queue_Handle gossiperTxMsgQueue;
extern Queue_Handle gossiperRxMsgQueue;
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
void gossiper_createtask(void);
#endif /* GOSSIPER_H_ */

View File

@@ -0,0 +1,267 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "Board.h"
#include "inc/common/global_header.h"
#include "inc/common/byteorder.h"
#include "inc/devices/eeprom.h"
#include <ti/drivers/I2C.h>
#ifndef UT_FRAMEWORK
#include <driverlib/emac.h> /* TODO: for htons - clean up this random include */
#endif
#include <string.h>
#define WP_ASSERT 1
#define WP_DEASSERT 0
extern Eeprom_Cfg eeprom_psu_sid;
extern Eeprom_Cfg eeprom_psu_inv;
static ReturnStatus i2c_eeprom_write(I2C_Handle i2cHandle,
uint8_t deviceAddress,
uint16_t regAddress,
const void *value,
size_t numofBytes);
static ReturnStatus i2c_eeprom_read(I2C_Handle i2cHandle,
uint16_t deviceAddress,
uint16_t regAddress,
void *value,
size_t numofbytes);
/*****************************************************************************
** FUNCTION NAME : eeprom_init
**
** DESCRIPTION : Initialize an EEPROM device (WP gpio / test read)
**
** ARGUMENTS : EEPROM config
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
bool eeprom_init(Eeprom_Cfg *cfg) {
/* Configure our WP pin (if any) and set to be low (protected) by default */
if (cfg->pin_wp) {
OcGpio_configure(cfg->pin_wp,
OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_HIGH);
}
/* Test communication to the EEPROM */
uint8_t test_byte;
if (eeprom_read(cfg, 0x00, &test_byte, sizeof(test_byte)) != RETURN_OK) {
return false;
}
return true;
}
/*****************************************************************************
** FUNCTION NAME : eeprom_read
**
** DESCRIPTION : Read the values from the EEPROM register.
**
** ARGUMENTS : EEPROM (Slave) address, Register address and
** pointer to value read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus eeprom_read(Eeprom_Cfg *cfg,
uint16_t address,
void *buffer,
size_t size)
{
ReturnStatus status = RETURN_OK;
I2C_Handle eepromHandle = i2c_get_handle(cfg->i2c_dev.bus);
if (!eepromHandle) {
LOGGER_ERROR("EEPROM:ERROR:: Failed to get I2C Bus for "
"EEPROM device 0x%x.\n", cfg->i2c_dev.slave_addr);
} else {
/* TODO: if we're concerned about hogging the bus, we could always
* page reads, but this doesn't seem necessary right now
*/
/* TODO: check for out-of-bounds addresses (some EEPROM wrap around
* when reading after the end, so this could lead to confusion)
*/
status = i2c_eeprom_read(eepromHandle, cfg->i2c_dev.slave_addr,
address, buffer, size);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : eeprom_write
**
** DESCRIPTION : Write the value to EEPROM register.
**
** ARGUMENTS : EEPROM (Slave) address, Register address and value
** to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus eeprom_write(const Eeprom_Cfg *cfg,
uint16_t address,
const void *buffer,
size_t size)
{
ReturnStatus status = RETURN_OK;
I2C_Handle eepromHandle = i2c_get_handle(cfg->i2c_dev.bus);
if (!eepromHandle) {
LOGGER_ERROR("EEPROM:ERROR:: Failed to get I2C Bus for "
"EEPROM device 0x%x.\n", cfg->i2c_dev.slave_addr);
} else {
/* Respect EEPROM page size */
const size_t page_size = cfg->type.page_size;
if (page_size) {
while (size > page_size) {
status = i2c_eeprom_write(eepromHandle, cfg->i2c_dev.slave_addr,
address, buffer, page_size);
size -= page_size;
address += page_size;
buffer = (const uint8_t *)buffer + page_size;
}
}
status = i2c_eeprom_write(eepromHandle, cfg->i2c_dev.slave_addr,
address, buffer, size);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : i2c_eeprom_write
**
** DESCRIPTION : Writing device register over i2c bus.
**
** ARGUMENTS : I2C handle, device address, register address and value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus i2c_eeprom_write(I2C_Handle i2cHandle,
uint8_t slaveAddress,
uint16_t memAddress,
const void *value,
size_t numofBytes)
{
ReturnStatus status = RETURN_OK;
uint8_t txBuffer[numofBytes + 1];
/*TODO: This approach needs to be looked into when same
* codebase is used for PSU and GBC
uint8_t txBuffer[numofBytes + 2];
*(uint16_t *)txBuffer = htobe16(memAddress);
memcpy((txBuffer + 2), value, numofBytes);
*/
*txBuffer = (memAddress & 0xFF);
slaveAddress |= ((memAddress >> 8 ) & 0x01);
memcpy((txBuffer + 1), value, numofBytes);
I2C_Transaction i2cTransaction;
i2cTransaction.slaveAddress = slaveAddress;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = sizeof(txBuffer);
i2cTransaction.readBuf = NULL;
i2cTransaction.readCount = 0;
if (I2C_transfer(i2cHandle, &i2cTransaction)) {
LOGGER_DEBUG("EEPROM:INFO:: I2C write success for device: 0x%x reg Addr: 0x%x\n",
slaveAddress, memAddress);
status = RETURN_OK;
} else {
LOGGER_ERROR("EEPROM:ERROR:: I2C write failed for for device: 0x%x reg Addr: 0x%x\n",
slaveAddress, memAddress);
status = RETURN_NOTOK;
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : i2c_eeprom_read
**
** DESCRIPTION : Reading device register over i2c bus.
**
** ARGUMENTS : I2C handle, device address, register address and value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus i2c_eeprom_read(I2C_Handle i2cHandle,
uint16_t slaveAddress,
uint16_t memAddress,
void *value,
size_t numofbytes)
{
ReturnStatus status = RETURN_OK;
// uint16_t txBuffer = htobe16(memAddress); /* Address is big-endian */
uint8_t txBuffer = (memAddress & 0xFF); /* Address is big-endian */
slaveAddress |= ((memAddress >> 8 )& 0x01);
I2C_Transaction i2cTransaction;
i2cTransaction.slaveAddress = slaveAddress;
i2cTransaction.writeBuf = &txBuffer;
i2cTransaction.writeCount = sizeof(txBuffer);
i2cTransaction.readBuf = value;
i2cTransaction.readCount = numofbytes;
if (I2C_transfer(i2cHandle, &i2cTransaction)) {
LOGGER_DEBUG("EEPROM:INFO:: I2C read success for device: 0x%x reg Addr: 0x%x\n",
slaveAddress, memAddress);
status = RETURN_OK;
} else {
LOGGER_ERROR("EEPROM:ERROR:: I2C write failed for for device: 0x%x reg Addr: 0x%x\n",
slaveAddress, memAddress);
status = RETURN_NOTOK;
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : eeprom_disable_write
**
** DESCRIPTION : Read the values from the EEPROM register.
**
** ARGUMENTS : EEPROM handle.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus eeprom_disable_write(Eeprom_Cfg *cfg)
{
if (cfg->pin_wp) {
OcGpio_write(cfg->pin_wp, WP_ASSERT);
}
/* TODO: error detection */
return RETURN_OK;
}
/*****************************************************************************
** FUNCTION NAME : eeprom_enable_write
**
** DESCRIPTION : Enable eeprom write operation.
**
** ARGUMENTS : EEPROM handle.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus eeprom_enable_write(Eeprom_Cfg *cfg)
{
if (cfg->pin_wp) {
OcGpio_write(cfg->pin_wp, WP_DEASSERT);
}
/* TODO: error detection */
return RETURN_OK;
}

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "threaded_int.h"
#include "inc/common/global_header.h"
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>
// Threaded interrupt info
//#define TI_TASKSTACKSIZE 1024
#define TI_TASKSTACKSIZE 512
#define TI_TASKPRIORITY 6
// This number is fairly superficial - just used to keep track of the
// various tasks, it can be increased without much overhead
#define MAX_DEVICES 30
// Config simply to map context to our GPIO interrupts
typedef struct InterruptConfig {
Semaphore_Handle sem; //!< Semaphore to wake up INT thread
ThreadedInt_Callback cb; //!< Callback to run when interrupt occurs
void *context; //!< Pointer to pass to cb function
} InterruptConfig;
static InterruptConfig s_intConfigs[MAX_DEVICES] = {};
static int s_numDevices = 0;
static void gpioIntFxn(const OcGpio_Pin *pin, void *context) {
Semaphore_Handle sem = context;
// TODO: this should probably be an assert
if (!sem) {
return;
}
/* Just wake up the TI task */
Semaphore_post(sem);
}
static void ThreadedInt_Task(UArg arg0, UArg arg1) {
InterruptConfig *cfg = (InterruptConfig *)arg0;
if (!cfg) {
DEBUG("Threaded Int started without configuration???\n");
return;
}
DEBUG("Threaded INT thread ready\n");
while (true) {
Semaphore_pend(cfg->sem, BIOS_WAIT_FOREVER);
cfg->cb(cfg->context);
}
}
// TODO: this function isn't thread safe at the moment
void ThreadedInt_Init(OcGpio_Pin *irqPin, ThreadedInt_Callback cb,
void *context) {
/*TODO: stop gap arrangement to prevent spawning tasks for monitoring alerts*/
// return;
// Build up table of all devices for interrupt handling. This is an ok
// workaround for TI RTOS GPIO interrupts for now (only using one device)
if (s_numDevices >= MAX_DEVICES) {
DEBUG("ThrdInt::FATAL: too many configurations");
return;
}
int devNum = s_numDevices++;
Semaphore_Handle sem = Semaphore_create(0, NULL, NULL);
if (!sem) {
DEBUG("ThrdInt::Can't create ISR semaphore\n");
return;
}
s_intConfigs[devNum] = (InterruptConfig) {
.sem = sem,
.cb = cb,
.context = context,
};
// Start interrupt handling task
// One task per interrupt, not that efficient, but we don't have much
// need to optimize into a thread pool
// TODO: look into error block and see if I should use it
Task_Params taskParams;
Task_Params_init(&taskParams);
taskParams.stackSize = TI_TASKSTACKSIZE;
taskParams.priority = TI_TASKPRIORITY;
taskParams.arg0 = (uintptr_t)&s_intConfigs[devNum];
Task_Handle task = Task_create(ThreadedInt_Task, &taskParams, NULL);
if (!task) {
DEBUG("ThrdInt::FATAL: Unable to start interrupt task\n");
Semaphore_delete(&sem);
s_numDevices--;
return;
}
// TODO: what do I do with task handle?
/* Set up IRQ pin callback */
OcGpio_setCallback(irqPin, gpioIntFxn, sem);
OcGpio_enableInt(irqPin);
}

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#ifndef DEVICES_I2C_THREADED_INT_H_
#define DEVICES_I2C_THREADED_INT_H_
#include "drivers/OcGpio.h"
typedef void (*ThreadedInt_Callback)(void *context);
void ThreadedInt_Init(OcGpio_Pin *irqPin, ThreadedInt_Callback cb,
void *context);
#endif /* DEVICES_I2C_THREADED_INT_H_ */

View File

@@ -0,0 +1,151 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "Board.h"
#include "helpers/array.h"
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
/* TI-RTOS driver files */
#include <ti/drivers/I2C.h>
#include <string.h>
//*****************************************************************************
// HANDLES DEFINITION
//*****************************************************************************
I2C_Handle OC_I2C_Handle[Board_I2CCOUNT] = {};
/*****************************************************************************
** FUNCTION NAME : i2c_open_bus
**
** DESCRIPTION : Initialize I2C Bus
**
** ARGUMENTS : I2C bus index
**
** RETURN TYPE : I2C_Handle (NULL on failure)
**
*****************************************************************************/
I2C_Handle i2c_open_bus(unsigned int index)
{
if (index >= ARRAY_SIZE(OC_I2C_Handle)) {
LOGGER_ERROR("I2CBUS:ERROR:: I2C bus %d not found\n", index);
return NULL;
}
I2C_Params i2cParams;
I2C_Params_init(&i2cParams);
i2cParams.bitRate = I2C_400kHz;
if (!OC_I2C_Handle[index]) {
OC_I2C_Handle[index] = I2C_open(index, &i2cParams);
if (!OC_I2C_Handle[index]) {
LOGGER_ERROR("I2CBUS:ERROR:: Failed Initializing I2C bus %d.\n",
index);
}
}
return OC_I2C_Handle[index];
}
/*****************************************************************************
** FUNCTION NAME : i2c_close_bus
**
** DESCRIPTION : Initialize I2C Bus
**
** ARGUMENTS : I2C bus index
**
** RETURN TYPE : None
**
*****************************************************************************/
void i2c_close_bus(I2C_Handle* i2cHandle)
{
I2C_close(*i2cHandle);
i2cHandle = NULL;
}
/*****************************************************************************
** FUNCTION NAME : i2c_reg_write
**
** DESCRIPTION : Writing device register over i2c bus.
**
** ARGUMENTS : I2C handle, device address, register address and value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus i2c_reg_write( I2C_Handle i2cHandle,
uint8_t deviceAddress,
uint8_t regAddress,
uint16_t value,
uint8_t numofBytes)
{
ReturnStatus status = RETURN_OK;
uint8_t txBuffer[3];
I2C_Transaction i2cTransaction;
txBuffer[0] = regAddress;
memcpy(&txBuffer[1],&value,numofBytes);
i2cTransaction.slaveAddress = deviceAddress;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = numofBytes + 1;
i2cTransaction.readBuf = NULL;
i2cTransaction.readCount = 0;
if (I2C_transfer(i2cHandle, &i2cTransaction)) {
//LOGGER_DEBUG("I2CBUS:INFO:: I2C write success for device: 0x%x reg Addr: 0x%x value: 0x%x.\n",
// deviceAddress, regAddress, value);
status = RETURN_OK;
} else {
LOGGER_ERROR("I2CBUS:ERROR:: I2C write failed for for device: 0x%x reg Addr: 0x%x value: 0x%x.\n",
deviceAddress, regAddress, value);
status = RETURN_NOTOK;
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : i2c_reg_read
**
** DESCRIPTION : Reading device register over i2c bus.
**
** ARGUMENTS : I2C handle, device address, register address and value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus i2c_reg_read( I2C_Handle i2cHandle,
uint8_t deviceAddress,
uint8_t regAddress,
uint16_t *value,
uint8_t numofBytes)
{
ReturnStatus status = RETURN_OK;
uint8_t txBuffer[1] = { 0 };
uint8_t rxBuffer[2] = { 0 };
txBuffer[0] = regAddress;
I2C_Transaction i2cTransaction;
i2cTransaction.slaveAddress = deviceAddress;
i2cTransaction.writeBuf = &txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = numofBytes;
if (I2C_transfer(i2cHandle, &i2cTransaction)) {
memcpy(value,rxBuffer,numofBytes);
LOGGER_ERROR("I2CBUS:INFO:: I2C read success for device: 0x%x reg Addr: 0x%x value : 0x%x.\n",
deviceAddress, regAddress, *value);
status = RETURN_OK;
} else {
LOGGER_ERROR("I2CBUS:ERROR:: I2C read failed for for device: 0x%x reg Addr: 0x%x.\n",
deviceAddress, regAddress);
status = RETURN_NOTOK;
}
return status;
}

View File

@@ -0,0 +1,596 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "devices/i2c/threaded_int.h"
#include "inc/common/byteorder.h"
#include "inc/common/global_header.h"
#include "inc/devices/ina226.h"
#include "helpers/memory.h"
/*****************************************************************************
* REGISTER DEFINITIONS
*****************************************************************************/
#define INA_CONFIGURATION_REG 0x00
#define INA_SHUNTVOLTAGE_REG 0x01
#define INA_BUSVOLTAGE_REG 0x02
#define INA_POWER_REG 0x03
#define INA_CURRENT_REG 0x04
#define INA_CALIBRATION_REG 0x05
#define INA_MASKENABLE_REG 0x06
#define INA_ALERTLIMIT_REG 0x07
#define INA_MANUFACTUREID_REG 0xFE
#define INA_DIEID_REG 0xFF
/*INA226 Device Info */
#define INA226_MANFACTURE_ID 0x5449
#define INA226_DEVICE_ID 0x2260
#define INA226_DEV_VERSION 0x00
/* Configuration Register Bits */
#define INA_CFG_RESET (1 << 15)
/*
* Conversion of current into Shunt Voltage Register contents and viceversa.
*
* First Calculate the Current Register Value from the given Current Value
* ui16rfINARegValue = ui16rfINACurrentLimit/(INA226_CURRENT_LSB);
* Calculate Shunt Voltage Alert Limit Register Value
* ui16rfINARegValue = (ui16rfINARegValue * 2048)/INA226_CALIBRATION_REG_VALUE;
*/
#define CURRENT_TO_REG(x) ((2048 *(x/INA226_CURRENT_LSB)/INA226_CAL_REG_VALUE))
#define REG_TO_CURRENT(y) ((y * INA226_CURRENT_LSB * INA226_CAL_REG_VALUE)/2048)
/*****************************************************************************
* CONSTANTS DEFINITIONS
*****************************************************************************/
/* INA226 LSB Values */
#define INA226_VSHUNT_LSB 2.5 /* 2.5uV or 2500nV (uV default) */
#define INA226_VBUS_LSB 1.25 /* 1.25mV or 1250uV (mV default) */
//#define INA226_CURRENT_LSB 0.1 /* 0.100mA 0r 100uA (mA default) */
#define INA226_CURRENT_LSB 0.00205 /* 0.100mA 0r 100uA (mA default) */
#define INA226_POWER_LSB 2.5 /* 2.5mW or 2500uW (mW default) */
/* Configure the Configuration register with Number of Samples and Conversion
* Time for Shunt and Bus Voltage.
* Min(Default):0x4127; Max: 0x4FFF; Average: 0x476F
*/
#define INA226_CONFIG_REG_VALUE 0x476F
/* Configure Calibration register with shunt resistor value and current LSB.
Current_LSB = Maximum Expected Current/2^15
Current_LSB = 2A/2^15 = 0.00006103515625 = 61uA ~ 100uA(Maximum Expected Current = 2A)
Calibration Register(CAL) = 0.00512/(Current_LSB*RSHUNT)
CAL = 0.00512/(100uA*2mOhm) = = 25600 = 0x6400.(RSHUNT = 2mohm)
*/
//#define INA226_CAL_REG_VALUE 0x6400
#define INA226_CAL_REG_VALUE 0xA3D7
#define INA226_MASKEN_REG_VALUE 0x8001
extern __attribute__((weak)) OcGpio_Port ec_io;
void watchdog_pin()
{
OcGpio_Pin pin_watchdog = { &ec_io, 2 };
const uint32_t pin_evt_cfg = 0;
OcGpio_configure(&pin_watchdog, pin_evt_cfg);
while(1) {
OcGpio_write(&pin_watchdog, true);
//Task_sleep(4*500);
OcGpio_write(&pin_watchdog, false);
}
return;
}
/*****************************************************************************
** FUNCTION NAME : read_ina_reg
**
** DESCRIPTION : Read a 16 bit value from INA226 register.
**
** ARGUMENTS : i2c device, Register address and value
** to be read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus read_ina_reg(const INA226_Dev *dev,
uint8_t regAddress,
uint16_t *regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle inaHandle = i2c_get_handle(dev->cfg.dev.bus);
if (!inaHandle) {
LOGGER_ERROR("INASENSOR:ERROR:: Failed to get I2C Bus for INA sensor "
"0x%x on bus 0x%x.\n", dev->cfg.dev.slave_addr,
dev->cfg.dev.bus);
} else {
status = i2c_reg_read(inaHandle, dev->cfg.dev.slave_addr, regAddress,
regValue, 2);
*regValue = betoh16(*regValue);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : write_ina_reg
**
** DESCRIPTION : Write 16 bit value to INA226 register.
**
** ARGUMENTS : i2c device, Register address and value
** to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus write_ina_reg(const INA226_Dev *dev,
uint8_t regAddress,
uint16_t regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle inaHandle = i2c_get_handle(dev->cfg.dev.bus);
if (!inaHandle) {
LOGGER_ERROR("INASENSOR:ERROR:: Failed to get I2C Bus for INA sensor "
"0x%x on bus 0x%x.\n", dev->cfg.dev.slave_addr,
dev->cfg.dev.bus);
} else {
regValue = htobe16(regValue);
status = i2c_reg_write(inaHandle, dev->cfg.dev.slave_addr, regAddress,
regValue, 2);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_dev_id
**
** DESCRIPTION : Read the device id of Current sensor.
**
** ARGUMENTS : i2c device and pointer to device Id.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus ina226_getDevId(INA226_Dev *dev, uint16_t *devID)
{
return read_ina_reg(dev, INA_DIEID_REG, devID);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_mfg_id
**
** DESCRIPTION : Read the mfg id of Current sensor.
**
** ARGUMENTS : i2c device and out-pointer to manufacturing ID.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus ina226_getMfgId(INA226_Dev *dev, uint16_t *mfgID)
{
return read_ina_reg(dev, INA_MANUFACTUREID_REG, mfgID);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_set_cfg_reg
**
** DESCRIPTION : Write the value to Current sensor configuration
** register.
**
** ARGUMENTS : i2c device and new value of configuration register.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus _set_cfg_reg(INA226_Dev *dev, uint16_t regValue)
{
return write_ina_reg(dev, INA_CONFIGURATION_REG, regValue);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_set_cal_reg
**
** DESCRIPTION : Write the value to Current sensor calibration register.
**
** ARGUMENTS : i2c device and new value of calibration register.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus _set_cal_reg(INA226_Dev *dev, uint16_t regValue)
{
return write_ina_reg(dev, INA_CALIBRATION_REG, regValue);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_curr_limit
**
** DESCRIPTION : Read the value of Current sensor alert limit register.
**
** ARGUMENTS : i2c device and out-pointer to current limit.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_readCurrentLim(INA226_Dev *dev, uint16_t* currLimit)
{
uint16_t regValue = 0x0000;
ReturnStatus status = read_ina_reg(dev, INA_ALERTLIMIT_REG, &regValue);
if (status == RETURN_OK) {
*currLimit = REG_TO_CURRENT(regValue);
LOGGER_DEBUG("INASENSOR:INFO:: INA sensor 0x%x on bus 0x%x is "
"reporting current limit of %d mA.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *currLimit);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_set_curr_limit
**
** DESCRIPTION : Write the value to Current sensor alert limit register.
**
** ARGUMENTS : i2c device and new current limit.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_setCurrentLim(INA226_Dev *dev, uint16_t currLimit)
{
uint16_t regValue = CURRENT_TO_REG(currLimit);
return write_ina_reg(dev, INA_ALERTLIMIT_REG, regValue);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_read_alert_reg
**
** DESCRIPTION : Read the value to Current sensor mask/enable register.
**
** ARGUMENTS : i2c device and out-pointer to enable and mask bits.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus _read_alert_reg(INA226_Dev *dev, uint16_t* regValue)
{
return read_ina_reg(dev, INA_MASKENABLE_REG, regValue);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_enable_alert
**
** DESCRIPTION : Write the value to Current sensor mask/enable register.
**
** ARGUMENTS : i2c device and alert to be enabled.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus _enable_alert(INA226_Dev *dev, uint16_t regValue)
{
return write_ina_reg(dev, INA_MASKENABLE_REG, regValue);
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_bus_volt_value
**
** DESCRIPTION : Read the value of Current sensor bus voltage value.
**
** ARGUMENTS : i2c device and out-pointer to bus voltage value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_readBusVoltage(INA226_Dev *dev,
uint16_t* busVoltValue)
{
uint16_t regValue;
ReturnStatus status = read_ina_reg(dev, INA_BUSVOLTAGE_REG, &regValue);
if (status == RETURN_OK) {
*busVoltValue = regValue * INA226_VBUS_LSB;
LOGGER_DEBUG("INASENSOR:INFO:: INA sensor 0x%x on bus 0x%x is "
"reporting bus voltage value of %d mV.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *busVoltValue);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_shunt_volt_value
**
** DESCRIPTION : Read the value of Current sensor shunt voltage value.
**
** ARGUMENTS : i2c device and out-pointer to shunt voltage.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_readShuntVoltage(INA226_Dev *dev,
uint16_t* shuntVoltValue)
{
uint16_t regValue;
ReturnStatus status = read_ina_reg(dev, INA_SHUNTVOLTAGE_REG, &regValue);
if (status == RETURN_OK) {
*shuntVoltValue = regValue * INA226_VSHUNT_LSB;
LOGGER_DEBUG("INASENSOR:INFO:: INA sensor 0x%x on bus 0x%x is "
"reporting shunt voltage value of %d uV.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *shuntVoltValue);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_curr_value
**
** DESCRIPTION : Read the value of Current sensor current value.
**
** ARGUMENTS : i2c device and out-pointer to current value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_readCurrent(INA226_Dev *dev, uint16_t* currValue)
{
uint16_t regValue;
ReturnStatus status = read_ina_reg(dev, INA_CURRENT_REG, &regValue);
if (status == RETURN_OK) {
*currValue = regValue * INA226_CURRENT_LSB;
LOGGER_DEBUG("INASENSOR:INFO:: INA sensor 0x%x on bus 0x%x "
"is reporting current value of %d mA.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *currValue);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : curr_sens_get_power_value
**
** DESCRIPTION : Read the value of Current sensor power value.
**
** ARGUMENTS : i2c device and out-pointer to power value.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ina226_readPower(INA226_Dev *dev, uint16_t* powValue)
{
uint16_t regValue;
ReturnStatus status = read_ina_reg(dev, INA_POWER_REG, &regValue);
if (status == RETURN_OK) {
*powValue = regValue * INA226_POWER_LSB;
LOGGER_DEBUG("INASENSOR:INFO:: INA sensor 0x%x on bus 0x%x is "
"reporting power value of %d mV.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *powValue);
}
return status;
}
/*****************************************************************************
* Internal IRQ handler - reads in triggered interrupts and dispatches CBs
*****************************************************************************/
static void _ina226_isr(void *context) {
INA226_Dev *dev = context;
/* Read the alert mask register (will clear the alert bit if set) */
/* TODO: this seems to be a strange bug in the sensor - sometimes it returns
* 0xFF as the lo-byte. If this occurs, we need to re-read it.
* NOTE: 0x1F is a perfectly legal value, but bits 5-9 are RFU and
* normally zero */
uint16_t alert_mask = 0xFFFF;
while (LOBYTE(alert_mask) == 0xFF) {
if (_read_alert_reg(dev, &alert_mask) != RETURN_OK) {
LOGGER_DEBUG("INA226:ERROR:: INT mask read failed\n");
return;
}
}
if (!dev->obj.alert_cb) {
return;
}
if (alert_mask & INA_MSK_AFF) {
/* This alert was caused by a fault */
/* Theory of operation: After reading the alert, we change the alert
* mask to look at the complement alert. For example, after getting a
* bus over-voltage alert, we switch the mask to tell us when it's
* under-voltage and thus back in operating limits so that it's less
* likely that we'll miss alerts on the shared line, although not
* guaranteed :( */
/* The device can only monitor one metric at a time, if multiple flags
* are set, it monitors the highest order bit, so check the config
* in order, from MSB to LSB */
uint16_t value;
uint16_t new_mask = alert_mask & (~INA_ALERT_EN_MASK);
INA226_Event evt;
uint16_t alert_lim;
ina226_readCurrentLim(dev, &alert_lim);
if (alert_mask & INA_MSK_SOL) {
if (dev->obj.evt_to_monitor == INA226_EVT_COL ||
dev->obj.evt_to_monitor == INA226_EVT_CUL) {
if (ina226_readCurrent(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
alert_lim -= INA_HYSTERESIS;
evt = INA226_EVT_COL;
} else {
if (ina226_readShuntVoltage(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
evt = INA226_EVT_SOL;
}
new_mask |= INA_MSK_SUL;
} else if (alert_mask & INA_MSK_SUL) {
if (dev->obj.evt_to_monitor == INA226_EVT_CUL ||
dev->obj.evt_to_monitor == INA226_EVT_COL) {
if (ina226_readCurrent(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
alert_lim += INA_HYSTERESIS;
evt = INA226_EVT_CUL;
} else {
if (ina226_readShuntVoltage(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
evt = INA226_EVT_SUL;
}
new_mask |= INA_MSK_SOL;
} else if (alert_mask & INA_MSK_BOL) {
if (ina226_readBusVoltage(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
evt = INA226_EVT_BOL;
new_mask |= INA_MSK_BUL;
} else if (alert_mask & INA_MSK_BUL) {
if (ina226_readBusVoltage(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
evt = INA226_EVT_BUL;
new_mask |= INA_MSK_BOL;
} else if (alert_mask & INA_MSK_POL) {
if (ina226_readPower(dev, &value) != RETURN_OK) {
value = UINT16_MAX;
}
evt = INA226_EVT_POL;
/* TODO: there isn't a PUL alert, not sure what to do here. We
* don't currently use this alert, but it would be nice to have a
* complete driver */
new_mask |= INA_MSK_POL;
} else {
LOGGER_ERROR("INA226:Unknown alert type\n");
return;
}
/* Set a new limit in order to account for hysteresis */
/* TODO: make this work for all alert types (this is a hack) */
ina226_setCurrentLim(dev, alert_lim);
/* Invert the alert type we're looking for */
if (_enable_alert(dev, new_mask) != RETURN_OK) {
/* TODO [HACK]: this sometimes reports failures at random times, so
* this is a hacked together retry to keep things stable*/
_enable_alert(dev, new_mask);
}
dev->obj.alert_cb(evt, value, dev->obj.cb_context);
}
/* TODO: Conversion ready not handled */
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus ina226_init(INA226_Dev *dev)
{
ReturnStatus status;
dev->obj = (INA226_Obj){};
/* Perform a device reset to be safe */
status = _set_cfg_reg(dev, INA_CFG_RESET);
if (status != RETURN_OK) {
return status;
}
/* Configure the Configuration register with number of samples and
* conversion time for shunt and bus voltage */
status = _set_cfg_reg(dev, INA226_CONFIG_REG_VALUE);
if (status != RETURN_OK) {
return status;
}
/* Configure the Calibration register with shunt resistor value and
* current LSB */
status = _set_cal_reg(dev, INA226_CAL_REG_VALUE);
if (status != RETURN_OK) {
return status;
}
/* Make sure we're talking to the right device */
// if (ina226_probe(dev) != POST_DEV_FOUND) {
// return RETURN_NOTOK;
// }
if (dev->cfg.pin_alert) {
const uint32_t pin_evt_cfg = OCGPIO_CFG_INPUT | OCGPIO_CFG_INT_FALLING;
if (OcGpio_configure(dev->cfg.pin_alert, pin_evt_cfg) < OCGPIO_SUCCESS) {
return RETURN_NOTOK;
}
/* Use a threaded interrupt to handle IRQ */
// ThreadedInt_Init(dev->cfg.pin_alert, _ina226_isr, (void *)dev);
}
return RETURN_OK;
}
/*****************************************************************************
*****************************************************************************/
void ina226_setAlertHandler(INA226_Dev *dev, INA226_CallbackFn alert_cb,
void *cb_context) {
dev->obj.alert_cb = alert_cb;
dev->obj.cb_context = cb_context;
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus ina226_enableAlert(INA226_Dev *dev, INA226_Event evt)
{
/* TODO: perhaps caching the mask is better? If we have an active alert,
* we'll inadvertently clear it here */
/* TODO: this isn't thread safe, but does it need to be? */
uint16_t alert_mask;
ReturnStatus res = _read_alert_reg(dev, &alert_mask);
if (res != RETURN_OK) {
return res;
}
alert_mask &= (~INA_ALERT_EN_MASK); /* Wipe out previous alert EN bits */
//alert_mask |= (INA_MSK_LEN); /* Enable latch mode (never miss an alert) */
dev->obj.evt_to_monitor = evt;
switch (evt) {
case INA226_EVT_COL:
alert_mask |= INA_MSK_SOL;
break;
case INA226_EVT_CUL:
alert_mask |= INA_MSK_SUL;
break;
default:
alert_mask |= evt;
}
return _enable_alert(dev, alert_mask);
}
/*****************************************************************************
*****************************************************************************/
ePostCode ina226_probe(INA226_Dev *dev, POSTData *postData)
{
uint16_t devId = 0x00;
uint16_t manfId = 0x0000;
if (ina226_getDevId(dev, &devId) != RETURN_OK) {
return POST_DEV_MISSING;
}
if (devId != INA226_DEVICE_ID) {
return POST_DEV_ID_MISMATCH;
}
if (ina226_getMfgId(dev, &manfId) != RETURN_OK) {
return POST_DEV_MISSING;
}
if (manfId != INA226_MANFACTURE_ID) {
return POST_DEV_ID_MISMATCH;
}
post_update_POSTData(postData, dev->cfg.dev.bus, dev->cfg.dev.slave_addr,manfId, devId);
return POST_DEV_FOUND;
}

View File

@@ -0,0 +1,604 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "devices/i2c/threaded_int.h"
#include "inc/common/byteorder.h"
#include "inc/devices/ltc4015.h"
#include "helpers/math.h"
#include "helpers/memory.h"
#include "ltc4015_registers.h"
#include <math.h>
#include <stdlib.h> /* For abort() */
#define WTF abort()
static ReturnStatus LTC4015_reg_write(const LTC4015_Dev *dev,
uint8_t regAddress,
uint16_t regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle battHandle = i2c_get_handle(dev->cfg.i2c_dev.bus);
if (!battHandle) {
LOGGER_ERROR("LTC4015:ERROR:: Failed to open I2C bus for battery "
"charge controller 0x%x.\n", dev->cfg.i2c_dev.slave_addr);
} else {
regValue = htole16(regValue);
status = i2c_reg_write(battHandle, dev->cfg.i2c_dev.slave_addr,
regAddress, regValue, 2);
}
return status;
}
static ReturnStatus LTC4015_reg_read(const LTC4015_Dev *dev,
uint8_t regAddress,
uint16_t *regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle battHandle = i2c_get_handle(dev->cfg.i2c_dev.bus);
if (!battHandle) {
LOGGER_ERROR("LTC4015:ERROR:: Failed to open I2C bus for battery "
"charge controller 0x%x.\n", dev->cfg.i2c_dev.slave_addr);
} else {
status = i2c_reg_read(battHandle, dev->cfg.i2c_dev.slave_addr,
regAddress, regValue, 2);
*regValue = letoh16(*regValue);
}
return status;
}
ReturnStatus LTC4015_cfg_icharge(LTC4015_Dev *dev,
uint16_t max_chargeCurrent) // milliAmps
{
/* Maximum charge current target = (ICHARGE_TARGET + 1) * 1mV/RSNSB
=> ICHARGE_TARGET = (target*RSNSB/1mV)-1 */
int icharge_target = round((max_chargeCurrent * dev->cfg.r_snsb) / 1000.0)
- 1;
icharge_target = MAX(0, icharge_target);
return LTC4015_reg_write(dev, LTC4015_ICHARGE_TARGET_SUBADDR,
icharge_target);
}
ReturnStatus LTC4015_get_cfg_icharge(LTC4015_Dev *dev,
uint16_t *max_chargeCurrent) // milliAmps
{
/* Maximum charge current target = (ICHARGE_TARGET + 1) * 1mV/RSNSB */
uint16_t ichargeCurrent = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_ICHARGE_TARGET_SUBADDR,
&ichargeCurrent);
*max_chargeCurrent = (ichargeCurrent + 1) * 1000 / dev->cfg.r_snsb;
return status;
}
ReturnStatus LTC4015_cfg_vcharge(LTC4015_Dev *dev,
uint16_t charge_voltageLevel) // millivolts
{
/* See datasheet, page 61:VCHARGE_SETTING */
const double target_v = charge_voltageLevel / (1000.0 * dev->cfg.cellcount);
double vchargeSetting;
switch (dev->cfg.chem) {
case LTC4015_CHEM_LEAD_ACID:
vchargeSetting = round((target_v - 2.0) * 105.0);
break;
case LTC4015_CHEM_LI_FE_PO4:
vchargeSetting = round((target_v - 3.4125) * 80.0);
break;
case LTC4015_CHEM_LI_ION:
vchargeSetting = round((target_v - 3.8125) * 80.0);
break;
default:
WTF;
break;
}
vchargeSetting = MAX(0, vchargeSetting);
return LTC4015_reg_write(dev, LTC4015_VCHARGE_SETTING_SUBADDR,
vchargeSetting);
}
ReturnStatus LTC4015_get_cfg_vcharge(LTC4015_Dev *dev,
uint16_t *charge_voltageLevel) // millivolts
{
/* See datasheet, page 61:VCHARGE_SETTING */
uint16_t vchargeSetting = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_VCHARGE_SETTING_SUBADDR,
&vchargeSetting);
switch (dev->cfg.chem) {
case LTC4015_CHEM_LEAD_ACID:
*charge_voltageLevel =
round(((vchargeSetting / 105.0) + 2.0) *
dev->cfg.cellcount * 1000.0);
break;
case LTC4015_CHEM_LI_FE_PO4:
*charge_voltageLevel =
round(((vchargeSetting / 80.0) + 3.4125) *
dev->cfg.cellcount * 1000.0);
break;
case LTC4015_CHEM_LI_ION:
*charge_voltageLevel =
round(((vchargeSetting / 80.0) + 3.8125) *
dev->cfg.cellcount * 1000.0);
break;
default:
WTF;
break;
}
/* TODO: bounds check? */
return status;
}
/* Convert a voltage to a valid vbat register value */
static uint16_t voltage_to_vbat_reg(LTC4015_Dev *dev,
int16_t voltage)
{
switch (dev->cfg.chem) {
case LTC4015_CHEM_LEAD_ACID:
return (voltage / (dev->cfg.cellcount * 128.176)) * 1000.0;
case LTC4015_CHEM_LI_FE_PO4:
case LTC4015_CHEM_LI_ION:
return (voltage / (dev->cfg.cellcount * 192.264)) * 1000.0;
default:
WTF;
break;
}
return 0; /* Should never get here, but keeps compiler happy */
}
ReturnStatus LTC4015_cfg_battery_voltage_low(LTC4015_Dev *dev,
int16_t underVoltage) //millivolts
{
/* See datasheet, page 56:VBAT_LO_ALERT_LIMIT
under voltage limit = [VBAT_*_ALERT_LIMIT] • x(uV) */
return LTC4015_reg_write(dev, LTC4015_VBAT_LO_ALERT_LIMIT_SUBADDR,
voltage_to_vbat_reg(dev, underVoltage));
}
/* Convert a voltage to a valid vbat register value */
static int16_t vbat_reg_to_voltage(LTC4015_Dev *dev,
uint16_t vbat_reg)
{
switch (dev->cfg.chem) {
case LTC4015_CHEM_LEAD_ACID:
return ((int16_t) vbat_reg / 1000.0) * (128.176 * dev->cfg.cellcount);
case LTC4015_CHEM_LI_FE_PO4:
case LTC4015_CHEM_LI_ION:
return ((int16_t) vbat_reg / 1000.0) * (192.264 * dev->cfg.cellcount);
default:
WTF;
break;
}
return 0; /* Should never get here, but keeps compiler happy */
}
ReturnStatus LTC4015_get_cfg_battery_voltage_low(LTC4015_Dev *dev,
int16_t *underVolatage) //millivolts
{
/* See datasheet, page 56 */
uint16_t vbatLoLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_VBAT_LO_ALERT_LIMIT_SUBADDR,
&vbatLoLimit);
*underVolatage = vbat_reg_to_voltage(dev, vbatLoLimit);
return status;
}
ReturnStatus LTC4015_cfg_battery_voltage_high(LTC4015_Dev *dev,
int16_t overVoltage) //millivolts
{
/* See datasheet, page 56:VBAT_HI_ALERT_LIMIT
under voltage limit = [VBAT_*_ALERT_LIMIT] • x(uV) */
return LTC4015_reg_write(dev, LTC4015_VBAT_HI_ALERT_LIMIT_SUBADDR,
voltage_to_vbat_reg(dev, overVoltage));
}
ReturnStatus LTC4015_get_cfg_battery_voltage_high(LTC4015_Dev *dev,
int16_t *overVoltage) //millivolts
{
/* See datasheet, page 56 */
uint16_t vbatHiLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_VBAT_HI_ALERT_LIMIT_SUBADDR,
&vbatHiLimit);
*overVoltage = vbat_reg_to_voltage(dev, vbatHiLimit);
return status;
}
ReturnStatus LTC4015_cfg_input_voltage_low(LTC4015_Dev *dev,
int16_t inputUnderVoltage) // millivolts
{
/* See datasheet, page 56:VIN_LO_ALERT_LIMIT
VIN_LO_ALERT_LIMIT = limit/1.648mV */
uint16_t vinLoLimit = (inputUnderVoltage / (1.648));
return LTC4015_reg_write(dev, LTC4015_VIN_LO_ALERT_LIMIT_SUBADDR,
vinLoLimit);
}
ReturnStatus LTC4015_get_cfg_input_voltage_low(LTC4015_Dev *dev,
int16_t *inpUnderVoltage) //millivolts
{
/* See datasheet, page 56
* VIN_LO_ALERT_LIMIT = (inpUnderVoltage/(1.648)) */
uint16_t vInLoAlertLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_VIN_LO_ALERT_LIMIT_SUBADDR,
&vInLoAlertLimit);
*inpUnderVoltage = (int16_t) vInLoAlertLimit * 1.648;
return status;
}
ReturnStatus LTC4015_cfg_input_current_high(LTC4015_Dev *dev,
int16_t inputOvercurrent) // milliAmps
{
/* See datasheet, page 56:IIN_HI_ALERT_LIMIT
IIN_HI_ALERT_LIMIT = (limit*RSNSI)/1.46487uV */
uint16_t iInHiLimit = ((inputOvercurrent * dev->cfg.r_snsi) / 1.46487);
return LTC4015_reg_write(dev, LTC4015_IIN_HI_ALERT_LIMIT_SUBADDR,
iInHiLimit);
}
ReturnStatus LTC4015_get_cfg_input_current_high(LTC4015_Dev *dev,
int16_t *inpOverCurrent)
{
/* See datasheet, page 56
* IIN_HI_ALERT_LIMIT = ((inpOverCurrent*PWR_INT_BATT_RSNSI)/(1.46487)) */
uint16_t iInHiALertLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_IIN_HI_ALERT_LIMIT_SUBADDR,
&iInHiALertLimit);
*inpOverCurrent = ((int16_t) iInHiALertLimit * 1.46487) / dev->cfg.r_snsi;
return status;
}
ReturnStatus LTC4015_cfg_battery_current_low(LTC4015_Dev *dev,
int16_t lowbattCurrent)
{
/* See datasheet, page 56:IBAT_LO_ALERT_LIMIT
IBAT_LO_ALERT_LIMIT = (limit*RSNSB)/1.46487uV */
uint16_t iBatLoAlertLimit = (lowbattCurrent * dev->cfg.r_snsb) / (1.46487);
return LTC4015_reg_write(dev, LTC4015_IBAT_LO_ALERT_LIMIT_SUBADDR,
iBatLoAlertLimit);
}
ReturnStatus LTC4015_get_cfg_battery_current_low(LTC4015_Dev *dev,
int16_t *lowbattCurrent)
{
/* See datasheet, page 56
* IBAT_LO_ALERT_LIMIT = ((current*PWR_INT_BATT_RSNSB)/(1.46487)) */
uint16_t iBatLoAlertLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_IBAT_LO_ALERT_LIMIT_SUBADDR,
&iBatLoAlertLimit);
*lowbattCurrent = ((int16_t) iBatLoAlertLimit * 1.46487) / dev->cfg.r_snsb;
return status;
}
ReturnStatus LTC4015_cfg_die_temperature_high(LTC4015_Dev *dev,
int16_t dieTemp) // Degrees C
{
/* See datasheet, page 57:DIE_TEMP_HI_ALERT_LIMIT
DIE_TEMP_HI_ALERT_LIMIT = (DIE_TEMP • 12010)/45.6°C */
uint16_t dieTempAlertLimit = (dieTemp * 45.6) + 12010;
return LTC4015_reg_write(dev, LTC4015_DIE_TEMP_HI_ALERT_LIMIT_SUBADDR,
dieTempAlertLimit);
}
ReturnStatus LTC4015_get_cfg_die_temperature_high(LTC4015_Dev *dev,
int16_t *dieTemp) // Degrees C
{
/* See datasheet, page 57
* DIE_TEMP_HI_ALERT_LIMIT = (dieTemp • 12010)/45.6°C */
uint16_t dieTempAlertLimit = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_DIE_TEMP_HI_ALERT_LIMIT_SUBADDR,
&dieTempAlertLimit);
*dieTemp = (((int16_t) dieTempAlertLimit - 12010) / 45.6);
return status;
}
ReturnStatus LTC4015_cfg_input_current_limit(LTC4015_Dev *dev,
uint16_t inputCurrentLimit) // milliAmps
{
/* See datasheet, page 61:IIN_LIMIT_SETTING
IIN_LIMIT_SETTING = (limit * RSNSI / 500uV) - 1 */
/* TODO: range check? this is only a 6-bit register */
uint16_t iInLimitSetting = ((inputCurrentLimit * dev->cfg.r_snsi) / 500) - 1;
return LTC4015_reg_write(dev, LTC4015_IIN_LIMIT_SETTING_SUBADDR,
iInLimitSetting);
}
ReturnStatus LTC4015_get_cfg_input_current_limit(LTC4015_Dev *dev,
uint16_t *currentLimit) //milli Amps
{
/* See datasheet, page 56
* Input current limit setting = (IIN_LIMIT_SETTING + 1) • 500uV / RSNSI */
uint16_t iInlimitSetting = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev,
LTC4015_IIN_LIMIT_SETTING_SUBADDR,
&iInlimitSetting);
*currentLimit = ((iInlimitSetting + 1) * 500.0) / dev->cfg.r_snsi;
return status;
}
ReturnStatus LTC4015_get_die_temperature(LTC4015_Dev *dev,
int16_t *dieTemp) // Degrees C
{
/* Datasheet page 71: temperature = (DIE_TEMP • 12010)/45.6°C */
uint16_t dieTemperature = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_DIE_TEMP_SUBADDR,
&dieTemperature);
*dieTemp = (((int16_t) dieTemperature - 12010) / 45.6);
return status;
}
ReturnStatus LTC4015_get_battery_current(LTC4015_Dev *dev,
int16_t *iBatt) //milliAmps
{
/* Page 70: Battery current = [IBAT] * 1.46487uV/Rsnsb */
uint16_t batteryCurrent = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_IBAT_SUBADDR,
&batteryCurrent);
*iBatt = ((float) ((int16_t) batteryCurrent * 1.46487)) / (dev->cfg.r_snsb);
return status;
}
ReturnStatus LTC4015_get_input_current(LTC4015_Dev *dev,
int16_t *iIn) //milliAmps
{
/* Page 71: Input current = [IIN] • 1.46487uV/Rsnsi */
uint16_t inputCurrent = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_IIN_SUBADDR,
&inputCurrent);
*iIn = ((float) ((int16_t) inputCurrent * 1.46487)) / (dev->cfg.r_snsi);
return status;
}
ReturnStatus LTC4015_get_battery_voltage(LTC4015_Dev *dev,
int16_t *vbat) //milliVolts
{
/* Page 71: 2's compliment VBATSENS/cellcount = [VBAT] • [x]uV */
uint16_t batteryVoltage = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_VBAT_SUBADDR,
&batteryVoltage);
*vbat = vbat_reg_to_voltage(dev, batteryVoltage);
return status;
}
ReturnStatus LTC4015_get_input_voltage(LTC4015_Dev *dev,
int16_t *vIn) //milliVolts
{
/* Page 71: 2's compliment Input voltage = [VIN] • 1.648mV */
uint16_t inputVoltage = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_VIN_SUBADDR,
&inputVoltage);
*vIn = (int16_t) inputVoltage * 1.648;
return status;
}
ReturnStatus LTC4015_get_system_voltage(LTC4015_Dev *dev,
int16_t *vSys) //milliVolts
{
/* Page 71: 2's compliment system voltage = [VSYS] • 1.648mV */
uint16_t sysVoltage = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_VSYS_SUBADDR,
&sysVoltage);
*vSys = (int16_t) sysVoltage * 1.648;
return status;
}
ReturnStatus LTC4015_get_icharge_dac(LTC4015_Dev *dev,
int16_t *icharge) //milliAmps
{
/* Page 72: (ICHARGE_DAC + 1) • 1mV/RSNSB */
uint16_t ichargeDAC = 0x0000;
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_ICHARGE_DAC_SUBADDR,
&ichargeDAC);
*icharge = (int16_t)((ichargeDAC + 1) / dev->cfg.r_snsb);
return status;
}
static ReturnStatus _enable_limit_alerts(LTC4015_Dev *dev, uint16_t alertConfig)
{
return LTC4015_reg_write(dev, LTC4015_EN_LIMIT_ALERTS_SUBADDR, alertConfig);
}
static ReturnStatus _read_enable_limit_alerts(LTC4015_Dev *dev, uint16_t* regValue)
{
return LTC4015_reg_read(dev, LTC4015_EN_LIMIT_ALERTS_SUBADDR, regValue);
}
static ReturnStatus _read_limit_alerts(LTC4015_Dev *dev, uint16_t* regValue)
{
return LTC4015_reg_read(dev, LTC4015_LIMIT_ALERTS_SUBADDR, regValue);
}
static ReturnStatus _enable_charger_state_alerts(LTC4015_Dev *dev,
uint16_t regValue)
{
return LTC4015_reg_write(dev, LTC4015_EN_CHARGER_STATE_ALERTS_SUBADDR,
regValue);
}
static ReturnStatus _read_enable_charger_state_alerts(LTC4015_Dev *dev,
uint16_t* regValue)
{
return LTC4015_reg_read(dev, LTC4015_EN_CHARGER_STATE_ALERTS_SUBADDR,
regValue);
}
static ReturnStatus _read_charger_state_alerts(LTC4015_Dev *dev,
uint16_t *regValue)
{
return LTC4015_reg_read(dev, LTC4015_CHARGER_STATE_ALERTS_SUBADDR,
regValue);
}
static ReturnStatus _read_system_status(LTC4015_Dev *dev, uint16_t *regValue)
{
ReturnStatus status = LTC4015_reg_read(dev, LTC4015_SYSTEM_STATUS_SUBADDR,
regValue);
return status;
}
ReturnStatus LTC4015_get_bat_presence(LTC4015_Dev *dev, bool *present)
{
ReturnStatus status = RETURN_OK;
uint16_t value = 0;
status = _read_charger_state_alerts(dev, &value);
*present = !(value & LTC4015_EVT_BMFA);
return status;
}
static void _ltc4015_isr(void *context) {
LTC4015_Dev *dev = context;
ReturnStatus status = RETURN_OK;
uint16_t alert_status = 0;
int16_t val = 0;
bool present;
/* See if we have a callback assigned to handle alerts */
if (!dev->obj.alert_cb) {
return;
}
/* Check battery missing alarm now */
status = LTC4015_get_bat_presence(dev, &present);
if (status != RETURN_OK) {
return;
}
/*If battery is missing no need to check other limit alerts*/
if (!present) {
dev->obj.alert_cb(LTC4015_EVT_BMFA, val, dev->obj.cb_context);
return;
}
/* Read the alert status register to clear the alert bits if set) */
if (_read_limit_alerts(dev, &alert_status) != RETURN_OK) {
LOGGER_DEBUG("LTC4015:ERROR:: INT limit alerts read failed\n");
return;
}
if (alert_status & LTC4015_EVT_BVL) {
status = LTC4015_get_battery_voltage(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_BVL, val, dev->obj.cb_context);
}
if (alert_status & LTC4015_EVT_BVH) {
status = LTC4015_get_battery_voltage(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_BVH, val, dev->obj.cb_context);
}
if (alert_status & LTC4015_EVT_IVL) {
status = LTC4015_get_input_voltage(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_IVL, val, dev->obj.cb_context);
}
if (alert_status & LTC4015_EVT_ICH) {
status = LTC4015_get_input_current(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_ICH, val, dev->obj.cb_context);
}
if (alert_status & LTC4015_EVT_BCL) {
status = LTC4015_get_battery_current(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_BCL, val, dev->obj.cb_context);
}
if (alert_status & LTC4015_EVT_DTH) {
status = LTC4015_get_die_temperature(dev, &val);
dev->obj.alert_cb(LTC4015_EVT_DTH, val, dev->obj.cb_context);
}
}
ReturnStatus LTC4015_init(LTC4015_Dev *dev)
{
dev->obj = (LTC4015_Obj){};
/* TODO: Do the pre-configuration here if needed */
if (dev->cfg.pin_alert) {
const uint32_t pin_evt_cfg = OCGPIO_CFG_INPUT | OCGPIO_CFG_INT_FALLING;
if (OcGpio_configure(dev->cfg.pin_alert, pin_evt_cfg) < OCGPIO_SUCCESS) {
return RETURN_NOTOK;
}
/* Use a threaded interrupt to handle IRQ */
// ThreadedInt_Init(dev->cfg.pin_alert, _ltc4015_isr, (void *)dev);
}
return RETURN_OK;
}
void LTC4015_setAlertHandler(LTC4015_Dev *dev, LTC4015_CallbackFn alert_cb,
void *cb_context) {
dev->obj.alert_cb = alert_cb;
dev->obj.cb_context = cb_context;
}
ReturnStatus LTC4015_enableLimitAlerts(LTC4015_Dev *dev, uint16_t alert_mask)
{
uint16_t alert_reg;
/* Read the alert status register to clear the alert bits if set) */
ReturnStatus res = _read_limit_alerts(dev, &alert_reg);
if (res != RETURN_OK) {
return res;
}
/* Get the previously configured alerts */
res = _read_enable_limit_alerts(dev, &alert_reg);
if (res != RETURN_OK) {
return res;
}
alert_reg |= alert_mask;
return _enable_limit_alerts(dev, alert_reg);
}
ReturnStatus LTC4015_enableChargerStateAlerts(LTC4015_Dev *dev,
uint16_t alert_mask)
{
uint16_t alert_reg;
/* Read the alert status register to clear the alert bits if set) */
ReturnStatus res = _read_charger_state_alerts(dev, &alert_reg);
if (res != RETURN_OK) {
return res;
}
/* Get the previously configured alerts */
res = _read_enable_charger_state_alerts(dev, &alert_reg);
if (res != RETURN_OK) {
return res;
}
alert_reg |= alert_mask;
return _enable_charger_state_alerts(dev, alert_reg);
}
void LTC4015_configure(LTC4015_Dev *dev)
{
// OcGpio_configure(&dev->cfg.pin_lt4015_i2c_sel, OCGPIO_CFG_OUTPUT);
}
ePostCode LTC4015_probe(LTC4015_Dev *dev, POSTData *postData)
{
uint16_t ltcStatusReg = 0;
/* TODO: Check reading bits from System regsiter is enough to conclude
* whether battery is connected or not */
if (_read_system_status(dev, &ltcStatusReg) != RETURN_OK) {
return POST_DEV_MISSING;
}
if (!(ltcStatusReg & LTC4015_CHARGER_ENABLED)) {
return POST_DEV_MISSING;
}
post_update_POSTData(postData, dev->cfg.i2c_dev.bus, dev->cfg.i2c_dev.slave_addr,0xFF, 0xFF);
return POST_DEV_FOUND;
}

View File

@@ -0,0 +1,400 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef CHARGECTRL_LTC4015_H_
#define CHARGECTRL_LTC4015_H_
/*****************************************************************************
* REGISTER DEFINITIONS
*****************************************************************************/
// Battery voltage low alert limit - BITS[15:0] 0x0000
#define LTC4015_VBAT_LO_ALERT_LIMIT_SUBADDR 0x01
// Battery voltage high alert limit - BITS[15:0] 0x0000
#define LTC4015_VBAT_HI_ALERT_LIMIT_SUBADDR 0x02
// Input voltage low alert limit - BITS[15:0] 0x0000
#define LTC4015_VIN_LO_ALERT_LIMIT_SUBADDR 0x03
// Input voltage high alert limit - BITS[15:0] 0x0000
#define LTC4015_VIN_HI_ALERT_LIMIT_SUBADDR 0x04
// Output voltage low alert limit - BITS[15:0] 0x0000
#define LTC4015_VSYS_LO_ALERT_LIMIT_SUBADDR 0x05
// Output voltage high alert limit - BITS[15:0] 0x0000
#define LTC4015_VSYS_HI_ALERT_LIMIT_SUBADDR 0x06
// Input current high alert limit - BITS[15:0] 0x0000
#define LTC4015_IIN_HI_ALERT_LIMIT_SUBADDR 0x07
// Charge current low alert limit - BITS[15:0] 0x0000
#define LTC4015_IBAT_LO_ALERT_LIMIT_SUBADDR 0x08
// Die temperature high alert limit, - BITS[15:0] 0x0000
#define LTC4015_DIE_TEMP_HI_ALERT_LIMIT_SUBADDR 0x09
// Battery series resistance high alert limit - BITS[15:0] 0x0000
#define LTC4015_BSR_HI_ALERT_LIMIT_SUBADDR 0x0A
// Thermistor ratio high (cold battery) alert limit - BITS[15:0] 0x0000
#define LTC4015_NTC_RATIO_HI_ALERT_LIMIT_SUBADDR 0x0B
// Thermistor ratio low (hot battery) alert limit - BITS[15:0] 0x0000
#define LTC4015_NTC_RATIO_LO_ALERT_LIMIT_SUBADDR 0x0C
/* Bit fields:
*
* 15 : Enable meas_sys_valid_alert
* 14 : N/A
* 13 : Enable coulomb counter value low alert
* 12 : Enable coulomb counter value high alert
* 11 : Enable battery undervoltage alert
* 10 : Enable battery overvoltage alert
* 9 : Enable input undervoltage alert
* 8 : Enable input overvoltage alert
* 7 : Enable output undervoltage alert
* 6 : Enable output overvoltage alert
* 5 : Enable input overcurrent alert
* 4 : Enable battery current low alert
* 3 : Enable die temperature high alert
* 2 : Enable battery series resistance high alert
* 1 : Enable thermistor ratio high (cold battery) alert
* 0 : Enable thermistor ratio low (hot battery) alert
*/
// Enable limit monitoring and alert notification via SMBALERT - BITS[15:0] 0x0000
#define LTC4015_EN_LIMIT_ALERTS_SUBADDR 0x0D
/* Bit fields:
*
* 15:11 : N/A
* 10 : Enable alert for lead-acid equalize charge state
* 9 : Enable alert for absorb charge state
* 8 : Enable alert for charger suspended state
* 7 : Enable alert for precondition charge state
* 6 : Enable alert for constant current constant voltage state
* 5 : Enable alert for thermistor pause state
* 4 : Enable alert for timer termination state
* 3 : Enable alert for C/x termination state
* 2 : Enable max_charge_time_fault alert
* 1 : Enable alert for missing battery fault state
* 0 : Enable alert for shorted battery fault state
*/
// Enable charger state alert notification via SMBALERT - BITS[15:0] 0x0000
#define LTC4015_EN_CHARGER_STATE_ALERTS_SUBADDR 0x0E
/* Bit fields:
*
* 15:4 : N/A
* 3 : Enable alert for input undervoltage current limit active
* 2 : Enable alert for input current limit active
* 1 : Enable alert for constant current status
* 0 : Enable alert for constant voltage status
*/
// Enable charge status alert notification via SMBALERT - BITS[15:0] 0x0000
#define LTC4015_EN_CHARGE_STATUS_ALERTS_SUBADDR 0x0F
// Coulomb counter QCOUNT low alert limit, same format as QCOUNT (0x13) - BITS[15:0] : 0x0000
#define LTC4015_QCOUNT_LO_ALERT_LIMIT_SUBADDR 0x10
// Coulomb counter QCOUNT high alert limit, same format as QCOUNT (0x13) - BITS[15:0] : 0x0000
#define LTC4015_QCOUNT_HI_ALERT_LIMIT_SUBADDR 0x11
// Coulomb counter prescale factor - BITS[15:0] : 0x0200
#define LTC4015_QCOUNT_PRESCALE_FACTOR_SUBADDR 0x12
// Coulomb counter value - BITS[15:0] : 0x8000
#define LTC4015_QCOUNT_SUBADDR 0x13
/* Bit fields:
*
* 15:9 : N/A
* 8 : Suspend battery charger operation
* 7:6 : N/A
* 5 : Perform a battery series resistance measurement
* 4 : Force measurement system to operate
* 3 : Enable Maximum Power Point Tracking
* 2 : Enable coulomb counter
* 1:0 : N/A
*/
// Configuration Settings - BITS[15:0] : 0x0000
#define LTC4015_CONFIG_BITS_SUBADDR 0x14
// Input current limit setting = (IIN_LIMIT_SETTING + 1) <20> 500uV / RSNSI - BITS[5:0] : 0x3F
#define LTC4015_IIN_LIMIT_SETTING_SUBADDR 0x15
// UVCLFB input undervoltage limit = (VIN_UVCL_SETTING + 1) <20> 4.6875mV - BITS[7:0] : 0xFF
#define LTC4015_VIN_UVCL_SETTING_SUBADDR 0x16
#define LTC4015_RESERVED_0X17_SUBADDR 0x17
#define LTC4015_RESERVED_0X18_SUBADDR 0x18
// Write 0x534D to arm ship mode. Once armed, ship mode cannot be disarmed.
#define LTC4015_ARM_SHIP_MODE_SUBADDR 0x19
// Maximum charge current target = (ICHARGE_TARGET + 1) <20> 1mV/RSNSB - BITS[4:0]
#define LTC4015_ICHARGE_TARGET_SUBADDR 0x1A
// Charge voltage target - BITS[5:0]
#define LTC4015_VCHARGE_SETTING_SUBADDR 0x1B
// Two<77>s complement Low IBAT threshold for C/x termination - BITS[15:0]
#define LTC4015_C_OVER_X_THRESHOLD_SUBADDR 0x1C
// Time in seconds with battery charger in the CV state before timer termination
// occurs (lithium chemistries only)
#define LTC4015_MAX_CV_TIME_SUBADDR 0x1D
// Time in seconds before a max_charge_time fault is declared. Set to zero to
// disable max_charge_time fault
#define LTC4015_MAX_CHARGE_TIME_SUBADDR 0x1E
// Value of NTC_RATIO for transition between JEITA regions 2 and 1 (off) - BITS[15:0] : 0x3F00
#define LTC4015_JEITA_T1_SUBADDR 0x1F
// Value of NTC_RATIO for transition between JEITA regions 3 and 2 - BITS[15:0] : 0x372A
#define LTC4015_JEITA_T2_SUBADDR 0x20
// Value of NTC_RATIO for transition between JEITA regions 4 and 3 - BITS[15:0] : 0x1F27
#define LTC4015_JEITA_T3_SUBADDR 0x21
// Value of NTC_RATIO for transition between JEITA regions 5 and 4 - BITS[15:0] : 0x1BCC
#define LTC4015_JEITA_T4_SUBADDR 0x22
// Value of NTC_RATIO for transition between JEITA regions 6 and 5 - BITS[15:0] : 0x18B9
#define LTC4015_JEITA_T5_SUBADDR 0x23
// Value of NTC_RATIO for transition between JEITA regions 7 (off) and 6 - BITS[15:0] : 0x136D
#define LTC4015_JEITA_T6_SUBADDR 0x24
/* Bit Fields:
*
* 15:10 : N/A
* 9:5 : vcharge_jeita_6
* 4:0 : vcharge_jeita_5
*/
// VCHARGE values for JEITA temperature regions 6 and 5
#define LTC4015_VCHARGE_JEITA_6_5_SUBADDR 0x25
/* Bit Fields:
*
* 15 : N/A
* 14:10 : vcharge_jeita_4
* 9:5 : vcharge_jeita_3
* 4:0 : vcharge_jeita_4
*/
// VCHARGE values for JEITA temperature regions 4, 3, and 2
#define LTC4015_VCHARGE_JEITA_4_3_2_SUBADDR 0x26
/* Bit Fields:
*
* 15:10 : N/A
* 9:5 : icharge_jeita_6
* 4:0 : icharge_jeita_5
*/
// ICHARGE_TARGET values for JEITA temperature regions 6 and 5 - BITS[15:0] : 0x01EF
#define LTC4015_ICHARGE_JEITA_6_5_SUBADDR 0x27
/* Bit Fields:
*
* 15 : N/A
* 14:10 : icharge_jeita_4
* 9:5 : icharge_jeita_3
* 4:0 : icharge_jeita_4
*/
// ICHARGE_TARGET value for JEITA temperature regions 4, 3, and 2 - BITS[15:0] : 0x7FEF
#define LTC4015_ICHARGE_JEITA_4_3_2_SUBADDR 0x28
/* Bit Fields:
*
* 15:3 : N/A
* 2 : Enable C/x termination
* 1 : Enable lead acid charge voltage temperature compensation
* 0 : Enable JEITA temperature profile
*/
// Battery charger configuration settings
#define LTC4015_CHARGER_CONFIG_BITS_SUBADDR 0x29
// LiFePO4/lead-acid absorb voltage adder, bits 15:6 are reserved
#define LTC4015_VABSORB_DELTA_SUBADDR 0x2A
// Maximum time for LiFePO4/lead-acid absorb charge
#define LTC4015_MAX_ABSORB_TIME_SUBADDR 0x2B
// Lead-acid equalize charge voltage adder, bits 15:6 are reserved - BITS[15:0] : 0x002A
#define LTC4015_VEQUALIZE_DELTA_SUBADDR 0x2C
// Lead-acid equalization time - BITS[15:0] : 0x0E10
#define LTC4015_EQUALIZE_TIME_SUBADDR 0x2D
// LiFeP04 recharge threshold - BITS[15:0] : 0x4410
#define LTC4015_LIFEPO4_RECHARGE_THRESHOLD_SUBADDR 0x2E
#define LTC4015_RESERVED_0X2F_SUBADDR 0x2F
// For lithium chemistries, indicates the time (in sec) that the battery has
// been charging
#define LTC4015_MAX_CHARGE_TIMER_SUBADDR 0x30
// For lithium chemistries, indicates the time (in sec) that the battery has
// been in constant-voltage regulation
#define LTC4015_CV_TIMER_SUBADDR 0x31
// For LiFePO4 and lead-acid batteries, indicates the time (in sec) that the
// battery has been in absorb phase
#define LTC4015_ABSORB_TIMER_SUBADDR 0x32
// For lead-acid batteries, indicates the time (in sec) that the battery has
// been in EQUALIZE phase
#define LTC4015_EQUALIZE_TIMER_SUBADDR 0x33
/* Bit Fields:
*
* 15:3 : N/A
* 10 : Indicates battery charger is in lead-acid equalization charge state
* 9 : Indicates battery charger is in absorb charge state
* 8 : Indicates battery charger is in charger suspended state
* 7 : Indicates battery charger is in precondition charge state
* 6 : Indicates battery charger is in CC-CV state
* 5 : Indicates battery charger is in thermistor pause state
* 4 : Indicates battery charger is in timer termination state
* 3 : Indicates battery charger is in C/x termination state
* 2 : indicates battery charger is in max_charge_time_fault state
* 1 : Indicates battery charger is in missing battery fault state
* 0 : Indicates battery charger is in shorted battery fault state
*/
// Real time battery charger state indicator. Individual bits are mutually
// exclusive. Bits 15:11 are reserved.
#define LTC4015_CHARGER_STATE_SUBADDR 0x34
/* Bit Fields:
*
* 15:4 : N/A
* 3 : Indicates the input undervoltage control loop is actively
* controlling power delivery based on VIN_UVCL_SETTING
* 2 : Indicates the input current limit control loop is actively
* controlling power delivery based on IIN_LIMIT[_DAC][_SETTING]
* 1 : Indicates the charge current control loop is actively controlling
* power delivery based on ICHARGE_DAC
* 0 : Indicates the battery voltage control loop is actively controlling
* power delivery based on VCHARGE_DAC
*/
// Charge status indicator. Individual bits are mutually exclusive. Only active
// in charging states.
#define LTC4015_CHARGE_STATUS_SUBADDR 0x35
/* Bit Fields:
*
* 15 : Indicates that measurement system results have become valid.
* 14 : N/A
* 13 : Indicates QCOUNT has fallen below QCOUNT_LO_ALERT_LIMIT
* 12 : Indicates QCOUNT has exceeded QCOUNT_HI_ALERT_LIMIT
* 11 : Indicates VBAT has fallen below VBAT_LO_ALERT_LIMIT
* 10 : Indicates VBAT has exceeded VBAT_HI_ALERT_LIMIT
* 9 : Indicates VIN has fallen below VIN_LO_ALERT_LIMIT
* 8 : Indicates VIN has exceeded VIN_HI_ALERT_LIMIT
* 7 : Indicates VSYS has fallen below VSYS_LO_ALERT_LIMIT
* 6 : Indicates VSYS has exceeded VSYS_HI_ALERT_LIMIT
* 5 : Indicates IIN has exceeded IIN_HI_ALERT_LIMIT
* 4 : Indicates IBAT has fallen below IBAT_LO_ALERT_LIMIT
* 3 : Indicates DIE_TEMP has exceeded DIE_TEMP_HI_ALERT_LIMIT
* 2 : Indicates BSR has exceeded BSR_HI_ALERT_LIMIT
* 1 : Indicates NTC_RATIO has exceeded NTC_RATIO_HI_ALERT_LIMIT
* 0 : Indicates NTC_RATIO has fallen below NTC_RATIO_LO_ALERT_LIMIT
*/
// Limit alert register.Individual bits are enabled by EN_LIMIT_ALERTS (0x0D).
// Writing 0 to any bit clears that alert. Once set, alert bits remain high
// until cleared or disabled.
#define LTC4015_LIMIT_ALERTS_SUBADDR 0x36
/* Bit Fields:
*
* 15:11 : N/A
* 10 : Alert indicates charger has entered equalize charge state
* 9 : Alert indicates charger has entered absorb charge state
* 8 : Alert indicates charger has been suspended
* 7 : Alert indicates charger has entered preconditioning charge state
* 6 : Alert indicates charger has entered CC-CV charge state
* 5 : Alert indicates charger has entered thermistor pause state
* 4 : Alert indicates timer termination has occurred
* 3 : Alert indicates C/x termination has occurred
* 2 : Alert indicates charger has entered max_charge_time_fault state
* 1 : Alert indicates battery missing fault has occurred
* 0 : Alert indicates battery short fault has occurred
*/
// Charger state alert register. Individual bits are enabled by EN_CHARGER_STATE_ALERTS (0x0E).
#define LTC4015_CHARGER_STATE_ALERTS_SUBADDR 0x37
/* Bit Fields:
*
* 15:4 : N/A
* 3 : Alert indicates that vin_uvcl_active has occurred
* 2 : Alert indicates iin_limit_active has occurred
* 1 : Alert indicates constant_current has occurred
* 0 : Alert indicates constant_voltage has occurred
*/
// Alerts that CHARGE_STATUS indicators have occurred.
// Individual bits are enabled by EN_CHARGE_STATUS_ALERTS (0x0F)
#define LTC4015_CHARGE_STATUS_ALERTS_SUBADDR 0x38
/* Bit Fields:
*
* 15:14 : N/A
* 13 : Indicates that the battery charger is active
* 12 : N/A
* 11 : Indicates the MPPT pin is set to enable Maximum Power Point Tracking
* 10 : Indicates a rising edge has been detected at the EQ pin, and an
* equalize charge is queued
* 9 : Indicates DRVCC voltage is above switching regulator undervoltage
* lockout level (4.3V typ)
* 8 : Indicates an invalid combination of CELLS pin settings
* 7 : N/A
* 6 : Indicates all system conditions are met to allow battery charger
* operation.
* 5 : Indicates no resistor has been detected at the RT pin
* 4 : Indicates die temperature is greater than thermal shutdown level
* (160C typical)
* 3 : Indicates VIN voltage is greater than overvoltage lockout level
* (38.6V typical)
* 2 : Indicates VIN voltage is sufficiently greater than BATSENSE for
* switching regulator operation (200mV typical)
* 1 : Indicates INTVCC voltage is above switching regulator undervoltage
* lockout level (4.3V typ)
* 0 : Indicates INTVCC voltage is greater than measurement system lockout
* level (2.8V typical)
*/
// Real time system status indicator bits
#define LTC4015_SYSTEM_STATUS_SUBADDR 0x39
// Two<77>s complement ADC measurement result for the BATSENS pin.
// VBATSENS/cellcount = [VBAT] <20> 192.264uV for lithium chemistries.
// VBATSENS/cellcount = [VBAT] <20> 128.176uV for lead-acid.
#define LTC4015_VBAT_SUBADDR 0x3A
// Two<77>s complement ADC measurement result for VIN.
// VVIN = [VIN] <20> 1.648mV
#define LTC4015_VIN_SUBADDR 0x3B
// Two<77>s complement ADC measurement result for VSYS.
// VSYS = [VSYS] <20> 1.648mV
#define LTC4015_VSYS_SUBADDR 0x3C
// Two<77>s complement ADC measurement result for (VCSP <20> VCSN).
// Charge current (into the battery) is represented as a positive number.
// Battery current = [IBAT] <20> 1.46487uV/RSNSB
#define LTC4015_IBAT_SUBADDR 0x3D
// Two<77>s complement ADC measurement result for (VCLP <20> VCLN).
// Input current = [IIN] <20> 1.46487uV/RSNSI
#define LTC4015_IIN_SUBADDR 0x3E
// Two<77>s complement ADC measurement result for die temperature.
// Temperature = (DIE_TEMP <20> 12010)/45.6<EFBFBD>C
#define LTC4015_DIE_TEMP_SUBADDR 0x3F
// Two<77>s complement ADC measurement result for NTC thermistor ratio.
// RNTC = NTC_RATIO <20> RNTCBIAS/(21845.0 <20> NTC_RATIO)
#define LTC4015_NTC_RATIO_SUBADDR 0x40
// Calculated battery series resistance.
// For lithium chemistries, series resistance/cellcount = BSR <20> RSNSB/500.0
// For lead-acid chemistries, series resistance/cellcount = BSR <20> RSNSB/750.0
#define LTC4015_BSR_SUBADDR 0x41
// JEITA temperature region of the NTC thermistor (Li Only).
// Active only when EN_JEITA=1 (Only Bits[2:0] used)
#define LTC4015_JEITA_REGION_SUBADDR 0x42
/* Bit Fields:
*
* 15:12 : N/A
* 11:8 : programmed battery chemistry
* 7:4 : Reserved
* 3:0 : Cell count as set by CELLS pins
*/
// Readout of CHEM and CELLS pin settings
#define LTC4015_CHEM_CELLS_SUBADDR 0x43
// Charge current control DAC control bits (Only Bits[4:0] used)
#define LTC4015_ICHARGE_DAC_SUBADDR 0x44
// Charge voltage control DAC control bits (Only Bits[5:0] used)
#define LTC4015_VCHARGE_DAC_SUBADDR 0x45
// Input current limit control DAC control word (Only Bits[5:0] used)
#define LTC4015_IIN_LIMIT_DAC_SUBADDR 0x46
// Digitally filtered two<77>s complement ADC measurement result for battery voltage
#define LTC4015_VBAT_FILT_SUBADDR 0x47
// This 16-bit two's complement word is the value of IBAT (0x3D) used in calculating BSR.
#define LTC4015_ICHARGE_BSR_SUBADDR 0x48
#define LTC4015_RESERVED_0X49_SUBADDR 0x49
// Measurement valid bit, bit 0 is a 1 when the telemetry(ADC) system is ready
#define LTC4015_MEAS_SYS_VALID_SUBADDR 0x4A
#endif /* CHARGECTRL_LTC4015_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,266 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "devices/i2c/threaded_int.h"
#include "helpers/math.h"
#include "helpers/memory.h"
#include "inc/common/byteorder.h"
#include "inc/devices/ltc4295.h"
#include "inc/subsystem/power/power.h"
#include <math.h>
#include <ti/sysbios/knl/Task.h>
tPower_PDStatus_Info PDStatus_Info;
/******************************************************************************
* @fn ltc4295_handle_irq
*
* @brief Read the change in the PD state and callbacks the registerd function.
*
* @args Alert Context
*
* @return None
*/
static void ltc4295_handle_irq(void *context) {
LTC4295_Dev *dev = context;
const IArg mutexKey = GateMutex_enter(dev->obj.mutex); {
ltc4295_update_status(dev);
} GateMutex_leave(dev->obj.mutex, mutexKey);
/* See if we have a callback assigned to handle alerts */
if (!dev->obj.alert_cb) {
return;
}
/* Since > CRIT implies above window, we only handle the highest priority
* event to avoid duplicate events being sent */
if (PDStatus_Info.pdalert == LTC4295_CONNECT_ALERT) {
dev->obj.alert_cb(LTC4295_CONNECT_EVT, dev->obj.cb_context);
} else if (PDStatus_Info.pdalert == LTC4295_DISCONNECT_ALERT) {
dev->obj.alert_cb(LTC4295_DISCONNECT_EVT, dev->obj.cb_context);
} else if (PDStatus_Info.pdalert == LTC4295_INCOMPATIBLE_ALERT) {
dev->obj.alert_cb(LTC4295_INCOMPATIBLE_EVT, dev->obj.cb_context);
}
}
/******************************************************************************
* @fn ltc4295_configure
*
* @brief configure GPIO's.
*
* @args None
*
* @return None
*/
void ltc4295_config(const LTC4295_Dev *dev)
{
OcGpio_configure(dev->cfg.pin_evt, OCGPIO_CFG_INPUT);
OcGpio_configure(dev->cfg.pin_detect, OCGPIO_CFG_INPUT);
}
/******************************************************************************
* @fn ltc4295_probe
*
* @brief Intializes PD update struct.
*
* @args None
*
* @return None
*/
ePostCode ltc4295_probe(const LTC4295_Dev *dev, POSTData *postData)
{
ePostCode postCode = POST_DEV_MISSING;
ePDPowerState pdStatus = LTC4295_POWERGOOD_NOTOK;
ReturnStatus ret = ltc4295_get_power_good(dev, &pdStatus);
if (ret != RETURN_OK) {
LOGGER("LTC4295::ERROR: Power good signal read failed.\n");
return postCode;
}
if (pdStatus == LTC4295_POWERGOOD ) {
PDStatus_Info.pdStatus.classStatus = LTC4295_CLASSTYPE_UNKOWN;
PDStatus_Info.pdStatus.powerGoodStatus = LTC4295_POWERGOOD;
PDStatus_Info.state = LTC4295_STATE_NOTOK;
PDStatus_Info.pdalert = LTC4295_DISCONNECT_ALERT;
postCode = POST_DEV_FOUND;
} else {
PDStatus_Info.pdStatus.classStatus = LTC4295_CLASSTYPE_UNKOWN;
PDStatus_Info.pdStatus.powerGoodStatus = LTC4295_POWERGOOD_NOTOK;
PDStatus_Info.state = LTC4295_STATE_NOTOK;
PDStatus_Info.pdalert = LTC4295_DISCONNECT_ALERT;
}
post_update_POSTData(postData, 0xFF, 0xFF, 0xFF, 0xFF);
return postCode;
}
/******************************************************************************
* @fn ltc4295_init
*
* @brief Intializes PD update struct.
*
* @args None
*
* @return None
*/
ReturnStatus ltc4295_init(LTC4295_Dev *dev)
{
ReturnStatus ret = RETURN_OK;
dev->obj = (LTC4295_Obj){};
dev->obj.mutex = GateMutex_create(NULL, NULL);
if (!dev->obj.mutex) {
return RETURN_NOTOK;
}
ret = ltc4295_get_power_good(dev, &PDStatus_Info.pdStatus.powerGoodStatus);
if (ret != RETURN_OK) {
LOGGER("LTC4295::ERROR: Power good signal read failed.\n");
return ret;
}
if (PDStatus_Info.pdStatus.powerGoodStatus == LTC4295_POWERGOOD) {
ret = ltc4295_get_class(dev, &PDStatus_Info.pdStatus.classStatus);
if (ret != RETURN_OK) {
LOGGER("LTC4295::ERROR: Reading PD classification failed.\n");
return ret;
}
if (PDStatus_Info.pdStatus.classStatus == LTC4295_CLASSTYPE_POEPP) {
PDStatus_Info.state = LTC4295_STATE_OK;
}
}
if (dev->cfg.pin_evt) {
const uint32_t pin_evt_cfg = OCGPIO_CFG_INPUT | OCGPIO_CFG_INT_BOTH_EDGES ;
if (OcGpio_configure(dev->cfg.pin_evt, pin_evt_cfg) < OCGPIO_SUCCESS) {
return RETURN_NOTOK;
}
/* Use a threaded interrupt to handle IRQ */
// ThreadedInt_Init(dev->cfg.pin_evt, ltc4295_handle_irq, (void *)dev);
}
return ret;
}
/******************************************************************************
* @fn ltc4295_set_alert_handler
*
* @brief Set the alert callback function and context.
*
* @args Device, callBack function and context
*
* @return None
*/
void ltc4295_set_alert_handler(LTC4295_Dev *dev, LTC4295_CallbackFn alert_cb,
void *cb_context)
{
dev->obj.alert_cb = alert_cb;
dev->obj.cb_context = cb_context;
}
/******************************************************************************
* @fn ltc4295_get_power_good
*
* @brief Read GPIO status based on that decide power good signal.
*
* @args Addrress
*
* @return ReturnStatus
*/
ReturnStatus ltc4295_get_power_good(const LTC4295_Dev *dev, ePDPowerState *val)
{
ReturnStatus ret = RETURN_OK;
/*set default to 1*/
*val = LTC4295_POWERGOOD_NOTOK;
/* Check Power Good */
*val = (ePDPowerState) OcGpio_read(dev->cfg.pin_evt);
if(*val == 0)
{
*val = LTC4295_POWERGOOD;
}
DEBUG("LTC4295:INFO:: PD power good is %d.\n", *val);
return ret;
}
/******************************************************************************
* @fn ltc4295_get_class
*
* @brief ReadGPIO status based on that decide the PD class.
*
* @args Addrress
*
* @return ReturnStatus
*/
ReturnStatus ltc4295_get_class(const LTC4295_Dev *dev, ePDClassType *val)
{
ReturnStatus ret = RETURN_OK;
uint8_t i = 0;
uint8_t value = 1;
uint8_t prev_value = 1;
uint8_t toggle = 0;
for (i = 0; i < 15; i++) {
value = OcGpio_read(dev->cfg.pin_detect);
LOGGER_DEBUG("LTC4295:INFO:: PD-nT2P activity status %d.\n", value);
if (value == 1) {
*val = LTC4295_CLASSTYPE_2;
} else if (value == 0) {
*val = LTC4295_CLASSTYPE_1;
}
/*Incremented only in the case of POE++ device*/
if (prev_value != value) {
toggle++;
}
prev_value = value;
Task_sleep(3);
}
if (toggle > 2) {
*val = LTC4295_CLASSTYPE_POEPP;
}
LOGGER("LTC4295:INFO:: PD detects POE of class 0x%x.\n", *val);
return ret;
}
/******************************************************************************
* @fn ltc4295_update_status
*
* @brief Maintains the PS status.
*
* @args CLass and power good state of PD.
*
* @return None
*/
void ltc4295_update_status(const LTC4295_Dev *dev)
{
ReturnStatus ret = RETURN_NOTOK;
ret = ltc4295_get_power_good(dev,&PDStatus_Info.pdStatus.powerGoodStatus);
if (ret != RETURN_OK) {
LOGGER("LTC4295::ERROR: Power good signal read failed.\n");
return;
}
if (PDStatus_Info.pdStatus.powerGoodStatus == LTC4295_POWERGOOD) {
ret = ltc4295_get_class(dev, &PDStatus_Info.pdStatus.classStatus);
if (ret != RETURN_OK) {
LOGGER("LTC4295::ERROR: Reading PD classification failed.\n");
return;
}
if (PDStatus_Info.pdStatus.classStatus == LTC4295_CLASSTYPE_POEPP) {
PDStatus_Info.state = LTC4295_STATE_OK;
PDStatus_Info.pdalert = LTC4295_CONNECT_ALERT;
}
} else {
PDStatus_Info.state = LTC4295_STATE_NOTOK;
PDStatus_Info.pdalert = LTC4295_DISCONNECT_ALERT;
PDStatus_Info.pdStatus.classStatus == LTC4295_CLASSTYPE_UNKOWN;
}
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/ocmp_wrappers/ocmp_eeprom_cat24c04.h"
#include "common/inc/global/Framework.h"
#include "inc/common/global_header.h"
#include "inc/devices/eeprom.h"
#include <string.h>
static ePostCode _init_eeprom(void *driver, const void **config,
const void *alert_token)
{
Eeprom_Cfg *eeprom = (Eeprom_Cfg *)driver;
uint8_t write = 0x01;
uint8_t read = 0x00;
eeprom_init(eeprom);
eeprom_enable_write(eeprom);
eeprom_write(eeprom, OC_TEST_ADDRESS, &write, 1);
NOP_DELAY(); /* TODO: the eeprom driver should handle this */
eeprom_disable_write(eeprom);
eeprom_read(eeprom, OC_TEST_ADDRESS, &read, 1);
if (write == read) {
return POST_DEV_CFG_DONE;
}
return POST_DEV_CFG_FAIL;
}
const Driver_fxnTable CAT24C04_psu_sid_fxnTable = {
/* Message handlers */
.cb_init = _init_eeprom,
};
const Driver_fxnTable CAT24C04_psu_inv_fxnTable= {
.cb_init = _init_eeprom,
};

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/Framework.h"
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
#include "inc/devices/debug_oci2c.h"
#include "inc/ocmp_wrappers/ocmp_debugi2c.h"
/* TI-RTOS driver files */
#include <ti/drivers/I2C.h>
/*****************************************************************************
** FUNCTION NAME : i2c_read
**
** DESCRIPTION : i2c read
**
** ARGUMENTS : i2c bus config, i2c config
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
bool i2c_read(void* i2c_cfg, void *oci2c )
{
S_I2C_Cfg* s_oc_i2c_cfg = (S_I2C_Cfg*)i2c_cfg;
S_OCI2C* s_oci2c = (S_OCI2C*)oci2c;
I2C_Handle i2cHandle = i2c_open_bus(s_oc_i2c_cfg->bus);
return (i2c_reg_read(i2cHandle, s_oci2c->slaveAddress, s_oci2c->reg_address, &s_oci2c->reg_value, s_oci2c->number_of_bytes) == RETURN_OK);
}
/*****************************************************************************
** FUNCTION NAME : i2c_write
**
** DESCRIPTION : i2c write
**
** ARGUMENTS : i2c bus config, i2c config
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
bool i2c_write(void* i2c_cfg, void *oci2c )
{
S_I2C_Cfg* s_oc_i2c_cfg = (S_I2C_Cfg*)i2c_cfg;
S_OCI2C* s_oci2c = (S_OCI2C*)oci2c;
I2C_Handle i2cHandle = i2c_open_bus(s_oc_i2c_cfg->bus);
return (i2c_reg_write(i2cHandle, s_oci2c->slaveAddress, s_oci2c->reg_address, s_oci2c->reg_value, s_oci2c->number_of_bytes) == RETURN_OK);
}

View File

@@ -0,0 +1,107 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/Framework.h"
#include "common/inc/global/ocmp_frame.h"
#include "inc/common/global_header.h"
#include "inc/devices/debug_ocgpio.h"
#include "inc/ocmp_wrappers/ocmp_debugocgpio.h"
#include <ti/drivers/GPIO.h>
#define NO_GPIO_PINS_IN_GROUP 8
extern GPIO_PinConfig gpioPinConfigs[];
/*****************************************************************************
** FUNCTION NAME : ocgpio_set
**
** DESCRIPTION : i2c read
**
** ARGUMENTS : i2c bus config, i2c config
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
bool ocgpio_set(void* gpio_cfg, void* oc_gpio )
{
S_OCGPIO_Cfg* oc_gpio_cfg = (S_OCGPIO_Cfg*)gpio_cfg;
S_OCGPIO* s_oc_gpio = (S_OCGPIO*)oc_gpio;
int ret = 0;
uint8_t idx = ((oc_gpio_cfg->group != 0)?(((oc_gpio_cfg->group-1) * NO_GPIO_PINS_IN_GROUP) + s_oc_gpio->pin):s_oc_gpio->pin);
// OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, ((oc_gpio_cfg->group != 0)?(gpioPinConfigs[idx]>>16):OCGPIO_CFG_OUT_STD)};
OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, OCGPIO_CFG_OUT_STD};
ret = OcGpio_configure(&ocgpio, OCGPIO_CFG_OUTPUT);
ret = OcGpio_write(&ocgpio,s_oc_gpio->value);
return (ret == 0);
}
/*****************************************************************************
** FUNCTION NAME : ocgpio_get
**
** DESCRIPTION : gpio read
**
** ARGUMENTS : i2c bus config, i2c config
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
bool ocgpio_get(void* gpio_cfg, void* oc_gpio )
{
S_OCGPIO_Cfg* oc_gpio_cfg = (S_OCGPIO_Cfg*)gpio_cfg;
S_OCGPIO* s_oc_gpio = (S_OCGPIO*)oc_gpio;
int ret = 0;
uint8_t idx = ((oc_gpio_cfg->group != 0)?(((oc_gpio_cfg->group-1) * NO_GPIO_PINS_IN_GROUP) + s_oc_gpio->pin):s_oc_gpio->pin);
// OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, ((oc_gpio_cfg->group!= 0)?(gpioPinConfigs[idx]>>16):OCGPIO_CFG_IN_PU)};
OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, 0};
ret = OcGpio_configure(&ocgpio, OCGPIO_CFG_INPUT);
s_oc_gpio->value = OcGpio_read(&ocgpio);
if ( s_oc_gpio->value < 0) {
ret = -1;
}
return (ret == 0);
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(S_OCGPIO_Cfg* oc_gpio_cfg)
{
if (OcGpio_probe(oc_gpio_cfg->port) != 0) {
return POST_DEV_MISSING;
} else {
return POST_DEV_FOUND;
}
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable DEBUG_OCGPIO_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
};

View File

@@ -0,0 +1,186 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/Framework.h"
#include "common/inc/ocmp_wrappers/ocmp_ina226.h"
#include "inc/devices/ina226.h"
typedef enum INA226Status {
INA226_STATUS_BUS_VOLTAGE = 0,
INA226_STATUS_SHUNT_VOLTAGE,
INA226_STATUS_CURRENT,
INA226_STATUS_POWER,
} INA226Status;
typedef enum INA226Config {
INA226_CONFIG_CURRENT_LIM = 0,
} INA226Config;
typedef enum INA226Alert {
INA226_ALERT_OVERCURRENT = 0,
} INA226Alert;
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf) {
switch (param_id) {
case INA226_STATUS_BUS_VOLTAGE: {
uint16_t *res = return_buf;
return (ina226_readBusVoltage(driver, res) == RETURN_OK);
}
case INA226_STATUS_SHUNT_VOLTAGE: {
uint16_t *res = return_buf;
return (ina226_readShuntVoltage(driver, res) == RETURN_OK);
}
case INA226_STATUS_CURRENT: {
uint16_t *res = return_buf;
return (ina226_readCurrent(driver, res) == RETURN_OK);
}
case INA226_STATUS_POWER: {
uint16_t *res = return_buf;
return (ina226_readPower(driver, res) == RETURN_OK);
}
default:
LOGGER_ERROR("INA226::Unknown status param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _get_config
**
** DESCRIPTION : ocmp wrapper for getting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_config(void *driver, unsigned int param_id,
void *return_buf) {
switch (param_id) {
case INA226_CONFIG_CURRENT_LIM: {
uint16_t *res = return_buf;
return (ina226_readCurrentLim(driver, res) == RETURN_OK);
}
default:
LOGGER_ERROR("INA226::Unknown config param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _set_config
**
** DESCRIPTION : ocmp wrapper for setting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _set_config(void *driver, unsigned int param_id,
const void *data) {
switch (param_id) {
case INA226_CONFIG_CURRENT_LIM: {
const uint16_t *limit = data;
return (ina226_setCurrentLim(driver, *limit) == RETURN_OK);
}
default:
LOGGER_ERROR("INA226::Unknown config param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver, POSTData *postData)
{
return ina226_probe(driver,postData);
}
/*****************************************************************************
** FUNCTION NAME : _alert_handler
**
** DESCRIPTION : call back function for handling alerts from device
** layer
**
** ARGUMENTS : event type , current value, alert config,
**
** RETURN TYPE :
**
*****************************************************************************/
static void _alert_handler(INA226_Event evt, uint16_t value, void *alert_data)
{
if (evt != INA226_EVT_COL) {
LOGGER_WARNING("IN226::Unsupported INA event 0x%x\n", evt);
return;
}
OCMP_GenerateAlert(alert_data, INA226_ALERT_OVERCURRENT, &value);
LOGGER_DEBUG("INA226 Event: 0x%x Current: %u\n", evt, value);
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
if (ina226_init(driver) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (!config) {
return POST_DEV_CFG_DONE;
}
const INA226_Config *ina226_config = config;
if (ina226_setCurrentLim(driver, ina226_config->current_lim) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
ina226_setAlertHandler(driver, _alert_handler, (void *)alert_token);
if (ina226_enableAlert(driver, INA226_EVT_COL) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable INA226_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
.cb_get_config = _get_config,
.cb_set_config = _set_config,
};

View File

@@ -0,0 +1,350 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/ocmp_wrappers/ocmp_ltc4015.h"
#include "inc/devices/ltc4015.h"
typedef enum LTC4015Status {
LTC4015_STATUS_BATTERY_VOLTAGE = 0,
LTC4015_STATUS_BATTERY_CURRENT,
LTC4015_STATUS_SYSTEM_VOLTAGE,
LTC4015_STATUS_INPUT_VOLATGE,
LTC4015_STATUS_INPUT_CURRENT,
LTC4015_STATUS_DIE_TEMPERATURE,
LTC4015_STATUS_ICHARGE_DAC
} LTC4015Status;
typedef enum LTC4015Config {
LTC4015_CONFIG_BATTERY_VOLTAGE_LOW = 0,
LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH,
LTC4015_CONFIG_BATTERY_CURRENT_LOW,
LTC4015_CONFIG_INPUT_VOLTAGE_LOW,
LTC4015_CONFIG_INPUT_CURRENT_HIGH,
LTC4015_CONFIG_INPUT_CURRENT_LIMIT,
LTC4015_CONFIG_ICHARGE,
LTC4015_CONFIG_VCHARGE,
LTC4015_CONFIG_DIE_TEMPERATURE_HIGH,
} LTC4015Config;
typedef enum LTC4015Alert {
LTC4015_ALERT_BATTERY_VOLTAGE_LOW = 0,
LTC4015_ALERT_BATTERY_VOLTAGE_HIGH,
LTC4015_ALERT_BATTERY_CURRENT_LOW,
LTC4015_ALERT_INPUT_VOLTAGE_LOW,
LTC4015_ALERT_INPUT_CURRENT_HIGH,
LTC4015_ALERT_DIE_TEMPERATURE_HIGH,
} LTC4015Alert;
#if 0
static bool _choose_battery_charger(LTC4015_Dev *dev) {
if (OcGpio_write(&dev->cfg.pin_lt4015_i2c_sel,
(dev->cfg.chem == LTC4015_CHEM_LI_ION)) < OCGPIO_SUCCESS) {
return false;
}
return true;
}
#endif
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf) {
// if(!_choose_battery_charger(driver))
// return false;
switch (param_id) {
case LTC4015_STATUS_BATTERY_VOLTAGE: {
int16_t *res = return_buf;
return (LTC4015_get_battery_voltage(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_BATTERY_CURRENT: {
int16_t *res = return_buf;
return (LTC4015_get_battery_current(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_SYSTEM_VOLTAGE: {
int16_t *res = return_buf;
return (LTC4015_get_system_voltage(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_INPUT_VOLATGE: {
int16_t *res = return_buf;
return (LTC4015_get_input_voltage(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_INPUT_CURRENT: {
int16_t *res = return_buf;
return (LTC4015_get_input_current(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_DIE_TEMPERATURE: {
int16_t *res = return_buf;
return (LTC4015_get_die_temperature(driver, res) == RETURN_OK);
}
case LTC4015_STATUS_ICHARGE_DAC: {
int16_t *res = return_buf;
return (LTC4015_get_icharge_dac(driver, res) == RETURN_OK);
}
default:
LOGGER_ERROR("LTC4015::Unknown status param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _get_config
**
** DESCRIPTION : ocmp wrapper for getting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_config(void *driver, unsigned int param_id,
void *return_buf) {
switch (param_id) {
case LTC4015_CONFIG_BATTERY_VOLTAGE_LOW: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_battery_voltage_low(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_battery_voltage_high(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_BATTERY_CURRENT_LOW: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_battery_current_low(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_VOLTAGE_LOW: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_input_voltage_low(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_CURRENT_HIGH: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_input_current_high(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_CURRENT_LIMIT: {
uint16_t *res = return_buf;
return (LTC4015_get_cfg_input_current_limit(driver, res)
== RETURN_OK);
}
case LTC4015_CONFIG_ICHARGE: {
uint16_t *res = return_buf;
return (LTC4015_get_cfg_icharge(driver, res) == RETURN_OK);
}
case LTC4015_CONFIG_VCHARGE: {
uint16_t *res = return_buf;
return (LTC4015_get_cfg_vcharge(driver, res) == RETURN_OK);
}
case LTC4015_CONFIG_DIE_TEMPERATURE_HIGH: {
int16_t *res = return_buf;
return (LTC4015_get_cfg_die_temperature_high(driver, res)
== RETURN_OK);
}
default:
LOGGER_ERROR("LTC4015::Unknown config param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _set_config
**
** DESCRIPTION : ocmp wrapper for setting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _set_config(void *driver, unsigned int param_id,
const void *data) {
switch (param_id) {
case LTC4015_CONFIG_BATTERY_VOLTAGE_LOW: {
const int16_t *limit = data;
return (LTC4015_cfg_battery_voltage_low(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH: {
const int16_t *limit = data;
return (LTC4015_cfg_battery_voltage_high(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_BATTERY_CURRENT_LOW: {
const int16_t *limit = data;
return (LTC4015_cfg_battery_current_low(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_VOLTAGE_LOW: {
const int16_t *limit = data;
return (LTC4015_cfg_input_voltage_low(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_CURRENT_HIGH: {
const int16_t *limit = data;
return (LTC4015_cfg_input_current_high(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_INPUT_CURRENT_LIMIT: {
const uint16_t *limit = data;
return (LTC4015_cfg_input_current_limit(driver, *limit)
== RETURN_OK);
}
case LTC4015_CONFIG_ICHARGE: {
const uint16_t *limit = data;
return (LTC4015_cfg_icharge(driver, *limit) == RETURN_OK);
}
case LTC4015_CONFIG_VCHARGE: {
const uint16_t *limit = data;
return (LTC4015_cfg_vcharge(driver, *limit) == RETURN_OK);
}
case LTC4015_CONFIG_DIE_TEMPERATURE_HIGH: {
const int16_t *limit = data;
return (LTC4015_cfg_die_temperature_high(driver, *limit)
== RETURN_OK);
}
default:
LOGGER_ERROR("LTC4015::Unknown config param %d\n", param_id);
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver, POSTData *postData)
{
LTC4015_configure(driver);
return LTC4015_probe(driver, postData);
}
static void _alert_handler(LTC4015_Event evt, int16_t value, void *alert_data)
{
unsigned int alert;
switch (evt) {
case LTC4015_EVT_BVL:
alert = LTC4015_ALERT_BATTERY_VOLTAGE_LOW;
break;
case LTC4015_EVT_BVH:
alert = LTC4015_ALERT_BATTERY_VOLTAGE_HIGH;
break;
case LTC4015_EVT_BCL:
alert = LTC4015_ALERT_BATTERY_CURRENT_LOW;
break;
case LTC4015_EVT_IVL:
alert = LTC4015_ALERT_INPUT_VOLTAGE_LOW;
break;
case LTC4015_EVT_ICH:
alert = LTC4015_ALERT_INPUT_CURRENT_HIGH;
break;
case LTC4015_EVT_DTH:
alert = LTC4015_ALERT_DIE_TEMPERATURE_HIGH;
break;
default:
LOGGER_ERROR("Unknown LTC4015 evt: %d\n", evt);
return;
}
OCMP_GenerateAlert(alert_data, alert, &value);
LOGGER_DEBUG("LTC4015 Event: %d Value: %d\n", evt, value);
}
static ePostCode _init(void *driver, const void *config,
const void *alert_token) {
// if(!_choose_battery_charger(driver))
// return false;
if (LTC4015_init(driver) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (!config) {
return POST_DEV_CFG_DONE;
}
const LTC4015_Config *ltc4015_config = config;
if (LTC4015_cfg_battery_voltage_low(driver,
ltc4015_config->batteryVoltageLow)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_cfg_battery_voltage_high(driver,
ltc4015_config->batteryVoltageHigh)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_cfg_battery_current_low(driver,
ltc4015_config->batteryCurrentLow)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_cfg_input_voltage_low(driver, ltc4015_config->inputVoltageLow)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_cfg_input_current_high(driver, ltc4015_config->inputCurrentHigh)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_cfg_input_current_limit(driver,
ltc4015_config->inputCurrentLimit)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (ltc4015_config->icharge) {
if (LTC4015_cfg_icharge(driver, ltc4015_config->icharge)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
}
if (ltc4015_config->vcharge) {
if (LTC4015_cfg_vcharge(driver, ltc4015_config->vcharge)
!= RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
}
LTC4015_setAlertHandler(driver, _alert_handler, (void *)alert_token);
if (LTC4015_enableLimitAlerts(driver,
LTC4015_EVT_BVL | LTC4015_EVT_BVH
| LTC4015_EVT_IVL | LTC4015_EVT_ICH
| LTC4015_EVT_BCL) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (LTC4015_enableChargerStateAlerts(driver, LTC4015_EVT_BMFA)) {
return POST_DEV_CFG_FAIL;
}
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable LTC4015_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
.cb_get_config = _get_config,
.cb_set_config = _set_config,
};

View File

@@ -0,0 +1,340 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/ocmp_wrappers/ocmp_ltc4274.h"
#include "helpers/array.h"
#include "helpers/math.h"
#include "inc/devices/ltc4274.h"
typedef enum LTC7274Status {
LTC7274_STATUS_DETECT = 0,
LTC7274_STATUS_CLASS ,
LTC7274_STATUS_POWERGOOD,
} LTC7274Status;
typedef enum LTC7274Config {
LTC4274_CONFIG_OPERATING_MODE = 0,
LTC4274_CONFIG_DETECT_ENABLE,
LTC4274_CONFIG_INTERRUPT_MASK,
LTC4274_CONFIG_INTERRUPT_ENABLE,
LTC4274_CONFIG_HP_ENABLE
} LTC7274Config;
typedef enum LTC7274Alert {
LTC4274_ALERT_NO_ACTIVE = 0,
LTC4274_ALERT_POWER_ENABLE,
LTC4274_ALERT_POWERGOOD,
LTC4274_ALERT_DISCONNECT,
LTC4274_ALERT_DETECTION ,
LTC4274_ALERT_CLASS,
LTC4274_ALERT_TCUT,
LTC4274_ALERT_TSTART,
LTC4274_ALERT_SUPPLY
} LTC7274Alert;
bool LTC4274_reset(void *driver, void *params)
{
ReturnStatus status = RETURN_OK;
status = ltc4274_reset();
return status;
}
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf) {
bool ret = true;
uint8_t *res = return_buf;
switch (param_id) {
case LTC7274_STATUS_DETECT:
{
if (ltc4274_get_detection_status(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: Reading PSE detection and classification failed.\n");
}
break;
}
case LTC7274_STATUS_CLASS:
{
if (ltc4274_get_class_status(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: Reading PSE power status failed.\n");
}
break;
}
case LTC7274_STATUS_POWERGOOD:
{
if (ltc4274_get_powergood_status(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: Reading PSE power status failed.\n");
return ret;
}
break;
}
default:
{
LOGGER("LTC4274:ERROR::Unkown parameter recived for PSE status.\n");
ret = false;
}
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _set_config
**
** DESCRIPTION : ocmp wrapper for setting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _set_config(void *driver, unsigned int param_id,
const void *data) {
bool ret = true;
uint8_t *res = (uint8_t*)data;
switch (param_id) {
case LTC4274_CONFIG_OPERATING_MODE:
{
if ( ltc4274_set_cfg_operation_mode(driver, *res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE operational mode setting mode failed.\n");
}
break;
}
case LTC4274_CONFIG_DETECT_ENABLE:
{
if (ltc4274_set_cfg_detect_enable(driver, *res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE detection and classification enable failed.\n");
}
break;
}
case LTC4274_CONFIG_INTERRUPT_MASK:
{
if (ltc4274_set_interrupt_mask(driver, *res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR::PSE interrupts mask enable failed.\n");
}
break;
}
case LTC4274_CONFIG_INTERRUPT_ENABLE:
{
if (ltc4274_cfg_interrupt_enable(driver, *res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE interrupt enable failed.\n");
}
break;
}
case LTC4274_CONFIG_HP_ENABLE:
{
if (ltc4274_set_cfg_pshp_feature(driver, *res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE configuration for LTEPOE++ failed.\n");
}
break;
}
default:
{
LOGGER("LTC4274:ERROR:: PSE configurion unkown parmeter passed.\n");
ret = false;
}
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _get_config
**
** DESCRIPTION : ocmp wrapper for getting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_config(void *driver, unsigned int param_id,
void *return_buf) {
bool ret = true;
uint8_t *res = return_buf;
switch (param_id) {
case LTC4274_CONFIG_OPERATING_MODE:
{
if (ltc4274_get_operation_mode(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE operational mode setting mode failed.\n");
}
break;
}
case LTC4274_CONFIG_DETECT_ENABLE:
{
if (ltc4274_get_detect_enable(driver, res)!= RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE detection and classification enable failed.\n");
}
break;
}
case LTC4274_CONFIG_INTERRUPT_MASK:
{
if (ltc4274_get_interrupt_mask(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR::PSE interrupts mask enable failed.\n");
}
break;
}
case LTC4274_CONFIG_INTERRUPT_ENABLE:
{
if (ltc4274_get_interrupt_enable(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE interrupt enable failed.\n");
}
break;
}
case LTC4274_CONFIG_HP_ENABLE:
{
if (ltc4274_get_pshp_feature(driver, res) != RETURN_OK) {
ret = false;
LOGGER("LTC4274:ERROR:: PSE configuration for LTEPOE++ failed.\n");
}
break;
}
default:
{
LOGGER("LTC4274:ERROR:: PSE configurion unkown parmeter passed.\n");
ret = false;
}
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver, POSTData *postData)
{
ltc4274_config(driver);
return ltc4274_probe(driver, postData);
}
/*****************************************************************************
** FUNCTION NAME : _alert_handler
**
** DESCRIPTION : call back function for handling alerts from device
** layer
**
** ARGUMENTS : event type , current value, alert config,
**
** RETURN TYPE :
**
*****************************************************************************/
static void _alert_handler(LTC4274_Event evt,
void *context)
{
unsigned int alert;
switch(evt) {
case LTC4274_EVT_SUPPLY:
alert = LTC4274_ALERT_SUPPLY;
break;
case LTC4274_EVT_TSTART:
alert = LTC4274_ALERT_TSTART;
break;
case LTC4274_EVT_TCUT:
alert = LTC4274_ALERT_TCUT;
break;
case LTC4274_EVT_CLASS:
alert = LTC4274_ALERT_CLASS;
break;
case LTC4274_EVT_DETECTION:
alert = LTC4274_ALERT_DETECTION;
break;
case LTC4274_EVT_DISCONNECT:
alert = LTC4274_ALERT_DISCONNECT;
break;
case LTC4274_EVT_POWERGOOD:
alert = LTC4274_ALERT_POWERGOOD;
break;
case LTC4274_EVT_POWER_ENABLE:
alert = LTC4274_ALERT_POWER_ENABLE;
break;
default:
{
alert = LTC4274_ALERT_NO_ACTIVE;
return;
}
}
uint8_t alert_data = 0x00;
OCMP_GenerateAlert(context, alert, &alert_data);
LOGGER_DEBUG("LTC7274 Event: %d \n", evt);
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
ltc4274_init(driver);
if (!config) {
return POST_DEV_CFG_DONE;
}
const LTC4274_Config *LTC7274_config = config;
if ( ltc4274_set_cfg_operation_mode(driver,LTC7274_config->operatingMode) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if ( ltc4274_set_cfg_detect_enable(driver,LTC7274_config->detectEnable) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if ( ltc4274_set_interrupt_mask(driver,LTC7274_config->interruptMask) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if ( ltc4274_set_cfg_pshp_feature(driver,LTC7274_config->pseHpEnable) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
ltc4274_set_alert_handler(driver, _alert_handler, (void *)alert_token);
//TODO: SET enable or disable.
if (ltc4274_cfg_interrupt_enable(driver, LTC7274_config->interruptEnable) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
ltc4274_update_stateInfo(driver);
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable LTC4274_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
.cb_get_config = _get_config,
.cb_set_config = _set_config,
};

View File

@@ -0,0 +1,128 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/ocmp_wrappers/ocmp_ltc4295.h"
#include "helpers/array.h"
#include "helpers/math.h"
#include "inc/devices/ltc4295.h"
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf)
{
bool ret = false;
switch (param_id) {
case LTC4295_STATUS_CLASS:
{
ePDClassType *res = (ePDClassType*)return_buf;
if (ltc4295_get_class(driver, res) == RETURN_OK) {
ret = true;
}
}
break;
case LTC4295_STATUS_POWERGOOD:
{
ePDPowerState *res =(ePDPowerState*) return_buf;
if (ltc4295_get_power_good(driver, res) == RETURN_OK) {
ret = true;
}
break;
}
default:
{
LOGGER_ERROR("LTC4295::Unknown status param %d\n", param_id);
ret = false;
}
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver, POSTData *postData)
{
ltc4295_config(driver);
return ltc4295_probe(driver,postData);
}
/*****************************************************************************
** FUNCTION NAME : _alert_handler
**
** DESCRIPTION : call back function for handling alerts from device
** layer
**
** ARGUMENTS : event type , current value, alert config,
**
** RETURN TYPE :
**
*****************************************************************************/
static void _alert_handler(LTC4295_Event evt, void *context)
{
unsigned int alert;
switch (evt) {
case LTC4295_CONNECT_EVT:
alert = LTC4295_CONNECT_ALERT;
break;
case LTC4295_DISCONNECT_EVT:
alert = LTC4295_DISCONNECT_ALERT;
break;
case LTC4295_INCOMPATIBLE_EVT:
alert = LTC4295_INCOMPATIBLE_ALERT;
break;
default:
LOGGER_ERROR("Unknown LTC4295evt: %d\n", evt);
return;
}
OCMP_GenerateAlert(context, alert, &evt);
LOGGER_DEBUG("LTC4295A alert: %d generated.\n", alert);
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
if (ltc4295_init(driver) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
ltc4295_set_alert_handler(driver, _alert_handler, (void *)alert_token);
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable LTC4295_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
};

View File

@@ -0,0 +1,73 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/Framework.h"
#include "common/inc/ocmp_wrappers/ocmp_powersource.h"
#include "helpers/array.h"
#include "inc/devices/powerSource.h"
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf)
{
bool ret = false;
pwr_get_source_info(driver);
if ( pwr_process_get_status_parameters_data(param_id,return_buf) == RETURN_OK) {
ret = true;
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver)
{
/* powersource is part of TIVA */
return POST_DEV_FOUND;
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
pwr_source_init();
return POST_DEV_NO_CFG_REQ;
}
const Driver_fxnTable PWRSRC_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
};

View File

@@ -0,0 +1,207 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/ocmp_wrappers/ocmp_se98a.h"
#include "helpers/array.h"
#include "helpers/math.h"
#include "inc/devices/se98a.h"
typedef enum Se98aStatus {
SE98A_STATUS_TEMPERATURE = 0,
} Se98aStatus;
typedef enum Se98aConfig {
SE98A_CONFIG_LIM_LOW = 0,
SE98A_CONFIG_LIM_HIGH,
SE98A_CONFIG_LIM_CRIT,
} Se98aConfig;
typedef enum Se98aAlert {
SE98A_ALERT_LOW = 0,
SE98A_ALERT_HIGH,
SE98A_ALERT_CRITICAL
} Se98aAlert;
/*****************************************************************************
** FUNCTION NAME : _get_status
**
** DESCRIPTION : ocmp wrapper for getting status
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_status(void *driver, unsigned int param_id,
void *return_buf) {
switch (param_id) {
case SE98A_STATUS_TEMPERATURE: {
int8_t *res = return_buf;
if (se98a_read(driver, res) == RETURN_OK) {
return true;
}
break;
}
default:
LOGGER_ERROR("SE98A::Unknown status param %d\n", param_id);
return false;
}
return false;
}
/*****************************************************************************
** FUNCTION NAME : _get_config
**
** DESCRIPTION : ocmp wrapper for getting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _get_config(void *driver, unsigned int param_id,
void *return_buf) {
switch (param_id) {
case SE98A_CONFIG_LIM_LOW:
case SE98A_CONFIG_LIM_HIGH:
case SE98A_CONFIG_LIM_CRIT: {
int8_t *res = return_buf;
if (se98a_get_limit(driver, param_id + 1, res) == RETURN_OK) {
return true;
}
break;
}
default:
LOGGER_ERROR("SE98A::Unknown config param %d\n", param_id);
return false;
}
return false;
}
/*****************************************************************************
** FUNCTION NAME : _set_config
**
** DESCRIPTION : ocmp wrapper for setting config parameter
**
** ARGUMENTS : driver , parameter id in ocmp msg , ocmp payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _set_config(void *driver, unsigned int param_id,
const void *data) {
switch (param_id) {
case SE98A_CONFIG_LIM_LOW:
case SE98A_CONFIG_LIM_HIGH:
case SE98A_CONFIG_LIM_CRIT: {
const int8_t *limit = data;
if (se98a_set_limit(driver, param_id + 1, *limit) == RETURN_OK) {
return true;
}
break;
}
default:
LOGGER_ERROR("SE98A::Unknown config param %d\n", param_id);
return false;
}
return false;
}
/*****************************************************************************
** FUNCTION NAME : _probe
**
** DESCRIPTION : ocmp wrapper for handling POST(power on self test)
**
** ARGUMENTS : driver , postData
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _probe(void *driver, POSTData *postData)
{
return se98a_probe(driver, postData);
}
/*****************************************************************************
** FUNCTION NAME : _alert_handler
**
** DESCRIPTION : call back function for handling alerts from device
** layer
**
** ARGUMENTS : event type , current value, alert config,
**
** RETURN TYPE :
**
*****************************************************************************/
static void _alert_handler(SE98A_Event evt, int8_t temperature,
void *context)
{
unsigned int alert;
switch (evt) {
case SE98A_EVT_ACT:
alert = SE98A_ALERT_CRITICAL;
break;
case SE98A_EVT_AAW:
alert = SE98A_ALERT_HIGH;
break;
case SE98A_EVT_BAW:
alert = SE98A_ALERT_LOW;
break;
default:
LOGGER_ERROR("Unknown SE98A evt: %d\n", evt);
return;
}
uint8_t alert_data = (uint8_t)MAX((int8_t)0, temperature);
OCMP_GenerateAlert(context, alert, &alert_data);
LOGGER_DEBUG("SE98A Event: %d Temperature: %d\n", evt, temperature);
}
/*****************************************************************************
** FUNCTION NAME : _init
**
** DESCRIPTION : ocmp wrapper for handling init
**
** ARGUMENTS : driver , driver config, context for cb function
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _init(void *driver, const void *config,
const void *alert_token)
{
if (se98a_init(driver) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
if (!config) {
return POST_DEV_CFG_DONE;
}
const SE98A_Config *se98a_config = config;
for (int i = 0; i < ARRAY_SIZE(se98a_config->limits); ++i) {
if (se98a_set_limit(driver, i + 1, se98a_config->limits[i]) !=
RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
}
se98a_set_alert_handler(driver, _alert_handler, (void *)alert_token);
if (se98a_enable_alerts(driver) != RETURN_OK) {
return POST_DEV_CFG_FAIL;
}
return POST_DEV_CFG_DONE;
}
const Driver_fxnTable SE98_fxnTable = {
/* Message handlers */
.cb_probe = _probe,
.cb_init = _init,
.cb_get_status = _get_status,
.cb_get_config = _get_config,
.cb_set_config = _set_config,
};

View File

@@ -0,0 +1,278 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "Board.h"
#include "inc/common/global_header.h"
#include "inc/common/i2cbus.h"
#include "inc/devices/powerSource.h"
#include "inc/subsystem/power/power.h"
#include <ti/sysbios/knl/Task.h>
#include <stdlib.h>
static tPowerSource Power_SourceInfo[PWR_SRC_MAX];
/*****************************************************************************
** FUNCTION NAME : pwr_update_source_info
**
** DESCRIPTION : Update power source information.
**
** ARGUMENTS : Power Source and Power source state.
**
** RETURN TYPE : None
**
*****************************************************************************/
static void pwr_update_source_info(ePowerSource powerSrc, ePowerSourceState pwrState)
{
ePowerSource itr = PWR_SRC_EXT ;
for (; itr < PWR_SRC_MAX; itr++) {
if (Power_SourceInfo[itr].powerSource == powerSrc) {
Power_SourceInfo[itr].state = pwrState;
LOGGER("POWER:INFO:: Power State updated for Power Source %d with %d.\n",
Power_SourceInfo[itr].powerSource,
Power_SourceInfo[itr].state);
}
}
}
/******************************************************************************
* @fn pwr_check_poe
*
* @brief Check presence of POE.
*
* @args None.
*
* @return ReturnStatus
******************************************************************************/
static ReturnStatus pwr_check_poe(PWRSRC_Dev *pwrSrcDev)
{
ReturnStatus ret = RETURN_NOTOK;
uint8_t value = 0;
ePowerSourceState status = PWR_SRC_NON_AVAILABLE;
//For Checking POE POWER SOURCE
value = OcGpio_read(&pwrSrcDev->cfg.pin_poe_prsnt_n);
if ( value == 0) {
status=PWR_SRC_AVAILABLE;
ret = RETURN_OK;
}
pwr_update_source_info(PWR_SRC_POE, status);
return ret;
}
/******************************************************************************
* @fn pwr_check_ext_power
*
* @brief Check presence of external power.
*
* @args None.
*
* @return ReturnStatus
******************************************************************************/
static ReturnStatus pwr_check_ext_power(PWRSRC_Dev *pwrSrcDev)
{
ReturnStatus ret = RETURN_NOTOK;
uint8_t value = 0;
ePowerSourceState status = PWR_SRC_NON_AVAILABLE;
//For Checking POE POWER SOURCE
value = OcGpio_read(&pwrSrcDev->cfg.pin_dc_present);
if ( value == 0) {
status=PWR_SRC_AVAILABLE;
ret = RETURN_OK;
}
pwr_update_source_info(PWR_SRC_EXT, status);
return ret;
}
/******************************************************************************
* @fn pwr_check_batt
*
* @brief Check presence of Battery.
*
* @args None.
*
* @return ReturnStatus
******************************************************************************/
static ReturnStatus pwr_check_batt(PWRSRC_Dev *pwrSrcDev)
{
ReturnStatus ret = RETURN_NOTOK;
uint8_t value = 0;
ePowerSourceState status = PWR_SRC_NON_AVAILABLE;
//For Checking POE POWER SOURCE
value = OcGpio_read(&pwrSrcDev->cfg.pin_int_bat_prsnt);
if ( value == 0) {
status=PWR_SRC_AVAILABLE;
ret = RETURN_OK;
}
pwr_update_source_info(PWR_SRC_LIION_BATT, status);
return ret;
}
/******************************************************************************
** FUNCTION NAME : pwr_check_presence_of_source
**
** DESCRIPTION : check for power source available.
**
** ARGUMENTS : pointer to powersource config
**
** RETURN TYPE : None
**
******************************************************************************/
static void pwr_check_presence_of_source(PWRSRC_Dev *pwrSrcDev)
{
ReturnStatus ret = RETURN_NOTOK;
ret = pwr_check_ext_power(pwrSrcDev);
LOGGER("POWER:INFO:: Power Source External %s.\n",
((ret == RETURN_OK) ? "available" : "not available"));
ret = pwr_check_poe(pwrSrcDev);
LOGGER("POWER:INFO:: Power Source POE %s.\n",
((ret == RETURN_OK) ? "available" : "not available"));
ret = pwr_check_batt(pwrSrcDev);
LOGGER("POWER:INFO:: Power Source BATTERY %s.\n",
((ret == RETURN_OK) ? "available" : "not available"));
return ;
}
/******************************************************************************
** FUNCTION NAME : pwr_source_inuse
**
** DESCRIPTION : Give info about currently used power source.
**
** ARGUMENTS : output pointer for storing powersource
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
******************************************************************************/
static ReturnStatus pwr_source_inuse(ePowerSource *inUse)
{
ReturnStatus ret = RETURN_NOTOK;
ePowerSource itr = PWR_SRC_EXT ;
for ( ; itr < PWR_SRC_MAX; itr++) {
if (Power_SourceInfo[itr].state == PWR_SRC_AVAILABLE) {
*inUse = itr;
ret = RETURN_OK;
break;
}
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : pwr_source_init
**
** DESCRIPTION : initialize power source information.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
void pwr_source_init()
{
ePowerSource itr = PWR_SRC_EXT ;
for (; itr < PWR_SRC_MAX; itr++) {
Power_SourceInfo[itr].powerSource = itr;
Power_SourceInfo[itr].state = PWR_SRC_NON_AVAILABLE;
}
return;
}
/*****************************************************************************
** FUNCTION NAME : pwr_get_source_info
**
** DESCRIPTION : initialize power source information.
**
** ARGUMENTS : power source config
**
** RETURN TYPE : None
**
*****************************************************************************/
void pwr_get_source_info(PWRSRC_Dev *pwrSrcDev)
{
ReturnStatus status = RETURN_NOTOK;
ePowerSource powerSource = PWR_SRC_EXT;
/* Check the presence of power sources*/
pwr_check_presence_of_source(pwrSrcDev);
/* Find the primary power source and update Power Source info for same.*/
status = pwr_source_inuse(&powerSource);
if (status != RETURN_OK) {
LOGGER("POWER:ERROR:: Failed to get current power source.\n");
} else {
LOGGER("POWER:INFO:: Current Power source is 0x%x.\n", powerSource);
pwr_update_source_info(powerSource, PWR_SRC_ACTIVE);
}
}
/*****************************************************************************
** FUNCTION NAME : pwr_process_get_status_parameters_data
**
** DESCRIPTION : Get Power Status Message.
**
** ARGUMENTS : parameter id ,Pointer to OCMPMessageFrame payload
**
** RETURN TYPE : RETURN_OK or RETURN_NOTOK
**
*****************************************************************************/
ReturnStatus
pwr_process_get_status_parameters_data(ePower_StatusParamId paramIndex,
uint8_t *pPowerStatusData)
{
ReturnStatus status = RETURN_OK;
switch (paramIndex) {
case PWR_STAT_EXT_PWR_AVAILABILITY: {
if ((Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_ACTIVE) ||
(Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_AVAILABLE))
*pPowerStatusData = 1;
break;
}
case PWR_STAT_EXT_PWR_ACTIVE: {
if (Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_ACTIVE)
*pPowerStatusData = 1;
break;
}
case PWR_STAT_POE_AVAILABILITY: {
if ((Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_ACTIVE) ||
(Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_AVAILABLE))
*pPowerStatusData = 1;
break;
}
case PWR_STAT_POE_ACTIVE: {
if (Power_SourceInfo[PWR_SRC_POE].state == PWR_SRC_ACTIVE)
*pPowerStatusData = 1;
break;
}
case PWR_STAT_BATT_AVAILABILITY: {
if ((Power_SourceInfo[PWR_SRC_LIION_BATT].state ==
PWR_SRC_ACTIVE) ||
(Power_SourceInfo[PWR_SRC_LIION_BATT].state ==
PWR_SRC_AVAILABLE))
*pPowerStatusData = 1;
break;
}
case PWR_STAT_BATT_ACTIVE: {
if (Power_SourceInfo[PWR_SRC_LIION_BATT].state == PWR_SRC_ACTIVE)
*pPowerStatusData = 1;
break;
}
default: {
LOGGER("POWER::ERROR: Invalid Power param status.\n");
}
}
return status;
}

View File

@@ -0,0 +1,405 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "devices/i2c/threaded_int.h"
#include "helpers/math.h"
#include "helpers/memory.h"
#include "inc/common/byteorder.h"
#include "inc/devices/se98a.h"
#include <ti/sysbios/knl/Task.h>
#include <math.h>
/*****************************************************************************
* Register Definitions
*****************************************************************************/
/* Register Addresses */
#define SE98A_REG_CAPS 0x00
#define SE98A_REG_CFG 0x01
#define SE98A_REG_HIGH_LIM 0x02
#define SE98A_REG_LOW_LIM 0x03
#define SE98A_REG_CRIT_LIM 0x04
#define SE98A_REG_TEMP 0x05
#define SE98A_REG_MFG_ID 0x06
#define SE98A_REG_DEV_ID 0x07
/* Temperature Sensor Info */
#define SE98A_MFG_ID 0x1131
#define SE98A_DEV_ID 0xA1
/* Configuration Bits */
#define SE98A_CFG_HEN_H (1 << 10) /* Hysteresis Enable High Bit */
#define SE98A_CFG_HEN_L (1 << 9) /* Hysteresis Enable Low Bit */
#define SE98A_CFG_SHMD (1 << 8) /* Shutdown Mode */
#define SE98A_CFG_CTLB (1 << 7) /* Critical Trip Lock Bit */
#define SE98A_CFG_AWLB (1 << 6) /* Alarm Window Lock Bit */
#define SE98A_CFG_CEVENT (1 << 5) /* (WO) Clear EVENT */
#define SE98A_CFG_ESTAT (1 << 4) /* (RO) EVENT Status */
#define SE98A_CFG_EOCTL (1 << 3) /* EVENT Output Control */
#define SE98A_CFG_CVO (1 << 2) /* Critical Event Only */
#define SE98A_CFG_EP (1 << 1) /* EVENT Polarity */
#define SE98A_CFG_EMD (1 << 0) /* EVENT Mode */
#define SE98A_CFG_HYS_0 (0x0 << 9)
#define SE98A_CFG_HYS_1P5 (0x1 << 9)
#define SE98A_CFG_HYS_3 (0x2 << 9)
#define SE98A_CFG_HYS_6 (0x3 << 9)
/* Default CFG plus interrupt mode (we don't support comparator mode) */
#define SE98A_CONFIG_DEFAULT (0x0000 | SE98A_CFG_EMD | SE98A_CFG_HYS_1P5)
/*****************************************************************************
* Helper to read from a SE98A register
*****************************************************************************/
static ReturnStatus se98a_reg_read(const SE98A_Dev *dev,
uint8_t regAddress,
uint16_t *regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle tempHandle = i2c_get_handle(dev->cfg.dev.bus);
if (!tempHandle) {
LOGGER_ERROR("SE98A:ERROR:: Failed to get I2C Bus for Temperature "
"sensor 0x%x on bus 0x%x.\n", dev->cfg.dev.slave_addr,
dev->cfg.dev.bus);
} else {
status = i2c_reg_read(tempHandle, dev->cfg.dev.slave_addr, regAddress,
regValue, 2);
*regValue = betoh16(*regValue);
}
return status;
}
/*****************************************************************************
* Helper to write to a SE98A register
*****************************************************************************/
static ReturnStatus se98a_reg_write(const SE98A_Dev *dev,
uint8_t regAddress,
uint16_t regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle tempHandle = i2c_get_handle(dev->cfg.dev.bus);
if (!tempHandle) {
LOGGER_ERROR("SE98A:ERROR:: Failed to get I2C Bus for Temperature "
"sensor 0x%x on bus 0x%x.\n", dev->cfg.dev.slave_addr,
dev->cfg.dev.bus);
} else {
regValue = htobe16(regValue);
status = i2c_reg_write(tempHandle, dev->cfg.dev.slave_addr, regAddress,
regValue, 2);
}
return status;
}
/*****************************************************************************
* Helper to read the device ID
*****************************************************************************/
static ReturnStatus se98a_get_dev_id(const SE98A_Dev *dev, uint8_t *devID)
{
uint16_t regValue;
ReturnStatus status = se98a_reg_read(dev, SE98A_REG_DEV_ID,
&regValue);
if (status == RETURN_OK) {
/* Strip off the revision - we don't care about it right now */
*devID = HIBYTE(regValue);
}
return status;
}
/*****************************************************************************
* Helper to read the manufacturer ID
*****************************************************************************/
static ReturnStatus se98a_get_mfg_id(const SE98A_Dev *dev, uint16_t *mfgID)
{
return se98a_reg_read(dev, SE98A_REG_MFG_ID, mfgID);
}
/*****************************************************************************
* Helper to write to the configuration register
*****************************************************************************/
static ReturnStatus se98a_set_config_reg(const SE98A_Dev *dev,
uint16_t configValue)
{
return se98a_reg_write(dev, SE98A_REG_CFG, configValue);
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus se98a_set_limit(SE98A_Dev *dev,
eTempSensor_ConfigParamsId limitToConfig,
int8_t tempLimitValue)
{
uint8_t regAddress = 0x00;
/* Get the limit to configure */
switch (limitToConfig) {
case CONF_TEMP_SE98A_LOW_LIMIT_REG:
regAddress = SE98A_REG_LOW_LIM;
break;
case CONF_TEMP_SE98A_HIGH_LIMIT_REG:
regAddress = SE98A_REG_HIGH_LIM;
break;
case CONF_TEMP_SE98A_CRITICAL_LIMIT_REG:
regAddress = SE98A_REG_CRIT_LIM;
break;
default:
return RETURN_NOTOK;
}
/*
* [15..13] RFU
* [12] SIGN (2's complement)
* [11..4] Integer part (8 bits)
* [3..2] Fractional part (0.5, 0.25)
* [1..0] RFU
*/
/* The device technically takes an int9, but is only rated from
* -40 to +125, so we'll settle for an int8 */
uint16_t regValue = ((int16_t)tempLimitValue & 0x00FF) << 4;
/* Set the sign bit if negative */
if (tempLimitValue < 0) {
regValue |= 0x1000;
}
return se98a_reg_write(dev, regAddress, regValue);
}
/*****************************************************************************
* Helper to convert a SE98A register value to a temperature
*****************************************************************************/
static int8_t reg2temp(uint16_t reg) {
/* The limit regs have lower precision, so by making this function common,
* we lose 0.125 precision... since we round to the nearest int, I'm not
* worried */
/* Calculate the Actual Temperature Value from fixed point register
* (bottom 4 bits are fractional part - divide by 16)
*
* Register map REG_TEMP / REG_LIM
* [15..13] Trip Status / RFU
* [12] Sign / Sign
* [11..5] 8-bit Int / 8-bit Int
* [4..2] Fraction / Fraction
* [1] Fraction / RFU
* [0] RFU
*/
int16_t temperature = (reg & 0x0FFC);
/* If negative, upper bits must be set (assume a 2's comp. system) */
if (reg & 0x1000) {
temperature |= 0xF000;
}
temperature = round(temperature / 16.0f);
return CONSTRAIN(temperature, INT8_MIN, INT8_MAX);
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus se98a_read(SE98A_Dev *dev, int8_t *tempValue)
{
/* The temperature value is 2's complement with the LSB equal to 0.0625.
* The resolution is 0.125 (bit 0 is unused)
*/
uint16_t regValue = 0x0000;
ReturnStatus status = se98a_reg_read(dev, SE98A_REG_TEMP, &regValue);
if (status == RETURN_OK) {
*tempValue = reg2temp(regValue);
LOGGER_DEBUG("TEMPSENSOR:INFO:: Temperature sensor 0x%x on bus "
"0x%x is reporting Temperature value of %d Celsius.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *tempValue);
}
return status;
}
/*****************************************************************************
* Helper to read the configuration register
*****************************************************************************/
static ReturnStatus se98a_get_config_reg(const SE98A_Dev *dev,
uint16_t *configValue)
{
return se98a_reg_read(dev, SE98A_REG_CFG, configValue);
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus se98a_get_limit(SE98A_Dev *dev,
eTempSensor_ConfigParamsId limitToConfig,
int8_t* tempLimitValue)
{
ReturnStatus status = RETURN_NOTOK;
uint16_t regValue = 0x0000;
uint8_t regAddress = 0x0000;
/*getting the limit to configure */
switch (limitToConfig) {
case CONF_TEMP_SE98A_LOW_LIMIT_REG:
regAddress = SE98A_REG_LOW_LIM;
break;
case CONF_TEMP_SE98A_HIGH_LIMIT_REG:
regAddress = SE98A_REG_HIGH_LIM;
break;
case CONF_TEMP_SE98A_CRITICAL_LIMIT_REG:
regAddress = SE98A_REG_CRIT_LIM;
break;
default:
return RETURN_NOTOK;
}
status = se98a_reg_read(dev, regAddress, &regValue);
if (status == RETURN_OK) {
*tempLimitValue = reg2temp(regValue);
LOGGER_DEBUG("TEMPSENSOR:INFO:: Temperature sensor 0x%x on bus "
"0x%x is having Limit configure to 0x%x.\n",
dev->cfg.dev.slave_addr, dev->cfg.dev.bus, *tempLimitValue);
}
return status;
}
/*****************************************************************************
* Internal IRQ handler - reads in triggered interrupts and dispatches CBs
*****************************************************************************/
static void se98a_handle_irq(void *context) {
SE98A_Dev *dev = context;
ReturnStatus res = RETURN_NOTOK;
const IArg mutexKey = GateMutex_enter(dev->obj.mutex); {
/* See if this event was from us (we can't just read the trip status
* since those bits are sticky - they could be from an old event) */
uint16_t config_reg;
if ((se98a_get_config_reg(dev, &config_reg) == RETURN_OK) &&
(config_reg & SE98A_CFG_ESTAT)) {
/* Clear the event */
config_reg |= SE98A_CFG_CEVENT;
res = se98a_set_config_reg(dev, config_reg);
}
} GateMutex_leave(dev->obj.mutex, mutexKey);
if (res != RETURN_OK) {
return;
}
/* Read the temperature register which also contains event status */
uint16_t regValue;
if (se98a_reg_read(dev, SE98A_REG_TEMP, &regValue) != RETURN_OK) {
/* Something really strange happened */
return;
}
/* Grab the upper 3 bits which represent the event trip status */
uint8_t trip_stat = (regValue >> 13) & 0x07;
int8_t temperature = reg2temp(regValue);
/* See if we have a callback assigned to handle alerts */
if (!dev->obj.alert_cb) {
return;
}
/* Since > CRIT implies above window, we only handle the highest priority
* event to avoid duplicate events being sent */
if (trip_stat & SE98A_EVT_ACT) {
dev->obj.alert_cb(SE98A_EVT_ACT, temperature, dev->obj.cb_context);
} else if (trip_stat & SE98A_EVT_AAW) {
dev->obj.alert_cb(SE98A_EVT_AAW, temperature, dev->obj.cb_context);
} else if (trip_stat & SE98A_EVT_BAW) {
dev->obj.alert_cb(SE98A_EVT_BAW, temperature, dev->obj.cb_context);
}
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus se98a_init(SE98A_Dev *dev)
{
dev->obj = (SE98A_Obj){};
dev->obj.mutex = GateMutex_create(NULL, NULL);
if (!dev->obj.mutex) {
return RETURN_NOTOK;
}
/* Make sure we're talking to the right device */
//if (se98a_probe(dev) != POST_DEV_FOUND) {
// return RETURN_NOTOK;
//}
/* The only way to truly reset this device is to cycle power - we'll just
* clear out the config register to be safe and clear any interrupts from
* a previous life */
if (se98a_set_config_reg(
dev, SE98A_CONFIG_DEFAULT | SE98A_CFG_CEVENT) !=
RETURN_OK) {
return RETURN_NOTOK;
}
if (dev->cfg.pin_evt) {
const uint32_t pin_evt_cfg = OCGPIO_CFG_INPUT | OCGPIO_CFG_INT_FALLING;
/*TODO:Temp*/
if (OcGpio_configure(dev->cfg.pin_evt, pin_evt_cfg) < OCGPIO_SUCCESS) {
return RETURN_NOTOK;
}
/* Use a threaded interrupt to handle IRQ */
// ThreadedInt_Init(dev->cfg.pin_evt, se98a_handle_irq, (void *)dev);
}
return RETURN_OK;
}
/*****************************************************************************
*****************************************************************************/
void se98a_set_alert_handler(SE98A_Dev *dev, SE98A_CallbackFn alert_cb,
void *cb_context)
{
dev->obj.alert_cb = alert_cb;
dev->obj.cb_context = cb_context;
}
/*****************************************************************************
*****************************************************************************/
ReturnStatus se98a_enable_alerts(SE98A_Dev *dev)
{
/* Wait 125ms after setting alarm window before enabling event pin
* see datasheet page 8 - 7.3.2.1 Alarm window */
Task_sleep(125);
ReturnStatus res = RETURN_NOTOK;
const IArg mutexKey = GateMutex_enter(dev->obj.mutex); {
uint16_t config_reg;
if (se98a_get_config_reg(dev, &config_reg) == RETURN_OK) {
config_reg |= SE98A_CFG_EOCTL;
res = se98a_set_config_reg(dev, config_reg);
}
} GateMutex_leave(dev->obj.mutex, mutexKey);
return res;
}
/*****************************************************************************
*****************************************************************************/
ePostCode se98a_probe(SE98A_Dev *dev, POSTData *postData)
{
uint8_t devId = 0x00;
uint16_t manfId = 0x0000;
if (se98a_get_dev_id(dev, &devId) != RETURN_OK) {
return POST_DEV_MISSING;
}
if (devId != SE98A_DEV_ID) {
return POST_DEV_ID_MISMATCH;
}
if (se98a_get_mfg_id(dev, &manfId) != RETURN_OK) {
return POST_DEV_MISSING;
}
if (manfId != SE98A_MFG_ID) {
return POST_DEV_ID_MISMATCH;
}
post_update_POSTData(postData, dev->cfg.dev.bus, dev->cfg.dev.slave_addr,manfId, devId);
return POST_DEV_FOUND;
}

View File

@@ -0,0 +1,832 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "inc/common/byteorder.h"
#include "inc/common/global_header.h"
#include "inc/devices/sx1509.h"
/*****************************************************************************
* REGISTER DEFINITIONS
*****************************************************************************/
#define SX1509_REG_INPUT_DISABLE_B 0x00 /* Input buffer disable register I/O[15..8] (Bank B) */
#define SX1509_REG_INPUT_DISABLE_A 0x01 /* Input buffer disable register I/O[7..0] (Bank A) */
#define SX1509_REG_LONG_SLEW_B 0x02 /* Output buffer long slew register I/O[15..8] (Bank B) */
#define SX1509_REG_LONG_SLEW_A 0x03 /* Output buffer long slew register I/O[7..0] (Bank A) */
#define SX1509_REG_LOW_DRIVE_B 0x04 /* Output buffer low drive register I/O[15..8] (Bank B) */
#define SX1509_REG_LOW_DRIVE_A 0x05 /* Output buffer low drive register I/O[7..0] (Bank A) */
#define SX1509_REG_PULL_UP_B 0x06 /* Pull_up register I/O[15..8] (Bank B) */
#define SX1509_REG_PULL_UP_A 0x07 /* Pull_up register I/O[7..0] (Bank A) */
#define SX1509_REG_PULL_DOWN_B 0x08 /* Pull_down register I/O[15..8] (Bank B) */
#define SX1509_REG_PULL_DOWN_A 0x09 /* Pull_down register I/O[7..0] (Bank A) */
#define SX1509_REG_OPEN_DRAIN_B 0x0A /* Open drain register I/O[15..8] (Bank B) */
#define SX1509_REG_OPEN_DRAIN_A 0x0B /* Open drain register I/O[7..0] (Bank A) */
#define SX1509_REG_POLARITY_B 0x0C /* Polarity register I/O[15..8] (Bank B) */
#define SX1509_REG_POLARITY_A 0x0D /* Polarity register I/O[7..0] (Bank A) */
#define SX1509_REG_DIR_B 0x0E /* Direction register I/O[15..8] (Bank B) */
#define SX1509_REG_DIR_A 0x0F /* Direction register I/O[7..0] (Bank A) */
#define SX1509_REG_DATA_B 0x10 /* Data register I/O[15..8] (Bank B) */
#define SX1509_REG_DATA_A 0x11 /* Data register I/O[7..0] (Bank A) */
#define SX1509_REG_INTERRUPT_MASK_B 0x12 /* Interrupt mask register I/O[15..8] (Bank B) */
#define SX1509_REG_INTERRUPT_MASK_A 0x13 /* Interrupt mask register I/O[7..0] (Bank A) */
#define SX1509_REG_SENSE_HIGH_B 0x14 /* Sense register for I/O[15:12] (Bank B) */
#define SX1509_REG_SENSE_LOW_B 0x15 /* Sense register for I/O[11:8] (Bank B) */
#define SX1509_REG_SENSE_HIGH_A 0x16 /* Sense register for I/O[7:4] (Bank A) */
#define SX1509_REG_SENSE_LOW_A 0x17 /* Sense register for I/O[3:0] (Bank A) */
#define SX1509_REG_INTERRUPT_SOURCE_B 0x18 /* Interrupt source register I/O[15..8] (Bank B) */
#define SX1509_REG_INTERRUPT_SOURCE_A 0x19 /* Interrupt source register I/O[7..0] (Bank A) */
#define SX1509_REG_EVENT_STATUS_B 0x1A /* Event status register I/O[15..8] (Bank B) */
#define SX1509_REG_EVENT_STATUS_A 0x1B /* Event status register I/O[7..0] (Bank A) */
#define SX1509_REG_LEVEL_SHIFTER_1 0x1C /* Level shifter register 1 */
#define SX1509_REG_LEVEL_SHIFTER_2 0x1D /* Level shifter register 2 */
#define SX1509_REG_CLOCK 0x1E /* Clock management register */
#define SX1509_REG_MISC 0x1F /* Miscellaneous device settings register */
#define SX1509_REG_LED_DRIVER_ENABLE_B 0x20 /* LED driver enable register I/O[15..8] (Bank B) */
#define SX1509_REG_LED_DRIVER_ENABLE_A 0x21 /* LED driver enable register I/O[7..0] (Bank A) */
#define SX1509_REG_DEBOUNCE_CONFIG 0x22 /* Debounce configuration register */
#define SX1509_REG_DEBOUNCE_ENABLE_B 0x23 /* Debounce enable register I/O[15..8] (Bank B) */
#define SX1509_REG_DEBOUNCE_ENABLE_A 0x24 /* Debounce enable register I/O[7..0] (Bank A) */
#define SX1509_REG_T_ON_0 0x29 /* ON time register for I/O[0] */
#define SX1509_REG_I_ON_0 0x2A /* ON intensity register for I/O[0] */
#define SX1509_REG_OFF_0 0x2B /* OFF time/intensity register for I/O[0] */
#define SX1509_REG_T_ON_1 0x2C /* ON time register for I/O[1] */
#define SX1509_REG_I_ON_1 0x2D /* ON intensity register for I/O[1] */
#define SX1509_REG_OFF_1 0x2E /* OFF time/intensity register for I/O[1] */
#define SX1509_REG_T_ON_2 0x2F /* ON time register for I/O[2] */
#define SX1509_REG_I_ON_2 0x30 /* ON intensity register for I/O[2] */
#define SX1509_REG_OFF_2 0x31 /* OFF time/intensity register for I/O[2] */
#define SX1509_REG_T_ON_3 0x32 /* ON time register for I/O[3] */
#define SX1509_REG_I_ON_3 0x33 /* ON intensity register for I/O[3] */
#define SX1509_REG_OFF_3 0x34 /* OFF time/intensity register for I/O[3] */
#define SX1509_REG_T_ON_4 0x35 /* ON time register for I/O[4] */
#define SX1509_REG_I_ON_4 0x36 /* ON intensity register for I/O[4] */
#define SX1509_REG_OFF_4 0x37 /* OFF time/intensity register for I/O[4] */
#define SX1509_REG_T_RISE_4 0x38 /* Fade in register for I/O[4] */
#define SX1509_REG_T_FALL_4 0x39 /* Fade out register for I/O[4] */
#define SX1509_REG_T_ON_5 0x3A /* ON time register for I/O[5] */
#define SX1509_REG_I_ON_5 0x3B /* ON intensity register for I/O[5] */
#define SX1509_REG_OFF_5 0x3C /* OFF time/intensity register for I/O[5] */
#define SX1509_REG_T_RISE_5 0x3D /* Fade in register for I/O[5] */
#define SX1509_REG_T_FALL_5 0x3E /* Fade out register for I/O[5] */
#define SX1509_REG_T_ON_6 0x3F /* ON time register for I/O[6] */
#define SX1509_REG_I_ON_6 0x40 /* ON intensity register for I/O[6] */
#define SX1509_REG_OFF_6 0x41 /* OFF time/intensity register for I/O[6] */
#define SX1509_REG_T_RISE_6 0x42 /* Fade in register for I/O[6] */
#define SX1509_REG_T_FALL_6 0x43 /* Fade out register for I/O[6] */
#define SX1509_REG_T_ON_7 0x44 /* ON time register for I/O[7] */
#define SX1509_REG_I_ON_7 0x45 /* ON intensity register for I/O[7] */
#define SX1509_REG_OFF_7 0x46 /* OFF time/intensity register for I/O[7] */
#define SX1509_REG_T_RISE_7 0x47 /* Fade in register for I/O[7] */
#define SX1509_REG_T_FALL_7 0x48 /* Fade out register for I/O[7] */
#define SX1509_REG_T_ON_8 0x49 /* ON time register for I/O[8] */
#define SX1509_REG_I_ON_8 0x4A /* ON intensity register for I/O[8] */
#define SX1509_REG_OFF_8 0x4B /* OFF time/intensity register for I/O[8] */
#define SX1509_REG_T_ON_9 0x4C /* ON time register for I/O[9] */
#define SX1509_REG_I_ON_9 0x4D /* ON intensity register for I/O[9] */
#define SX1509_REG_OFF_9 0x4E /* OFF time/intensity register for I/O[9] */
#define SX1509_REG_T_ON_10 0x4F /* ON time register for I/O[10] */
#define SX1509_REG_I_ON_10 0x50 /* ON intensity register for I/O[10] */
#define SX1509_REG_OFF_10 0x51 /* OFF time/intensity register for I/O[10] */
#define SX1509_REG_T_ON_11 0x52 /* ON time register for I/O[11] */
#define SX1509_REG_I_ON_11 0x53 /* ON intensity register for I/O[11] */
#define SX1509_REG_OFF_11 0x54 /* OFF time/intensity register for I/O[11] */
#define SX1509_REG_T_ON_12 0x55 /* ON time register for I/O[12] */
#define SX1509_REG_I_ON_12 0x56 /* ON intensity register for I/O[12] */
#define SX1509_REG_OFF_12 0x57 /* OFF time/intensity register for I/O[12] */
#define SX1509_REG_T_RISE_12 0x58 /* Fade in register for I/O[12] */
#define SX1509_REG_T_FALL_12 0x59 /* Fade out register for I/O[12] */
#define SX1509_REG_T_ON_13 0x5A /* ON time register for I/O[13] */
#define SX1509_REG_I_ON_13 0x5B /* ON intensity register for I/O[13] */
#define SX1509_REG_OFF_13 0x5C /* OFF time/intensity register for I/O[13] */
#define SX1509_REG_T_RISE_13 0x5D /* Fade in register for I/O[13] */
#define SX1509_REG_T_FALL_13 0x5E /* Fade out register for I/O[13] */
#define SX1509_REG_T_ON_14 0x5F /* ON time register for I/O[14] */
#define SX1509_REG_I_ON_14 0x60 /* ON intensity register for I/O[14] */
#define SX1509_REG_OFF_14 0x61 /* OFF time/intensity register for I/O[14] */
#define SX1509_REG_T_RISE_14 0x62 /* Fade in register for I/O[14] */
#define SX1509_REG_T_FALL_14 0x63 /* Fade out register for I/O[14] */
#define SX1509_REG_T_ON_15 0x64 /* ON time register for I/O[15] */
#define SX1509_REG_I_ON_15 0x65 /* ON intensity register for I/O[15] */
#define SX1509_REG_OFF_15 0x66 /* OFF time/intensity register for I/O[15] */
#define SX1509_REG_T_RISE_15 0x67 /* Fade in register for I/O[15] */
#define SX1509_REG_T_FALL_15 0x68 /* Fade out register for I/O[15] */
#define SX1509_REG_HIGH_INPUT_B 0x69 /* High input enable register I/O[15..8] (Bank B) */
#define SX1509_REG_HIGH_INPUT_A 0x6A /* High input enable register I/O[7..0] (Bank A) */
#define SX1509_REG_RESET 0x7D /* Software reset register */
#define SX1509_REG_TEST_1 0x7E /* Test register 1 */
#define SX1509_REG_TEST_2 0x7F /* Test register 2 */
/* Values being used for Soft reset of SX1509 */
#define SX1509_SOFT_RESET_REG_VALUE_1 0x12
#define SX1509_SOFT_RESET_REG_VALUE_2 0x34
static uint8_t SX1509_REG_T_ON[16] = {
SX1509_REG_T_ON_0, SX1509_REG_T_ON_1, SX1509_REG_T_ON_2, SX1509_REG_T_ON_3,
SX1509_REG_T_ON_4, SX1509_REG_T_ON_5, SX1509_REG_T_ON_6, SX1509_REG_T_ON_7,
SX1509_REG_T_ON_8, SX1509_REG_T_ON_9, SX1509_REG_T_ON_10, SX1509_REG_T_ON_11,
SX1509_REG_T_ON_12, SX1509_REG_T_ON_13, SX1509_REG_T_ON_14, SX1509_REG_T_ON_15
};
static uint8_t SX1509_REG_OFF[16] = {
SX1509_REG_OFF_0, SX1509_REG_OFF_1, SX1509_REG_OFF_2, SX1509_REG_OFF_3,
SX1509_REG_OFF_4, SX1509_REG_OFF_5, SX1509_REG_OFF_6, SX1509_REG_OFF_7,
SX1509_REG_OFF_8, SX1509_REG_OFF_9, SX1509_REG_OFF_10, SX1509_REG_OFF_11,
SX1509_REG_OFF_12, SX1509_REG_OFF_13, SX1509_REG_OFF_14, SX1509_REG_OFF_15
};
#if 0
static uint8_t SX1509_REG_I_ON[16] = {
SX1509_REG_I_ON_0, SX1509_REG_I_ON_1, SX1509_REG_I_ON_2, SX1509_REG_I_ON_3,
SX1509_REG_I_ON_4, SX1509_REG_I_ON_5, SX1509_REG_I_ON_6, SX1509_REG_I_ON_7,
SX1509_REG_I_ON_8, SX1509_REG_I_ON_9, SX1509_REG_I_ON_10, SX1509_REG_I_ON_11,
SX1509_REG_I_ON_12, SX1509_REG_I_ON_13, SX1509_REG_I_ON_14, SX1509_REG_I_ON_15 };
#endif
/*****************************************************************************
** FUNCTION NAME : ioexp_led_raw_read
**
** DESCRIPTION : Read the register value from IO Expander with LED
** driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register address and pointer
** to value read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus ioexp_led_raw_read(const I2C_Dev *i2c_dev,
uint8_t regAddress,
uint8_t *regValue)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle sx1509_handle = i2c_get_handle(i2c_dev->bus);
uint16_t value = 0x0000;
if (!sx1509_handle) {
LOGGER_ERROR("SX1509:ERROR:: Failed to get I2C Bus for SX1509 0x%02x "
"on bus 0x%02x.\n", i2c_dev->slave_addr, i2c_dev->bus);
} else {
status = i2c_reg_read(sx1509_handle, i2c_dev->slave_addr, regAddress,
&value, 1);
if (status == RETURN_OK) {
*regValue = (uint8_t)(value);
}
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_raw_write
**
** DESCRIPTION : Write the register value(s) to IO Expander with LED
** driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register address, value 1
** & value 2 to be written and No of bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
static ReturnStatus ioexp_led_raw_write(const I2C_Dev *i2c_dev,
uint8_t regAddress,
uint8_t regValue1,
uint8_t regValue2,
uint8_t noOfBytes)
{
ReturnStatus status = RETURN_NOTOK;
I2C_Handle sx1509_handle = i2c_get_handle(i2c_dev->bus);
uint16_t value = 0x00;
if (noOfBytes == 2) {
value = (regValue2<<8) | (regValue1);
value = htobe16(value);
} else {
value = regValue1;
}
if (!sx1509_handle) {
LOGGER_ERROR("SX1509:ERROR:: Failed to get I2C Bus for SX1509 0x%02x "
"on bus 0x%02x.\n", i2c_dev->slave_addr, i2c_dev->bus);
} else {
status = i2c_reg_write(sx1509_handle, i2c_dev->slave_addr, regAddress,
value, noOfBytes);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_get_data
**
** DESCRIPTION : Read the Data Register Value from IO Expander with LED
** driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type and pointer
** to value read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_get_data(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t *regValue)
{
ReturnStatus status = RETURN_OK;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_DATA_A) : (SX1509_REG_DATA_B);
status = ioexp_led_raw_read(i2c_dev, regAddress, regValue);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_set_data
**
** DESCRIPTION : Write the Data Register Value(s) into IO Expander with
** LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_set_data(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t regValue1,
uint8_t regValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_DATA_A) : (SX1509_REG_DATA_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, regValue1,
regValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_set_on_time
**
** DESCRIPTION : Write the ON Time Register Value into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, index to On time Register
** and value to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_set_on_time(const I2C_Dev *i2c_dev, uint8_t index,
uint8_t tOnRegValue)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_T_ON[index],
tOnRegValue, 0, 1);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_set_off_time
**
** DESCRIPTION : Write the OFF Time Register Value into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, index to Off time Register
** and value to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_set_off_time(const I2C_Dev *i2c_dev, uint8_t index,
uint8_t tOffRegValue)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_OFF[index],
tOffRegValue, 0, 1);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_software_reset
**
** DESCRIPTION : Do LED SX159 Soft Reset by writing 0x12 followed by
** 0x34 on software reset register.
**
** ARGUMENTS : Subsystem and Slave address.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_software_reset(const I2C_Dev *i2c_dev)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_RESET,
SX1509_SOFT_RESET_REG_VALUE_1, 0, 1);
if (status == RETURN_OK) {
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_RESET,
SX1509_SOFT_RESET_REG_VALUE_2, 0, 1);
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_inputbuffer
**
** DESCRIPTION : Write the Input Diable Input Buffer Register Value(s)
** into IO Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_inputbuffer(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t inputBuffRegValue1,
uint8_t inputBuffRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_INPUT_DISABLE_A) : (SX1509_REG_INPUT_DISABLE_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, inputBuffRegValue1,
inputBuffRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_pullup
**
** DESCRIPTION : Write the Pull_up Register Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_pullup(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t pullUpRegValue1,
uint8_t pullUpRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_PULL_UP_A) : (SX1509_REG_PULL_UP_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, pullUpRegValue1,
pullUpRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_pulldown
**
** DESCRIPTION : Write the Pull Down Register Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_pulldown(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t pullDownRegValue1,
uint8_t pullDownRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_PULL_DOWN_A) : (SX1509_REG_PULL_DOWN_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, pullDownRegValue1,
pullDownRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_opendrain
**
** DESCRIPTION : Write the Open drain Register Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_opendrain(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t openDrainRegValue1,
uint8_t openDrainRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_OPEN_DRAIN_A) : (SX1509_REG_OPEN_DRAIN_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, openDrainRegValue1,
openDrainRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_data_direction
**
** DESCRIPTION : Write the Direction Register Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_data_direction(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t directionRegValue1,
uint8_t directionRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_DIR_A) : (SX1509_REG_DIR_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, directionRegValue1,
directionRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_polarity
**
** DESCRIPTION : Write the Polarity Register Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_polarity(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t polarityRegValue1,
uint8_t polarityRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_POLARITY_A) : (SX1509_REG_POLARITY_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, polarityRegValue1,
polarityRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_clock
**
** DESCRIPTION : Write the Clock management Register Value into IO
** Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address and value to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
/* RegClock:
* 6:5 - Oscillator frequency souce
* 00: off, 01: external input, 10: internal 2MHz, 11: reserved
* 4 - OSCIO pin function
* 0: input, 1 ouptut
* 3:0 - Frequency of oscout pin
* 0: LOW, 0xF: high, else fOSCOUT = FoSC/(2^(RegClock[3:0]-1))
*/
ReturnStatus ioexp_led_config_clock(const I2C_Dev *i2c_dev, uint8_t oscSource,
uint8_t oscPin)
{
ReturnStatus status = RETURN_OK;
uint8_t regValue = 0;
regValue = oscSource << 5;
regValue |= oscPin << 4;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_CLOCK, regValue, 0, 1);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_misc
**
** DESCRIPTION : Write the Miscellaneous device settings Register Value
** into IO Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address and value to be written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_misc(const I2C_Dev *i2c_dev, uint8_t regValue)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_MISC, regValue, 0, 1);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_enable_leddriver
**
** DESCRIPTION : Write the LED driver enable Value(s) into IO Expander
** with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_enable_leddriver(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t ledEnableRegValue1,
uint8_t ledEnableRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_LED_DRIVER_ENABLE_A) :
(SX1509_REG_LED_DRIVER_ENABLE_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, ledEnableRegValue1,
ledEnableRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_read_testregister_1
**
** DESCRIPTION : Read the Test Register Value from IO Expander with LED
** driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address and pointer to value read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_read_testregister_1(const I2C_Dev *i2c_dev,
uint8_t *regValue)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_read(i2c_dev, SX1509_REG_TEST_1, regValue);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_interrupt
**
** DESCRIPTION : Write the Interrupt Mask Register Value(s) into IO
** Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_interrupt(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t interruptMaskRegValue1,
uint8_t interruptMaskRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_INTERRUPT_MASK_A) :
(SX1509_REG_INTERRUPT_MASK_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, interruptMaskRegValue1,
interruptMaskRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_edge_sense_A
**
** DESCRIPTION : Write the Edge Sense Register A(I/O[7:0]) Value(s)
** into IO Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, Low byte value
** & High byte values of A to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
/*
* 00 : None
* 01 : Rising
* 10 : Falling
* 11 : Both
*/
ReturnStatus ioexp_led_config_edge_sense_A(const I2C_Dev *i2c_dev,
sx1509EdgeSenseRegType regType,
uint8_t edgeSenseLowARegValue,
uint8_t edgeSenseHighARegValue)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_EDGE_SENSE_REG_LOW) ?
(SX1509_REG_SENSE_LOW_A) : (SX1509_REG_SENSE_HIGH_A);
if (regType == SX1509_EDGE_SENSE_REG_LOW_HIGH) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, edgeSenseLowARegValue,
edgeSenseHighARegValue, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_edge_sense_B
**
** DESCRIPTION : Write the Edge Sense Register B(I/O[15:8]) Value(s)
** into IO Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, Low byte value
** & High byte values of B to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_config_edge_sense_B(const I2C_Dev *i2c_dev,
sx1509EdgeSenseRegType regType,
uint8_t edgeSenseLowBRegValue,
uint8_t edgeSenseHighBRegValue)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_EDGE_SENSE_REG_LOW) ?
(SX1509_REG_SENSE_LOW_B) : (SX1509_REG_SENSE_HIGH_B);
if (regType == SX1509_EDGE_SENSE_REG_LOW_HIGH) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, edgeSenseLowBRegValue,
edgeSenseHighBRegValue, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_config_debounce
**
** DESCRIPTION : Write the Debounce time Value into IO Expander with
** LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address and debounce Time(ms) to be
** written.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
/* Debounce time-to-byte map: (assuming fOsc = 2MHz; 2^(n-1))
* 0: 0.5ms 1: 1ms
* 2: 2ms 3: 4ms
* 4: 8ms 5: 16ms
* 6: 32ms 7: 64ms
*/
ReturnStatus ioexp_led_config_debounce_time(const I2C_Dev *i2c_dev,
uint8_t debounceTime)
{
ReturnStatus status = RETURN_OK;
uint8_t index = 0;
uint8_t regValue = 0;
for (index = 0; index < 8; index++) {
if (debounceTime & (1 << index)) {
regValue = index + 1;
break;
}
}
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_DEBOUNCE_CONFIG,
regValue, 0, 1);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_enable_debounce
**
** DESCRIPTION : Write the Debounce enable Register Value into
** IO Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type, value 1 &
** value 2 to be written and No of Bytes.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_enable_debounce(const I2C_Dev *i2c_dev,
sx1509RegType regType,
uint8_t debounceEnableRegValue1,
uint8_t debounceEnableRegValue2)
{
ReturnStatus status = RETURN_OK;
uint8_t noOfBytes = 1;
uint8_t regAddress = (regType == SX1509_REG_A) ?
(SX1509_REG_DEBOUNCE_ENABLE_A) : (SX1509_REG_DEBOUNCE_ENABLE_B);
if (regType == SX1509_REG_AB) {
noOfBytes = 2;
}
status = ioexp_led_raw_write(i2c_dev, regAddress, debounceEnableRegValue1,
debounceEnableRegValue2, noOfBytes);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_read_interrupt_source
**
** DESCRIPTION : Read the Interrupt Source Register Value from IO
** Expander with LED driver SX1509.
**
** ARGUMENTS : Subsystem, Slave address, Register Type and pointer
** to value read.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_get_interrupt_source(const I2C_Dev *i2c_dev,
uint16_t *intPins)
{
ReturnStatus status = RETURN_OK;
uint8_t regValueA = 0;
uint8_t regValueB = 0;
status = ioexp_led_raw_read(i2c_dev, SX1509_REG_INTERRUPT_SOURCE_A,
&regValueA);
if (status != RETURN_OK) {
return status;
}
status = ioexp_led_raw_read(i2c_dev, SX1509_REG_INTERRUPT_SOURCE_B,
&regValueB);
*intPins = (uint16_t) ((regValueB << 8) | regValueA);
return status;
}
/*****************************************************************************
** FUNCTION NAME : ioexp_led_clear_interrupt_source
**
** DESCRIPTION : Clear the Interrupt status.
**
** ARGUMENTS : Subsystem and Slave address.
**
** RETURN TYPE : Success or failure
**
*****************************************************************************/
ReturnStatus ioexp_led_clear_interrupt_source(const I2C_Dev *i2c_dev)
{
ReturnStatus status = RETURN_OK;
status = ioexp_led_raw_write(i2c_dev, SX1509_REG_INTERRUPT_SOURCE_B,
0xFF, 0xFF, 2);
return status;
}

View File

@@ -0,0 +1,273 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "GpioNative.h"
#include "common/inc/global/OC_CONNECT1.h"
#include "inc/common/global_header.h"
#include <ti/drivers/GPIO.h>
#include <ti/sysbios/gates/GateMutex.h>
#include <stdlib.h>
static GateMutex_Handle s_cb_data_mutex;
/*****************************************************************************
** FUNCTION NAME : GpioNative_probe
**
** DESCRIPTION : probe function called as part of POST
**
** ARGUMENTS : none
**
** RETURN TYPE : OCGPIO_SUCCESS or OCGPIO_FAILURE
**
*****************************************************************************/
static int GpioNative_probe(void) {
//This probe function is just a dummy as we are all ready accessing EC.
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioNative_init
**
** DESCRIPTION : inits as part of system bootup
**
** ARGUMENTS : NONE
**
** RETURN TYPE : None
**
*****************************************************************************/
void GpioNative_init(void) {
s_cb_data_mutex = GateMutex_create(NULL, NULL);
}
/*****************************************************************************
** FUNCTION NAME : GpioNative_write
**
** DESCRIPTION : gpio write for the required pin and value
**
** ARGUMENTS : pin index , value
**
** RETURN TYPE : OCGPIO_SUCCESS or OCGPIO_FAILURE
**
*****************************************************************************/
static int GpioNative_write(const OcGpio_Pin *pin, bool value) {
if (pin->hw_cfg & OCGPIO_CFG_INVERT) {
value = !value;
}
GPIO_write(pin->idx, value);
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioNative_read
**
** DESCRIPTION : does a gpio read for the provided pin
**
** ARGUMENTS : pin index
**
** RETURN TYPE : int
**
*****************************************************************************/
static int GpioNative_read(const OcGpio_Pin *pin) {
bool value = GPIO_read(pin->idx);
if (pin->hw_cfg & OCGPIO_CFG_INVERT) {
value = !value;
}
return value;
}
/*****************************************************************************
** FUNCTION NAME : GetBank
**
** DESCRIPTION : configure the pins with the provided config
**
** ARGUMENTS : pointer to pin, config
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioNative_configure(const OcGpio_Pin *pin, uint32_t cfg) {
/* TODO: translate config values to account for inversion
* eg. If inverted, change rising edge trigger to falling edge
*/
/* TODO: need to be careful in multi-subscriber case - if we reconfigure,
* the TI driver clears any interrupts on this pin, so we could potentially
* miss edges for already subscribed pins
*/
const OcGpio_HwCfg hw_cfg = { .uint16 = pin->hw_cfg };
const OcGpio_ioCfg io_cfg = { .uint32 = cfg };
uint32_t ti_cfg = 0x00;
if (cfg & OCGPIO_CFG_INPUT) {
ti_cfg |= GPIO_CFG_INPUT;
ti_cfg |= (hw_cfg.in_cfg << GPIO_CFG_IO_LSB); /* Include PU/PD cfg */
/* Process interrupt config (respect inversion settings) */
if (hw_cfg.invert) {
switch ((uint32_t)io_cfg.int_cfg << GPIO_CFG_INT_LSB) {
case GPIO_CFG_IN_INT_FALLING:
ti_cfg |= GPIO_CFG_IN_INT_RISING;
break;
case GPIO_CFG_IN_INT_RISING:
ti_cfg |= GPIO_CFG_IN_INT_FALLING;
break;
case GPIO_CFG_IN_INT_LOW:
ti_cfg |= GPIO_CFG_IN_INT_HIGH;
break;
case GPIO_CFG_IN_INT_HIGH:
ti_cfg |= GPIO_CFG_IN_INT_LOW;
break;
case OCGPIO_CFG_INT_NONE:
case GPIO_CFG_IN_INT_BOTH_EDGES:
default:
/* No change */
ti_cfg |= (io_cfg.int_cfg << GPIO_CFG_INT_LSB);
break;
}
} else {
ti_cfg |= (io_cfg.int_cfg << GPIO_CFG_INT_LSB);
}
} else {
ti_cfg |= GPIO_CFG_OUTPUT;
ti_cfg |= (hw_cfg.out_cfg << GPIO_CFG_IO_LSB); /* Include od/pu/pd cfg */
ti_cfg |= (hw_cfg.out_str << GPIO_CFG_OUT_STRENGTH_LSB);
ti_cfg |= (io_cfg.default_val << GPIO_CFG_OUT_BIT);
}
GPIO_setConfig(pin->idx, ti_cfg);
return OCGPIO_SUCCESS;
}
/* TODO: since every GPIO driver will probably need this, might be worth
* moving out to GPIO I/F module
*/
typedef struct GpioCallbackData {
const OcGpio_Pin *pin;
OcGpio_CallbackFn callback;
void *context;
struct GpioCallbackData *next; /*!< Pointer to next pin subscriber */
} GpioCallbackData;
/* This allows us to work around the native GPIO driver's poor design and allow
* a context pointer to be passed to the calling function
*/
static GpioCallbackData *cb_data[OC_EC_GPIOCOUNT];
/*
*/
/*****************************************************************************
** FUNCTION NAME : _nativeCallback
**
** DESCRIPTION : Wrapper to allow us to map TI-GPIO callback to all
** our subscribers (with context passing)
**
** ARGUMENTS : pin index
**
** RETURN TYPE : NONE
**
*****************************************************************************/
static void _nativeCallback(unsigned int idx) {
GpioCallbackData *cbData = cb_data[idx];
while (cbData) {
cbData->callback(cbData->pin, cbData->context);
cbData = cbData->next;
}
return;
}
/*****************************************************************************
** FUNCTION NAME : GpioNative_setCallback
**
** DESCRIPTION : set call back function for handling interrupts.
**
** ARGUMENTS : pointer to pin , call back function pointer , context
** to be passed as argument to the call back function
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioNative_setCallback(const OcGpio_Pin *pin,
OcGpio_CallbackFn callback,
void *context) {
/* TODO: we may want to support callback removal at some point */
if (!callback) {
return OCGPIO_FAILURE;
}
GpioCallbackData *cb_entry = malloc(sizeof(GpioCallbackData));
if (!cb_entry) {
LOGGER_ERROR("Unable to malloc GPIO callback");
return OCGPIO_FAILURE;
}
*cb_entry = (GpioCallbackData){
.pin = pin,
.callback = callback,
.context = context,
};
/* find next blank entry & assign new callback data (protect against
* multiple tasks accessing simultaneously)
* Note: we don't need to worry about the actual callback function using
* a mutex, since the 'next' pointer assignment is atomic */
const IArg mutexKey = GateMutex_enter(s_cb_data_mutex);
{
GpioCallbackData **next = &cb_data[pin->idx];
while (*next) {
next = &(*next)->next;
}
*next = cb_entry;
}
GateMutex_leave(s_cb_data_mutex, mutexKey);
GPIO_setCallback(pin->idx, _nativeCallback);
return OCGPIO_SUCCESS;
}
/* TODO: what if multiple tasks are sharing a pin and one of them
* disables the interrupt? */
/*****************************************************************************
** FUNCTION NAME : GpioNative_disableInt
**
** DESCRIPTION : identify the bank.
**
** ARGUMENTS : pin index
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioNative_disableInt(const OcGpio_Pin *pin) {
GPIO_disableInt(pin->idx);
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioNative_enableInt
**
** DESCRIPTION : enable interrupt for a particular pin
**
** ARGUMENTS : pin index
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioNative_enableInt(const OcGpio_Pin *pin) {
GPIO_enableInt(pin->idx);
return OCGPIO_SUCCESS;
}
const OcGpio_FnTable GpioNative_fnTable = {
.probe = GpioNative_probe,
.write = GpioNative_write,
.read = GpioNative_read,
.configure = GpioNative_configure,
.setCallback = GpioNative_setCallback,
.disableInt = GpioNative_disableInt,
.enableInt = GpioNative_enableInt,
};

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _GPIONATIVE_H_
#define _GPIONATIVE_H_
#include "OcGpio.h"
extern const OcGpio_FnTable GpioNative_fnTable;
/*
* Must be called before using the GPIO Native driver
*/
void GpioNative_init(void);
#endif /* _GPIONATIVE_H_ */

View File

@@ -0,0 +1,503 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "devices/i2c/threaded_int.h"
#include "GpioSX1509.h"
#include "helpers/memory.h"
#include "inc/common/global_header.h"
#include "inc/devices/sx1509.h"
#include <stdlib.h>
#include <string.h>
/*****************************************************************************
** FUNCTION NAME : GetBank
**
** DESCRIPTION : identify the bank.
**
** ARGUMENTS : pin index
**
** RETURN TYPE : SX1509_REG_B or SX1509_REG_A
**
*****************************************************************************/
static sx1509RegType GetBank(uint8_t pin_idx) {
return (pin_idx > 7) ? SX1509_REG_B : SX1509_REG_A;
}
/*****************************************************************************
** FUNCTION NAME : RelativePinIdx
**
** DESCRIPTION : identify the relative pin index.
**
** ARGUMENTS : pin idx
**
** RETURN TYPE : uint8_t
**
*****************************************************************************/
static uint8_t RelativePinIdx(uint8_t pin_idx) {
return (pin_idx > 7) ? (pin_idx - 8) : pin_idx;
}
/*****************************************************************************
** FUNCTION NAME : HandleIRQ
**
** DESCRIPTION : IRQ handler - reads in triggered interrupts and
** dispatches
**
** ARGUMENTS : None
**
** RETURN TYPE : none
**
*****************************************************************************/
static void HandleIRQ(void *context) {
const OcGpio_Port *port = context;
const SX1509_Cfg *sx_cfg = port->cfg;
SX1509_Obj *obj = port->object_data;
/* Figure out which pin this interrupt came from */
/* TODO: this seems risky - what if an interrupt occurs between reading
* src and clearing it? It's dumb that the IC doesn't clear the irq on
* reading the source */
uint16_t irq_src;
ioexp_led_get_interrupt_source(&sx_cfg->i2c_dev, &irq_src);
ioexp_led_clear_interrupt_source(&sx_cfg->i2c_dev);
// Dispatch the interrupt handlers
int pin_idx = 0;
while (irq_src) {
if (irq_src & 0x01) {
SX1509CallbackData *cbData = obj->cb_data[pin_idx];
while (cbData) {
cbData->callback(cbData->pin, cbData->context);
cbData = cbData->next;
}
}
++pin_idx;
irq_src >>= 1;
}
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_probe
**
** DESCRIPTION : post related api which check connected to the device.
**
** ARGUMENTS : pointer to port
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_probe(const OcGpio_Port *port) {
/* if we are able to read configuration register this means PCA device is accessible*/
const SX1509_Cfg *sx_cfg = port->cfg;
SX1509_Obj *obj = port->object_data;
uint8_t input_reg;
if (ioexp_led_get_data(&sx_cfg->i2c_dev, 0, &input_reg) != RETURN_OK) {
return OCGPIO_FAILURE;
}
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_init
**
** DESCRIPTION : init .
**
** ARGUMENTS : pointer to the port
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_init(const OcGpio_Port *port) {
const SX1509_Cfg *sx_cfg = port->cfg;
SX1509_Obj *obj = port->object_data;
obj->mutex = GateMutex_create(NULL, NULL);
for (int i = 0; i < SX1509_NUM_BANKS; ++i) {
obj->regs[i] = (SX1509_Registers){
/* We only need to set the non-zero registers */
.direction = 0xff,
.data = 0xff,
.int_mask = 0xff,
};
}
memset(obj->cb_data, 0, sizeof(obj->cb_data));
/* Make sure the IC is set to default config */
if (ioexp_led_software_reset(&sx_cfg->i2c_dev)
!= RETURN_OK) {
return OCGPIO_FAILURE;
}
/* Register the SX1509's own IRQ pin (optional) */
if (sx_cfg->pin_irq) {
const uint32_t pin_irq_cfg = OCGPIO_CFG_INPUT | OCGPIO_CFG_INT_FALLING;
if (OcGpio_configure(sx_cfg->pin_irq, pin_irq_cfg) < OCGPIO_SUCCESS) {
return OCGPIO_FAILURE;
}
/* Use a threaded interrupt to handle IRQ */
// ThreadedInt_Init(sx_cfg->pin_irq, HandleIRQ, (void *)port);
}
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_write
**
** DESCRIPTION : write into a particular pin
**
** ARGUMENTS : pointer to pin, value
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_write(const OcGpio_Pin *pin, bool value) {
const SX1509_Cfg *sx_cfg = pin->port->cfg;
SX1509_Obj *obj = pin->port->object_data;
int res = OCGPIO_FAILURE;
const IArg mutexKey = GateMutex_enter(obj->mutex);
{
/* Reading the value of output pins seems unreliable on the SX1509,
* so we cache the output value instead (it's faster anyway)
*/
const sx1509RegType bank = GetBank(pin->idx);
const uint8_t pin_idx = RelativePinIdx(pin->idx);
const uint8_t new_reg_value = set_bit8(obj->regs[bank].data,
pin_idx, value);
if (ioexp_led_set_data(&sx_cfg->i2c_dev, bank, new_reg_value, 0x00)
!= RETURN_OK) {
goto cleanup;
}
obj->regs[bank].data = new_reg_value;
res = OCGPIO_SUCCESS;
}
cleanup:
GateMutex_leave(obj->mutex, mutexKey);
return res;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_read
**
** DESCRIPTION : read a particular pin
**
** ARGUMENTS : pointer to pin
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_read(const OcGpio_Pin *pin) {
const SX1509_Cfg *sx_cfg = pin->port->cfg;
/* We don't need a mutex here since i2c driver protects against
* simultaneous access and we're just reading a value */
const sx1509RegType bank = GetBank(pin->idx);
const uint8_t pin_idx = RelativePinIdx(pin->idx);
uint8_t input_reg;
if (ioexp_led_get_data(&sx_cfg->i2c_dev, bank, &input_reg) != RETURN_OK) {
return OCGPIO_FAILURE;
}
return (input_reg >> pin_idx) & 0x01;
}
/* TODO: this mapping is pretty gross with the shifts */
static const uint8_t EDGE_SENSE_MAP[] = {
[OCGPIO_CFG_INT_NONE >> OCGPIO_CFG_INT_LSB] = 0x00, /* 00 */
[OCGPIO_CFG_INT_RISING >> OCGPIO_CFG_INT_LSB] = 0x01, /* 01 */
[OCGPIO_CFG_INT_FALLING >> OCGPIO_CFG_INT_LSB] = 0x02, /* 10 */
[OCGPIO_CFG_INT_BOTH_EDGES >> OCGPIO_CFG_INT_LSB] = 0x03, /* 11 */
};
/* TODO: handle things nicely if we get a failure part way through config -
* right now we break the rule of the other functions to only store the new
* value if the IC accepted the changed value */
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_configure
**
** DESCRIPTION : configure the pins with the provided config
**
** ARGUMENTS : pointer to pin, sx1509 config
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_configure(const OcGpio_Pin *pin, uint32_t cfg) {
const SX1509_Cfg *sx_cfg = pin->port->cfg;
SX1509_Obj *obj = pin->port->object_data;
int res = OCGPIO_FAILURE;
const OcGpio_ioCfg io_cfg = { .uint32 = cfg };
const sx1509RegType bank = GetBank(pin->idx);
const uint8_t pin_idx = RelativePinIdx(pin->idx);
SX1509_Registers *reg = &obj->regs[bank];
const IArg mutexKey = GateMutex_enter(obj->mutex);
{
/* Invert the polarity (1) if necessary */
reg->polarity = set_bit8(reg->polarity, pin_idx,
pin->hw_cfg & OCGPIO_CFG_INVERT);
if (ioexp_led_config_polarity(&sx_cfg->i2c_dev, bank, reg->polarity,
0x00) != RETURN_OK) {
goto cleanup;
}
bool pu_en;
bool pd_en;
/* Set pull-up/down registers */
/* Set output-specific registers if applicable */
if (io_cfg.dir == OCGPIO_CFG_OUTPUT) {
/* Enable (1) open drain */
const bool od_en = (pin->hw_cfg & OCGPIO_CFG_OUT_OD_MASK);
reg->open_drain = set_bit8(reg->open_drain, pin_idx, od_en);
if (ioexp_led_config_opendrain(&sx_cfg->i2c_dev,
bank,
reg->open_drain,
0x00) != RETURN_OK) {
goto cleanup;
}
/* Disable (1) the input buffer */
reg->input_buf_disable = set_bit8(reg->input_buf_disable, pin_idx,
1);
if (ioexp_led_config_inputbuffer(&sx_cfg->i2c_dev,
bank,
reg->input_buf_disable,
0x00) != RETURN_OK) {
goto cleanup;
}
/* Set default value */
GpioSX1509_write(pin, io_cfg.default_val);
/* TODO: this is kind of gross, not sure if it's worth keeping
* compatibility with TI-GPIO cfg */
pu_en = ((pin->hw_cfg & OCGPIO_CFG_OUT_OD_MASK) ==
OCGPIO_CFG_OUT_OD_PU);
pd_en = ((pin->hw_cfg & OCGPIO_CFG_OUT_OD_MASK) ==
OCGPIO_CFG_OUT_OD_PD);
} else {
/* Enable (0) the input buffer */
reg->input_buf_disable = set_bit8(reg->input_buf_disable, pin_idx,
0);
if (ioexp_led_config_inputbuffer(&sx_cfg->i2c_dev,
bank,
reg->input_buf_disable,
0x00) != RETURN_OK) {
goto cleanup;
}
/* Set interrupt edge detection */
/* This is a bit tricky since we need to set a pair of bits */
const uint16_t EDGE_SENSE_MASK = 0x03 << (pin_idx * 2);
reg->edge_sense &= ~EDGE_SENSE_MASK;
reg->edge_sense |= EDGE_SENSE_MAP[io_cfg.int_cfg] << (pin_idx * 2);
switch (bank) {
case SX1509_REG_A:
if (ioexp_led_config_edge_sense_A(
&sx_cfg->i2c_dev,
SX1509_EDGE_SENSE_REG_LOW_HIGH,
LOBYTE(reg->edge_sense),
HIBYTE(reg->edge_sense)) != RETURN_OK) {
goto cleanup;
}
break;
case SX1509_REG_B:
if (ioexp_led_config_edge_sense_B(
&sx_cfg->i2c_dev,
SX1509_EDGE_SENSE_REG_LOW_HIGH,
LOBYTE(reg->edge_sense),
HIBYTE(reg->edge_sense)) != RETURN_OK) {
goto cleanup;
}
break;
default:
LOGGER_ERROR("SX1509: Unknown bank number: %d\n", bank);
goto cleanup;
}
pu_en = ((pin->hw_cfg & OCGPIO_CFG_IN_PULL_MASK) ==
OCGPIO_CFG_IN_PU);
pd_en = ((pin->hw_cfg & OCGPIO_CFG_IN_PULL_MASK) ==
OCGPIO_CFG_IN_PD);
}
/* Set pull-up/down registers */
reg->pull_up = set_bit8(reg->pull_up, pin_idx, pu_en);
if (ioexp_led_config_pullup(&sx_cfg->i2c_dev,
bank,
reg->pull_up,
0x00) != RETURN_OK) {
goto cleanup;
}
reg->pull_down = set_bit8(reg->pull_down, pin_idx, pd_en);
if (ioexp_led_config_pulldown(&sx_cfg->i2c_dev,
bank,
reg->pull_down,
0x00) != RETURN_OK) {
goto cleanup;
}
/* Set pin direction (0 output, 1 input) */
reg->direction = set_bit8(reg->direction, pin_idx, io_cfg.dir);
if (ioexp_led_config_data_direction(&sx_cfg->i2c_dev,
bank,
reg->direction,
0x00) != RETURN_OK) {
goto cleanup;
}
/* The SX1509 doesn't support drive strength */
res = OCGPIO_SUCCESS;
}
cleanup:
GateMutex_leave(obj->mutex, mutexKey);
return res;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_setCallback
**
** DESCRIPTION : set call back function for handling interrupts.
**
** ARGUMENTS : pointer to pin , call back function pointer , context
** to be passed as argument to the call back function
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_setCallback(const OcGpio_Pin *pin,
OcGpio_CallbackFn callback,
void *context) {
SX1509_Obj *obj = pin->port->object_data;
/* TODO: we may want to support callback removal at some point */
if (!callback) {
return OCGPIO_FAILURE;
}
SX1509CallbackData *cb_entry = malloc(sizeof(SX1509CallbackData));
if (!cb_entry) {
LOGGER_ERROR("Unable to malloc GPIO callback");
return OCGPIO_FAILURE;
}
*cb_entry = (SX1509CallbackData){
.pin = pin,
.callback = callback,
.context = context,
};
/* find next blank entry & assign new callback data (protect against
* multiple tasks accessing simultaneously)
* Note: we don't need to worry about the actual callback function using
* a mutex, since the 'next' pointer assignment is atomic */
const IArg mutexKey = GateMutex_enter(obj->mutex);
{
SX1509CallbackData **next = &obj->cb_data[pin->idx];
while (*next) {
next = &(*next)->next;
}
*next = cb_entry;
}
GateMutex_leave(obj->mutex, mutexKey);
return OCGPIO_SUCCESS;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_disableInt
**
** DESCRIPTION : disable interrupts for the provided pin.
**
** ARGUMENTS : pointer to the pin
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_disableInt(const OcGpio_Pin *pin) {
const SX1509_Cfg *sx_cfg = pin->port->cfg;
SX1509_Obj *obj = pin->port->object_data;
int res = OCGPIO_FAILURE;
const sx1509RegType bank = GetBank(pin->idx);
const uint8_t pin_idx = RelativePinIdx(pin->idx);
SX1509_Registers *reg = &obj->regs[bank];
/* Disable (1) interrupt */
const IArg mutexKey = GateMutex_enter(obj->mutex);
{
const uint8_t new_reg_value = set_bit8(reg->int_mask, pin_idx, 1);
if (ioexp_led_config_interrupt(&sx_cfg->i2c_dev,
bank,
new_reg_value,
0x00) != RETURN_OK) {
goto cleanup;
}
reg->int_mask = new_reg_value;
res = OCGPIO_SUCCESS;
}
cleanup:
GateMutex_leave(obj->mutex, mutexKey);
return res;
}
/*****************************************************************************
** FUNCTION NAME : GpioSX1509_enableInt
**
** DESCRIPTION : enable interrupt on a gpio pin
**
** ARGUMENTS : pointer to the pin
**
** RETURN TYPE : OCGPIO_FAILURE or OCGPIO_SUCCESS
**
*****************************************************************************/
static int GpioSX1509_enableInt(const OcGpio_Pin *pin) {
const SX1509_Cfg *sx_cfg = pin->port->cfg;
SX1509_Obj *obj = pin->port->object_data;
int res = OCGPIO_FAILURE;
const sx1509RegType bank = GetBank(pin->idx);
const uint8_t pin_idx = RelativePinIdx(pin->idx);
SX1509_Registers *reg = &obj->regs[bank];
/* Enable (0) interrupt */
const IArg mutexKey = GateMutex_enter(obj->mutex);
{
const uint8_t new_reg_value = set_bit8(reg->int_mask, pin_idx, 0);
if (ioexp_led_config_interrupt(&sx_cfg->i2c_dev,
bank,
new_reg_value,
0x00) != RETURN_OK) {
goto cleanup;
}
reg->int_mask = new_reg_value;
res = OCGPIO_SUCCESS;
}
cleanup:
GateMutex_leave(obj->mutex, mutexKey);
return res;
}
const OcGpio_FnTable GpioSX1509_fnTable = {
.probe = GpioSX1509_probe,
.init = GpioSX1509_init,
.write = GpioSX1509_write,
.read = GpioSX1509_read,
.configure = GpioSX1509_configure,
.setCallback = GpioSX1509_setCallback,
.disableInt = GpioSX1509_disableInt,
.enableInt = GpioSX1509_enableInt,
};

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _GPIOSX1509_H_
#define _GPIOSX1509_H_
#include "common/inc/global/ocmp_frame.h"
#include "inc/devices/sx1509.h"
#include "OcGpio.h"
#include <ti/sysbios/gates/GateMutex.h>
#include <stdint.h>
#define SX1509_NUM_BANKS 2
#define SX1509_PINS_PER_BANK 8
#define SX1509_PIN_COUNT (SX1509_NUM_BANKS * SX1509_PINS_PER_BANK)
extern const OcGpio_FnTable GpioSX1509_fnTable;
typedef struct SX1509_Cfg {
I2C_Dev i2c_dev;
OcGpio_Pin *pin_irq;
} SX1509_Cfg;
/* Private SX1509 driver data */
typedef struct SX1509_Registers {
uint8_t data;
uint8_t input_buf_disable;
uint8_t pull_up;
uint8_t pull_down;
uint8_t open_drain;
uint8_t polarity;
uint8_t direction;
uint8_t int_mask;
uint16_t edge_sense; /*!< Could be split into high and low if needed */
} SX1509_Registers;
/* TODO: possibly dedupe with GpioNative */
typedef struct SX1509CallbackData {
const OcGpio_Pin *pin;
OcGpio_CallbackFn callback;
void *context;
struct SX1509CallbackData *next; /*!< Pointer to next pin subscriber */
} SX1509CallbackData;
typedef struct SX1509_Obj {
GateMutex_Handle mutex; /*!< Prevent simultaneous editing of registers */
SX1509_Registers regs[SX1509_NUM_BANKS];
SX1509CallbackData *cb_data[SX1509_PIN_COUNT];
} SX1509_Obj;
#endif /* _GPIOSX1509_H_ */

View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "drivers/OcGpio.h"

View File

@@ -0,0 +1,265 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _OCGPIO_H_
#define _OCGPIO_H_
#include <stdbool.h>
#include <stdint.h>
/* OC-GPIO functions will return a negative on failure */
#define OCGPIO_SUCCESS 0
#define OCGPIO_FAILURE -1
typedef struct OcGpio_Pin OcGpio_Pin;
typedef struct OcGpio_Port OcGpio_Port;
typedef void (*OcGpio_CallbackFn) (const OcGpio_Pin *pin, void *context);
/* Interface virtual function definitions */
typedef int (*OcGpio_initFn) (const OcGpio_Port *port);
typedef int (*OcGpio_writeFn) (const OcGpio_Pin *pin, bool value);
typedef int (*OcGpio_readFn) (const OcGpio_Pin *pin);
typedef int (*OcGpio_configFn) (const OcGpio_Pin *pin, uint32_t cfg);
typedef int (*OcGpio_setCallbackFn) (const OcGpio_Pin *pin,
OcGpio_CallbackFn callback,
void *context);
typedef int (*OcGpio_disableIntFn) (const OcGpio_Pin *pin);
typedef int (*OcGpio_enableIntFn) (const OcGpio_Pin *pin);
typedef struct OcGpio_FnTable {
OcGpio_initFn probe;
OcGpio_initFn init; /*!< Port initialization - called once */
OcGpio_writeFn write;
OcGpio_readFn read;
OcGpio_configFn configure;
OcGpio_setCallbackFn setCallback;
OcGpio_disableIntFn disableInt;
OcGpio_enableIntFn enableInt;
} OcGpio_FnTable;
/*! A port defines a specific driver instance to route through */
struct OcGpio_Port {
const OcGpio_FnTable *fn_table; /*!< virtual table for driver */
const void *cfg; /*!< driver-specific config settings */
void *object_data; /*!< driver-specific data (in RAM) */
};
/*! A pin provides us with everything we need to route data to the appropriate
* driver - a port instance, a pin index, and board-sprcific configuration
* settings
*/
struct OcGpio_Pin {
const OcGpio_Port *port; /*!< Pointer to IO driver instance */
uint16_t idx; /*!< Driver-specific index */
uint16_t hw_cfg; /*!< Any special attributes for the pin (eg. invert) */
};
/*
* OC GPIO hardware configuration settings - these are to be used in the board
* config file since they're largely depicted by the layout. One may provide
* separate input and output configurations for bi-directional pins
*
* Note: these definitions are compatible with the TI GPIO driver configs with
* a small amount of shifting
* ============================================================================
*/
typedef union OcGpio_HwCfg {
struct {
bool invert:1;
uint16_t in_cfg:3;
uint16_t out_cfg:3;
uint16_t out_str:2;
};
uint16_t uint16;
} OcGpio_HwCfg;
#define OCGPIO_CFG_POL_MASK (((uint32_t) 1) << OCGPIO_CFG_POL_LSB)
#define OCGPIO_CFG_IN_PULL_MASK (((uint32_t) 6) << OCGPIO_CFG_IN_LSB)
#define OCGPIO_CFG_OUT_OD_MASK (((uint32_t) 7) << OCGPIO_CFG_OUT_LSB)
#define OCGPIO_CFG_OUT_STR_MASK (((uint32_t) 3) << OCGPIO_CFG_OUT_STR_LSB)
#define OCGPIO_CFG_POL_LSB 0
#define OCGPIO_CFG_IN_LSB 1
#define OCGPIO_CFG_OUT_LSB 4
#define OCGPIO_CFG_OUT_STR_LSB 7
#define OCGPIO_CFG_POL_STD (((uint32_t) 0) << OCGPIO_CFG_POL_LSB) /*!< Standard polarity */
#define OCGPIO_CFG_INVERT (((uint32_t) 1) << OCGPIO_CFG_POL_LSB) /*!< Polarity inverted */
#define OCGPIO_CFG_IN_NOPULL (((uint32_t) 0) << OCGPIO_CFG_IN_LSB) /*!< Input pin has no PU/PD */
#define OCGPIO_CFG_IN_PU (((uint32_t) 2) << OCGPIO_CFG_IN_LSB) /*!< Input pin has Pullup */
#define OCGPIO_CFG_IN_PD (((uint32_t) 4) << OCGPIO_CFG_IN_LSB) /*!< Input pin has Pulldown */
#define OCGPIO_CFG_OUT_STD (((uint32_t) 0) << OCGPIO_CFG_OUT_LSB) /*!< Output pin is not Open Drain */
#define OCGPIO_CFG_OUT_OD_NOPULL (((uint32_t) 2) << OCGPIO_CFG_OUT_LSB) /*!< Output pin is Open Drain */
#define OCGPIO_CFG_OUT_OD_PU (((uint32_t) 4) << OCGPIO_CFG_OUT_LSB) /*!< Output pin is Open Drain w/ pull up */
#define OCGPIO_CFG_OUT_OD_PD (((uint32_t) 6) << OCGPIO_CFG_OUT_LSB) /*!< Output pin is Open Drain w/ pull dn */
#define OCGPIO_CFG_OUT_STR_LOW (((uint32_t) 0) << OCGPIO_CFG_OUT_STR_LSB) /*!< Low drive strength */
#define OCGPIO_CFG_OUT_STR_MED (((uint32_t) 1) << OCGPIO_CFG_OUT_STR_LSB) /*!< Medium drive strength */
#define OCGPIO_CFG_OUT_STR_HIGH (((uint32_t) 2) << OCGPIO_CFG_OUT_STR_LSB) /*!< High drive strength */
/*
* OC GPIO I/O configuration settings - these are to be used by drivers that
* control GPIO pins. These are settings that are generic enough that every
* GPIO driver should support. These settings aren't layout specific, but are
* instead dictated by the higher level driver (see OcGpio_configure)
* ============================================================================
*/
typedef union OcGpio_ioCfg {
struct {
uint32_t dir:1;
uint32_t default_val:1;
uint32_t int_cfg:3;
};
uint32_t uint32;
} OcGpio_ioCfg;
#define OCGPIO_CFG_DIR_BIT 0
#define OCGPIO_CFG_OUT_BIT 1
#define OCGPIO_CFG_INT_LSB 2
#define OCGPIO_CFG_OUTPUT (((uint32_t) 0) << OCGPIO_CFG_DIR_BIT) /*!< Pin is an output. */
#define OCGPIO_CFG_INPUT (((uint32_t) 1) << OCGPIO_CFG_DIR_BIT) /*!< Pin is an input. */
#define OCGPIO_CFG_OUT_LOW (((uint32_t) 0) << OCGPIO_CFG_OUT_BIT) /*!< Output low by default */
#define OCGPIO_CFG_OUT_HIGH (((uint32_t) 1) << OCGPIO_CFG_OUT_BIT) /*!< Output high by default */
#define OCGPIO_CFG_INT_NONE (((uint32_t) 0) << OCGPIO_CFG_INT_LSB) /*!< No Interrupt */
#define OCGPIO_CFG_INT_FALLING (((uint32_t) 1) << OCGPIO_CFG_INT_LSB) /*!< Interrupt on falling edge */
#define OCGPIO_CFG_INT_RISING (((uint32_t) 2) << OCGPIO_CFG_INT_LSB) /*!< Interrupt on rising edge */
#define OCGPIO_CFG_INT_BOTH_EDGES (((uint32_t) 3) << OCGPIO_CFG_INT_LSB) /*!< Interrupt on both edges */
#define OCGPIO_CFG_INT_LOW (((uint32_t) 4) << OCGPIO_CFG_INT_LSB) /*!< Interrupt on low level */
#define OCGPIO_CFG_INT_HIGH (((uint32_t) 5) << OCGPIO_CFG_INT_LSB) /*!< Interrupt on high level */
/* Wrapper functions to dispatch call to appropriate v-table
* ==================================================================
*/
/* Since this is simply an interface definition, define the functions in the
* header to allow them to be inlined for better efficiency. Any functions added
* to this module that are more than a simple wrapper should be added to
* OcGpio.c instead.
*/
/*! Probe the device for POStT
* probe function
* @param pin OcGPio_Port pointer to the driver instance to find the device
* @return 0 on success, negative on failure
*/
static inline int OcGpio_probe(const OcGpio_Port *port) {
if( port && port->fn_table && port->fn_table->probe) {
return port->fn_table->probe(port);
} else {
return OCGPIO_FAILURE;
}
}
/*! Initialize the port - tempted to remove in favor of more generic device
* init function
* @param pin OcGPio_Port pointer to the driver instance to initialize
* @return 0 on success, negative on failure
*/
static inline int OcGpio_init(const OcGpio_Port *port) {
if( port && port->fn_table && port->fn_table->init) {
return port->fn_table->init(port);
} else {
return OCGPIO_FAILURE;
}
}
/*! Write a value to a GPIO pin
* @param pin OcGPio_Pin pointer for the pin to be controlled
* @param value Boolean value to write to the pin
* @return 0 on success, negative on failure
*/
static inline int OcGpio_write(const OcGpio_Pin *pin, bool value) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->write) {
return pin->port->fn_table->write(pin, value);
} else {
return OCGPIO_FAILURE;
}
}
/*! Read a value from a GPIO pin
* @param pin OcGPio_Pin pointer for the pin to read
* @return Boolean value of pin, or negative if failure
*/
static inline int OcGpio_read(const OcGpio_Pin *pin) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->read) {
return pin->port->fn_table->read(pin);
} else {
return OCGPIO_FAILURE;
}
}
/*! Configure a GPIO pin's parameters (both io and hw params)
* @note This must be called before using the pin
* @param pin OcGPio_Pin pointer to the pin to configure
* @param cfg Bitfield of OCGPIO_CFG io values (direction, interrupt edge)
* @return 0 on success, negative on failure
*/
static inline int OcGpio_configure(const OcGpio_Pin *pin, uint32_t cfg) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->configure) {
return pin->port->fn_table->configure(pin, cfg);
} else {
return OCGPIO_FAILURE;
}
}
/*! Add a callback subscriber to an interrupt-enabled pin
* @note Multiple callbacks can be subscribed to a single pin
* @param pin OcGPio_Pin pointer to subscribe to changes on
* @param callback Function to call when interrupt is triggered
* @param context Context pointer that is passed to callback function
* @return 0 on success, negative on failure
*/
static inline int OcGpio_setCallback (const OcGpio_Pin *pin,
OcGpio_CallbackFn callback,
void *context) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->setCallback) {
return pin->port->fn_table->setCallback(pin, callback, context);
} else {
return OCGPIO_FAILURE;
}
}
/*! Disable pin interrupt
* @param pin OcGPio_Pin pointer for the pin to disable the interrupt on
* @return 0 on success, negative on failure
*/
static inline int OcGpio_disableInt(const OcGpio_Pin *pin) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->disableInt) {
return pin->port->fn_table->disableInt(pin);
} else {
return OCGPIO_FAILURE;
}
}
/*! Enable pin interrupt
* @note This must be called after OcGpio_setCallback in order to activate the
* interrupt
* @param pin OcGPio_Pin pointer for the pin to enable the interrupt on
* @return 0 on success, negative on failure
*/
static inline int OcGpio_enableInt(const OcGpio_Pin *pin) {
if( pin && pin->port && pin->port->fn_table &&
pin->port->fn_table->enableInt) {
return pin->port->fn_table->enableInt(pin);
} else {
return OCGPIO_FAILURE;
}
}
#endif /* _OCGPIO_H_ */

View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#ifndef HELPERS_ARRAY_H_
#define HELPERS_ARRAY_H_
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif /* HELPERS_ARRAY_H_ */

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#ifndef HELPERS_ATTRIBUTE_H_
#define HELPERS_ATTRIBUTE_H_
#define PACKED __attribute__ ((__packed__))
#define UNUSED(x) (void)(x)
#endif /* HELPERS_ATTRIBUTE_H_ */

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#ifndef HELPERS_MATH_H_
#define HELPERS_MATH_H_
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
#define CONSTRAIN(x, min, max) MIN(MAX((x), (min)), (max))
#endif /* HELPERS_MATH_H_ */

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "memory.h"
#include "inc/common/global_header.h"
void printMemory(const void *start, size_t size) {
for (size_t i = 0; i < size; ++i) {
DEBUG("0x%02x ", ((uint8_t *)start)[i]);
if ((i+1) % 8 == 0) {
DEBUG("\n");
} else if ((i+1) % 4 == 0) {
DEBUG(" ");
}
}
DEBUG("\n");
}
uint8_t set_bit8(uint8_t byte, uint8_t bit, bool value) {
const uint8_t mask = 1 << bit;
if (value) {
byte |= mask;
} else {
byte &= ~mask;
}
return byte;
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#ifndef HELPERS_MEMORY_H_
#define HELPERS_MEMORY_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef HIWORD
#define HIWORD(x) ((uint16_t)((x) >> 16))
#endif
#ifndef LOWORD
#define LOWORD(x) ((uint16_t)(x))
#endif
#ifndef HIBYTE
#define HIBYTE(x) ((uint8_t)((x) >> 8))
#endif
#ifndef LOBYTE
#define LOBYTE(x) ((uint8_t)(x))
#endif
#define zalloc(size) calloc((size), 1)
void printMemory(const void *start, size_t size);
/* Sets a bit in a uint8 to the specified value (1/0)
* @param byte The original value we're modifying
* @param bit The index of the bit we want to set/clear
* @param value The value the bit should be set to (1/0)
* @return The modified byte with the bit's new value
*/
uint8_t set_bit8(uint8_t byte, uint8_t bit, bool value);
#endif /* HELPERS_MEMORY_H_ */

View File

@@ -0,0 +1,517 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "comm/gossiper.h"
#include "common/inc/global/ocmp_frame.h"
#include "inc/interfaces/uartdma.h"
#include "inc/common/global_header.h"
#include <driverlib/gpio.h>
#include <driverlib/interrupt.h>
#include <driverlib/pin_map.h>
#include <driverlib/sysctl.h>
#include <driverlib/uart.h>
#include <driverlib/udma.h>
#include <inc/hw_ints.h>
#include <inc/hw_memmap.h>
#include <inc/hw_uart.h>
#include <ti/drivers/UART.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <stdlib.h>
#include <string.h>
char input[64];
UART_Handle uart;
/*****************************************************************************
* HANDLES DEFINITION
*****************************************************************************/
/* Semaphore */
Semaphore_Handle semUART;
Semaphore_Handle semUARTTX;
/* Queue object */
Queue_Struct uartRxMsg;
Queue_Struct uartTxMsg;
Queue_Handle uartRxMsgQueue;
Queue_Handle uartTxMsgQueue;
/* Global Task Configuration Variables */
Task_Struct ocUARTDMATask;
Char ocUARTDMATaskStack[OCUARTDMA_TASK_STACK_SIZE];
Task_Struct ocUARTDMATxTask;
Char ocUARTDMATxTaskStack[OCUARTDMATX_TASK_STACK_SIZE];
/*****************************************************************************
* The transmit and receive buffers used for the UART transfers. There is one
* transmit buffer and a pair of recieve ping-pong buffers.
******************************************************************************/
static uint8_t ui8TxBuf[UART_TXBUF_SIZE];
static uint8_t ui8RxBufA[UART_RXBUF_SIZE];
static uint8_t ui8RxBufB[UART_RXBUF_SIZE];
static uint8_t ui8uartdmaRxBuf[UART_RXBUF_SIZE];
/*****************************************************************************
* The control table used by the uDMA controller. This table must be aligned
* to a 1024 byte boundary.
*****************************************************************************/
#pragma DATA_ALIGN(pui8ControlTable, 1024)
uint8_t pui8ControlTable[1024];
/*****************************************************************************
*
* The interrupt handler for uDMA errors. This interrupt will occur if the
* uDMA encounters a bus error while trying to perform a transfer. This
* handler just increments a counter if an error occurs.
*****************************************************************************/
void uDMAErrorHandler(void)
{
uint32_t ui32Status;
/* Check for uDMA error bit. */
ui32Status = uDMAErrorStatusGet();
/* If there is a uDMA error, then clear the error and increment the error
* counter.*/
if (ui32Status) {
uDMAErrorStatusClear();
LOGGER_WARNING("UARTDMACTR:WARNING::Something went bad in uDMA.\n");
}
}
/*****************************************************************************
*
* The interrupt handler for UART4.
*
*****************************************************************************/
void UART4IntHandler(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
ui32Status = UARTIntStatus(UART4_BASE, 1);
/* Clear any pending status*/
UARTIntClear(UART4_BASE, ui32Status);
/*Primary Buffer*/
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT);
if (ui32Mode == UDMA_MODE_STOP) {
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART4_BASE + UART_O_DR),
ui8RxBufA, sizeof(ui8RxBufA));
/*Preparing message to send to UART RX Queue*/
memset(ui8uartdmaRxBuf,'\0',UART_RXBUF_SIZE);
memcpy(ui8uartdmaRxBuf,ui8RxBufA,sizeof(ui8RxBufA));
Semaphore_post(semUART);
}
/*Alternate Buffer*/
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_TMR0A | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP) {
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0A | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART4_BASE + UART_O_DR),
ui8RxBufB, sizeof(ui8RxBufB));
/*Preparing message to send to UART RX Queue*/
memset(ui8uartdmaRxBuf,'\0',UART_RXBUF_SIZE);
memcpy(ui8uartdmaRxBuf,ui8RxBufB,sizeof(ui8RxBufB));
Semaphore_post(semUART);
}
}
/*****************************************************************************
* Reset and configure DMA and UART.
*****************************************************************************/
void resetUARTDMA(void)
{
LOGGER_WARNING("UARTDMACTR:WARNING::Configuring UART DMA again.....!!!\n");
// Configure UART.*/
ConfigureUART();
/* Configure UART.*/
uartdma_init();
LOGGER("UARTDMACTR:INFO::Re-Configuring UART DMA again.....!!!\n");
}
typedef enum DK_TM4C129X_UARTName {
DK_TM4C129X_UART0 = 0,
DK_TM4C129X_UART1,
DK_TM4C129X_UART2,
DK_TM4C129X_UART3,
DK_TM4C129X_UART4,
DK_TM4C129X_UARTCOUNT
} DK_TM4C129X_UARTName;
/*****************************************************************************
* Configure the UART and its pins. This must be called before UARTprintf().
*****************************************************************************/
void ConfigureUART(void)
{
LOGGER_DEBUG("UARTDMACTR:INFO::Configuring UART interface for communication.\n");
UART_Params uartParams;
/* Enable the GPIO Peripheral used by the UART.*/
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
/* Enable UART4 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART4);
// SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
// SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);
/* Configure GPIO Pins for UART mode.*/
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
// GPIOPinConfigure(GPIO_PC4_U1RX);
// GPIOPinConfigure(GPIO_PC5_U1TX);
// GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
UART_init();
/* Create a UART with data processing off. */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudRate = 115200;
uart = UART_open(DK_TM4C129X_UART4, &uartParams);
// uart = UART_open(DK_TM4C129X_UART1, &uartParams);
}
/****************************************************************************
*
* Initializes the UART4 peripheral and sets up the TX and RX uDMA channels.
*****************************************************************************/
void InitUART4Transfer(void)
{
LOGGER_DEBUG("UARTDMACTR:INFO::Configuring UART interrupt and uDMA channel for communication to GPP.\n");
uint_fast16_t ui16Idx;
const uint32_t SysClock = 120000000;
/* TX buffer init to 0.*/
for (ui16Idx = 0; ui16Idx < UART_TXBUF_SIZE; ui16Idx++) {
ui8TxBuf[ui16Idx] = 0;
}
/* Enable the UART peripheral, and configure it to operate even if the CPU
* is in sleep.*/
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART4);
/* Configure the UART communication parameters.*/
UARTConfigSetExpClk(UART4_BASE, SysClock, 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);
/* Set both the TX and RX trigger thresholds to 4. */
UARTFIFOLevelSet(UART4_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
/* Enable the UART for operation, and enable the uDMA interface for both TX
* and RX channels.*/
UARTEnable(UART4_BASE);
UARTDMAEnable(UART4_BASE, UART_DMA_RX | UART_DMA_TX);
uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR0A, UDMA_ATTR_ALTSELECT
| UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY
| UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
uDMAChannelControlSet(UDMA_CHANNEL_TMR0A | UDMA_ALT_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART4_BASE + UART_O_DR),
ui8RxBufA, sizeof(ui8RxBufA));
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0A | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART4_BASE + UART_O_DR),
ui8RxBufB, sizeof(ui8RxBufB));
uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR0B,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
uDMAChannelAttributeEnable(UDMA_CHANNEL_TMR0B, UDMA_ATTR_USEBURST);
uDMAChannelControlSet(UDMA_CHANNEL_TMR0B | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0B | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, ui8TxBuf,
(void *)(UART4_BASE + UART_O_DR),
sizeof(ui8TxBuf));
uDMAChannelAssign(UDMA_CH18_UART4RX);
uDMAChannelAssign(UDMA_CH19_UART4TX);
uDMAChannelEnable(UDMA_CHANNEL_TMR0A);
uDMAChannelEnable(UDMA_CHANNEL_TMR0B);
/* Enable the UART DMA TX/RX interrupts.*/
UARTIntEnable(UART4_BASE, UART_INT_DMARX );
/* Enable the UART peripheral interrupts.*/
IntEnable(INT_UART4);
}
/*****************************************************************************
* Intialize UART uDMA for the data transfer. This will initialise both Tx and
* Rx Channel associated with UART Tx and Rx
****************************************************************************/
void uartdma_init(void)
{
LOGGER_DEBUG("UARTDMACTR:INFO::Starting uDMA intilaization.\n");
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
IntEnable(INT_UDMAERR);
uDMAEnable();
uDMAControlBaseSet(pui8ControlTable);
InitUART4Transfer();
}
/*****************************************************************************
* Initialize the UART with DMA interface.
****************************************************************************/
void uartDMAinterface_init(void)
{
/* Configure UART */
ConfigureUART();
/* Initialize UART */
// uartdma_init();
/*UART RX Semaphore */
LOGGER_DEBUG("UARTDMACTR:INFO:: uartDMA interface intialization.\n");
semUART = Semaphore_create(0, NULL, NULL);
if (semUART == NULL) {
LOGGER_ERROR("UARTDMACTR:ERROR::UART RX Semaphore creation failed.\n");
}
/*UART OCMP RX Message Queue*/
uartRxMsgQueue = Util_constructQueue(&uartRxMsg);
LOGGER_DEBUG("UARTDMACTR:INFO::Constructing message Queue 0x%x for UART RX OCMP Messages.\n",
uartRxMsgQueue);
LOGGER_DEBUG("UARTDMACTR:INFO::Waiting for OCMP UART RX messgaes....!!!\n");
}
/*****************************************************************************
* uartdma_rx_taskfxn -Handles the UART received data.
****************************************************************************/
static void uartdma_rx_taskfxn(UArg arg0, UArg arg1)
{
// Initialize application
uartDMAinterface_init();
// Application main loop
while (true) {
UART_read(uart, &input, 64);
// if (Semaphore_pend(semUART, BIOS_WAIT_FOREVER)) {
if(1) {
/* Reset Uart DMA if the SOF is not equal to 0X55 */
// if (ui8uartdmaRxBuf[0] != OCMP_MSG_SOF) {
if (input[0] != OCMP_MSG_SOF) {
// resetUARTDMA();
} else {
/* OCMP UART RX Messgaes */
uint8_t * pWrite = NULL;
pWrite = (uint8_t *) malloc(
sizeof(OCMPMessageFrame) + OCMP_FRAME_MSG_LENGTH);
if (pWrite != NULL) {
memset(pWrite, '\0', UART_RXBUF_SIZE);
memcpy(pWrite, input, UART_RXBUF_SIZE);
#if 0
uint8_t i = 0;
LOGGER_DEBUG("UARTDMACTR:INFO:: UART RX BUFFER:\n");
for( i = 0; i < UART_RXBUF_SIZE; i++)
{
LOGGER_DEBUG("0x%x ",input[i]);
}
LOGGER_DEBUG("\n");
#endif
Util_enqueueMsg(gossiperRxMsgQueue, semGossiperMsg, pWrite);
} else {
LOGGER_ERROR("UARTDMACTR:ERROR:: No memory left for Msg Length %d.\n",
UART_RXBUF_SIZE);
}
}
}
}
}
/*****************************************************************************
* uartdma_tx_taskinit - Creating IPC objects
*****************************************************************************/
void uartdma_tx_taskinit(void)
{
LOGGER_DEBUG("UARTDMACTR:INFO:: uartDMA interface intialization.\n");
/*UART TX Semaphore */
semUARTTX = Semaphore_create(0, NULL, NULL);
if (semUARTTX == NULL) {
LOGGER_ERROR("UARTDMACTR:ERROR::UART TX Semaphore creation failed.\n");
}
/*UART OCMP TX Message Queue*/
uartTxMsgQueue = Util_constructQueue(&uartTxMsg);
LOGGER_DEBUG("UARTDMACTR:INFO::Constructing message Queue 0x%x for UART TX OCMP Messages.\n",
uartTxMsgQueue);
}
/*****************************************************************************
** FUNCTION NAME : uartdma_process_tx_message
**
** DESCRIPTION : transmitt TX Messages to UART physical medium
**
** ARGUMENTS : Pointer to UARTDMATX_Evt_t structure
**
** RETURN TYPE : None
**
*****************************************************************************/
static ReturnStatus uartdma_process_tx_message(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
if (1) {
memset(ui8TxBuf, '\0', UART_TXBUF_SIZE);
memcpy(ui8TxBuf, pMsg, UART_TXBUF_SIZE);
#if 0
uint8_t i = 0;
LOGGER_DEBUG("UARTDMACTR:INFO:: UART TX BUFFER:\n");
for( i = 0; i < UART_TXBUF_SIZE; i++)
{
LOGGER_DEBUG("0x%x ",ui8TxBuf[i]);
}
LOGGER_DEBUG("\n");
#endif
UART_write(uart, ui8TxBuf, UART_TXBUF_SIZE);
} else {
status = RETURN_NOTOK;
}
return status;
}
/*
static ReturnStatus uartdma_process_tx_message(uint8_t *pMsg)
{
ReturnStatus status = RETURN_OK;
if (!uDMAChannelIsEnabled(UDMA_CHANNEL_TMR0B)) {
memset(ui8TxBuf, '\0', UART_TXBUF_SIZE);
memcpy(ui8TxBuf, pMsg, UART_TXBUF_SIZE);
#if 1
uint8_t i = 0;
LOGGER_DEBUG("UARTDMACTR:INFO:: UART TX BUFFER:\n");
for( i = 0; i < UART_TXBUF_SIZE; i++)
{
LOGGER_DEBUG("0x%x ",ui8TxBuf[i]);
}
LOGGER_DEBUG("\n");
#endif
uDMAChannelTransferSet(UDMA_CHANNEL_TMR0B | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, ui8TxBuf,
(void *) (UART4_BASE + UART_O_DR), sizeof(ui8TxBuf));
uDMAChannelEnable(UDMA_CHANNEL_TMR0B);
} else {
status = RETURN_NOTOK;
}
return status;
}
*/
/*****************************************************************************
* uartdma_tx_taskfxn - Handles the UART sent data.
****************************************************************************/
static void uartdma_tx_taskfxn(UArg arg0, UArg arg1)
{
/* UARTDMA TX init*/
uartdma_tx_taskinit();
// Application main loop
while (true) {
if (Semaphore_pend(semUARTTX, BIOS_WAIT_FOREVER)) {
/* OCMP UART TX Messgaes */
while (!Queue_empty(uartTxMsgQueue)) {
uint8_t *pWrite = (uint8_t *) Util_dequeueMsg(uartTxMsgQueue);
if (pWrite) {
uartdma_process_tx_message(pWrite);
}
free(pWrite);
}
}
}
}
/******************************************************************************
** FUNCTION NAME : uartdma_rx_createtask
**
** DESCRIPTION : Task creation function for the UARTDMA
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
******************************************************************************/
void uartdma_rx_createtask(void)
{
Task_Params taskParams;
Task_Params_init(&taskParams);
taskParams.stackSize = OCUARTDMA_TASK_STACK_SIZE;
taskParams.stack = &ocUARTDMATaskStack;
taskParams.instance->name = "UART_DMA_TASK";
taskParams.priority = OCUARTDMA_TASK_PRIORITY;
Task_construct(&ocUARTDMATask, (Task_FuncPtr) uartdma_rx_taskfxn,
&taskParams, NULL);
LOGGER_DEBUG("UARTDMACTRl:INFO::Creating UART DMA task function.\n");
}
/******************************************************************************
** FUNCTION NAME : uartdma_tx_createtask
**
** DESCRIPTION : Task creation function for the UARTDMA TX
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
******************************************************************************/
void uartdma_tx_createtask(void)
{
Task_Params taskParams;
Task_Params_init(&taskParams);
taskParams.stackSize = OCUARTDMATX_TASK_STACK_SIZE;
taskParams.stack = &ocUARTDMATxTaskStack;
taskParams.instance->name = "UART_DMA_TX_TASK";
taskParams.priority = OCUARTDMATX_TASK_PRIORITY;
Task_construct(&ocUARTDMATxTask, (Task_FuncPtr) uartdma_tx_taskfxn,
&taskParams, NULL);
LOGGER_DEBUG("UARTDMACTRl:INFO::Creating UART DMA TX task function.\n");
}

74
firmware/psu/src/main.c Normal file
View File

@@ -0,0 +1,74 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "Board.h"
#include "inc/common/bigbrother.h"
#include "inc/common/global_header.h"
#include <driverlib/sysctl.h>
#include <ti/sysbios/BIOS.h>
#define xstr(a) str(a)
#define str(a) #a
//*****************************************************************************
// FUNCTION DECLARATIONS
//*****************************************************************************
extern int ethernet_start(void);
static void openCellular_init(void)
{
LOGGER_DEBUG("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("|||| |||| |||| ||||| |||||| |||| |||| |||| ||||||||| ||||||||| |||| |||| ||||||||| |||| ||||\n");
LOGGER_DEBUG("|||| |||| |||| |||| |||| |||||||||| | ||||| |||| ||||||||| ||||||||| ||||||||| ||||||||| |||| |||| ||||||||| |||| |||| |||| ||||\n");
LOGGER_DEBUG("|||| |||| |||| |||| |||| |||||||||| || |||| |||| ||||||||| ||||||||| ||||||||| ||||||||| |||| |||| ||||||||| |||| |||| |||| ||||\n");
LOGGER_DEBUG("|||| |||| |||| |||| ||||| ||| ||| |||| ||||||||| |||| ||||||||| ||||||||| |||| |||| ||||||||| |||| ||||\n");
LOGGER_DEBUG("|||| |||| |||| |||||||||| |||||||||| |||| || |||| ||||||||| ||||||||| ||||||||| ||||||||| |||| |||| ||||||||| |||| |||| || ||||||\n");
LOGGER_DEBUG("|||| |||| |||| |||||||||| |||||||||| ||||| | |||| ||||||||| ||||||||| ||||||||| ||||||||| |||| |||| ||||||||| |||| |||| ||| |||||\n");
LOGGER_DEBUG("|||| |||| |||||||||| ||||| |||||| |||| |||| |||| |||| |||| |||| |||| |||| |||| |||| ||||\n");
LOGGER_DEBUG("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("\nOCWare v"
xstr(_FW_REV_MAJOR_)"."
xstr(_FW_REV_MINOR_)"."
xstr(_FW_REV_BUGFIX_)"-"
xstr(_FW_REV_TAG_)"\n");
LOGGER_DEBUG("Build Date: "__DATE__" "__TIME__"\n\n");
}
static void exit_handler(int unused)
{
/* Perform a full system reset if we fault,
* hope it doesn't happen again */
SysCtlReset();
}
/*Main Function */
int main(void)
{
/* Install an exit handler to catch if we fault out */
// OcGpio_Pin pin_watchdog = { &ec_io, OC_EC_WD_INPUT };
System_atexit(exit_handler);
openCellular_init();
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
Board_initI2C();
//TODO: PWR2
// Board_initUART();
bigbrother_createtask();
/* Start BIOS */
BIOS_start();
return (0);
}

View File

@@ -0,0 +1,418 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
//*****************************************************************************
#include "comm/gossiper.h"
#include "common/inc/global/ocmp_frame.h"
#include "common/inc/global/post_frame.h"
#include "inc/common/bigbrother.h"
#include "inc/common/post.h"
#include "inc/subsystem/hci/hci.h"
#include "inc/subsystem/power/power.h"
#include "inc/utils/ocmp_util.h"
#include "registry/SSRegistry.h"
#include <ti/sysbios/BIOS.h>
#include <stdlib.h>
#include <string.h>
//*****************************************************************************
// HANDLES DEFINITION
//*****************************************************************************
/* Queue object */
/*
* Semaphore for the POST task where it will be waiting on
* sub systems or BigBrother postmessages.
*/
Semaphore_Handle semPOSTMsg;
static Queue_Struct postRxMsg;
/*
* postRxMsgQueue - Used by the BigBrother/Subsystem to pass the POST request
* and ack message.
*/
Queue_Handle postRxMsgQueue;
/* Global Task Configuration Variables */
static Task_Struct postTask;
static Char postTaskStack[POST_TASK_STACK_SIZE];
/* POST state */
static uint8_t postState = 0;
static OCMPSubsystem POST_subSystem;
extern POSTData PostResult[POST_RECORDS];
/*****************************************************************************
* FUNCTION DECLARATIONS
*****************************************************************************/
static void post_taskfxn(UArg a0, UArg a1);
static void post_task_init(void);
static ReturnStatus post_process_msg(OCMPSubsystem OC_subSystem);
static OCMPMessageFrame* post_create_execute_msg(OCMPSubsystem OC_subSystem);
static void post_activate(OCMPMessageFrame *pPOSTMsg);
static void post_process_rx_msg(OCMPMessageFrame *pPOSTMsg);
static void post_move_to_next_subsystem();
static void post_update_result_to_bigbrother(OCMPMessageFrame *pPOSTMsg);
extern ReturnStatus bb_sys_post_complete(void);
/*****************************************************************************
** FUNCTION NAME : _post_complete
**
** DESCRIPTION : Get POST results from EEPROM.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
void _post_complete()
{
uint8_t iter = 0;
LOGGER_DEBUG("POST:INFO::POST test is completed.\n");
LOGGER_DEBUG("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("|||||||||||||||||||||||||||||||||||||||||||||||||||||||POST TABLE|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
/* POST results */
for (iter = 0; iter < POST_RECORDS; iter++) {
LOGGER_DEBUG("\t POST:INFO:: POSTRESULT SS: 0x%x Device S.No: 0x%x I2C Bus: 0x%x Device Addr: 0x%x Device Id: 0x%x Manufacture Id: 0x%x Status: 0x%x.\n",
PostResult[iter].subsystem, PostResult[iter].devSno,
PostResult[iter].i2cBus, PostResult[iter].devAddr,
PostResult[iter].devId, PostResult[iter].manId,
PostResult[iter].status);
}
LOGGER_DEBUG("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
LOGGER_DEBUG("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
}
/*****************************************************************************
** FUNCTION NAME : post_data_init
**
** DESCRIPTION : Initializes post struct.
**
** ARGUMENTS : subsystem , device serial number
**
** RETURN TYPE : None
**
*****************************************************************************/
void post_init_POSTData(POSTData *pData,OCMPSubsystem subsystem, uint8_t devSno)
{
pData->subsystem = subsystem;
pData->devSno = devSno;
pData->i2cBus = 0xFF;
pData->devAddr = 0xFF;
pData->manId = 0xFFFF;
pData->devId = 0xFFFF;
pData->status = POST_DEV_MISSING;
}
/*****************************************************************************
** FUNCTION NAME : post_update_deviceInfo
**
** DESCRIPTION : Update bus, device address, manufacturing ID and device ID in post struct.\
** if no I2C bus is associated with device than it will be updated to 0xFF.
**
** ARGUMENTS : I2C Bus, Address, man Id, device Id.
**
** RETURN TYPE : None
**
*****************************************************************************/
void post_update_POSTData(POSTData *pData, uint8_t I2CBus, uint8_t devAddress, uint16_t manId, uint16_t devId)
{
pData->i2cBus = I2CBus;
pData->devAddr = devAddress;
pData->manId = manId;
pData->devId = devId;
}
/*****************************************************************************
** FUNCTION NAME : post_update_deviceStatus
**
** DESCRIPTION : Update post status
**
** ARGUMENTS : POSTData and status.
**
** RETURN TYPE : None
**
*****************************************************************************/
void post_update_POSTStatus(POSTData *pData, ePostCode status)
{
pData->status = status;
}
/*****************************************************************************
** FUNCTION NAME : post_move_to_next_subsystem
**
** DESCRIPTION : Move to next subssytem in the OCSubSystem.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void post_move_to_next_subsystem()
{
POST_subSystem = (OCMPSubsystem) (POST_subSystem + (OCMPSubsystem) 1);
if (POST_subSystem > OC_SS_MAX_LIMIT) {
POST_subSystem = OC_SS_PWR;
}
}
/*****************************************************************************
** FUNCTION NAME : post_update_result_to_bigbrother
**
** DESCRIPTION : Send POST completion status to Bigbrother.
**
** ARGUMENTS : OCMPMessageFrame pointer for the update status
**
** RETURN TYPE : None
**
*****************************************************************************/
static void post_update_result_to_bigbrother(OCMPMessageFrame *pPOSTMsg)
{
pPOSTMsg->message.subsystem = OC_SS_PWR; //OC_SUBSYSTEM_MAX_LIMIT subsystem number taken for bigbrother
memcpy((pPOSTMsg->message.ocmp_data), &postState, 1);
Util_enqueueMsg(bigBrotherRxMsgQueue, semBigBrotherMsg,
(uint8_t*) pPOSTMsg);
}
/*****************************************************************************
** FUNCTION NAME : post_process_msg
**
** DESCRIPTION : Forward excecute POST message to subsystem.
**
** ARGUMENTS : Subsystem
**
** RETURN TYPE : None
**
*****************************************************************************/
static ReturnStatus post_process_msg(OCMPSubsystem OC_subSystem)
{
ReturnStatus status = RETURN_OK;
if (OC_subSystem == OC_SS_MAX_LIMIT) {
_post_complete();
POST_subSystem = OC_SS_PWR;
} else {
OCMPMessageFrame *postFrame = post_create_execute_msg(OC_subSystem);
if (postFrame) {
if (!SSRegistry_sendMessage(OC_subSystem, postFrame)) {
LOGGER_DEBUG("POST:ERROR::Subsystem %d does not exist\n",
OC_subSystem);
}
} else {
LOGGER_DEBUG("POST:ERROR::Out of memory.\n");
status = RETURN_NOTOK;
}
}
return status;
}
/*****************************************************************************
** FUNCTION NAME : post_create_execute_msg
**
** DESCRIPTION : create execute POST message for subsystem.
**
** ARGUMENTS : Subsystem
**
** RETURN TYPE : None
**
*****************************************************************************/
static OCMPMessageFrame* post_create_execute_msg(OCMPSubsystem OC_subSystem)
{
LOGGER_DEBUG("POST:INFO::Activation POST for SS %d.",OC_subSystem);
OCMPMessageFrame *postExeMsg = create_ocmp_msg_frame(OC_subSystem,
OCMP_MSG_TYPE_POST,
OCMP_AXN_TYPE_ACTIVE,
0x00,0x00,1);
return postExeMsg;
}
/*****************************************************************************
** FUNCTION NAME : post_create_enable_msg
**
** DESCRIPTION : create execute POST message for subsystem.
**
** ARGUMENTS : Subsystem
**
** RETURN TYPE : None
**
*****************************************************************************/
static OCMPMessageFrame* post_create_enable_msg(OCMPSubsystem OC_subSystem)
{
uint8_t dummyByte = 0xff;
OCMPActionType actionType = OCMP_AXN_TYPE_ENABLE;
LOGGER_DEBUG("POST:INFO::Enabling system for POST.");
if(OC_subSystem == OC_SS_MAX_LIMIT) {
OC_subSystem = OC_SS_PWR;
actionType = OCMP_AXN_TYPE_REPLY;
} else {
actionType = OCMP_AXN_TYPE_ENABLE;
}
OCMPMessageFrame *postExeMsg = create_ocmp_msg_frame(OC_subSystem,
OCMP_MSG_TYPE_POST,
actionType,0x00,0x00,1);
return postExeMsg;
}
/*****************************************************************************
** FUNCTION NAME : post_activate
**
** DESCRIPTION : Processes the POST Acks received from the subssystems.
**
** ARGUMENTS : Pointer to POST_AckEvt_t structure
**
** RETURN TYPE : None
**
*****************************************************************************/
static void post_activate(OCMPMessageFrame *pPOSTMsg)
{
ReturnStatus POSTAckstatus = RETURN_NOTOK;
LOGGER_DEBUG("POST:INFO:: Processing POST Ack received from the "
"Subsystem %d.\n",POST_subSystem);
System_flush();
//Do the casting for the pMsg
//POSTAckstatus = (ReturnStatus) (pPOSTMsg->message.ocmp_data);
memcpy(&POSTAckstatus, pPOSTMsg->message.ocmp_data, 1);
if ( (pPOSTMsg->message.subsystem == OC_SS_PWR)
&& (pPOSTMsg->message.action == OCMP_AXN_TYPE_ACTIVE) ){
post_process_msg(POST_subSystem);
} else {
if (pPOSTMsg->message.subsystem == POST_subSystem) {
postState = (!POSTAckstatus) & postState;
LOGGER_ERROR("POST:INFO:: POST status for 0x%x Subsystem is 0x%x"
" and OC POST status is 0x%x.\n",
POST_subSystem, POSTAckstatus, postState);
if (pPOSTMsg) {
free(pPOSTMsg);
}
}
post_move_to_next_subsystem();
post_process_msg(POST_subSystem);
}
}
/*****************************************************************************
** FUNCTION NAME : post_process_rx_msg
**
** DESCRIPTION : Processes the POST Acks received from the subssystems.
**
** ARGUMENTS : Pointer to POST_AckEvt_t structure
**
** RETURN TYPE : None
**
*****************************************************************************/
static void post_process_rx_msg(OCMPMessageFrame *pPOSTMsg)
{
LOGGER_DEBUG("POST:INFO::Processing POST messages.\n");
switch (pPOSTMsg->message.action) {
case OCMP_AXN_TYPE_ACTIVE:
case OCMP_AXN_TYPE_REPLY:
post_activate(pPOSTMsg);
bb_sys_post_complete();
break;
default:
{
LOGGER_ERROR("POST::ERROR::Unkown action type 0x%x for POST"
" message.\n", pPOSTMsg->message.action);
/*TODO: Return POST fail to BB*/
}
}
}
/*****************************************************************************
** FUNCTION NAME : post_task_init
**
** DESCRIPTION : Initializes the POST task.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
static void post_task_init(void)
{
/*Creating Semaphore for RX Message Queue*/
semPOSTMsg = Semaphore_create(0, NULL, NULL);
if (semPOSTMsg == NULL) {
LOGGER_ERROR("POST:ERROR::POST RX Semaphore creation failed.\n");
}
/*Creating RX Message Queue*/
postRxMsgQueue = Util_constructQueue(&postRxMsg);
LOGGER_DEBUG("POST:INFO::Constructing message Queue for 0x%x POST RX Messages.\n",
postRxMsgQueue);
/* Reset POST state to fail */
postState = 0;
POST_subSystem = OC_SS_PWR;
OCMPMessageFrame *postEnableMsg = create_ocmp_msg_frame(OC_SS_PWR,
OCMP_MSG_TYPE_POST,
OCMP_AXN_TYPE_ACTIVE,
0x00,
0x00,
1);
/*Ask for activate permission from BB system*/
if (postEnableMsg) {
Util_enqueueMsg(bigBrotherRxMsgQueue, semBigBrotherMsg,
(uint8_t*) postEnableMsg);
}
}
/******************************************************************************
** FUNCTION NAME : post_taskfxn
**
** DESCRIPTION : Executes POST test for Open cellular.
**
** ARGUMENTS : a0, a1 - not used
**
** RETURN TYPE : None
**
******************************************************************************/
static void post_taskfxn(UArg a0, UArg a1)
{
post_task_init();
while (true) {
if (Semaphore_pend(semPOSTMsg, BIOS_WAIT_FOREVER)) {
while (!Queue_empty(postRxMsgQueue)) {
OCMPMessageFrame *pWrite = (OCMPMessageFrame *) Util_dequeueMsg(
postRxMsgQueue);
if (pWrite) {
post_process_rx_msg(pWrite);
}
}
}
}
}
/*******************************************************************************
** FUNCTION NAME : post_createtask
**
** DESCRIPTION : Task creation function for the POST.
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*******************************************************************************/
void post_createtask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = postTaskStack;
taskParams.stackSize = POST_TASK_STACK_SIZE;
taskParams.priority = OC_POST_TASKPRIORITY;
Task_construct(&postTask, post_taskfxn, &taskParams, NULL);
}

View File

@@ -0,0 +1,227 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "inc/common/post_util.h"
#include "inc/common/post.h"
#include "inc/common/system_states.h"
#include "platform/oc-sdr/schema/schema.h"
#include "src/registry/SSRegistry.h"
extern const Component sys_schema[OC_SS_MAX_LIMIT];
extern OCSubsystem *ss_reg[SUBSYSTEM_COUNT];
POSTData PostResult[POST_RECORDS] = { { 0xFF } };
static uint8_t deviceCount = 0;
#ifdef UT_POST
/*
* TODO: Duplicating the definition of the following three functions from post.c for the UT framework
* If we include post.c in the UT framework , we are exposing a lot of OS dependent APIs like create_task ,
* util_queue etc to the Windows Cygwin environment which will create linking issues.
* This will get fixed as part of #419
*/
void post_update_POSTStatus(POSTData *pData, ePostCode status)
{
pData->status = status;
}
void post_init_POSTData(POSTData *pData,OCMPSubsystem subsystem, uint8_t devSno)
{
pData->subsystem = subsystem;
pData->devSno = devSno;
pData->i2cBus = 0xFF;
pData->devAddr = 0xFF;
pData->manId = 0xFFFF;
pData->devId = 0xFFFF;
pData->status = POST_DEV_MISSING;
}
void post_update_POSTData(POSTData *pData, uint8_t I2CBus, uint8_t devAddress, uint16_t manId, uint16_t devId)
{
pData->i2cBus = I2CBus;
pData->devAddr = devAddress;
pData->manId = manId;
pData->devId = devId;
}
#else
/* */
/*****************************************************************************
** FUNCTION NAME : _postDriver
**
** DESCRIPTION : Execute POST for a given device driver
** (performs deep copy of alert_data)
**
** ARGUMENTS : pointer to subsytem, device, alert config
** post data config and subsystem config
**
** RETURN TYPE : ePostCode
**
*****************************************************************************/
static ePostCode _postDriver(const Component *subsystem,
const Component *dev,
const AlertData *alert_data,
POSTData* postData, OCSubsystem *ss)
{
#if 0
if (!dev->driver) {
return POST_DEV_NO_DRIVER_EXIST;
}
#endif
ePostCode postcode = POST_DEV_FOUND;
if (dev->driver->fxnTable->cb_probe) {
postcode = dev->driver->fxnTable->cb_probe(dev->driver_cfg,postData);
post_update_POSTStatus(postData, postcode);
}
LOGGER_DEBUG("%s:INFO:: %s (%s) %s\n", subsystem->name,
dev->name, dev->driver->name,
(postcode == POST_DEV_FOUND) ? "found" : "not found");
if (postcode == POST_DEV_FOUND) {
if (ss->state == SS_STATE_INIT) {
if (dev->driver->fxnTable->cb_init) {
AlertData *alert_data_cp = malloc(sizeof(AlertData));
*alert_data_cp = *alert_data;
postcode = dev->driver->fxnTable->cb_init(dev->driver_cfg,
dev->factory_config,
alert_data_cp);
} else {
postcode = POST_DEV_NO_CFG_REQ;
}
post_update_POSTStatus(postData, postcode);
LOGGER_DEBUG("%s:INFO:: Configuration for %s (%s) is %s\n",
subsystem->name,
dev->name,
dev->driver->name,
(postcode == POST_DEV_CFG_DONE) ? "ok":(postcode == POST_DEV_NO_CFG_REQ) ? "not required." : "failed.");
}
}
}
/*****************************************************************************
** FUNCTION NAME : OCMP_mallocFrame
**
** DESCRIPTION : API to allocate an OCMP frame of a given data length
**
** ARGUMENTS : size of the payload of frame
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
ReturnStatus _execPost(OCMPMessageFrame *pMsg,
unsigned int subsystem_id)
{
const Component *subsystem = &sys_schema[subsystem_id];
OCSubsystem *ss = ss_reg[subsystem_id];
/* TODO: this is messy and assumes we have a pointer to the subsystem -
* we'll want to change this once the framework is more mature */
if (ss->state == SS_STATE_PWRON) {
ss->state = SS_STATE_INIT;
}
/* Iterate over each component & device within the subsystem, calling
* its post callback */
ReturnStatus status = RETURN_OK;
if((subsystem->ssHookSet)&&
(ss->state == SS_STATE_INIT)) {
if(subsystem->ssHookSet->preInitFxn) {
if (!(subsystem->ssHookSet->preInitFxn(subsystem->driver_cfg, &(ss->state)))) {
status = RETURN_NOTOK;
return status;
}
}
}
POSTData postData;
ePostCode postcode = POST_DEV_MISSING;
uint8_t devSno = 0;
const Component *comp = &subsystem->components[0];
for (uint8_t comp_id = 0; (comp && comp->name); ++comp, ++comp_id) { /* Component level (ec, ap, ch1, etc.) */
/* If we have a driver at the component level, init */
AlertData alert_data = {
.subsystem = (OCMPSubsystem)subsystem_id,
.componentId = comp_id,
.deviceId = 0,
};
if(!comp->components) {
if (comp->postDisabled == POST_DISABLED ) {
continue ;
}
devSno++;
post_init_POSTData(&postData,subsystem_id,devSno);
//TODO: If postcode is configuration failure what should beth recovery action.
if (_postDriver(subsystem, comp, &alert_data, &postData, ss) == POST_DEV_NO_DRIVER_EXIST) {
devSno--;
} else {
post_update_POSTresult(&postData);
}
} else {
const Component *dev = &comp->components[0];
for (uint8_t dev_id = 0; (dev && dev->name); ++dev, ++dev_id) { /* Device level (ts, ina, etc) */
AlertData alert_data = {
.subsystem = (OCMPSubsystem)subsystem_id,
.componentId = comp_id,
.deviceId = dev_id,
};
if(dev->postDisabled == POST_DISABLED ) {
continue;
}
devSno++;
post_init_POSTData(&postData,subsystem_id,devSno);
if(_postDriver(subsystem, dev, &alert_data, &postData, ss) == POST_DEV_NO_DRIVER_EXIST) {
devSno--;
} else {
post_update_POSTresult(&postData);
}
}
}
}
if((subsystem->ssHookSet)&&(ss->state == SS_STATE_INIT)) {
if(subsystem->ssHookSet->postInitFxn){
if (!(subsystem->ssHookSet->postInitFxn(subsystem->driver_cfg, &(ss->state)))) {
ss->state = SS_STATE_FAULTY;
}
}
}
if (ss->state == SS_STATE_INIT && status == RETURN_OK) {
ss->state = SS_STATE_CFG;
} else {
ss->state = SS_STATE_FAULTY;
}
LOGGER("%s:INFO:: Modules and sensors are %s.\n", subsystem->name,
((status == RETURN_OK) ? "initialized." : "not initialized."));
return status;
}
/* *****************************************************************************
** FUNCTION NAME : post_update_POSTresult
**
** DESCRIPTION : save post result to flash
**
** ARGUMENTS : a0, a1 - not used
**
** RETURN TYPE : None
**
******************************************************************************/
void post_update_POSTresult(POSTData *postData)
{
/* Write a device info to flash but use a dummy function for REV B boards.*/
uint8_t iter = 0;
/* Dump structure at particular location*/
if ( (postData->subsystem == OC_SS_PWR) && (postData->devSno == 1 ) ) {
deviceCount = 0;
memset(PostResult, '\0', (POST_RECORDS * sizeof(POSTData)));
} else {
deviceCount++;
}
//LOGGER_DEBUG("POST:INFO:: Updating POST results for the Subsystem %d , Device Serial offset %d , Total Number of records %d.\n",
// postData->subsystem,postData->devSno,deviceCount+1);
memcpy(&PostResult[deviceCount],postData,sizeof(POSTData));
}
#endif

View File

@@ -0,0 +1,662 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "common/inc/global/Framework.h"
#include "helpers/array.h"
#include "inc/common/bigbrother.h" /* For sending msg back via BB */
#include "inc/common/post.h"
#include "inc/common/post_util.h" /* For sending POST response */
#include "inc/common/global_header.h"
#include "inc/utils/ocmp_util.h"
#include "inc/utils/util.h"
#include "platform/oc-sdr/schema/schema.h"
#include "SSRegistry.h"
#include <ti/sysbios/BIOS.h>
#define OCMP_ACTION_TYPE_GET 1
#define OCMP_ACTION_TYPE_SET 2
#define OCMP_ACTION_TYPE_REPLY 3
#define OCMP_ACTION_TYPE_ACTIVE 4
#define OCMP_ACTION_TYPE_UPDATE 5
/* TODO: configurable directory (allow us to target different platforms) */
#define OC_TASK_STACK_SIZE 1000
#define OC_TASK_PRIORITY 2
static char OC_task_stack[SUBSYSTEM_COUNT][OC_TASK_STACK_SIZE];
extern const Component sys_schema[SUBSYSTEM_COUNT];
OCSubsystem *ss_reg[SUBSYSTEM_COUNT] = {};
static const size_t PARAM_SIZE_MAP[] = {
[TYPE_NULL] = 0,
[TYPE_INT8] = sizeof(int8_t),
[TYPE_UINT8] = sizeof(uint8_t),
[TYPE_INT16] = sizeof(int16_t),
[TYPE_UINT16] = sizeof(uint16_t),
[TYPE_INT32] = sizeof(int32_t),
[TYPE_UINT32] = sizeof(uint32_t),
[TYPE_INT64] = sizeof(int64_t),
[TYPE_UINT64] = sizeof(uint64_t),
[TYPE_STR] = 1, /* TODO: properly handle strings */
[TYPE_BOOL] = sizeof(bool),
[TYPE_ENUM] = 1, /* TODO: this really depends on enum - param_size should
iterate over definition to determine size requirement*/
};
/*****************************************************************************
** FUNCTION NAME : _subcompCount
**
** DESCRIPTION : API to calculate number of components
**
** ARGUMENTS : pointer to the component structure
**
** RETURN TYPE : int
**
*****************************************************************************/
static unsigned int _subcompCount(const Component *comp) {
unsigned int i = 0;
if (comp) {
while (comp->components[i].name) {
++i;
}
}
return i;
}
/*****************************************************************************
** FUNCTION NAME : _paramSize
**
** DESCRIPTION : API to calculate size of parameter from schema
**
** ARGUMENTS : pointer to the parameter structure
**
** RETURN TYPE : size_t
**
*****************************************************************************/
static size_t _paramSize(const Parameter *param) {
if (!param || (param->type >= ARRAY_SIZE(PARAM_SIZE_MAP))) {
return 0;
}
if (param->type == TYPE_STR) {
return param->size;
}
return PARAM_SIZE_MAP[param->type];
}
/*****************************************************************************
** FUNCTION NAME : _compIsValid
**
** DESCRIPTION : API to check if component is valid
**
** ARGUMENTS : pointer to component
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _compIsValid(const Component *comp)
{
return comp && comp->name;
}
/*****************************************************************************
** FUNCTION NAME : _paramIsValid
**
** DESCRIPTION : API to check if the parameter is valid
**
** ARGUMENTS : pointer to parameter
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _paramIsValid(const Parameter *param)
{
return param && param->name;
}
/*****************************************************************************
** FUNCTION NAME : OCMP_mallocFrame
**
** DESCRIPTION : alert handler at the SS registry level
**
** ARGUMENTS : pointer to alert_data , alert id , pointer to payload
**
** RETURN TYPE : None
**
*****************************************************************************/
void OCMP_GenerateAlert(const AlertData *alert_data,
unsigned int alert_id,
const void *data)
{
if (!alert_data) {
return;
}
const Component *subsystem = &sys_schema[alert_data->subsystem];
const Component *component = &subsystem->components[alert_data->componentId];
const Driver *driver = component->components[alert_data->deviceId].driver;
const Parameter *param = &driver->alerts[alert_id];
/* Count all previous parameters before this component */
unsigned int param_sum = 0;
for (int i = 0; i < alert_data->deviceId; ++i) {
const Parameter *param = &component->components[i].driver->alerts[0];
for (; _paramIsValid(param); ++param) {
param_sum += 1;
}
}
uint16_t parameters = 0x01 << (param_sum + alert_id);
/* Align to 4 byte boundary (bug in host) */
size_t param_size = (_paramSize(param) + 3) & ~0x03;
OCMPMessageFrame *pMsg = create_ocmp_msg_frame(alert_data->subsystem,
OCMP_MSG_TYPE_ALERT,
OCMP_AXN_TYPE_ACTIVE,
alert_data->componentId + 1, /* TODO: inconsistency indexing in host */
parameters,
param_size);
if (pMsg) {
memcpy(pMsg->message.ocmp_data, data, _paramSize(param));
Util_enqueueMsg(bigBrotherTxMsgQueue, semBigBrotherMsg,
(uint8_t*) pMsg);
} else {
LOGGER_ERROR("ERROR::Unable to allocate alert packet\n");
}
}
/*****************************************************************************
** FUNCTION NAME : _handleMsgTypeCmd
**
** DESCRIPTION : handle all messages with command msgtype
**
** ARGUMENTS : pointer to message, pointer to compoenet
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handleMsgTypeCmd(OCMPMessageFrame *pMsg, const Component *comp)
{
const Command *cmd;
Component *dev;
if (comp) {
if (pMsg->message.parameters > 0) {
dev = &comp->components[(pMsg->message.parameters)-1];
} else {
dev = comp;
}
if (dev->driver && dev->driver->commands) {
cmd = &dev->driver->commands[pMsg->message.action];
} else {
cmd = &dev->commands[pMsg->message.action];
}
if (cmd && cmd->cb_cmd) {
cmd->cb_cmd(dev->driver_cfg, pMsg->message.ocmp_data);
return true;
}
}
return false;
}
/*****************************************************************************
** FUNCTION NAME : OCMP_mallocFrame
**
** DESCRIPTION : handle message of config msgtype with set/get
** actiontype
**
** ARGUMENTS : pointer to message , pointer to component, pointer to
** parameter id , double pointer to the message payload
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handle_cmd_get(OCMPMessageFrame *pMsg, const Component *comp,
unsigned int param_id, void *buf_ptr)
{
switch (pMsg->message.msgtype) {
case OCMP_MSG_TYPE_CONFIG:
return (comp->driver->fxnTable->cb_get_config &&
comp->driver->fxnTable->cb_get_config(comp->driver_cfg, param_id,
buf_ptr));
case OCMP_MSG_TYPE_STATUS:
return (comp->driver->fxnTable->cb_get_status &&
comp->driver->fxnTable->cb_get_status(comp->driver_cfg, param_id,
buf_ptr));
default:
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _handle_cmd_set
**
** DESCRIPTION : handle message of config msgtype with set actiontype
**
** ARGUMENTS : pointer to message , pointer to component , pointer to
** parameter id , pointer to the message payload
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
static bool _handle_cmd_set(OCMPMessageFrame *pMsg, const Component *comp,
unsigned int param_id, const void *data)
{
switch (pMsg->message.msgtype) {
case OCMP_MSG_TYPE_CONFIG:
return (comp->driver->fxnTable->cb_set_config &&
comp->driver->fxnTable->cb_set_config(comp->driver_cfg, param_id,
data));
default:
return false;
}
}
/*****************************************************************************
** FUNCTION NAME : _handleDevStatCfg
**
** DESCRIPTION : handle status and config msgtype messages
**
** ARGUMENTS : pointer to message , pointer to device, pointer to
** parameter id , double pointer to the message payload
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
static bool _handleDevStatCfg(OCMPMessageFrame *pMsg, const Component *dev,
unsigned int *param_id, uint8_t **buf_ptr)
{
if (!dev->driver) {
return false;
}
const Parameter *param_list = NULL;
switch (pMsg->message.msgtype) {
case OCMP_MSG_TYPE_CONFIG:
param_list = dev->driver->config;
break;
case OCMP_MSG_TYPE_STATUS:
param_list = dev->driver->status;
break;
default:
return false;
}
if (!param_list) {
return false;
}
bool dev_handled = false;
unsigned int normalized_id = 0;
while (param_list[normalized_id].name) {
if (pMsg->message.parameters & (1 << *param_id)) {
switch (pMsg->message.action) {
case OCMP_ACTION_TYPE_GET:
if (_handle_cmd_get(pMsg, dev, normalized_id,
*buf_ptr)) {
dev_handled = true;
} else {
pMsg->message.parameters &= ~(1 << *param_id);
}
break;
case OCMP_ACTION_TYPE_SET:
if (_handle_cmd_set(pMsg, dev, normalized_id,
*buf_ptr)) {
dev_handled = true;
} else {
pMsg->message.parameters &= ~(1 << *param_id);
}
break;
default:
pMsg->message.parameters &= ~(1 << *param_id);
break;
}
}
if (!dev->driver->payload_fmt_union) {
*buf_ptr += _paramSize(&param_list[normalized_id]);
}
(*param_id)++;
normalized_id++;
}
return dev_handled;
}
/*****************************************************************************
** FUNCTION NAME : _handle_post_enable
**
** DESCRIPTION : handle post messages with enable action type
**
** ARGUMENTS : pointer to message, subsystem id
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handle_post_enable(const Component *comp, OCMPMessageFrame *pMsg)
{
bool ret = false;
OCMPMessageFrame *buffer;
const Post *postCmd = &comp->driver->post[(pMsg->message.action)-1];
if (postCmd && postCmd->cb_postCmd) {
ret = postCmd->cb_postCmd(&buffer);
if (ret) {
Util_enqueueMsg(postRxMsgQueue, semPOSTMsg, (uint8_t*)buffer);
}
}
pMsg->message.ocmp_data[0] = !(ret); //RETURN_OK =0;
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _handle_post_active
**
** DESCRIPTION : handle post message with active action type
**
** ARGUMENTS : pointer to message, subsystem id
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handle_post_active(OCMPMessageFrame *pMsg,unsigned int subsystem_id)
{
ReturnStatus status = _execPost(pMsg, subsystem_id);
return (status == RETURN_OK);
}
/*****************************************************************************
** FUNCTION NAME : _handle_post_get_results
**
** DESCRIPTION : handles messages with get result actiontype for post
**
** ARGUMENTS : pointer to component , pointer to message
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handle_post_get_results(const Component *comp,OCMPMessageFrame *pMsg)
{
bool ret = false;
const Post *postCmd = &comp->driver->post[(pMsg->message.action)-1];
if (postCmd && postCmd->cb_postCmd) {
postCmd->cb_postCmd(pMsg);
ret = true;
}
return ret;
}
/*****************************************************************************
** FUNCTION NAME : _handleMsgTypePOST
**
** DESCRIPTION : handles all messages with post msgtype
**
** ARGUMENTS : pointer to message, pointer to comp, subsytem id
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handleMsgTypePOST(OCMPMessageFrame *pMsg, const Component *comp, unsigned int subsystem_id)
{
/* Determine driver & parameter */
unsigned int param_id = 0;
uint8_t *buf_ptr = pMsg->message.ocmp_data;
bool dev_handled = false;
switch (pMsg->message.action) {
case OCMP_ACTION_TYPE_SET:
if (_handle_post_enable(comp, pMsg)) {
dev_handled = true;
}
break;
case OCMP_ACTION_TYPE_ACTIVE:
if (_handle_post_active(pMsg,subsystem_id)) {
dev_handled = true;
}
break;
case OCMP_ACTION_TYPE_GET:
if (_handle_post_get_results(comp, pMsg)) {
dev_handled = true;
}
break;
/* case OCMP_ACTION_REPLY:
if (_handle_post_reply(pMsg, *buf_ptr)) {
dev_handled = true;
}
break;*/
default:
break;
}
return dev_handled;
}
/*****************************************************************************
** FUNCTION NAME : _handleMsgTypeStatCfg
**
** DESCRIPTION : handles status and config msg type
**
** ARGUMENTS : pointer to the msg and pointer to the comp
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool _handleMsgTypeStatCfg(OCMPMessageFrame *pMsg, const Component *comp)
{
/* Determine driver & parameter */
unsigned int param_id = 0;
uint8_t *buf_ptr = pMsg->message.ocmp_data;
bool dev_handled = false;
/* Handle component-level driver */
if (_handleDevStatCfg(pMsg, comp, &param_id, &buf_ptr)) {
dev_handled = true;
}
/* Handle sub-components (devices) */
const Component *dev = &comp->components[0];
for (; _compIsValid(dev); ++dev) {
if (_handleDevStatCfg(pMsg, dev, &param_id, &buf_ptr)) {
dev_handled = true;
}
}
return dev_handled;
}
/*****************************************************************************
** FUNCTION NAME : ocmp_route
**
** DESCRIPTION : Routing function which calls the required ocmp layer
**
** ARGUMENTS : pointer to the message frame, subsytem id
**
** RETURN TYPE : true or false
**
*****************************************************************************/
static bool ocmp_route(OCMPMessageFrame *pMsg, unsigned int subsystem_id)
{
const Component *subsystem = &sys_schema[subsystem_id];
/* Validate component ID */
if (pMsg->message.componentID > _subcompCount(subsystem)) {
LOGGER_ERROR("Component %d out of bounds\n", pMsg->message.componentID);
return false;
}
const Component *comp = &subsystem->components[(pMsg->message.componentID)-1];
/* TODO: clean up special handling for commands */
bool dev_handled = false;
switch (pMsg->message.msgtype) {
case OCMP_MSG_TYPE_COMMAND:
dev_handled = _handleMsgTypeCmd(pMsg, comp);
break;
case OCMP_MSG_TYPE_CONFIG:
case OCMP_MSG_TYPE_STATUS:
dev_handled = _handleMsgTypeStatCfg(pMsg, comp);
break;
case OCMP_MSG_TYPE_POST:
dev_handled = _handleMsgTypePOST(pMsg, comp, subsystem_id);
//pMsg->message.action = OCMP_ACTION_TYPE_REPLY;
//Util_enqueueMsg(postRxMsgQueue, semPOSTMsg, (uint8_t*) pMsg);
break;
default:
break;
}
/* If we couldn't handle this message, return error */
if (!dev_handled) {
pMsg->message.parameters = 0x00;
}
/* The main exception to the flow right now is POST - check for it first */
if ((pMsg->message.msgtype == OCMP_MSG_TYPE_POST) && (pMsg->message.action == OCMP_ACTION_TYPE_ACTIVE)) {
pMsg->message.action = OCMP_ACTION_TYPE_REPLY;
Util_enqueueMsg(postRxMsgQueue, semPOSTMsg, (uint8_t*) pMsg);
} else if ((pMsg->message.msgtype == OCMP_MSG_TYPE_POST) &&
(pMsg->message.action == OCMP_ACTION_TYPE_UPDATE)) {
Util_enqueueMsg(bigBrotherTxMsgQueue, semBigBrotherMsg, (uint8_t *)pMsg);
} else {
/* Send reply to the middleware */
pMsg->message.action = OCMP_ACTION_TYPE_REPLY;
Util_enqueueMsg(bigBrotherTxMsgQueue, semBigBrotherMsg, (uint8_t *)pMsg);
}
return true;
}
/*****************************************************************************
** FUNCTION NAME : _subsystem_event_loop
**
** DESCRIPTION : subsytem module which is waits for message triger
** from SSRegistry task
**
** ARGUMENTS : OCSubsystem, subsytem id
**
** RETURN TYPE : None
**
*****************************************************************************/
static void _subsystem_event_loop(UArg a0, UArg a1)
{
OCSubsystem *ss = (OCSubsystem *)a0;
if (!ss) {
return;
}
while (1) {
if (Semaphore_pend(ss->sem, BIOS_WAIT_FOREVER)) {
while (!Queue_empty(ss->msgQueue)) {
OCMPMessageFrame *pMsg =
(OCMPMessageFrame *) Util_dequeueMsg(ss->msgQueue);
if (pMsg) {
/* Attempt to route the message to the correct driver
(if successful, no need to clean up message here) */
if (!ocmp_route(pMsg, a1)) {
LOGGER_ERROR("ERROR:: Unable to route OCMP message\n");
free(pMsg);
}
}
}
}
}
}
/*****************************************************************************
** FUNCTION NAME : subsystem_init
**
** DESCRIPTION : API to initialise ss_reg and create subsytem tasks
**
** ARGUMENTS : subsytem id
**
** RETURN TYPE : None
**
*****************************************************************************/
static void subsystem_init(OCMPSubsystem ss_id) {
OCSubsystem *ss = (OCSubsystem*)malloc(sizeof(OCSubsystem));
if (!ss) {
return;
}
ss_reg[ss_id] = ss;
ss->state = SS_STATE_PWRON;
/* Create Semaphore for RX Message Queue */
Semaphore_construct(&ss->semStruct, 0, NULL);
ss->sem = Semaphore_handle(&ss->semStruct);
if (!ss->sem) {
LOGGER_DEBUG("SS REG:ERROR:: Failed in Creating RX Semaphore for "
"subsystem %d\n", ss_id);
}
/* Create Message Queue for RX Messages */
ss->msgQueue = Util_constructQueue(&ss->queueStruct);
if (!ss->msgQueue) {
LOGGER_ERROR("SS REG:ERROR:: Failed in Constructing Message Queue for "
"RX Message for subsystem %d\n", ss_id);
}
/* Spin up the task */
Task_Params taskParams;
Task_Params_init(&taskParams);
taskParams.stack = OC_task_stack[ss_id];// ss->taskStack;
taskParams.stackSize = OC_TASK_STACK_SIZE;//ss->taskStackSize;
taskParams.priority = OC_TASK_PRIORITY;//ss->taskPriority;
taskParams.arg0 = (UArg)ss;
taskParams.arg1 = ss_id;
Task_construct(&ss->taskStruct, _subsystem_event_loop, &taskParams, NULL);
LOGGER_DEBUG("SS REG:DEBUG:: Creating Task for Subsystem %d\n", ss_id);
}
/*****************************************************************************
** FUNCTION NAME : SSRegistry_init
**
** DESCRIPTION : initialise the ss_reg sturcture during system init
**
** ARGUMENTS : None
**
** RETURN TYPE : None
**
*****************************************************************************/
void SSRegistry_init(void) {
for (OCMPSubsystem i = (OCMPSubsystem)0; i < SUBSYSTEM_COUNT; ++i) {
subsystem_init(i);
}
}
/*****************************************************************************
** FUNCTION NAME : SSRegistry_Get
**
** DESCRIPTION : API to return the ss registry entry given the
** subsytem id
**
** ARGUMENTS : subsystem id
**
** RETURN TYPE : OCSubsystem*
**
*****************************************************************************/
OCSubsystem* SSRegistry_Get(OCMPSubsystem ss_id) {
if (ss_id >= SUBSYSTEM_COUNT) {
return NULL;
}
return ss_reg[ss_id];
}
/*****************************************************************************
** FUNCTION NAME : SSRegistry_sendMessage
**
** DESCRIPTION : API to send message to the desired susbsytem
**
** ARGUMENTS : subsytem id , pointer to the msg to be sent
**
** RETURN TYPE : TRUE or FALSE
**
*****************************************************************************/
bool SSRegistry_sendMessage(OCMPSubsystem ss_id, void *pMsg) {
OCSubsystem *ss = SSRegistry_Get(ss_id);
if (!ss) {
return false;
}
return Util_enqueueMsg(ss->msgQueue, ss->sem, (uint8_t*) pMsg);
}

View File

@@ -0,0 +1,60 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef _SSREGISTRY_H_
#define _SSREGISTRY_H_
#include "common/inc/global/ocmp_frame.h"
#include "inc/common/system_states.h"
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>
#include <stdbool.h>
typedef void (*SS_ProcessMsg_Cb)(OCMPMessageFrame *pBmsMsg);
/**
* Common subsystem attributes (message queue, task entry point, etc.)
*/
typedef struct OCSubsystem {
/* Message queue handles */
Queue_Handle msgQueue;
Semaphore_Handle sem;
/* Private variables (reduce dynamic allocation needs) */
Queue_Struct queueStruct;
Semaphore_Struct semStruct;
Task_Struct taskStruct;
eSubSystemStates state;
} OCSubsystem;
/**
* Initializes the subsystem registry by creating message queues
* and spawning the tasks for each subsystem
*/
void SSRegistry_init(void);
/**
* Retrieves the pointer to the #OCSubsystem struct associated with a given ID
* @param ss_id The ID of the requested subsystem
* @return #OCSubsystem pointer if valid ID, else NULL
*/
OCSubsystem* SSRegistry_Get(OCMPSubsystem ss_id);
/**
* Enters a message into the desired subsystem's message queue
* @note This is mostly for legacy support for the alerts manager
* @param ss_id ID of the subsystem to send the message to
* @param pMsg Message pointer to be inserted into the subsystem's queue
* @return true if successful, false if subsystem not found or queue full
*/
bool SSRegistry_sendMessage(OCMPSubsystem ss_id, void *pMsg);
#endif /* _SSREGISTRY_H_ */

View File

@@ -0,0 +1,100 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//*****************************************************************************
// HEADER FILES
/* Board Header files */
#include "common/inc/global/Framework.h"
#include "inc/subsystem/power/power.h"
#include "inc/common/post.h"
#define SUBSYTEM_CHECK (PostResult[iter].subsystem <= getpostResultMsg->message.ocmp_data[0])
extern POSTData PostResult[POST_RECORDS];
/*****************************************************************************
** FUNCTION NAME : psuCore_pre_init
**
** DESCRIPTION : Get POST results from EEPROM.
**
** ARGUMENTS : None
**
** RETURN TYPE : bool
**
*****************************************************************************/
bool psuCore_pre_init(void *driver, void *returnValue)
{
//Configuring GPIOS
PWRSRC_Dev *gpioCfg = (PWRSRC_Dev *)driver;
OcGpio_configure(&gpioCfg->cfg.pin_dc_present, OCGPIO_CFG_INPUT);
OcGpio_configure(&gpioCfg->cfg.pin_poe_prsnt_n, OCGPIO_CFG_INPUT);
OcGpio_configure(&gpioCfg->cfg.pin_int_bat_prsnt, OCGPIO_CFG_INPUT);
OcGpio_configure(&gpioCfg->cfg.pin_disable_dc_input, OCGPIO_CFG_OUTPUT);
OcGpio_configure(&gpioCfg->cfg.pin_dc_input_fault, OCGPIO_CFG_INPUT);
OcGpio_configure(&gpioCfg->cfg.pin_oc_input_present, OCGPIO_CFG_INPUT);
OcGpio_configure(&gpioCfg->cfg.pin_power_off, OCGPIO_CFG_OUTPUT);
OcGpio_write(&gpioCfg->cfg.pin_disable_dc_input, false);
OcGpio_write(&gpioCfg->cfg.pin_power_off, false);
return true;
}
/*****************************************************************************
** FUNCTION NAME : PWR_post_get_results
**
** DESCRIPTION : Get POST results from EEPROM.
**
** ARGUMENTS : None
**
** RETURN TYPE : bool
**
*****************************************************************************/
bool PWR_post_get_results(void **getpostResult)
{
ReturnStatus status = RETURN_OK;
/* Return the POST results*/
uint8_t iter = 0x00;
uint8_t index = 0x00;
OCMPMessageFrame *getpostResultMsg = (OCMPMessageFrame *)getpostResult;
/* Get the subsystem info for which message is required */
OCMPMessageFrame *postResultMsg = create_ocmp_msg_frame(
getpostResultMsg->message.subsystem, OCMP_MSG_TYPE_POST,
0x05,0x00,0x00,40);
if (postResultMsg) {
/* Getting data assigned*/
postResultMsg->header.ocmpSof = getpostResultMsg->header.ocmpSof;
postResultMsg->header.ocmpInterface = getpostResultMsg->header
.ocmpInterface;
postResultMsg->header.ocmpSeqNumber = getpostResultMsg->header
.ocmpSeqNumber;
for (iter = 0; SUBSYTEM_CHECK; iter++) {
if (PostResult[iter].subsystem
== getpostResultMsg->message.ocmp_data[0]) {
postResultMsg->message.ocmp_data[(3 * index) + 0] =
PostResult[iter].subsystem;
postResultMsg->message.ocmp_data[(3 * index) + 1] =
PostResult[iter].devSno; //Device serial Number
postResultMsg->message.ocmp_data[(3 * index) + 2] =
PostResult[iter].status; //Status ok
index++;
}
}
LOGGER_DEBUG("POWER:INFO::POST message sent for subsystem 0x%x.\n");
/*Size of payload*/
postResultMsg->header.ocmpFrameLen = index * 3;
/*Updating Subsystem*/
//postResultMsg->message.subsystem = (OCMPSubsystem)PostResult[iter].subsystem;
/* Number of devices found under subsystem*/
postResultMsg->message.parameters = index;
index = 0;
} else {
LOGGER("POWER:ERROR:: Failed to allocate memory for POST results.\n");
}
memcpy(((OCMPMessageFrame*)getpostResult), postResultMsg, 64);
return status;
}

View File

@@ -0,0 +1,115 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/*****************************************************************************
* HEADER FILES
*****************************************************************************/
#include "inc/utils/ocmp_util.h"
/*****************************************************************************
** FUNCTION NAME : OCMP_mallocFrame
**
** DESCRIPTION : API to allocate an OCMP frame of a given data length
**
** ARGUMENTS : size of the payload of frame
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame * OCMP_mallocFrame(uint16_t len)
{
OCMPMessageFrame *pMsg;
// Allocate memory for NPI Frame
pMsg = (OCMPMessageFrame *)malloc(sizeof(OCMPMessageFrame)+len);
if (pMsg != NULL) {
// Assign Data Length of Frame
pMsg->header.ocmpFrameLen = len;
// Assign pData to first byte of payload
// Pointer arithmetic of + 1 is equal to sizeof(OCMPMessageFrame) bytes
// then cast to unsigned char * for pData
//pMsg->message.ocmp_data = (unsigned char *)(pMsg + 1);
//pMsg->message.ocmp_data = (unsigned char *)(pMsg + 2);
}
return pMsg;
}
/*****************************************************************************
** FUNCTION NAME : create_ocmp_msg_frame
**
** DESCRIPTION : Create a OCMP message.
**
** ARGUMENTS : OCMPSubsystem subSystem,
** OCMPMsgType msgtype,
** OCMPActionType actionType,
** ComponentId,
** ParemeterID,
** Payload size
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame* create_ocmp_msg_frame(OCMPSubsystem subSystem,
OCMPMsgType msgtype,
OCMPActionType actionType,
uint8_t componentId,
uint16_t parameters,
uint8_t payloadSize)
{
OCMPMessageFrame *ocmp_msg = (OCMPMessageFrame *) OCMP_mallocFrame(
payloadSize);
if (ocmp_msg) {
*ocmp_msg = (OCMPMessageFrame){
.header = {
.ocmpSof = OCMP_MSG_SOF,
.ocmpInterface = OCMP_COMM_IFACE_UART,
.ocmpFrameLen = payloadSize,
//.ocmp_seqNumber = 0x00;
//.ocmp_timestamp = 0x00; //Get RTC TimeStamp
},
.message = {
.subsystem = subSystem,
.componentID = componentId,
.parameters = parameters,
.msgtype = msgtype,
.action = actionType,
}
};
memset(&(ocmp_msg->message.ocmp_data[0]),0x00,payloadSize);
}
return ocmp_msg;
}
/*****************************************************************************
** FUNCTION NAME : create_ocmp_alert_from_Evt
**
** DESCRIPTION : Create the OCMP Alert frame from the Event message.
**
** ARGUMENTS : OCMPMessageFrame to be used to create Alert,
** ComponentId,
** ParemeterID
**
** RETURN TYPE : OCMPMessageFrame
**
*****************************************************************************/
OCMPMessageFrame* create_ocmp_alert_from_Evt(OCMPMessageFrame* ocmpEventMsg,
uint8_t componentId,
uint16_t parameters )
{
OCMPMessageFrame *ocmpAlertMsg =
(OCMPMessageFrame *) OCMP_mallocFrame(1);
if (ocmpAlertMsg != NULL) {
memset(ocmpAlertMsg, 0x00, (sizeof(OCMPMessageFrame)));
memcpy(ocmpAlertMsg, ocmpEventMsg,
(sizeof(OCMPMessageFrame)) + 1);
ocmpAlertMsg->message.msgtype = OCMP_MSG_TYPE_ALERT;
ocmpAlertMsg->message.componentID = componentId;
ocmpAlertMsg->message.parameters = parameters;
}
return ocmpAlertMsg;
}

View File

@@ -0,0 +1,329 @@
/*******************************************************************************
Filename: util.c
Revised: $Date: 2015-06-02 11:18:40 -0700 (Tue, 02 Jun 2015) $
Revision: $Revision: 43957 $
Description: This file contains utility functions.
Copyright 2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED <20>AS IS<49> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "inc/utils/util.h"
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
#include <stdbool.h>
#include <stdlib.h>
/*********************************************************************
* TYPEDEFS
*/
// RTOS queue for profile/app messages.
typedef struct _queueRec_
{
Queue_Elem _elem; // queue element
uint8_t *pData; // pointer to app data
} queueRec_t;
/*********************************************************************
* LOCAL FUNCTIONS
*/
/*******************************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* LOCAL VARIABLES
*/
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Util_constructClock
*
* @brief Initialize a TIRTOS Clock instance.
*
* @param pClock - pointer to clock instance structure.
* @param clockCB - callback function upon clock expiration.
* @param clockDuration - longevity of clock timer in milliseconds
* @param clockPeriod - if set to a value other than 0, the first
* expiry is determined by clockDuration. All
* subsequent expiries use the clockPeriod value.
* @param startFlag - TRUE to start immediately, FALSE to wait.
* @param arg - argument passed to callback function.
*
* @return Clock_Handle - a handle to the clock instance.
*/
Clock_Handle Util_constructClock(Clock_Struct *pClock,
Clock_FuncPtr clockCB,
uint32_t clockDuration,
uint32_t clockPeriod,
uint8_t startFlag,
UArg arg)
{
Clock_Params clockParams;
// Convert clockDuration in milliseconds to ticks.
uint32_t clockTicks = clockDuration * (1000 / Clock_tickPeriod);
// Setup parameters.
Clock_Params_init(&clockParams);
// Setup argument.
clockParams.arg = arg;
// If period is 0, this is a one-shot timer.
clockParams.period = clockPeriod * (1000 / Clock_tickPeriod);
// Starts immediately after construction if true, otherwise wait for a call
// to start.
clockParams.startFlag = startFlag;
// Initialize clock instance.
Clock_construct(pClock, clockCB, clockTicks, &clockParams);
return Clock_handle(pClock);
}
/*********************************************************************
* @fn Util_startClock
*
* @brief Start a clock.
*
* @param pClock - pointer to clock struct
*
* @return none
*/
void Util_startClock(Clock_Struct *pClock)
{
Clock_Handle handle = Clock_handle(pClock);
// Start clock instance
Clock_start(handle);
}
/*********************************************************************
* @fn Util_restartClock
*
* @brief Restart a clock by changing the timeout.
*
* @param pClock - pointer to clock struct
* @param clockTimeout - longevity of clock timer in milliseconds
*
* @return none
*/
void Util_restartClock(Clock_Struct *pClock, uint32_t clockTimeout)
{
uint32_t clockTicks;
Clock_Handle handle;
handle = Clock_handle(pClock);
if (Clock_isActive(handle))
{
// Stop clock first
Clock_stop(handle);
}
// Convert timeout in milliseconds to ticks.
clockTicks = clockTimeout * (1000 / Clock_tickPeriod);
// Set the initial timeout
Clock_setTimeout(handle, clockTicks);
// Start clock instance
Clock_start(handle);
}
/*********************************************************************
* @fn Util_isActive
*
* @brief Determine if a clock is currently active.
*
* @param pClock - pointer to clock struct
*
* @return TRUE or FALSE
*/
bool Util_isActive(Clock_Struct *pClock)
{
Clock_Handle handle = Clock_handle(pClock);
// Start clock instance
return Clock_isActive(handle);
}
/*********************************************************************
* @fn Util_stopClock
*
* @brief Stop a clock.
*
* @param pClock - pointer to clock struct
*
* @return none
*/
void Util_stopClock(Clock_Struct *pClock)
{
Clock_Handle handle = Clock_handle(pClock);
// Stop clock instance
Clock_stop(handle);
}
/*********************************************************************
* @fn Util_rescheduleClock
*
* @brief Reschedule a clock by changing the timeout and period values.
*
* @param pClock - pointer to clock struct
* @param clockPeriod - longevity of clock timer in milliseconds
* @return none
*/
void Util_rescheduleClock(Clock_Struct *pClock, uint32_t clockPeriod)
{
bool running;
uint32_t clockTicks;
Clock_Handle handle;
handle = Clock_handle(pClock);
running = Clock_isActive(handle);
if (running)
{
Clock_stop(handle);
}
// Convert period in milliseconds to ticks.
clockTicks = clockPeriod * (1000 / Clock_tickPeriod);
Clock_setTimeout(handle, clockTicks);
Clock_setPeriod(handle, clockTicks);
if (running)
{
Clock_start(handle);
}
}
/*********************************************************************
* @fn Util_constructQueue
*
* @brief Initialize an RTOS queue to hold messages to be processed.
*
* @param pQueue - pointer to queue instance structure.
*
* @return A queue handle.
*/
Queue_Handle Util_constructQueue(Queue_Struct *pQueue)
{
// Construct a Queue instance.
Queue_construct(pQueue, NULL);
return Queue_handle(pQueue);
}
/*********************************************************************
* @fn Util_enqueueMsg
*
* @brief Creates a queue node and puts the node in RTOS queue.
*
* @param msgQueue - queue handle.
* @param sem - thread's event processing semaphore that queue is
* associated with.
* @param pMsg - pointer to message to be queued
*
* @return TRUE if message was queued, FALSE otherwise.
*/
uint8_t Util_enqueueMsg(Queue_Handle msgQueue, Semaphore_Handle sem,
uint8_t *pMsg)
{
queueRec_t *pRec;
// Allocated space for queue node.
if (pRec = (queueRec_t *)malloc(sizeof(queueRec_t)))
{
pRec->pData = pMsg;
Queue_enqueue(msgQueue, &pRec->_elem);
// Wake up the application thread event handler.
if (sem)
{
Semaphore_post(sem);
}
return TRUE;
}
// Free the message.
free(pMsg);
return FALSE;
}
/*********************************************************************
* @fn Util_dequeueMsg
*
* @brief Dequeues the message from the RTOS queue.
*
* @param msgQueue - queue handle.
*
* @return pointer to dequeued message, NULL otherwise.
*/
uint8_t *Util_dequeueMsg(Queue_Handle msgQueue)
{
if (!Queue_empty(msgQueue))
{
queueRec_t *pRec = Queue_dequeue(msgQueue);
uint8_t *pData = pRec->pData;
// Free the queue node
// Note: this does not free space allocated by data within the node.
free(pRec);
return pData;
}
return NULL;
}

View File

@@ -0,0 +1,45 @@
/******************************************************************************
*
* Default Linker Command file for the Texas Instruments TM4C1230E6PM
*
* This is derived from revision 15071 of the TivaWare Library.
*
*****************************************************************************/
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00020000
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M4_T_le_eabi.lib */
/* Section allocation in memory */
SECTIONS
{
.intvecs: > 0x00000000
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > 0x20000000
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
__STACK_TOP = __stack + 512;

1
firmware/src/.exclude Normal file
View File

@@ -0,0 +1 @@
This file exists to prevent Eclipse/CDT from adding the C sources contained in this directory (or below) to any enclosing project.

Some files were not shown because too many files have changed in this diff Show More