From faa5fb552835ed4960336e835f686f6d33f41b3c Mon Sep 17 00:00:00 2001 From: Manoj Koppolu Date: Wed, 13 Dec 2023 14:32:04 +0530 Subject: [PATCH] am243x/am64x: pruicss_pwm: add pruicss pwm sync eg -add pruicss pwm sync api calls -add pruicss pwm sync example -add pruicss pwm sync documentation -update rov files Fixes: PINDSW-7096 Signed-off-by: Manoj Koppolu --- .metadata/.tirex/am243x.content.tirex.json | 32 ++ .project/device/project_am243x.js | 2 +- .project/device/project_am64x.js | 3 - .../docs/api_guide/device/am243x/examples.cfg | 3 +- .../docs/api_guide/device/am64x/examples.cfg | 2 +- docs_src/docs/api_guide/examples/examples.md | 1 + ...ruicss_pwm.md => pruicss_pwm_dutycycle.md} | 11 +- .../examples/pruicss_pwm_epwm_sync.md | 62 ++++ ...soc_epwm_pruicss_pwm_sync_probe_output.png | Bin 0 -> 74880 bytes .../ti-arm-clang/syscfg_c.rov.xs | 2 +- .../ti-arm-clang/syscfg_c.rov.xs | 2 +- .../pruicss_pwm_epwm_sync/.project/project.js | 14 + .../.project/project_am243x.js | 121 +++++++ .../r5fss0-0_freertos/example.syscfg | 76 +++++ .../am243x-lp/r5fss0-0_freertos/main.c | 84 +++++ .../r5fss0-0_freertos/pruicss_pwm_epwm_sync.c | 257 +++++++++++++++ .../ti-arm-clang/example.projectspec | 115 +++++++ .../r5fss0-0_freertos/ti-arm-clang/linker.cmd | 148 +++++++++ .../r5fss0-0_freertos/ti-arm-clang/makefile | 309 ++++++++++++++++++ .../ti-arm-clang/makefile_ccs_bootimage_gen | 106 ++++++ .../ti-arm-clang/makefile_projectspec | 20 ++ .../ti-arm-clang/syscfg_c.rov.xs | 8 + makefile.am243x | 13 + makefile_projectspec.am243x | 13 + source/pruicss_pwm/driver/pruicss_pwm.c | 55 ++++ source/pruicss_pwm/include/pruicss_pwm.h | 22 ++ 26 files changed, 1469 insertions(+), 12 deletions(-) rename docs_src/docs/api_guide/examples/{pruicss_pwm.md => pruicss_pwm_dutycycle.md} (91%) create mode 100644 docs_src/docs/api_guide/examples/pruicss_pwm_epwm_sync.md create mode 100644 docs_src/docs/api_guide/images/pruicss_pwm/am243x_lp_soc_epwm_pruicss_pwm_sync_probe_output.png create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/.project/project.js create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/.project/project_am243x.js create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/example.syscfg create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/main.c create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/pruicss_pwm_epwm_sync.c create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/linker.cmd create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec create mode 100644 examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs diff --git a/.metadata/.tirex/am243x.content.tirex.json b/.metadata/.tirex/am243x.content.tirex.json index 7ab74a1..eff71d4 100644 --- a/.metadata/.tirex/am243x.content.tirex.json +++ b/.metadata/.tirex/am243x.content.tirex.json @@ -876,6 +876,38 @@ ] ] }, + { + "resourceType": "project.ccs", + "resourceClass": [ + "example" + ], + "resourceSubClass": [ + "example.general" + ], + "description": "A Pruicss Pwm Epwm Sync Example. CPU is R5FSS0-0 running FREERTOS.", + "name": "pruicss_pwm_epwm_sync", + "location": "../../examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec", + "devtools": [ + "AM243x_LAUNCHPAD" + ], + "kernel": [ + "freertos" + ], + "compiler": [ + "ticlang" + ], + "subCategories": [ + "pruicss_pwm", + "pruicss_pwm_epwm_sync", + "r5fss0-0_freertos" + ], + "mainCategories": [ + [ + "Examples", + "Development Tools" + ] + ] + }, { "resourceType": "web.page", "resourceClass": [ diff --git a/.project/device/project_am243x.js b/.project/device/project_am243x.js index 311d604..6a894e7 100644 --- a/.project/device/project_am243x.js +++ b/.project/device/project_am243x.js @@ -30,8 +30,8 @@ const example_file_list = [ "examples/position_sense/bissc_diagnostic/multi_channel_single_pru/.project/project.js", "examples/current_sense/icss_sdfm/.project/project.js", "examples/current_sense/icss_sdfm_three_channel_with_phase_compensation/.project/project.js", - "examples/pruicss_pwm/.project/project.js", "examples/pruicss_pwm/pruicss_pwm_duty_cycle/.project/project.js", + "examples/pruicss_pwm/pruicss_pwm_epwm_sync/.project/project.js", "source/current_sense/sdfm/firmware/.project/project.js", "source/position_sense/endat/firmware/multi_channel_load_share/.project/project.js", "source/position_sense/endat/firmware/single_channel/.project/project.js", diff --git a/.project/device/project_am64x.js b/.project/device/project_am64x.js index 9c091f2..39d8ac4 100644 --- a/.project/device/project_am64x.js +++ b/.project/device/project_am64x.js @@ -22,9 +22,6 @@ const example_file_list = [ "examples/position_sense/hdsl_diagnostic/single_channel/.project/project.js", "examples/position_sense/tamagawa_diagnostic/multi_channel/.project/project.js", "examples/position_sense/tamagawa_diagnostic/single_channel/.project/project.js", - "examples/pruicss_pwm/.project/project.js", - "examples/position_sense/tamagawa_diagnostic/single_channel/.project/project.js", - "examples/current_sense/icss_sdfm/.project/project.js", "examples/pruicss_pwm/pruicss_pwm_duty_cycle/.project/project.js", "source/current_sense/sdfm/firmware/.project/project.js", "source/position_sense/endat/firmware/multi_channel_load_share/.project/project.js", diff --git a/docs_src/docs/api_guide/device/am243x/examples.cfg b/docs_src/docs/api_guide/device/am243x/examples.cfg index c394f81..4c1e872 100644 --- a/docs_src/docs/api_guide/device/am243x/examples.cfg +++ b/docs_src/docs/api_guide/device/am243x/examples.cfg @@ -6,4 +6,5 @@ INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/sdfm_example. INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/bissc_example.md INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/dcl/dcl_pi/dcl_pi.md INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/dcl/dcl_df22/dcl_df22.md -INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/pruicss_pwm.md +INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/pruicss_pwm_dutycycle.md +INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/pruicss_pwm_epwm_sync.md diff --git a/docs_src/docs/api_guide/device/am64x/examples.cfg b/docs_src/docs/api_guide/device/am64x/examples.cfg index affa5bd..5717736 100644 --- a/docs_src/docs/api_guide/device/am64x/examples.cfg +++ b/docs_src/docs/api_guide/device/am64x/examples.cfg @@ -3,4 +3,4 @@ INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/hdsl_example. INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/endat_example.md INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/tamagawa_example.md INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/sdfm_example.md -INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/pruicss_pwm.md \ No newline at end of file +INPUT+= $(MOTOR_CONTROL_SDK_PATH)/docs_src/docs/api_guide/examples/pruicss_pwm_dutycycle.md \ No newline at end of file diff --git a/docs_src/docs/api_guide/examples/examples.md b/docs_src/docs/api_guide/examples/examples.md index 510befc..a70b6ee 100644 --- a/docs_src/docs/api_guide/examples/examples.md +++ b/docs_src/docs/api_guide/examples/examples.md @@ -25,6 +25,7 @@ This page lists all the examples and demos supported in this SDK. -# \subpage EXAMPLES_DCL_DF22 - PRUICSS PWM -# \subpage EXAMPLE_PRUICSS_PWM_DUTY_CYCLE + -# \subpage EXAMPLE_PRUICSS_PWM_EPWM_SYNC \endcond \cond SOC_AM263X diff --git a/docs_src/docs/api_guide/examples/pruicss_pwm.md b/docs_src/docs/api_guide/examples/pruicss_pwm_dutycycle.md similarity index 91% rename from docs_src/docs/api_guide/examples/pruicss_pwm.md rename to docs_src/docs/api_guide/examples/pruicss_pwm_dutycycle.md index 09b36b7..1fd9469 100644 --- a/docs_src/docs/api_guide/examples/pruicss_pwm.md +++ b/docs_src/docs/api_guide/examples/pruicss_pwm_dutycycle.md @@ -17,6 +17,7 @@ The example Uses PRUICSSG1 PWM module and does below - PWM0_2_NEG(alias signal PWM0_B2) uses IEP0 CMP6 EVENT to control Duty cycle and IEP0 CMP0 to control output Frequency - Configures IEP0 CMP0 value with PWM0_2_NEG(alias signal PWM0_B2) output period value - Configures IEP0 CMP6 value with PWM0_2_NEG(alias signal PWM0_B2) output duty cycle value +- Configures IEP counter reset on CMP0 event - PRG1_PWM0_B2 can be probed on J16 PIN1 #### AM243X-EVM Probe Output @@ -31,8 +32,9 @@ The example Uses PRUICSSG0 PWM module and does below - PWM0_0_POS(alias signal PWM0_A0) uses IEP0 CMP1 EVENT to control Duty cycle and IEP0 CMP0 to control output Frequency - PWM3_2_NEG(alias signal PWM3_B2) uses IEP1 CMP12 EVENT to control Duty cycle and IEP0 CMP0 to control output Frequency - Configures IEP0 CMP0 value with PWM0_0_POS(alias signal PWM0_A0) and PWM3_2_NEG(alias signal PWM3_B2) output period value +- Configures IEP counter reset on CMP0 event - Configures IEP0 CMP6 value with PWM0_0_POS(alias signal PWM0_A0) output duty cycle value -- Configures IEP1 CMP12 value with PWM0_0_POS(alias signal PWM0_A0) output duty cycle value +- Configures IEP1 CMP12 value with PWM3_2_NEG(alias signal PWM3_B2) output duty cycle value - PWM0_0_POS(alias signal PWM0_A0) and PWM3_2_NEG(alias signal PWM3_B2) will be in sync with respect to each other as IEP0 CMP0 value is used to control output period of these signals - PRG0_PWM0_A0 can be probed on J1.5 - PRG0_PWM3_B2 can be probed on J2.8 @@ -52,6 +54,7 @@ The example Uses PRUICSSG1 PWM module and does below - PWM0_2_NEG(alias signal PWM0_B2) uses IEP0 CMP6 EVENT to control Duty cycle and IEP0 CMP0 to control output Frequency - Configures IEP0 CMP0 value with PWM0_2_NEG(alias signal PWM0_B2) output period value - Configures IEP0 CMP6 value with PWM0_2_NEG(alias signal PWM0_B2) output duty cycle value +- Configures IEP counter reset on CMP0 event - PRG1_PWM0_B2 can be probed on J16 PIN1 #### AM64X-EVM Probe Output @@ -61,7 +64,7 @@ The example Uses PRUICSSG1 PWM module and does below \endcond -# Supported Combinations {#EXAMPLES_DRIVERS_EPWM_DUTY_CYCLE_COMBOS} +# Supported Combinations \cond SOC_AM64X @@ -70,7 +73,7 @@ The example Uses PRUICSSG1 PWM module and does below CPU + OS | r5fss0-0 freertos Toolchain | ti-arm-clang Board | @VAR_BOARD_NAME_LOWER - Example folder | examples/drivers/epwm/epwm_duty_cycle/ + Example folder | examples/pruicss_pwm/pruicss_pwm_dutycycle \endcond @@ -81,7 +84,7 @@ The example Uses PRUICSSG1 PWM module and does below CPU + OS | r5fss0-0 freertos Toolchain | ti-arm-clang Boards | @VAR_BOARD_NAME_LOWER, @VAR_LP_BOARD_NAME_LOWER - Example folder | examples/drivers/epwm/epwm_duty_cycle/ + Example folder | examples/pruicss_pwm/pruicss_pwm_dutycycle \endcond diff --git a/docs_src/docs/api_guide/examples/pruicss_pwm_epwm_sync.md b/docs_src/docs/api_guide/examples/pruicss_pwm_epwm_sync.md new file mode 100644 index 0000000..96e9c0b --- /dev/null +++ b/docs_src/docs/api_guide/examples/pruicss_pwm_epwm_sync.md @@ -0,0 +1,62 @@ +# PRUICSS PWM EPWM SYNC {#EXAMPLE_PRUICSS_PWM_EPWM_SYNC} + +[TOC] + +# Introduction + +This example generates a signal for a specified time and duty cycle using +PRUICSS PWM and SOC EPWM. The time and duty cycle can be configured by the user. + +\cond SOC_AM243X + +## AM243X-LP +The example Uses PRUICSSG0 PWM module and does below + +- Configures EPWM0_CHANNEL_A to generate a 1KHz signal with 25% duty cycle +- Configures EPWM0_SYNC_OUT to output high when SOC EPWM PERIOD VAL reaches zero +- Configures IEP counter reset on EPWM0_SYNC_OUT event +- Configures PWM0_0_POS(alias signal PWM0_A0) to generate a 1KHz signal with 50% duty cycle +- Configures PWM3_2_NEG(alias signal PWM3_B2) to generate a 1KHz signal with 75% duty cycle +- PWM0_0_POS(alias signal PWM0_A0) uses IEP0 CMP1 EVENT to control Duty cycle and EPWM0 SYNC OUT to control output Frequency +- PWM3_2_NEG(alias signal PWM3_B2) uses IEP1 CMP12 EVENT to control Duty cycle and EPWM0 SYNC OUT to control output Frequency +- Configures IEP0 CMP6 value with PWM0_0_POS(alias signal PWM0_A0) output duty cycle value +- Configures IEP1 CMP12 value with PWM3_2_NEG(alias signal PWM3_B2) output duty cycle value +- Configures IEP0 CMP0 value with zero to make state transition to intial on IEP counter reset +- PWM0_0_POS(alias signal PWM0_A0) and PWM3_2_NEG(alias signal PWM3_B2) and EPWM0_CHANNEL_A will be in sync with respect to each other as EPWM0_SYNC_OUT is used to control output period of these signals +- PRG0_PWM0_A0 can be probed on J1.5 +- PRG0_PWM3_B2 can be probed on J2.8 +- EPWM0_CHANNEL_A can be probed on J4.1 + +#### AM243X-LP Probe Output +\imageStyle{am243x_lp_soc_epwm_pruicss_pwm_sync_probe_output.png,width:85%} +\image html am243x_lp_soc_epwm_pruicss_pwm_sync_probe_output.png "PRUICSS PWM EPWM SYNC PROBE OUTPUT" + +\endcond + +# Supported Combinations + +\cond SOC_AM243X + + Parameter | Value + ---------------|----------- + CPU + OS | r5fss0-0 freertos + Toolchain | ti-arm-clang + Boards | @VAR_LP_BOARD_NAME_LOWER + Example folder | examples/pruicss_pwm/pruicss_pwm_epwm_sync + +\endcond + +# Steps to Run the Example + +- **When using CCS projects to build**, import the CCS project for the required combination + and build it using the CCS project menu (see Using SDK with CCS Projects ). +- **When using makefiles to build**, note the required combination and build using + make command (see Using SDK with Makefiles ) +- Launch a CCS debug session and run the executable, see CCS Launch, Load and Run +- To probe the PRUICSS PWM output please refer setup details as mentioned above in Introduction section + +# See Also + +\ref PRUICSS_PWM_API + + diff --git a/docs_src/docs/api_guide/images/pruicss_pwm/am243x_lp_soc_epwm_pruicss_pwm_sync_probe_output.png b/docs_src/docs/api_guide/images/pruicss_pwm/am243x_lp_soc_epwm_pruicss_pwm_sync_probe_output.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa84d3c6c1ba24a7ca6bd6c82eee80c255b4b45 GIT binary patch literal 74880 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∓|Tp5ElY%9`=QGMYV>KH{uyfr*U5&HBX4 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/// + */ +const filedirs = { + common: [ + "..", /* core_os_combo base */ + "../../..", /* Example base */ + ], +}; + +const libdirs_freertos = { + common: [ + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/lib", + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/drivers/lib", + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/board/lib", + "${MOTOR_CONTROL_SDK_PATH}/source/pruicss_pwm/lib" + ], +}; + +const includes_freertos_r5f = { + common: [ + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/FreeRTOS-Kernel/include", + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/portable/TI_ARM_CLANG/ARM_CR5F", + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/config/am243x/r5f", + "${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/drivers/pruicss/g_v0", + "${MOTOR_CONTROL_SDK_PATH}/source/pruicss_pwm/include" + + ], +}; + +const libs_freertos_r5f = { + common: [ + "freertos.am243x.r5f.ti-arm-clang.${ConfigName}.lib", + "drivers.am243x.r5f.ti-arm-clang.${ConfigName}.lib", + "board.am243x.r5f.ti-arm-clang.${ConfigName}.lib", + "pruicss_pwm.am243x.r5f.ti-arm-clang.${ConfigName}.lib", + ], +}; + + + +const lnkfiles = { + common: [ + "linker.cmd", + ] +}; + +const syscfgfile = "../example.syscfg"; + +const readmeDoxygenPageTag = "EXAMPLE_PRUICSS_PWM_EPWM_SYNC"; + +const templates_freertos_r5f = +[ + { + input: ".project/templates/am243x/common/linker_r5f.cmd.xdt", + output: "linker.cmd", + }, + { + input: ".project/templates/am243x/freertos/main_freertos.c.xdt", + output: "../main.c", + options: { + entryFunction: "pruicss_pwm_epwm_sync_main", + }, + } +]; + +const buildOptionCombos = [ + { device: device, cpu: "r5fss0-0", cgt: "ti-arm-clang", board: "am243x-lp", os: "freertos"}, +]; + +function getComponentProperty() { + let property = {}; + + property.dirPath = path.resolve(__dirname, ".."); + property.type = "executable"; + property.name = "pruicss_pwm_epwm_sync"; + property.isInternal = false; + property.buildOptionCombos = buildOptionCombos; + property.isSkipTopLevelBuild = false; + + return property; +} + +function getComponentBuildProperty(buildOption) { + let build_property = {}; + + build_property.files = files; + build_property.filedirs = filedirs; + build_property.lnkfiles = lnkfiles; + build_property.syscfgfile = syscfgfile; + build_property.readmeDoxygenPageTag = readmeDoxygenPageTag; + + if(buildOption.cpu.match(/r5f*/)) { + if(buildOption.os.match(/freertos*/) ) + { + build_property.includes = includes_freertos_r5f; + build_property.libdirs = libdirs_freertos; + build_property.libs = libs_freertos_r5f; + build_property.templates = templates_freertos_r5f; + + } + } + + return build_property; +} + +module.exports = { + getComponentProperty, + getComponentBuildProperty, +}; diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/example.syscfg b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/example.syscfg new file mode 100644 index 0000000..5a18d00 --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/example.syscfg @@ -0,0 +1,76 @@ +/** + * These arguments were used when this file was generated. They will be automatically applied on subsequent loads + * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. + * @cliArgs --device "AM243x_ALX_beta" --package "ALX" --part "ALX" --context "r5fss0-0" --product "MOTOR_CONTROL_SDK@09.01.00" + * @versions {"tool":"1.18.0+3266"} + */ + +/** + * Import the modules used in this configuration. + */ +const epwm = scripting.addModule("/drivers/epwm/epwm", {}, false); +const epwm1 = epwm.addInstance(); +const pruicss = scripting.addModule("/drivers/pruicss/pruicss", {}, false); +const pruicss1 = pruicss.addInstance(); +const debug_log = scripting.addModule("/kernel/dpl/debug_log"); +const mpu_armv7 = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false); +const mpu_armv71 = mpu_armv7.addInstance(); +const mpu_armv72 = mpu_armv7.addInstance(); +const mpu_armv73 = mpu_armv7.addInstance(); +const mpu_armv74 = mpu_armv7.addInstance(); +const mpu_armv75 = mpu_armv7.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +epwm1.$name = "CONFIG_EPWM0"; +epwm1.EPWM.$assign = "EHRPWM0"; +epwm1.EPWM.B.$used = false; +epwm1.EPWM.SYNCO.$used = false; +epwm1.EPWM.SYNCI.$used = false; + +pruicss1.$name = "CONFIG_PRU_ICSS0"; +pruicss1.AdditionalICSSSettings[0].$name = "CONFIG_PRU_ICSS_IO0"; + +debug_log.enableUartLog = true; +debug_log.uartLog.$name = "CONFIG_UART_CONSOLE"; +debug_log.uartLog.UART.$assign = "USART0"; + +const uart_v0_template = scripting.addModule("/drivers/uart/v0/uart_v0_template", {}, false); +const uart_v0_template1 = uart_v0_template.addInstance({}, false); +uart_v0_template1.$name = "drivers_uart_v0_uart_v0_template0"; +debug_log.uartLog.child = uart_v0_template1; + +mpu_armv71.$name = "CONFIG_MPU_REGION0"; +mpu_armv71.size = 31; +mpu_armv71.attributes = "Device"; +mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD"; +mpu_armv71.allowExecute = false; + +mpu_armv72.$name = "CONFIG_MPU_REGION1"; +mpu_armv72.size = 15; +mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD"; + +mpu_armv73.$name = "CONFIG_MPU_REGION2"; +mpu_armv73.baseAddr = 0x41010000; +mpu_armv73.size = 15; +mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD"; + +mpu_armv74.$name = "CONFIG_MPU_REGION3"; +mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD"; +mpu_armv74.baseAddr = 0x70000000; +mpu_armv74.size = 21; + +mpu_armv75.$name = "CONFIG_MPU_REGION4"; +mpu_armv75.baseAddr = 0x60000000; +mpu_armv75.size = 28; +mpu_armv75.accessPermissions = "Supervisor RD, User RD"; + +/** + * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future + * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to + * re-solve from scratch. + */ +epwm1.EPWM.A.$suggestSolution = "GPMC0_AD3"; +debug_log.uartLog.UART.RXD.$suggestSolution = "UART0_RXD"; +debug_log.uartLog.UART.TXD.$suggestSolution = "UART0_TXD"; diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/main.c b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/main.c new file mode 100644 index 0000000..c9ab9b3 --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/main.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018-2021 Texas Instruments Incorporated + * + * 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. + */ + +#include +#include +#include "ti_drivers_config.h" +#include "ti_board_config.h" +#include "FreeRTOS.h" +#include "task.h" + +#define MAIN_TASK_PRI (configMAX_PRIORITIES-1) + +#define MAIN_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE)) +StackType_t gMainTaskStack[MAIN_TASK_SIZE] __attribute__((aligned(32))); + +StaticTask_t gMainTaskObj; +TaskHandle_t gMainTask; + +void pruicss_pwm_epwm_sync_main(void *args); + +void freertos_main(void *args) +{ + pruicss_pwm_epwm_sync_main(NULL); + + vTaskDelete(NULL); +} + + +int main(void) +{ + /* init SOC specific modules */ + System_init(); + Board_init(); + + /* This task is created at highest priority, it should create more tasks and then delete itself */ + gMainTask = xTaskCreateStatic( freertos_main, /* Pointer to the function that implements the task. */ + "freertos_main", /* Text name for the task. This is to facilitate debugging only. */ + MAIN_TASK_SIZE, /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */ + NULL, /* We are not using the task parameter. */ + MAIN_TASK_PRI, /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */ + gMainTaskStack, /* pointer to stack base */ + &gMainTaskObj ); /* pointer to statically allocated task object memory */ + configASSERT(gMainTask != NULL); + + /* Start the scheduler to start the tasks executing. */ + vTaskStartScheduler(); + + /* The following line should never be reached because vTaskStartScheduler() + will only return if there was not enough FreeRTOS heap memory available to + create the Idle and (if configured) Timer tasks. Heap management, and + techniques for trapping heap exhaustion, are described in the book text. */ + DebugP_assertNoLog(0); + + return 0; +} diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/pruicss_pwm_epwm_sync.c b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/pruicss_pwm_epwm_sync.c new file mode 100644 index 0000000..9ec1d32 --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/pruicss_pwm_epwm_sync.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2021 Texas Instruments Incorporated + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "ti_drivers_config.h" +#include "ti_drivers_open_close.h" +#include "ti_board_open_close.h" +#include +#include +#include + +/* Frequency of PWM output signal in Hz - 1 KHz is selected */ +#define SOC_EPWM_OUTPUT_FREQ (1U * 1000U) +/* TB frequency in Hz - so that /4 divider is used */ +#define SOC_EPWM_TB_FREQ (CONFIG_EPWM0_FCLK / 4U) +/* PRD value - this determines the period */ +#define SOC_EPWM_PRD_VAL (SOC_EPWM_TB_FREQ / SOC_EPWM_OUTPUT_FREQ) +/* Duty Cycle of PWM output signal in % - give value from 1 to 99 */ +#define SOC_EPWM_DUTY_CYCLE (25U) +/* DUTY CYCLE width - this determines width of PWM output signal duty cycle*/ +#define SOC_EPWM_COMPA_VAL (SOC_EPWM_PRD_VAL - ((SOC_EPWM_DUTY_CYCLE *SOC_EPWM_PRD_VAL) / 100U)) + +/*FIXME: IEP0_CLK_FREQ macro to be included in driver_config.h sysconfig generated file*/ +#define PRUICSS_IEP0_CLK_FREQ (200000000U) +/* Modify this to change the IEP counter increment value*/ +#define PRUICSS_IEP_COUNT_INCREMENT_VALUE (5U) +/* Duty Cycle of PWM output signal in % - give value from 1 to 99 */ +#define APP_PRUICSS_PWM0_A0_DUTY_CYCLE (50U) +/* Duty Cycle of PWM output signal in % - give value from 1 to 99 */ +#define APP_PRUICSS_PWM3_B2_DUTY_CYCLE (75U) +/* Frequency of PWM output signal in Hz - 1 KHz is selected */ +#define APP_PRUICSS_PWM_OUTPUT_FREQ (SOC_EPWM_OUTPUT_FREQ) +/* PRD value - this determines the period */ +#define APP_PRUICSS_PWM_PRD_VAL (((PRUICSS_IEP0_CLK_FREQ / APP_PRUICSS_PWM_OUTPUT_FREQ))*(PRUICSS_IEP_COUNT_INCREMENT_VALUE)) +/* DUTY CYCLE width - this determines width of PWM output signal duty cycle*/ +#define APP_PRUICSS_IEP0_COMP1_VAL (APP_PRUICSS_PWM_PRD_VAL-((APP_PRUICSS_PWM0_A0_DUTY_CYCLE*APP_PRUICSS_PWM_PRD_VAL)/100)) +/* DUTY CYCLE width - this determines width of PWM output signal duty cycle*/ +#define APP_PRUICSS_IEP1_COMP12_VAL (APP_PRUICSS_PWM_PRD_VAL-((APP_PRUICSS_PWM3_B2_DUTY_CYCLE*APP_PRUICSS_PWM_PRD_VAL)/100)) + +/*FIXME: Add pinmux in sysconfig generated file*/ +Pinmux_PerCfg_t gPinMuxMainDomainCfg1[] = { + + /* PRU_ICSSG0_PWM0 pin config */ + /* PRG0_PWM0_A0 -> PRG0_PRU0_GPO12 (K1) */ + { + PIN_PRG0_PRU0_GPO12, + ( PIN_MODE(3) | PIN_PULL_DISABLE ) + }, + /* PRU_ICSSG0_PWM3 pin config */ + /* PRG0_PWM3_B2 -> PRG0_PRU0_GPO5 (F2) */ + { + PIN_PRG0_PRU0_GPO5, + ( PIN_MODE(3) | PIN_PULL_DISABLE ) + }, + {PINMUX_END, PINMUX_END} + +}; + +/* Function Prototypes */ +static void App_epwmConfig(uint32_t epwmBaseAddr, uint32_t epwmCh, uint32_t epwmFuncClk); +static void pruicss_iep_init(void *args); +static void pruicss_pwm_init(void *args); + +/* variable to hold base address of EPWM that is used */ +uint32_t gEpwmBaseAddr; + +/* Global Structure pointer holding PRUICSSG0 memory Map. */ +PRUICSS_Handle gPruIcssHandle; + +void pruicss_pwm_epwm_sync_main(void *args) +{ + + /* Open drivers to open the UART driver for console */ + Drivers_open(); + Board_driversOpen(); + + gPruIcssHandle = PRUICSS_open(CONFIG_PRU_ICSS0); + DebugP_assert(gPruIcssHandle != NULL); + + Pinmux_config(gPinMuxMainDomainCfg1, PINMUX_DOMAIN_ID_MAIN); + + pruicss_pwm_init(NULL); + + pruicss_iep_init(NULL); + + /* Address translate */ + gEpwmBaseAddr = (uint32_t)AddrTranslateP_getLocalAddr(CONFIG_EPWM0_BASE_ADDR); + + /* Configure SOC EPWM */ + App_epwmConfig(gEpwmBaseAddr, EPWM_OUTPUT_CH_A, CONFIG_EPWM0_FCLK); + + while (1) + { + ClockP_usleep(1); + } + + Board_driversClose(); + Drivers_close(); +} + +static void App_epwmConfig(uint32_t epwmBaseAddr, uint32_t epwmCh, uint32_t epwmFuncClk) +{ + EPWM_AqActionCfg aqConfig; + + /* Configure Time base submodule */ + EPWM_tbTimebaseClkCfg(epwmBaseAddr, SOC_EPWM_TB_FREQ, epwmFuncClk); + EPWM_tbPwmFreqCfg(epwmBaseAddr, SOC_EPWM_TB_FREQ, SOC_EPWM_OUTPUT_FREQ, EPWM_TB_COUNTER_DIR_UP, EPWM_SHADOW_REG_CTRL_ENABLE); + EPWM_tbSyncDisable(epwmBaseAddr); + EPWM_tbSetSyncOutMode(epwmBaseAddr, EPWM_TB_SYNC_OUT_EVT_CNT_EQ_ZERO); + EPWM_tbSetEmulationMode(epwmBaseAddr, EPWM_TB_EMU_MODE_FREE_RUN); + + /* Configure counter compare submodule */ + EPWM_counterComparatorCfg(epwmBaseAddr, EPWM_CC_CMP_A, SOC_EPWM_COMPA_VAL, EPWM_SHADOW_REG_CTRL_ENABLE, EPWM_CC_CMP_LOAD_MODE_CNT_EQ_ZERO, TRUE); + + /* Configure Action Qualifier Submodule */ + aqConfig.zeroAction = EPWM_AQ_ACTION_LOW; + aqConfig.prdAction = EPWM_AQ_ACTION_DONOTHING; + aqConfig.cmpAUpAction = EPWM_AQ_ACTION_HIGH; + aqConfig.cmpADownAction = EPWM_AQ_ACTION_DONOTHING; + aqConfig.cmpBUpAction = EPWM_AQ_ACTION_DONOTHING; + aqConfig.cmpBDownAction = EPWM_AQ_ACTION_DONOTHING; + EPWM_aqActionOnOutputCfg(epwmBaseAddr, epwmCh, &aqConfig); + + /* Configure Dead Band Submodule */ + EPWM_deadbandBypass(epwmBaseAddr); + + /* Configure Chopper Submodule */ + EPWM_chopperEnable(epwmBaseAddr, FALSE); + + /* Configure trip zone Submodule */ + EPWM_tzTripEventDisable(epwmBaseAddr, EPWM_TZ_EVENT_ONE_SHOT, 0U); + EPWM_tzTripEventDisable(epwmBaseAddr, EPWM_TZ_EVENT_CYCLE_BY_CYCLE, 0U); + + /* Configure event trigger Submodule */ + EPWM_etIntrCfg(epwmBaseAddr, EPWM_ET_INTR_EVT_CNT_EQ_ZRO, EPWM_ET_INTR_PERIOD_FIRST_EVT); + EPWM_etIntrEnable(epwmBaseAddr); +} + +static void pruicss_iep_init(void *args) +{ + + int status; + /*Disable IEP0 counter*/ + status= PRUICSS_controlIepCounter(gPruIcssHandle, PRUICSS_IEP_INST0, 0); + DebugP_assert(SystemP_SUCCESS == status); + + status = PRUICSS_PWM_enableIEPResetOnEPWM0SyncOut(gPruIcssHandle, PRUICSS_IEP_INST0, 1); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable IEP1 slave mode*/ + status = PRUICSS_PWM_enableIEP1Slave(gPruIcssHandle, 1); + DebugP_assert(SystemP_SUCCESS == status); + + /*Intialize IEP0 count value*/ + PRUICSS_PWM_setIepCounterLower_32bitValue(gPruIcssHandle, PRUICSS_IEP_INST0, 0xFFFFFFFF); + PRUICSS_PWM_setIepCounterUpper_32bitValue(gPruIcssHandle, PRUICSS_IEP_INST0, 0xFFFFFFFF); + + /*FIXME: Either compare event is not hit or no state transition when compare 0 configured with 0x00000000*/ + /*configure cmp 0 value of IEP0 with APP_PRUICSS_PWM_PRD_VAL*/ + status = PRUICSS_PWM_setIepCompareEventLower_32bitValue(gPruIcssHandle, PRUICSS_IEP_INST0, CMP_EVENT0, ((0x00000001) & 0xFFFFFFFF)); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure cmp 1 value with APP_PRUICSS_IEP0_COMP1_VAL*/ + status = PRUICSS_PWM_setIepCompareEventLower_32bitValue(gPruIcssHandle, PRUICSS_IEP_INST0, CMP_EVENT1, (APP_PRUICSS_IEP0_COMP1_VAL & 0xFFFFFFFF)); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure cmp 12 value with APP_PRUICSS_IEP1_COMP12_VAL*/ + status = PRUICSS_PWM_setIepCompareEventLower_32bitValue(gPruIcssHandle, PRUICSS_IEP_INST1, CMP_EVENT12, (APP_PRUICSS_IEP1_COMP12_VAL & 0xFFFFFFFF)); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable cmp 0 and cmp 1 of IEP0*/ + status = PRUICSS_PWM_configureIepCompareEnable(gPruIcssHandle, PRUICSS_IEP_INST0, 0x3); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable cmp12 of IEP1*/ + status = PRUICSS_PWM_configureIepCompareEnable(gPruIcssHandle, PRUICSS_IEP_INST1, 0x1000); + DebugP_assert(SystemP_SUCCESS == status); + + /*Set IEP0 counter Increment value*/ + status = PRUICSS_setIepCounterIncrementValue(gPruIcssHandle, PRUICSS_IEP_INST0, PRUICSS_IEP_COUNT_INCREMENT_VALUE); + DebugP_assert(SystemP_SUCCESS == status); + + /*Disable cmp 0 reset of IEP0 counter*/ + status = PRUICSS_PWM_configureIepCmp0ResetEnable(gPruIcssHandle, PRUICSS_IEP_INST0, 0x0); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable IEP0 counter*/ + status = PRUICSS_controlIepCounter(gPruIcssHandle, PRUICSS_IEP_INST0, 1); + DebugP_assert(SystemP_SUCCESS == status); + +} + +static void pruicss_pwm_init(void *args){ + + int status; + /*Enable IEP CMP flags to auto clear after state transition*/ + status = PRUICSS_PWM_configurePwmEfficiencyModeEnable(gPruIcssHandle, 1); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable compare0 trip reset of set 0*/ + status = PRUICSS_PWM_configurePwmCmp0TripResetEnable(gPruIcssHandle, PRUICSS_PWM_SET0, 1); + DebugP_assert(SystemP_SUCCESS == status); + + /*Enable compare0 trip reset of set 3 */ + status = PRUICSS_PWM_configurePwmCmp0TripResetEnable(gPruIcssHandle, PRUICSS_PWM_SET3, 1); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure PWM B2 signal of set 0, intial state to low*/ + status = PRUICSS_PWM_actionOnOutputCfgPwmSignalA0(gPruIcssHandle, PRUICSS_PWM_SET0, PRUICSS_PWM_INTIAL_STATE,1); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure PWM B2 signal of set 0, active state to high*/ + status = PRUICSS_PWM_actionOnOutputCfgPwmSignalA0(gPruIcssHandle, PRUICSS_PWM_SET0, PRUICSS_PWM_ACTIVE_STATE,2); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure PWM B2 signal of set 0, intial state to low*/ + status = PRUICSS_PWM_actionOnOutputCfgPwmSignalB2(gPruIcssHandle, PRUICSS_PWM_SET3, PRUICSS_PWM_INTIAL_STATE,1); + DebugP_assert(SystemP_SUCCESS == status); + + /*configure PWM B2 signal of set 0, active state to high*/ + status = PRUICSS_PWM_actionOnOutputCfgPwmSignalB2(gPruIcssHandle, PRUICSS_PWM_SET3, PRUICSS_PWM_ACTIVE_STATE,2); + DebugP_assert(SystemP_SUCCESS == status); +} + diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec new file mode 100644 index 0000000..b248fdd --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/linker.cmd b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/linker.cmd new file mode 100644 index 0000000..69640f4 --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/linker.cmd @@ -0,0 +1,148 @@ + +/* This is the stack that is used by code running within main() + * In case of NORTOS, + * - This means all the code outside of ISR uses this stack + * In case of FreeRTOS + * - This means all the code until vTaskStartScheduler() is called in main() + * uses this stack. + * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack + */ +--stack_size=16384 +/* This is the heap size for malloc() API in NORTOS and FreeRTOS + * This is also the heap used by pvPortMalloc in FreeRTOS + */ +--heap_size=32768 +-e_vectors /* This is the entry of the application, _vector MUST be plabed starting address 0x0 */ + +/* This is the size of stack when R5 is in IRQ mode + * In NORTOS, + * - Here interrupt nesting is enabled + * - This is the stack used by ISRs registered as type IRQ + * In FreeRTOS, + * - Here interrupt nesting is disabled + * - This is stack that is used initally when a IRQ is received + * - But then the mode is switched to SVC mode and SVC stack is used for all user ISR callbacks + * - Hence in FreeRTOS, IRQ stack size is less and SVC stack size is more + */ +__IRQ_STACK_SIZE = 256; +/* This is the size of stack when R5 is in IRQ mode + * - In both NORTOS and FreeRTOS nesting is disabled for FIQ + */ +__FIQ_STACK_SIZE = 256; +__SVC_STACK_SIZE = 4096; /* This is the size of stack when R5 is in SVC mode */ +__ABORT_STACK_SIZE = 256; /* This is the size of stack when R5 is in ABORT mode */ +__UNDEFINED_STACK_SIZE = 256; /* This is the size of stack when R5 is in UNDEF mode */ + +SECTIONS +{ + /* This has the R5F entry point and vector table, this MUST be at 0x0 */ + .vectors:{} palign(8) > R5F_VECS + + /* This has the R5F boot code until MPU is enabled, this MUST be at a address < 0x80000000 + * i.e this cannot be placed in DDR + */ + GROUP { + .text.hwi: palign(8) + .text.cache: palign(8) + .text.mpu: palign(8) + .text.boot: palign(8) + .text:abort: palign(8) /* this helps in loading symbols when using XIP mode */ + } > MSRAM + + /* This is rest of code. This can be placed in DDR if DDR is available and needed */ + GROUP { + .text: {} palign(8) /* This is where code resides */ + .rodata: {} palign(8) /* This is where const's go */ + } > MSRAM + + /* This is rest of initialized data. This can be placed in DDR if DDR is available and needed */ + GROUP { + .data: {} palign(8) /* This is where initialized globals and static go */ + } > MSRAM + + /* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */ + GROUP { + .bss: {} palign(8) /* This is where uninitialized globals go */ + RUN_START(__BSS_START) + RUN_END(__BSS_END) + .sysmem: {} palign(8) /* This is where the malloc heap goes */ + .stack: {} palign(8) /* This is where the main() stack goes */ + } > MSRAM + + /* This is where the stacks for different R5F modes go */ + GROUP { + .irqstack: {. = . + __IRQ_STACK_SIZE;} align(8) + RUN_START(__IRQ_STACK_START) + RUN_END(__IRQ_STACK_END) + .fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8) + RUN_START(__FIQ_STACK_START) + RUN_END(__FIQ_STACK_END) + .svcstack: {. = . + __SVC_STACK_SIZE;} align(8) + RUN_START(__SVC_STACK_START) + RUN_END(__SVC_STACK_END) + .abortstack: {. = . + __ABORT_STACK_SIZE;} align(8) + RUN_START(__ABORT_STACK_START) + RUN_END(__ABORT_STACK_END) + .undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8) + RUN_START(__UNDEFINED_STACK_START) + RUN_END(__UNDEFINED_STACK_END) + } > MSRAM + + /* Sections needed for C++ projects */ + GROUP { + .ARM.exidx: {} palign(8) /* Needed for C++ exception handling */ + .init_array: {} palign(8) /* Contains function pointers called before main */ + .fini_array: {} palign(8) /* Contains function pointers called after main */ + } > MSRAM + + /* General purpose user shared memory, used in some examples */ + .bss.user_shared_mem (NOLOAD) : {} > USER_SHM_MEM + /* this is used when Debug log's to shared memory are enabled, else this is not used */ + .bss.log_shared_mem (NOLOAD) : {} > LOG_SHM_MEM + /* this is used only when IPC RPMessage is enabled, else this is not used */ + .bss.ipc_vring_mem (NOLOAD) : {} > RTOS_NORTOS_IPC_SHM_MEM + /* General purpose non cacheable memory, used in some examples */ + .bss.nocache (NOLOAD) : {} > NON_CACHE_MEM +} + +/* +NOTE: Below memory is reserved for DMSC usage + - During Boot till security handoff is complete + 0x701E0000 - 0x701FFFFF (128KB) + - After "Security Handoff" is complete (i.e at run time) + 0x701F4000 - 0x701FFFFF (48KB) + + Security handoff is complete when this message is sent to the DMSC, + TISCI_MSG_SEC_HANDOVER + + This should be sent once all cores are loaded and all application + specific firewall calls are setup. +*/ + +MEMORY +{ + R5F_VECS : ORIGIN = 0x00000000 , LENGTH = 0x00000040 + R5F_TCMA : ORIGIN = 0x00000040 , LENGTH = 0x00007FC0 + R5F_TCMB0 : ORIGIN = 0x41010000 , LENGTH = 0x00008000 + + /* memory segment used to hold CPU specific non-cached data, MAKE to add a MPU entry to mark this as non-cached */ + NON_CACHE_MEM : ORIGIN = 0x70060000 , LENGTH = 0x8000 + + /* when using multi-core application's i.e more than one R5F/M4F active, make sure + * this memory does not overlap with other R5F's + */ + MSRAM : ORIGIN = 0x70080000 , LENGTH = 0x40000 + + /* This section can be used to put XIP section of the application in flash, make sure this does not overlap with + * other CPUs. Also make sure to add a MPU entry for this section and mark it as cached and code executable + */ + FLASH : ORIGIN = 0x60100000 , LENGTH = 0x80000 + + /* shared memory segments */ + /* On R5F, + * - make sure there is a MPU entry which maps below regions as non-cache + */ + USER_SHM_MEM : ORIGIN = 0x701D0000, LENGTH = 0x180 + LOG_SHM_MEM : ORIGIN = 0x701D0000 + 0x180, LENGTH = 0x00004000 - 0x180 + RTOS_NORTOS_IPC_SHM_MEM : ORIGIN = 0x701D4000, LENGTH = 0x0000C000 +} diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile new file mode 100644 index 0000000..290c04a --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile @@ -0,0 +1,309 @@ +# +# Auto generated makefile +# + +export MOTOR_CONTROL_SDK_PATH?=$(abspath ../../../../../..) +include $(MOTOR_CONTROL_SDK_PATH)/imports.mak +include $(MOTOR_CONTROL_SDK_PATH)/devconfig/devconfig.mak + +CG_TOOL_ROOT=$(CGT_TI_ARM_CLANG_PATH) + +CC=$(CG_TOOL_ROOT)/bin/tiarmclang +LNK=$(CG_TOOL_ROOT)/bin/tiarmclang +STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip +OBJCOPY=$(CG_TOOL_ROOT)/bin/tiarmobjcopy +ifeq ($(OS), Windows_NT) + PYTHON=python +else + PYTHON=python3 +endif + +PROFILE?=release +ConfigName:=$(PROFILE) + +OUTNAME:=pruicss_pwm_epwm_sync.$(PROFILE).out + +BOOTIMAGE_PATH=$(abspath .) +BOOTIMAGE_NAME:=pruicss_pwm_epwm_sync.$(PROFILE).appimage +BOOTIMAGE_NAME_XIP:=pruicss_pwm_epwm_sync.$(PROFILE).appimage_xip +BOOTIMAGE_NAME_SIGNED:=pruicss_pwm_epwm_sync.$(PROFILE).appimage.signed +BOOTIMAGE_RPRC_NAME:=pruicss_pwm_epwm_sync.$(PROFILE).rprc +BOOTIMAGE_RPRC_NAME_XIP:=pruicss_pwm_epwm_sync.$(PROFILE).rprc_xip +BOOTIMAGE_RPRC_NAME_TMP:=pruicss_pwm_epwm_sync.$(PROFILE).rprc_tmp +BOOTIMAGE_NAME_HS:=pruicss_pwm_epwm_sync.$(PROFILE).appimage.hs +BOOTIMAGE_NAME_HS_FS:=pruicss_pwm_epwm_sync.$(PROFILE).appimage.hs_fs +TARGETS := $(BOOTIMAGE_NAME) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_HS) +endif + +FILES_common := \ + main.c \ + pruicss_pwm_epwm_sync.c \ + ti_drivers_config.c \ + ti_drivers_open_close.c \ + ti_board_config.c \ + ti_board_open_close.c \ + ti_dpl_config.c \ + ti_pinmux_config.c \ + ti_power_clock_config.c \ + +FILES_PATH_common = \ + .. \ + ../../.. \ + generated \ + +INCLUDES_common := \ + -I${CG_TOOL_ROOT}/include/c \ + -I${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source \ + -I${MOTOR_CONTROL_SDK_PATH}/source \ + -I${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/FreeRTOS-Kernel/include \ + -I${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/portable/TI_ARM_CLANG/ARM_CR5F \ + -I${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/config/am243x/r5f \ + -I${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/drivers/pruicss/g_v0 \ + -I${MOTOR_CONTROL_SDK_PATH}/source/pruicss_pwm/include \ + -Igenerated \ + +DEFINES_common := \ + -DSOC_AM243X \ + +CFLAGS_common := \ + -mcpu=cortex-r5 \ + -mfloat-abi=hard \ + -mfpu=vfpv3-d16 \ + -mthumb \ + -Wall \ + -Werror \ + -g \ + -Wno-gnu-variable-sized-type-not-at-end \ + -Wno-unused-function \ + +CFLAGS_cpp_common := \ + -Wno-c99-designator \ + -Wno-extern-c-compat \ + -Wno-c++11-narrowing \ + -Wno-reorder-init-list \ + -Wno-deprecated-register \ + -Wno-writable-strings \ + -Wno-enum-compare \ + -Wno-reserved-user-defined-literal \ + -Wno-unused-const-variable \ + -x c++ \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -Os \ + +LNK_FILES_common = \ + linker.cmd \ + +LIBS_PATH_common = \ + -Wl,-i${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/lib \ + -Wl,-i${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/drivers/lib \ + -Wl,-i${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/board/lib \ + -Wl,-i${MOTOR_CONTROL_SDK_PATH}/source/pruicss_pwm/lib \ + -Wl,-i${CG_TOOL_ROOT}/lib \ + +LIBS_common = \ + -lfreertos.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + -ldrivers.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + -lboard.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + -lpruicss_pwm.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + -llibc.a \ + -llibsysbm.a \ + +LFLAGS_common = \ + -Wl,--diag_suppress=10063 \ + -Wl,--ram_model \ + -Wl,--reread_libs \ + + +LIBS_NAME = \ + freertos.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + drivers.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + board.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + pruicss_pwm.am243x.r5f.ti-arm-clang.${ConfigName}.lib \ + libc.a \ + libsysbm.a \ + +LIBS_PATH_NAME = \ + ${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/kernel/freertos/lib \ + ${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/drivers/lib \ + ${MOTOR_CONTROL_SDK_PATH}/mcu_plus_sdk/source/board/lib \ + ${MOTOR_CONTROL_SDK_PATH}/source/pruicss_pwm/lib \ + ${CG_TOOL_ROOT}/lib \ + +FILES := $(FILES_common) $(FILES_$(PROFILE)) +ASMFILES := $(ASMFILES_common) $(ASMFILES_$(PROFILE)) +FILES_PATH := $(FILES_PATH_common) $(FILES_PATH_$(PROFILE)) +CFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +DEFINES := $(DEFINES_common) $(DEFINES_$(PROFILE)) +INCLUDES := $(INCLUDES_common) $(INCLUDE_$(PROFILE)) +LIBS := $(LIBS_common) $(LIBS_$(PROFILE)) +LIBS_PATH := $(LIBS_PATH_common) $(LIBS_PATH_$(PROFILE)) +LFLAGS := $(LFLAGS_common) $(LFLAGS_$(PROFILE)) +LNKOPTFLAGS := $(LNKOPTFLAGS_common) $(LNKOPTFLAGS_$(PROFILE)) +LNK_FILES := $(LNK_FILES_common) $(LNK_FILES_$(PROFILE)) + +OBJDIR := obj/$(PROFILE)/ +OBJS := $(FILES:%.c=%.obj) +OBJS += $(ASMFILES:%.S=%.obj) +DEPS := $(FILES:%.c=%.d) + +vpath %.obj $(OBJDIR) +vpath %.c $(FILES_PATH) +vpath %.S $(FILES_PATH) +vpath %.lib $(LIBS_PATH_NAME) +vpath %.a $(LIBS_PATH_NAME) + +$(OBJDIR)/%.obj %.obj: %.c + @echo Compiling: am243x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: am243x:r5fss0-0:freertos:ti-arm-clang $(LIBNAME): $< + $(CC) -c $(CFLAGS) -o $(OBJDIR)/$@ $< + +all: $(TARGETS) + +SYSCFG_GEN_FILES=generated/ti_drivers_config.c generated/ti_drivers_config.h +SYSCFG_GEN_FILES+=generated/ti_drivers_open_close.c generated/ti_drivers_open_close.h +SYSCFG_GEN_FILES+=generated/ti_dpl_config.c generated/ti_dpl_config.h +SYSCFG_GEN_FILES+=generated/ti_pinmux_config.c generated/ti_power_clock_config.c +SYSCFG_GEN_FILES+=generated/ti_board_config.c generated/ti_board_config.h +SYSCFG_GEN_FILES+=generated/ti_board_open_close.c generated/ti_board_open_close.h + +$(OUTNAME): syscfg $(SYSCFG_GEN_FILES) $(OBJS) $(LNK_FILES) $(LIBS_NAME) + @echo . + @echo Linking: am243x:r5fss0-0:freertos:ti-arm-clang $@ ... + $(LNK) $(LNKOPTFLAGS) $(LFLAGS) $(LIBS_PATH) -Wl,-m=$(basename $@).map -o $@ $(addprefix $(OBJDIR), $(OBJS)) $(LIBS) $(LNK_FILES) + @echo Linking: am243x:r5fss0-0:freertos:ti-arm-clang $@ Done !!! + @echo . + +clean: + @echo Cleaning: am243x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(OUTNAME) + $(RM) $(BOOTIMAGE_NAME) + $(RM) $(BOOTIMAGE_NAME_XIP) + $(RM) $(BOOTIMAGE_NAME_SIGNED) + $(RM) $(BOOTIMAGE_NAME_HS) + $(RM) $(BOOTIMAGE_NAME_HS_FS) + $(RM) $(BOOTIMAGE_RPRC_NAME) + $(RM) $(BOOTIMAGE_RPRC_NAME_XIP) + $(RMDIR) generated/ + +scrub: + @echo Scrubing: am243x:r5fss0-0:freertos:ti-arm-clang pruicss_pwm_epwm_sync ... + $(RMDIR) obj +ifeq ($(OS),Windows_NT) + $(RM) \*.out + $(RM) \*.map + $(RM) \*.appimage* + $(RM) \*.rprc* + $(RM) \*.tiimage* + $(RM) \*.bin +else + $(RM) *.out + $(RM) *.map + $(RM) *.appimage* + $(RM) *.rprc* + $(RM) *.tiimage* + $(RM) *.bin +endif + $(RMDIR) generated + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + $(MKDIR) $@ + + +.NOTPARALLEL: + +.INTERMEDIATE: syscfg +$(SYSCFG_GEN_FILES): syscfg + +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_SDKPRODUCT) --context r5fss0-0 --part ALX --package ALX --output generated/ ../example.syscfg + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_SDKPRODUCT) --device AM243x_ALX_beta --context r5fss0-0 --part ALX --package ALX --output generated/ ../example.syscfg + +# +# Generation of boot image which can be loaded by Secondary Boot Loader (SBL) +# +ifeq ($(OS),Windows_NT) +EXE_EXT=.exe +endif +ifeq ($(OS),Windows_NT) + BOOTIMAGE_CERT_GEN_CMD=powershell -executionpolicy unrestricted -command $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/x509CertificateGen.sh +endif +BOOTIMAGE_TEMP_OUT_FILE=temp_stdout_$(PROFILE).txt + +BOOTIMAGE_CERT_KEY=$(APP_SIGNING_KEY) + +BOOTIMAGE_CORE_ID_r5fss0-0 = 4 +BOOTIMAGE_CORE_ID_r5fss0-1 = 5 +BOOTIMAGE_CORE_ID_r5fss1-0 = 6 +BOOTIMAGE_CORE_ID_r5fss1-1 = 7 +BOOTIMAGE_CORE_ID_m4fss0-0 = 14 +SBL_RUN_ADDRESS=0x70000000 +SBL_DEV_ID=55 + +MULTI_CORE_IMAGE_GEN = $(SYSCFG_NODE) $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/multicoreImageGen/multicoreImageGen.js +OUTRPRC_CMD = $(SYSCFG_NODE) $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/out2rprc/elf2rprc.js +APP_IMAGE_SIGN_CMD = $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/appimage_x509_cert_gen.py + +ifeq ($(OS),Windows_NT) + XIPGEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/xipGen/xipGen.exe +else + XIPGEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/xipGen/xipGen.out +endif + +MULTI_CORE_IMAGE_PARAMS = \ + $(BOOTIMAGE_RPRC_NAME)@$(BOOTIMAGE_CORE_ID_r5fss0-0) \ + +MULTI_CORE_IMAGE_PARAMS_XIP = \ + $(BOOTIMAGE_RPRC_NAME_XIP)@$(BOOTIMAGE_CORE_ID_r5fss0-0) \ + +$(BOOTIMAGE_NAME): $(OUTNAME) + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$@ ... +ifneq ($(OS),Windows_NT) + $(CHMOD) a+x $(XIPGEN_CMD) +endif + $(OUTRPRC_CMD) $(OUTNAME) >> $(BOOTIMAGE_TEMP_OUT_FILE) + $(COPY) $(BOOTIMAGE_RPRC_NAME) $(BOOTIMAGE_RPRC_NAME_TMP) + $(RM) $(BOOTIMAGE_RPRC_NAME) + $(XIPGEN_CMD) -i $(BOOTIMAGE_RPRC_NAME_TMP) -o $(BOOTIMAGE_RPRC_NAME) -x $(BOOTIMAGE_RPRC_NAME_XIP) --flash-start-addr 0x60000000 -v > $(BOOTIMAGE_TEMP_OUT_FILE) + $(MULTI_CORE_IMAGE_GEN) --devID $(SBL_DEV_ID) --out $(BOOTIMAGE_NAME) $(MULTI_CORE_IMAGE_PARAMS) >> $(BOOTIMAGE_TEMP_OUT_FILE) + $(MULTI_CORE_IMAGE_GEN) --devID $(SBL_DEV_ID) --out $(BOOTIMAGE_NAME_XIP) $(MULTI_CORE_IMAGE_PARAMS_XIP) >> $(BOOTIMAGE_TEMP_OUT_FILE) +# Sign the appimage for HS-FS using appimage signing script + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --output $(BOOTIMAGE_NAME_HS_FS) + $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) + $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$@ Done !!! + @echo . + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! + @echo . + +$(BOOTIMAGE_NAME_HS): $(BOOTIMAGE_NAME) +ifeq ($(DEVICE_TYPE), HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --output $(BOOTIMAGE_NAME_HS) +else + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --output $(BOOTIMAGE_NAME_HS) + $(RM) $(BOOTIMAGE_NAME)-enc +endif + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! + @echo . +endif +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen new file mode 100644 index 0000000..8666cfd --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -0,0 +1,106 @@ +# +# Auto generated makefile +# + +# Below variables need to be defined outside this file or via command line +# - MOTOR_CONTROL_SDK_PATH +# - PROFILE +# - CG_TOOL_ROOT +# - OUTNAME +# - CCS_INSTALL_DIR +# - CCS_IDE_MODE + +CCS_PATH=$(CCS_INSTALL_DIR) +include ${MOTOR_CONTROL_SDK_PATH}/imports.mak +include ${MOTOR_CONTROL_SDK_PATH}/devconfig/devconfig.mak + +STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip +OBJCOPY=$(CG_TOOL_ROOT)/bin/tiarmobjcopy +ifeq ($(OS), Windows_NT) + PYTHON=python +else + PYTHON=python3 +endif + +OUTFILE=$(PROFILE)/$(OUTNAME).out +BOOTIMAGE_PATH=$(abspath ${PROFILE}) +BOOTIMAGE_NAME:=$(BOOTIMAGE_PATH)/$(OUTNAME).appimage +BOOTIMAGE_NAME_XIP:=$(BOOTIMAGE_PATH)/$(OUTNAME).appimage_xip +BOOTIMAGE_NAME_SIGNED:=$(BOOTIMAGE_PATH)/$(OUTNAME).appimage.signed +BOOTIMAGE_RPRC_NAME:=$(BOOTIMAGE_PATH)/$(OUTNAME).rprc +BOOTIMAGE_RPRC_NAME_XIP:=$(BOOTIMAGE_PATH)/$(OUTNAME).rprc_xip +BOOTIMAGE_RPRC_NAME_TMP:=$(BOOTIMAGE_PATH)/$(OUTNAME).rprc_tmp + +# +# Generation of boot image which can be loaded by Secondary Boot Loader (SBL) +# +ifeq ($(OS),Windows_NT) +EXE_EXT=.exe +endif +ifeq ($(OS),Windows_NT) + BOOTIMAGE_CERT_GEN_CMD=powershell -executionpolicy unrestricted -command $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/x509CertificateGen.sh +endif +BOOTIMAGE_TEMP_OUT_FILE=$(PROFILE)/temp_stdout_$(PROFILE).txt + +BOOTIMAGE_CORE_ID_r5fss0-0 = 4 +BOOTIMAGE_CORE_ID_r5fss0-1 = 5 +BOOTIMAGE_CORE_ID_r5fss1-0 = 6 +BOOTIMAGE_CORE_ID_r5fss1-1 = 7 +BOOTIMAGE_CORE_ID_m4fss0-0 = 14 +SBL_RUN_ADDRESS=0x70000000 +SBL_DEV_ID=55 + +MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/multicoreImageGen/multicoreImageGen.js +OUTRPRC_CMD = $(CCS_NODE) $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/out2rprc/elf2rprc.js +APP_IMAGE_SIGN_CMD = $(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/signing/appimage_x509_cert_gen.py + +ifeq ($(OS),Windows_NT) + XIPGEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/xipGen/xipGen.exe +else + XIPGEN_CMD=$(MOTOR_CONTROL_SDK_PATH)/mcu_plus_sdk/tools/boot/xipGen/xipGen.out +endif + +MULTI_CORE_IMAGE_PARAMS = \ + $(BOOTIMAGE_RPRC_NAME)@$(BOOTIMAGE_CORE_ID_r5fss0-0) \ + +MULTI_CORE_IMAGE_PARAMS_XIP = \ + $(BOOTIMAGE_RPRC_NAME_XIP)@$(BOOTIMAGE_CORE_ID_r5fss0-0) \ + +all: +ifeq ($(CCS_IDE_MODE),cloud) +# No post build steps +else + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME) ... + $(OUTRPRC_CMD) $(OUTFILE) >> $(BOOTIMAGE_TEMP_OUT_FILE) + $(COPY) $(OUTNAME).rprc $(BOOTIMAGE_RPRC_NAME) + $(COPY) $(BOOTIMAGE_RPRC_NAME) $(BOOTIMAGE_RPRC_NAME_TMP) + $(RM) $(BOOTIMAGE_RPRC_NAME) + $(XIPGEN_CMD) -i $(BOOTIMAGE_RPRC_NAME_TMP) -o $(BOOTIMAGE_RPRC_NAME) -x $(BOOTIMAGE_RPRC_NAME_XIP) --flash-start-addr 0x60000000 -v > $(BOOTIMAGE_TEMP_OUT_FILE) + $(MULTI_CORE_IMAGE_GEN) --devID $(SBL_DEV_ID) --out $(BOOTIMAGE_NAME) $(MULTI_CORE_IMAGE_PARAMS) >> $(BOOTIMAGE_TEMP_OUT_FILE) + $(MULTI_CORE_IMAGE_GEN) --devID $(SBL_DEV_ID) --out $(BOOTIMAGE_NAME_XIP) $(MULTI_CORE_IMAGE_PARAMS_XIP) >> $(BOOTIMAGE_TEMP_OUT_FILE) +# Sign the appimage for HS-FS using appimage signing script + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --output $(BOOTIMAGE_NAME).hs_fs +ifeq ($(DEVICE_TYPE),HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --output $(BOOTIMAGE_NAME).hs +else + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME) --authtype 1 --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --output $(BOOTIMAGE_NAME).hs + $(RM) $(BOOTIMAGE_NAME)-enc +endif +endif + $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME) Done !!! + @echo . +ifeq ($(DEVICE_TYPE),HS) + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! + @echo . +else + @echo Boot image: am243x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo . +endif +endif diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec new file mode 100644 index 0000000..eb2fa40 --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec @@ -0,0 +1,20 @@ +# +# Auto generated makefile +# + +export MOTOR_CONTROL_SDK_PATH?=$(abspath ../../../../../..) +include $(MOTOR_CONTROL_SDK_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang + +all: + $(CCS_ECLIPSE) -noSplash -data $(MOTOR_CONTROL_SDK_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(MOTOR_CONTROL_SDK_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(MOTOR_CONTROL_SDK_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(MOTOR_CONTROL_SDK_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs new file mode 100644 index 0000000..c2be5da --- /dev/null +++ b/examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs @@ -0,0 +1,8 @@ +/* + * ======== syscfg_c.rov.xs ======== + * This file contains the information needed by the Runtime Object + * View (ROV) tool. + */ +var crovFiles = [ + "mcu_plus_sdk/kernel/freertos/rov/FreeRTOS.rov.js", +]; diff --git a/makefile.am243x b/makefile.am243x index fa9230a..1c9820e 100644 --- a/makefile.am243x +++ b/makefile.am243x @@ -77,6 +77,7 @@ help: @echo $(MAKE) -s -C examples/current_sense/icss_sdfm_three_channel_with_phase_compensation/am243x-lp/r5fss0-0_freertos/ti-arm-clang [all clean syscfg-gui syscfg] @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-evm/r5fss0-0_freertos/ti-arm-clang [all clean syscfg-gui syscfg] @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang [all clean syscfg-gui syscfg] + @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang [all clean syscfg-gui syscfg] @echo $(MAKE) -s -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt [all clean syscfg-gui syscfg] @echo $(MAKE) -s -C source/position_sense/endat/firmware/multi_channel_load_share/am243x-evm/icssg0-pru1_fw/ti-pru-cgt [all clean syscfg-gui syscfg] @echo $(MAKE) -s -C source/position_sense/endat/firmware/multi_channel_load_share/am243x-evm/icssg0-rtupru1_fw/ti-pru-cgt [all clean syscfg-gui syscfg] @@ -247,6 +248,7 @@ BUILD_COMBO_EXAMPLE_ALL += icss_sdfm_three_channel_with_phase_compensation_am243 BUILD_COMBO_EXAMPLE_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang BUILD_COMBO_EXAMPLE_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang BUILD_COMBO_EXAMPLE_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang +BUILD_COMBO_EXAMPLE_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang # Various System Example Targets BUILD_COMBO_EXAMPLE_PRIVATE_ALL = @@ -358,6 +360,9 @@ examples-private: $(BUILD_COMBO_EXAMPLE_PRIVATE_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile all + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile all + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile all @@ -448,6 +453,7 @@ BUILD_COMBO_EXAMPLE_CLEAN_ALL += icss_sdfm_three_channel_with_phase_compensation BUILD_COMBO_EXAMPLE_CLEAN_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean BUILD_COMBO_EXAMPLE_CLEAN_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang_clean BUILD_COMBO_EXAMPLE_CLEAN_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean +BUILD_COMBO_EXAMPLE_CLEAN_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean # Various System Example Clean Targets BUILD_COMBO_EXAMPLE_PRIVATE_CLEAN_ALL = @@ -559,6 +565,9 @@ examples-private-clean: $(BUILD_COMBO_EXAMPLE_PRIVATE_CLEAN_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile clean + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile clean + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt_clean: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile clean @@ -649,6 +658,7 @@ BUILD_COMBO_EXAMPLE_SCRUB_ALL += icss_sdfm_three_channel_with_phase_compensation BUILD_COMBO_EXAMPLE_SCRUB_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang_scrub BUILD_COMBO_EXAMPLE_SCRUB_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang_scrub BUILD_COMBO_EXAMPLE_SCRUB_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_scrub +BUILD_COMBO_EXAMPLE_SCRUB_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_scrub # Various System Example Scrub Targets BUILD_COMBO_EXAMPLE_PRIVATE_SCRUB_ALL = @@ -760,6 +770,9 @@ examples-scrub-private: $(BUILD_COMBO_EXAMPLE_PRIVATE_SCRUB_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_scrub: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile scrub + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_scrub: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile scrub + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt_scrub: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile scrub diff --git a/makefile_projectspec.am243x b/makefile_projectspec.am243x index 314a724..f4cdbfd 100644 --- a/makefile_projectspec.am243x +++ b/makefile_projectspec.am243x @@ -34,6 +34,7 @@ BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_ALL += icss_sdfm_three_channel_with_phase_ BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang_build BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang_build BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_build +BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_build # Various System Example Projectspec Build Targets BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_PRIVATE_ALL = @@ -145,6 +146,9 @@ all-private: $(BUILD_COMBO_EXAMPLE_PROJECTSPEC_BUILD_PRIVATE_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_build: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec all + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_build: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec all + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt_build: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile_projectspec all @@ -236,6 +240,7 @@ BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_ALL += icss_sdfm_three_channel_with_phase_ BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang_clean BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean +BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean # Various System Example Projectspec Clean Targets BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_PRIVATE_ALL = @@ -347,6 +352,9 @@ clean-private: $(BUILD_COMBO_EXAMPLE_PROJECTSPEC_CLEAN_PRIVATE_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec clean + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_clean: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec clean + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt_clean: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile_projectspec clean @@ -438,6 +446,7 @@ BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_ALL += icss_sdfm_three_channel_with_phase BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_ALL += icss_sdfm_three_channel_with_phase_compensation_am243x-lp_r5fss0-0_freertos_ti-arm-clang_export BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_ALL += pruicss_pwm_duty_cycle_am243x-evm_r5fss0-0_freertos_ti-arm-clang_export BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_ALL += pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_export +BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_ALL += pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_export # Various System Example Projectspec Export Targets BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_PRIVATE_ALL = @@ -549,6 +558,9 @@ export-private: $(BUILD_COMBO_EXAMPLE_PROJECTSPEC_EXPORT_PRIVATE_ALL) pruicss_pwm_duty_cycle_am243x-lp_r5fss0-0_freertos_ti-arm-clang_export: $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec export + pruicss_pwm_epwm_sync_am243x-lp_r5fss0-0_freertos_ti-arm-clang_export: + $(MAKE) -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec export + sdfm_firmware_am243x-evm_icssg0-pru0_fw_ti-pru-cgt_export: $(MAKE) -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile_projectspec export @@ -665,6 +677,7 @@ help: @echo $(MAKE) -s -C examples/current_sense/icss_sdfm_three_channel_with_phase_compensation/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec [export all clean] @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-evm/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec [export all clean] @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_duty_cycle/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec [export all clean] + @echo $(MAKE) -s -C examples/pruicss_pwm/pruicss_pwm_epwm_sync/am243x-lp/r5fss0-0_freertos/ti-arm-clang -f makefile_projectspec [export all clean] @echo $(MAKE) -s -C source/current_sense/sdfm/firmware/am243x-evm/icssg0-pru0_fw/ti-pru-cgt -f makefile_projectspec [export all clean] @echo $(MAKE) -s -C source/position_sense/endat/firmware/multi_channel_load_share/am243x-evm/icssg0-pru1_fw/ti-pru-cgt -f makefile_projectspec [export all clean] @echo $(MAKE) -s -C source/position_sense/endat/firmware/multi_channel_load_share/am243x-evm/icssg0-rtupru1_fw/ti-pru-cgt -f makefile_projectspec [export all clean] diff --git a/source/pruicss_pwm/driver/pruicss_pwm.c b/source/pruicss_pwm/driver/pruicss_pwm.c index 6bda74b..dcaaa21 100644 --- a/source/pruicss_pwm/driver/pruicss_pwm.c +++ b/source/pruicss_pwm/driver/pruicss_pwm.c @@ -1395,3 +1395,58 @@ int32_t PRUICSS_PWM_enableIEP1Slave(PRUICSS_Handle handle, uint8_t enable) } +int32_t PRUICSS_PWM_enableIEPResetOnEPWM0SyncOut(PRUICSS_Handle handle, uint8_t iepInstance, uint8_t enable) +{ + + PRUICSS_HwAttrs const *hwAttrs; + int32_t retVal = SystemP_FAILURE; + + if ((handle != NULL) && (iepInstance < PRUICSS_NUM_IEP_INSTANCES) && (enable < 2)) + { + retVal = SystemP_SUCCESS; + hwAttrs = (PRUICSS_HwAttrs const *)handle->hwAttrs; + + switch (iepInstance) + { + case 0: + HW_WR_FIELD32((hwAttrs->iep0RegBase + CSL_ICSS_G_PR1_IEP0_SLV_PWM_REG), + CSL_ICSS_G_PR1_IEP0_SLV_PWM_REG_PWM0_RST_CNT_EN, enable); + break; + case 1: + HW_WR_FIELD32((hwAttrs->iep1RegBase + CSL_ICSS_G_PR1_IEP1_SLV_PWM_REG), + CSL_ICSS_G_PR1_IEP1_SLV_PWM_REG_PWM0_RST_CNT_EN, enable); + break; + } + } + + return retVal; + +} + +int32_t PRUICSS_PWM_enableIEPResetOnEPWM3SyncOut(PRUICSS_Handle handle, uint8_t iepInstance, uint8_t enable) +{ + + PRUICSS_HwAttrs const *hwAttrs; + int32_t retVal = SystemP_FAILURE; + + if ((handle != NULL) && (iepInstance < PRUICSS_NUM_IEP_INSTANCES) && (enable < 2)) + { + retVal = SystemP_SUCCESS; + hwAttrs = (PRUICSS_HwAttrs const *)handle->hwAttrs; + + switch (iepInstance) + { + case 0: + HW_WR_FIELD32((hwAttrs->iep0RegBase + CSL_ICSS_G_PR1_IEP0_SLV_PWM_REG), + CSL_ICSS_G_PR1_IEP0_SLV_PWM_REG_PWM3_RST_CNT_EN, enable); + break; + case 1: + HW_WR_FIELD32((hwAttrs->iep1RegBase + CSL_ICSS_G_PR1_IEP1_SLV_PWM_REG), + CSL_ICSS_G_PR1_IEP1_SLV_PWM_REG_PWM3_RST_CNT_EN, enable); + break; + } + } + + return retVal; + +} \ No newline at end of file diff --git a/source/pruicss_pwm/include/pruicss_pwm.h b/source/pruicss_pwm/include/pruicss_pwm.h index be0cf61..8ffa392 100644 --- a/source/pruicss_pwm/include/pruicss_pwm.h +++ b/source/pruicss_pwm/include/pruicss_pwm.h @@ -531,6 +531,28 @@ int32_t PRUICSS_PWM_configurePwmEfficiencyModeEnable(PRUICSS_Handle handle, uint */ int32_t PRUICSS_PWM_enableIEP1Slave(PRUICSS_Handle handle, uint8_t enable); +/** + * \brief This API sets enables/disables of IEP counter reset on EPWM0 SYNC OUT event in IEP module. + * + * \param handle PRUICSS_Handle returned from PRUICSS_open() + * \param iepInstance 0 for IEP0, 1 for IEP1 + * \param enable 0 for disable, 1 for enable + * \return SystemP_SUCCESS on success, SystemP_FAILURE on error + * + */ +int32_t PRUICSS_PWM_enableIEPResetOnEPWM0SyncOut(PRUICSS_Handle handle, uint8_t iepInstance, uint8_t enable); + +/** + * \brief This API sets enables/disables of IEP counter reset on EPWM3 SYNCOUT in IEP module. + * + * \param handle PRUICSS_Handle returned from PRUICSS_open() + * \param iepInstance 0 for IEP0, 1 for IEP1 + * \param enable 0 for disable, 1 for enable + * \return SystemP_SUCCESS on success, SystemP_FAILURE on error + * + */ +int32_t PRUICSS_PWM_enableIEPResetOnEPWM3SyncOut(PRUICSS_Handle handle, uint8_t iepInstance, uint8_t enable); + /** @} */ #ifdef __cplusplus