From 7347ff42105970c93cd5c5f76ca396b83e24315f Mon Sep 17 00:00:00 2001 From: Ayushman Date: Fri, 12 Jun 2026 19:30:25 +0530 Subject: [PATCH 1/2] am261x: SPI max frequency Signed-off-by: Ayushman a-ayushman@ti.com --- .github/workflows/ccs_build.yml | 6 +- .github/workflows/makefile.yml | 6 +- .metadata/product.json | 30 +- .../common/pru_blocks_static_module.syscfg.js | 6 +- .../pru_io_blocks/pru_spi_read.syscfg.js | 198 +++++++---- .../pru_io_blocks/pru_spi_transfer.syscfg.js | 127 ++++--- .../pru_io_blocks/pru_spi_write.syscfg.js | 155 ++++---- .../pru_io_blocks/uart_rx_op.syscfg.js | 3 +- .../pru_io_blocks/uart_tx_op.syscfg.js | 3 +- .../pru_blocks/utils/data_splitter.syscfg.js | 2 +- .../utils/memory_access_block.syscfg.js | 6 +- README.md | 6 +- .../pru_spi_read_block.md | 14 +- .../pru_spi_transfer_block.md | 14 +- .../pru_spi_write_block.md | 14 +- .../ti-arm-clang/example.projectspec | 10 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 120 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 94 ++--- .../ti-arm-clang/example.projectspec | 8 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 122 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 95 ++--- .../ti-arm-clang/example.projectspec | 10 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 120 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 94 ++--- .../ti-arm-clang/example.projectspec | 10 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 120 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 94 ++--- examples/makefile | 1 + .../am261x-lp/icss_m1_pru0_fw/example.syscfg | 50 +++ .../ti-pru-cgt/example.projectspec | 83 +++++ .../icss_m1_pru0_fw/ti-pru-cgt/linker.cmd | 54 +++ .../icss_m1_pru0_fw/ti-pru-cgt/makefile | 55 +++ .../ti-pru-cgt/makefile_projectspec | 16 + .../am261x-lp/icss_m1_pru1_fw/example.syscfg | 49 +++ .../ti-pru-cgt/example.projectspec | 83 +++++ .../icss_m1_pru1_fw/ti-pru-cgt/linker.cmd | 54 +++ .../icss_m1_pru1_fw/ti-pru-cgt/makefile | 55 +++ .../ti-pru-cgt/makefile_projectspec | 16 + examples/spi_10mhz/firmware/main.asm | 40 +++ examples/spi_10mhz/images/spi_10mhz.png | Bin 0 -> 13368 bytes examples/spi_10mhz/makefile | 106 ++++++ .../r5fss0-0_freertos/example.syscfg | 327 +++++++++++++++++ .../am261x-lp/r5fss0-0_freertos/main.c | 84 +++++ .../ti-arm-clang/example.projectspec | 116 ++++++ .../r5fss0-0_freertos/ti-arm-clang/makefile | 336 ++++++++++++++++++ .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 95 +++++ .../ti-arm-clang/makefile_projectspec | 16 + .../ti-arm-clang/syscfg_c.rov.xs | 12 + examples/spi_10mhz/mcuplus/empty_example.c | 86 +++++ examples/spi_10mhz/readme.md | 169 +++++++++ .../ti-arm-clang/example.projectspec | 10 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 120 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 94 ++--- .../ti-arm-clang/example.projectspec | 10 +- .../r5fss0-0_freertos/ti-arm-clang/makefile | 120 +++---- .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 94 ++--- 63 files changed, 2932 insertions(+), 1004 deletions(-) create mode 100644 examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile create mode 100644 examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec create mode 100644 examples/spi_10mhz/firmware/main.asm create mode 100644 examples/spi_10mhz/images/spi_10mhz.png create mode 100644 examples/spi_10mhz/makefile create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/main.c create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec create mode 100644 examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs create mode 100644 examples/spi_10mhz/mcuplus/empty_example.c create mode 100644 examples/spi_10mhz/readme.md create mode 100644 examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs diff --git a/.github/workflows/ccs_build.yml b/.github/workflows/ccs_build.yml index 2aa3852..bfafe9d 100644 --- a/.github/workflows/ccs_build.yml +++ b/.github/workflows/ccs_build.yml @@ -158,9 +158,9 @@ jobs: sdk_installer: mcu_plus_sdk_am243x_11_02_00_24-linux-x64-installer.run sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-ouHbHEm1PK/11.02.00.24/mcu_plus_sdk_am243x_11_02_00_24-linux-x64-installer.run - device: am261x - mcu_plus_sdk: mcu_plus_sdk_am261x_10_02_00_15 - sdk_installer: mcu_plus_sdk_am261x_10_02_00_15-linux-x64-installer.run - sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-h64OlWnQrg/10.02.00.15/mcu_plus_sdk_am261x_10_02_00_15-linux-x64-installer.run + mcu_plus_sdk: mcu_plus_sdk_am261x_26_00_00_06 + sdk_installer: mcu_plus_sdk_am261x_26_00_00_06-linux-x64-installer.run + sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-h64OlWnQrg/26.00.00.06.STS/mcu_plus_sdk_am261x_26_00_00_06-linux-x64-installer.run - device: am263px mcu_plus_sdk: mcu_plus_sdk_am263px_10_02_00_15 sdk_installer: mcu_plus_sdk_am263px_10_02_00_15-linux-x64-installer.run diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index f831a5b..0202e9e 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -28,9 +28,9 @@ jobs: sdk_installer: mcu_plus_sdk_am243x_11_02_00_24-linux-x64-installer.run sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-ouHbHEm1PK/11.02.00.24/mcu_plus_sdk_am243x_11_02_00_24-linux-x64-installer.run - device: am261x - mcu_plus_sdk: mcu_plus_sdk_am261x_10_02_00_15 - sdk_installer: mcu_plus_sdk_am261x_10_02_00_15-linux-x64-installer.run - sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-h64OlWnQrg/10.02.00.15/mcu_plus_sdk_am261x_10_02_00_15-linux-x64-installer.run + mcu_plus_sdk: mcu_plus_sdk_am261x_26_00_00_06 + sdk_installer: mcu_plus_sdk_am261x_26_00_00_06-linux-x64-installer.run + sdk_url: https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-h64OlWnQrg/26.00.00.06.STS/mcu_plus_sdk_am261x_26_00_00_06-linux-x64-installer.run - device: am263px mcu_plus_sdk: mcu_plus_sdk_am263px_10_02_00_15 sdk_installer: mcu_plus_sdk_am263px_10_02_00_15-linux-x64-installer.run diff --git a/.metadata/product.json b/.metadata/product.json index bfab36d..d6704c6 100644 --- a/.metadata/product.json +++ b/.metadata/product.json @@ -14,7 +14,9 @@ "AM243x_ALV_beta", "AM243x_ALX_beta", "AM261x_ZFG", - "AM261x_ZCZ" + "AM261x_ZCZ", + "AM261x_ZNC", + "AM261x_ZFG_400", ], "contexts": { "AM64x": [{ @@ -91,6 +93,19 @@ "name": "icss_g1_tx_pru1", "targetdbId": "icss_g1_tx_pru1" }], + "AM261x_ZFG_400": [{ + "name": "icss_m0_pru0", + "targetdbId": "icss_m0_pru0" + },{ + "name": "icss_m0_pru1", + "targetdbId": "icss_m0_pru1" + },{ + "name": "icss_m1_pru0", + "targetdbId": "icss_m1_pru0" + },{ + "name": "icss_m1_pru1", + "targetdbId": "icss_m1_pru1" + }], "AM261x_ZFG": [{ "name": "icss_m0_pru0", "targetdbId": "icss_m0_pru0" @@ -117,6 +132,19 @@ "name": "icss_m1_pru1", "targetdbId": "icss_m1_pru1" }], + "AM261x_ZNC": [{ + "name": "icss_m0_pru0", + "targetdbId": "icss_m0_pru0" + },{ + "name": "icss_m0_pru1", + "targetdbId": "icss_m0_pru1" + },{ + "name": "icss_m1_pru0", + "targetdbId": "icss_m1_pru0" + },{ + "name": "icss_m1_pru1", + "targetdbId": "icss_m1_pru1" + }], "AM243x_ALX_beta": [{ "name": "icss_g0_pru0", "targetdbId": "icss_g0_pru0" diff --git a/.metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js index c198baf..21a84f5 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js @@ -930,10 +930,8 @@ function validate(inst, report) validateR31SimulationInput(inst, report); // Check for UART blocks and warn about unsupported simulation - const uartTxModule = system.modules["/pru_blocks/pru_io_blocks/uart_tx"]; - const uartRxModule = system.modules["/pru_blocks/pru_io_blocks/uart_rx"]; - const hasUartBlock = (uartTxModule && uartTxModule.$instances && uartTxModule.$instances.length > 0) || - (uartRxModule && uartRxModule.$instances && uartRxModule.$instances.length > 0); + const uartModule = system.modules["/pru_blocks/pru_io_blocks/uart_config"]; + const hasUartBlock = (uartModule && uartModule.$instances && uartModule.$instances.length > 0) if (hasUartBlock) { report.logWarning( diff --git a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_read.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_read.syscfg.js index 69f6cbb..4605174 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_read.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_read.syscfg.js @@ -69,25 +69,32 @@ function validate(inst, report) { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + if (mode === "MODE0") { - // delay_component1 = high - 4, delay_component2 = low - 3 + // delay_component1 = high - 4, delay_component2 = low - 3 - dataSetup if (high < 4) report.logError("MODE0: SCLK High Width must be at least 4 cycles (overhead compensation for delay_component1)", inst, "sclk high pulse width (in PRU cycles)"); - if (low < 3) report.logError("MODE0: SCLK Low Width must be at least 3 cycles (overhead compensation for delay_component2)", inst, "sclk low pulse width (in PRU cycles)"); + if (low < 3 + dataSetup) report.logError(`MODE0: SCLK Low Width must be at least ${3 + dataSetup} cycles (3 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); } else if (mode === "MODE1") { - // delay_component1 = high - 1, delay_component2 = low - 6 - if (high < 1) report.logError("MODE1: SCLK High Width must be at least 1 cycle (overhead compensation for delay_component1)", inst, "sclk high pulse width (in PRU cycles)"); - if (low < 6) report.logError("MODE1: SCLK Low Width must be at least 6 cycles (overhead compensation for delay_component2)", inst, "sclk low pulse width (in PRU cycles)"); + // delay_component1 = high - 2 - dataSetup, delay_component2 = low - 5 + if (high < 2 + dataSetup) report.logError(`MODE1: SCLK High Width must be at least ${2 + dataSetup} cycles (2 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); + if (low < 5) report.logError("MODE1: SCLK Low Width must be at least 5 cycles (overhead compensation for delay_component2)", inst, "sclk low pulse width (in PRU cycles)"); } else if (mode === "MODE2") { - // delay_component1 = low - 4, delay_component2 = high - 3 + // delay_component1 = low - 4, delay_component2 = high - 3 - dataSetup if (low < 4) report.logError("MODE2: SCLK Low Width must be at least 4 cycles (overhead compensation for delay_component1)", inst, "sclk low pulse width (in PRU cycles)"); - if (high < 3) report.logError("MODE2: SCLK High Width must be at least 3 cycles (overhead compensation for delay_component2)", inst, "sclk high pulse width (in PRU cycles)"); + if (high < 3 + dataSetup) report.logError(`MODE2: SCLK High Width must be at least ${3 + dataSetup} cycles (3 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); } else if (mode === "MODE3") { - // delay_component1 = low - 1, delay_component2 = high - 6 - if (low < 1) report.logError("MODE3: SCLK Low Width must be at least 1 cycle (overhead compensation for delay_component1)", inst, "sclk low pulse width (in PRU cycles)"); - if (high < 6) report.logError("MODE3: SCLK High Width must be at least 6 cycles (overhead compensation for delay_component2)", inst, "sclk high pulse width (in PRU cycles)"); + // delay_component1 = low - 2 - dataSetup, delay_component2 = high - 5 + if (low < 2 + dataSetup) report.logError(`MODE3: SCLK Low Width must be at least ${2 + dataSetup} cycles (2 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); + if (high < 5) report.logError("MODE3: SCLK High Width must be at least 5 cycles (overhead compensation for delay_component2)", inst, "sclk high pulse width (in PRU cycles)"); } } } @@ -180,13 +187,13 @@ function getMacro(pruInstructionMacro, opCode) { READ_BIT_LOOP?: set r30, r30, ${SCLK_PIN} sub ${bitId}, ${bitId}, 1 - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - clr r30, r30, ${SCLK_PIN} - .loop ${DATA_SETUP_TIME} + .loop ${DELAY_COMPEN_1} nop .endloop + clr r30, r30, ${SCLK_PIN} qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} set ${dataReg}, ${dataReg}, ${bitId} qba SKIP_BIT_ENTRY_0? @@ -211,14 +218,13 @@ SKIP_BIT_ENTRY_0?: ldi ${bitId}, 0 READ_BIT_LOOP?: set r30, r30, ${SCLK_PIN} - ; m_wait_cycles 7 - .loop ${DELAY_COMPEN_1} ; 6 + .loop ${DATA_SETUP_TIME} nop .endloop - clr r30, r30, ${SCLK_PIN} - .loop ${DATA_SETUP_TIME} + .loop ${DELAY_COMPEN_1} nop .endloop + clr r30, r30, ${SCLK_PIN} qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} set ${dataReg}, ${dataReg}, ${bitId} qba SKIP_BIT_ENTRY_0? @@ -246,11 +252,11 @@ SKIP_BIT_ENTRY_0?: ldi ${bitId}, ${PACKETSIZE} READ_BIT_LOOP?: sub ${bitId}, ${bitId}, 1 - set r30, r30, ${SCLK_PIN} - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - .loop ${DATA_SETUP_TIME} + set r30, r30, ${SCLK_PIN} + .loop ${DELAY_COMPEN_1} nop .endloop qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} @@ -277,11 +283,11 @@ SKIP_BIT_ENTRY_0?: .endloop ldi ${bitId}, 0 READ_BIT_LOOP?: - set r30, r30, ${SCLK_PIN} - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - .loop ${DATA_SETUP_TIME} + set r30, r30, ${SCLK_PIN} + .loop ${DELAY_COMPEN_1} nop .endloop qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} @@ -314,13 +320,13 @@ SKIP_BIT_ENTRY_0?: READ_BIT_LOOP?: clr r30, r30, ${SCLK_PIN} sub ${bitId}, ${bitId}, 1 - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - set r30, r30, ${SCLK_PIN} - .loop ${DATA_SETUP_TIME} + .loop ${DELAY_COMPEN_1} nop .endloop + set r30, r30, ${SCLK_PIN} qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} set ${dataReg}, ${dataReg}, ${bitId} qba SKIP_BIT_ENTRY_0? @@ -346,19 +352,19 @@ SKIP_BIT_ENTRY_0?: ldi ${bitId}, 0 READ_BIT_LOOP?: clr r30, r30, ${SCLK_PIN} - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - set r30, r30, ${SCLK_PIN} - .loop ${DATA_SETUP_TIME} + .loop ${DELAY_COMPEN_1} nop .endloop + nop + set r30, r30, ${SCLK_PIN} qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} set ${dataReg}, ${dataReg}, ${bitId} qba SKIP_BIT_ENTRY_0? BIT_ENTRY_0?: clr ${dataReg}, ${dataReg}, ${bitId} - nop SKIP_BIT_ENTRY_0?: add ${bitId}, ${bitId}, 1 .loop ${DELAY_COMPEN_2} @@ -381,11 +387,11 @@ SKIP_BIT_ENTRY_0?: ldi ${bitId}, ${PACKETSIZE} READ_BIT_LOOP?: sub ${bitId}, ${bitId}, 1 - clr r30, r30, ${SCLK_PIN} - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - .loop ${DATA_SETUP_TIME} + clr r30, r30, ${SCLK_PIN} + .loop ${DELAY_COMPEN_1} nop .endloop qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} @@ -413,11 +419,11 @@ SKIP_BIT_ENTRY_0?: .endloop ldi ${bitId}, 0 READ_BIT_LOOP?: - clr r30, r30, ${SCLK_PIN} - .loop ${DELAY_COMPEN_1} + .loop ${DATA_SETUP_TIME} nop .endloop - .loop ${DATA_SETUP_TIME} + clr r30, r30, ${SCLK_PIN} + .loop ${DELAY_COMPEN_1} nop .endloop qbbc BIT_ENTRY_0?, r31, ${SDI_PIN} @@ -730,7 +736,7 @@ const spi_read1 = pru_spi_read.addInstance(); | sclk low pulse width (in PRU cycles) | Integer | 1-0xFFFFFFFF | 7 | Clock low time (Controller only) | | CS Setup Time | Integer | 0-10000 | 35 | CS setup time in nanoseconds (Controller only) | | CS Hold Time | Integer | 0-10000 | 10 | CS hold time in nanoseconds (Controller only) | -| Data Setup Time | Integer | 0-100 | 0 | Data setup time in PRU cycles (Controller only) | +| Data Setup Time | Integer | 0-10000 | 0 | Data setup time in nanoseconds, converted to PRU cycles internally (Controller only) | | CS Filter Cycles | Integer | 1-0xFFFFFFFF | 2 | CS glitch filter cycles (Peripheral only) | ### Example Configurations @@ -856,14 +862,20 @@ SPI is a synchronous serial communication protocol with: - The **SPI Clock Frequency** field below automatically calculates the actual frequency based on your configured PRU clock - Peripheral mode follows controller's clock timing -### Maximum Achievable Frequency (at 200 MHz PRU Clock) -Different SPI modes have different minimum SCLK width requirements due to timing overhead: -- **MODE0**: Min High=4, Min Low=3 → Max Frequency = 28.57 MHz (Total: 7 cycles) -- **MODE1**: Min High=1, Min Low=6 → Max Frequency = 28.57 MHz (Total: 7 cycles) -- **MODE2**: Min High=3, Min Low=4 → Max Frequency = 28.57 MHz (Total: 7 cycles) -- **MODE3**: Min High=6, Min Low=1 → Max Frequency = 28.57 MHz (Total: 7 cycles) +### Maximum Achievable Frequency +Different SPI modes have different minimum SCLK width requirements due to timing overhead. +Cycles per bit: **(2+d1) + (5+d2)** + +**Theoretical Maximum (d1=0, d2=0 — controller overhead only):** +- **MODE0**: Min High=4, Min Low=3 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) +- **MODE1**: Min High=1, Min Low=6 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) +- **MODE2**: Min High=3, Min Low=4 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) +- **MODE3**: Min High=6, Min Low=1 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) + +**Practical Maximum (d1=10, d2=7 — recommended for reliable operation):** +- All modes: Min High+Low = 24 cycles → **200 MHz = 8.33 MHz** | **333 MHz = 13.88 MHz** -**Note**: These are theoretical maximums at 200 MHz PRU clock. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. Always verify with oscilloscope and increase pulse widths if data corruption occurs. +**Note**: Theoretical maximums assume ideal peripheral response. Practical values (d1=10, d2=7) are recommended for reliable operation and are validated against the open-pru SPI slave macros. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. Always verify with oscilloscope and increase pulse widths if data corruption occurs. ### Setup and Hold Times (Controller Mode Only) @@ -871,9 +883,9 @@ Different SPI modes have different minimum SCLK width requirements due to timing - **CS Setup Time**: Time delay (in nanoseconds) after CS assertion before starting SPI transaction. This ensures the peripheral device is ready before data transfer begins. - **CS Hold Time**: Time delay (in nanoseconds) after the last bit is transferred before CS deassertion. This ensures the peripheral device has latched the data properly. -- **Data Setup Time**: Time delay (in PRU cycles) after clock edge before sampling data. This provides additional setup time for data stability on slow devices. +- **Data Setup Time**: Minimum time (in nanoseconds) MISO data must be stable before the sampling clock edge. Nops are inserted before the sampling edge. Automatically converted to PRU cycles internally using Math.ceil. -**Note**: CS Setup Time and CS Hold Time are specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. +**Note**: CS Setup Time, CS Hold Time, and Data Setup Time are all specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. ### Peripheral Mode Parameters - **CS Filter Cycles**: Number of consecutive cycles CS must be stable to be considered valid. This provides glitch rejection for noisy CS signals. @@ -1011,10 +1023,18 @@ exports = { default : "TEMP_REG1", getValue: (inst) => { if (inst["Device Mode"] === "controller") { + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); // Controller mode: dataReg, PACKETSIZE, bitId, SCLK_PIN, SDI_PIN, DELAY_COMPEN_1, DELAY_COMPEN_2, CS_PIN, CS_SETUP_TIME, CS_HOLD_TIME, DATA_SETUP_TIME return inst["packetSize"] + ", TEMP_REG1.b0, " + inst["SCLK Signal"] +", " + inst["SDI Signal"] + ", " + inst["delay_component1"] + ", " + inst["delay_component2"] + ", " + inst["CS Signal"] - + ", " + inst["CS Setup Time"] + ", " + inst["CS Hold Time"] + ", " + inst["Data Setup Time"]; + + ", " + csSetupCycles + ", " + csHoldCycles + ", " + dataSetupCycles; } else { // Peripheral mode: dataReg, PACKETSIZE, bitId, SCLK_PIN, SDI_PIN, CS_PIN, CS_FILTER_CYCLES (MODE removed - now in macro name) return inst["packetSize"] + ", TEMP_REG1.b0, " + inst["SCLK Signal"] @@ -1151,10 +1171,10 @@ exports = { }, { name: "Data Setup Time", - displayName: "Data Setup Time", - description: "Time delay after clock edge before sampling data (setup time for data stability)", + displayName: "Data Setup Time (ns)", + description: "Time after clock edge before sampling data (nanoseconds). Converted to PRU cycles internally using Math.ceil.", default: 0, - range: [0, 100], + range: [0, 10000], hidden: false }, { @@ -1166,7 +1186,7 @@ exports = { }, { name: "CS Setup Time", - displayName: "CS Setup Time (nanoseconds)", + displayName: "CS Setup Time (ns)", description: "Time delay after CS assertion before starting SPI transaction", default: 35, range: [0, 10000], @@ -1174,7 +1194,7 @@ exports = { }, { name: "CS Hold Time", - displayName: "CS Hold Time (nanoseconds)", + displayName: "CS Hold Time (ns)", description: "Time delay after SPI transaction before CS deassertion", default: 10, range: [0, 10000], @@ -1194,21 +1214,29 @@ exports = { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + let value = 0; // MODE0: SHIFTING_EDGE = SET SCLK (HIGH pulse starts), overhead = 5 if (mode === "MODE0") value = high - 4; - // MODE1: SHIFTING_EDGE = SET SCLK (HIGH pulse starts), overhead = 1 - else if (mode === "MODE1") value = high - 1; + // MODE1: DATA_SETUP_TIME is now in the HIGH half (before CLR SCLK sampling edge) + // HIGH half overhead: SET SCLK + sub (1) + dataSetup = 2 + dataSetup + else if (mode === "MODE1") value = high - 2 - dataSetup; - // MODE2: SHIFTING_EDGE = CLR SCLK (LOW pulse starts), overhead = 5 - // Uses LOW parameter because clock is inverted - else if (mode === "MODE2") value = low - 4; + // MODE2: DATA_SETUP_TIME is in the HIGH half (before CLR SCLK sampling edge) + // HIGH half overhead: sub(1) + dataSetup + DELAY_COMPEN_1 → delay_component1 = low - 1 - dataSetup (using low as HIGH pulse base) + else if (mode === "MODE2") value = low - 4 ; - // MODE3: SHIFTING_EDGE = CLR SCLK (LOW pulse starts), overhead = 2 - // Uses LOW parameter because clock is inverted - else value = low - 1; // MODE3 + // MODE3: DATA_SETUP_TIME is now in the LOW half (before SET SCLK sampling edge) + // LOW half overhead: CLR SCLK + sub (1) + dataSetup = 2 + dataSetup + else value = low - 2 - dataSetup; // MODE3 // Ensure delay component is not negative return Math.max(0, value); @@ -1228,23 +1256,30 @@ exports = { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + let value = 0; - // MODE0: CLR SCLK starts LOW pulse, overhead = 3 - if (mode === "MODE0") value = low - 3; + // MODE0: DATA_SETUP_TIME is in the LOW half (before SET SCLK sampling edge) + // LOW half overhead: CLR SCLK + dataSetup + bit handling (4) + qbne (1) = 6 + dataSetup + if (mode === "MODE0") value = low - 3 - dataSetup; - // MODE1: CLR SCLK starts LOW pulse, overhead = 6 - // 1(clr) + DATA_SETUP_TIME + 4(bit handling) + DELAY_COMPEN_2 + 1(qbne) = 6 + delay - else if (mode === "MODE1") value = low - 6; + // MODE1: DATA_SETUP_TIME is in the HIGH half (not here) + // LOW half overhead: CLR SCLK + bit handling (4) + qbne (1) = 6 + else if (mode === "MODE1") value = low - 5; - // MODE2: SET SCLK starts HIGH pulse, overhead = 3 - // Uses HIGH parameter because clock is inverted - else if (mode === "MODE2") value = high - 3; + // MODE2: DATA_SETUP_TIME is in the HIGH half (not here — DELAY_COMPEN_2 is in LOW half) + // LOW half overhead: read SDI(4) + SET SCLK(1) + add/sub(1) + qbne(1) = 7... using base of 3 + else if (mode === "MODE2") value = high - 3 - dataSetup; - // MODE3: SET SCLK starts HIGH pulse, overhead = 6 - // 1(set) + DATA_SETUP_TIME + 4(bit handling) + DELAY_COMPEN_2 + 1(qbne) = 6 + delay - // Uses HIGH parameter because clock is inverted - else value = high - 6; // MODE3 + // MODE3: DATA_SETUP_TIME is in the LOW half (not here) + // HIGH half overhead: SET SCLK + bit handling (4) + qbne (1) = 6 + else value = high - 5; // MODE3 // Ensure delay component is not negative return Math.max(0, value); @@ -1372,16 +1407,21 @@ exports = { // Controller mode: includes CS setup, bit loop, and CS hold time // Peripheral mode: includes CS filter, bit loop (no CS setup/hold) if (inst["Device Mode"] === "controller") { - const csSetupTime = inst["CS Setup Time"]; - const csHoldTime = inst["CS Hold Time"]; - const dataSetupTime = inst["Data Setup Time"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); - // Cycles per bit: 7 fixed + DATA_SETUP_TIME + delay_component1 + delay_component2 - const cyclesPerBit = 7 + dataSetupTime + inst["delay_component1"] + inst["delay_component2"]; + // Cycles per bit: fixed overhead + DATA_SETUP_TIME + delay_component1 + delay_component2 + const cyclesPerBit = 7 + dataSetupCycles + inst["delay_component1"] + inst["delay_component2"]; - return 1 + csSetupTime + 1 + + return 1 + csSetupCycles + 1 + (inst["packetSize"] * cyclesPerBit) + - csHoldTime + 1; + csHoldCycles + 1; } else { return 4 + inst["delay_component1"] + (inst["packetSize"] - 1) * (6 + inst["delay_component1"] + inst["delay_component2"]); } diff --git a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_transfer.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_transfer.syscfg.js index 59fd443..7b95e68 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_transfer.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_transfer.syscfg.js @@ -79,36 +79,47 @@ function validate(inst, report) { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + if (mode === "MODE0") { - if (high < 4) { - report.logError("MODE0: SCLK High Width must be at least 4 cycles", inst, "sclk high pulse width (in PRU cycles)"); + // delay_component1 = low - 6 - dataSetup, delay_component2 = high - 4 + if (low < 6 + dataSetup) { + report.logError(`MODE0: SCLK Low Width must be at least ${6 + dataSetup} cycles (6 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); } - if (low < 6) { - report.logError("MODE0: SCLK Low Width must be at least 6 cycles (overhead compensation)", inst, "sclk low pulse width (in PRU cycles)"); + if (high < 4) { + report.logError("MODE0: SCLK High Width must be at least 4 cycles (overhead compensation)", inst, "sclk high pulse width (in PRU cycles)"); } } else if (mode === "MODE1") { - if (high < 2) { - report.logError("MODE1: SCLK High Width must be at least 2 cycles", inst, "sclk high pulse width (in PRU cycles)"); + // delay_component1 = high - 4 - dataSetup, delay_component2 = low - 6 + if (high < 4 + dataSetup) { + report.logError(`MODE1: SCLK High Width must be at least ${4 + dataSetup} cycles (4 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); } if (low < 6) { - report.logError("MODE1: SCLK Low Width must be at least 6 cycles", inst, "sclk low pulse width (in PRU cycles)"); + report.logError("MODE1: SCLK Low Width must be at least 6 cycles (overhead compensation)", inst, "sclk low pulse width (in PRU cycles)"); } } else if (mode === "MODE2") { + // delay_component1 = high - 6 - dataSetup, delay_component2 = low - 4 + if (high < 6 + dataSetup) { + report.logError(`MODE2: SCLK High Width must be at least ${6 + dataSetup} cycles (6 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); + } if (low < 4) { report.logError("MODE2: SCLK Low Width must be at least 4 cycles (overhead compensation)", inst, "sclk low pulse width (in PRU cycles)"); } - if (high < 6) { - report.logError("MODE2: SCLK High Width must be at least 6 cycles (overhead compensation)", inst, "sclk high pulse width (in PRU cycles)"); - } } else if (mode === "MODE3") { - if (low < 2) { - report.logError("MODE3: SCLK Low Width must be at least 2 cycles", inst, "sclk low pulse width (in PRU cycles)"); + // delay_component1 = low - 4 - dataSetup, delay_component2 = high - 6 + if (low < 4 + dataSetup) { + report.logError(`MODE3: SCLK Low Width must be at least ${4 + dataSetup} cycles (4 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); } if (high < 6) { - report.logError("MODE3: SCLK High Width must be at least 6 cycles", inst, "sclk high pulse width (in PRU cycles)"); + report.logError("MODE3: SCLK High Width must be at least 6 cycles (overhead compensation)", inst, "sclk high pulse width (in PRU cycles)"); } } } @@ -1011,7 +1022,7 @@ const spi1 = pru_spi_transfer.addInstance(); | sclk low pulse width (in PRU cycles) | Integer | 1-0xFFFFFFFF | 7 | Clock low time (Controller only) | | CS Setup Time | Integer | 0-10000 | 35 | CS setup time in nanoseconds (Controller only) | | CS Hold Time | Integer | 0-10000 | 10 | CS hold time in nanoseconds (Controller only) | -| Data Setup Time | Integer | 0-100 | 0 | Data setup time in PRU cycles (Controller only) | +| Data Setup Time | Integer | 0-10000 | 0 | Data setup time in nanoseconds, converted to PRU cycles internally (Controller only) | | CS Filter Cycles | Integer | 1-0xFFFFFFFF | 2 | CS glitch filter cycles (Peripheral only) | ### Example Configurations @@ -1142,20 +1153,26 @@ SPI is a synchronous serial communication protocol with: - 200 MHz: 1 cycle = 5ns - 250 MHz: 1 cycle = 4ns - 333.333 MHz: 1 cycle = 3ns -- **Example** (at 333.333 MHz): High=13, Low=11 → 24 cycles per bit → ~13.9MHz SPI clock -- **Example** (at 200 MHz): High=13, Low=11 → 24 cycles per bit → ~8.3MHz SPI clock +- **Example** (at 333.333 MHz): High=13, Low=13 → 26 cycles per bit → ~12.8MHz SPI clock +- **Example** (at 200 MHz): High=13, Low=13 → 26 cycles per bit → ~7.69MHz SPI clock - The **SPI Clock Frequency** field below automatically calculates the actual frequency based on your configured PRU clock - Peripheral mode follows controller's clock timing - **Important**: Timing margins must be sufficient for peripheral response time. Increase pulse widths if data transfer is unreliable. -### Maximum Achievable Frequency (at 200 MHz PRU Clock) -Different SPI modes have different minimum SCLK width requirements due to timing overhead: -- **MODE0**: Min High=4, Min Low=6 → Max Frequency = 20.00 MHz (Total: 10 cycles) -- **MODE1**: Min High=2, Min Low=6 → Max Frequency = 25.00 MHz (Total: 8 cycles) -- **MODE2**: Min High=6, Min Low=4 → Max Frequency = 20.00 MHz (Total: 10 cycles) -- **MODE3**: Min High=6, Min Low=2 → Max Frequency = 25.00 MHz (Total: 8 cycles) +### Maximum Achievable Frequency +Different SPI modes have different minimum SCLK width requirements due to timing overhead. +Cycles per bit: **(4+d1) + (6+d2)** + +**Theoretical Maximum (d1=0, d2=0 — controller overhead only):** +- **MODE0**: Min High=4, Min Low=6 → 200 MHz = 20.00 MHz | 333 MHz = 33.30 MHz (Total: 10 cycles) +- **MODE1**: Min High=2, Min Low=6 → 200 MHz = 25.00 MHz | 333 MHz = 41.63 MHz (Total: 8 cycles) +- **MODE2**: Min High=6, Min Low=4 → 200 MHz = 20.00 MHz | 333 MHz = 33.30 MHz (Total: 10 cycles) +- **MODE3**: Min High=6, Min Low=2 → 200 MHz = 25.00 MHz | 333 MHz = 41.63 MHz (Total: 8 cycles) + +**Practical Maximum (d1=9, d2=7 — validated for PRU-to-PRU loopback):** +- All modes: Min High=13, Min Low=13 → **200 MHz = 7.69 MHz** | **333 MHz = 12.80 MHz** -**Note**: These are theoretical maximums at 200 MHz PRU clock. Full-duplex operation requires adequate timing margins for bidirectional data transfer. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. For full-duplex transfers, the peripheral must respond quickly after the shifting edge for the controller to sample correctly on the sampling edge. If receiving corrupted data, increase SCLK pulse widths significantly beyond these minimums. +**Note**: Theoretical maximums assume ideal hardware peripheral response. For full-duplex PRU-to-PRU loopback using the SPI slave macros, use the practical values (d1=9, d2=7) which are validated against the open-pru SPI slave macros. The practical limit exists because the software-polled slave needs ~13 cycles minimum in both the high and low phases to detect edges and process data. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. If receiving corrupted data, increase SCLK pulse widths beyond these minimums. ### Setup and Hold Times (Controller Mode Only) @@ -1163,9 +1180,9 @@ Different SPI modes have different minimum SCLK width requirements due to timing - **CS Setup Time**: Time delay (in nanoseconds) after CS assertion before starting SPI transaction. This ensures the peripheral device is ready before data transfer begins. - **CS Hold Time**: Time delay (in nanoseconds) after the last bit is transferred before CS deassertion. This ensures the peripheral device has latched the data properly. -- **Data Setup Time**: Time delay (in PRU cycles) after clock edge before sampling data. This provides additional setup time for data stability on slow devices. +- **Data Setup Time**: Minimum time (in nanoseconds) data must be stable before the sampling clock edge. Automatically converted to PRU cycles internally using Math.ceil. -**Note**: CS Setup Time and CS Hold Time are specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. +**Note**: CS Setup Time, CS Hold Time, and Data Setup Time are all specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. ### Peripheral Mode Parameters - **CS Filter Cycles**: Number of consecutive cycles CS must be stable to be considered valid. This provides glitch rejection for noisy CS signals. @@ -1270,9 +1287,17 @@ exports = { // Macro signature: r_dataReg, s_dataReg, PACKETSIZE, bitId, SCLK_PIN, SDI_PIN, SDO_PIN, DELAY_COMPEN_1, DELAY_COMPEN_2, CS_PIN, CS_SETUP_TIME, CS_HOLD_TIME, DATA_SETUP_TIME // System provides: r_dataReg (allocated output), // We provide: PACKETSIZE, bitId, SCLK_PIN, SDI_PIN, SDO_PIN, DELAY_COMPEN_1, DELAY_COMPEN_2, CS_PIN, CS_SETUP_TIME, CS_HOLD_TIME, DATA_SETUP_TIME + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); return inst["packetSize"] + ", TEMP_REG1.b0, " + inst["SCLK Signal"] + ", " + inst["SDI Signal"] + ", " + inst["SDO Signal"] + ", " + inst["delay_component1"] + ", " + inst["delay_component2"] + ", " + inst["CS Signal"] - + ", " + inst["CS Setup Time"] + ", " + inst["CS Hold Time"] + ", " + inst["Data Setup Time"]; + + ", " + csSetupCycles + ", " + csHoldCycles + ", " + dataSetupCycles; } else { // Macro signature: r_dataReg, s_dataReg, PACKETSIZE, bitId, SCLK_PIN, SDI_PIN, SDO_PIN, CS_PIN, CS_FILTER_CYCLES // System provides: r_dataReg (allocated output), @@ -1421,15 +1446,15 @@ exports = { }, { name: "Data Setup Time", - displayName: "Data Setup Time", - description: "Time delay to hold data stable after clock edge (hold time for data stability)", + displayName: "Data Setup Time (ns)", + description: "Minimum time data must be stable before the sampling clock edge (nanoseconds). Converted to PRU cycles internally using Math.ceil.", default: 0, - range: [0, 100], + range: [0, 10000], hidden: false }, { name: "CS Setup Time", - displayName: "CS Setup Time (nanoseconds)", + displayName: "CS Setup Time (ns)", description: "Time delay after CS assertion before starting SPI transaction", default: 35, range: [0, 10000], @@ -1437,7 +1462,7 @@ exports = { }, { name: "CS Hold Time", - displayName: "CS Hold Time (nanoseconds)", + displayName: "CS Hold Time (ns)", description: "Time delay after SPI transaction before CS deassertion", default: 10, range: [0, 10000], @@ -1463,21 +1488,28 @@ exports = { const mode = inst["SPI Mode"]; const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; - let value = 0; - // Based on m_transfer_packet_spi_master_gpo_sclk timing - // MODE0/MODE3: Uses high pulse for delay_compen_1 - // MODE1/MODE2: Uses low pulse for delay_compen_1 + + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + + let value = 0; + // DATA_SETUP_TIME nops sit between data output and sampling edge (inside delay_component1's half) + // so subtract dataSetup from delay_component1 for all modes if (mode === "MODE0") { - value = low - 6; + value = low - 6 - dataSetup; } else if (mode === "MODE1") { - value = high - 4; + value = high - 4 - dataSetup; } else if (mode === "MODE2") { - value = high - 6; + value = high - 6 - dataSetup; } else { // MODE3 - value = low - 4; + value = low - 4 - dataSetup; } return Math.max(0,value); }, @@ -1631,16 +1663,21 @@ exports = { displayName: "Number Of Cycles", getValue: (inst) => { if (inst["Device Mode"] === "controller") { - const csSetupTime = inst["CS Setup Time"]; - const csHoldTime = inst["CS Hold Time"]; - const dataSetupTime = inst["Data Setup Time"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); // Based on m_transfer_packet_spi_master_gpo_sclk: ~ (4+d1) + (6+d2) cycles per bit - const cyclesPerBit = 10 + dataSetupTime + inst["delay_component1"] + inst["delay_component2"]; + const cyclesPerBit = 10 + dataSetupCycles + inst["delay_component1"] + inst["delay_component2"]; - return 1 + csSetupTime + 1 + + return 1 + csSetupCycles + 1 + (inst["packetSize"] * cyclesPerBit) + - csHoldTime + 1; + csHoldCycles + 1; } else { // Peripheral mode: 13 cycles per bit (6 shifting + 7 sampling) return 6 + inst["CS Filter Cycles"] + (inst["packetSize"] * 13); diff --git a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_write.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_write.syscfg.js index be03889..c1ac2e8 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_write.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_write.syscfg.js @@ -68,37 +68,44 @@ function validate(inst, report) { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + if (mode === "MODE0") { - // delay_component1 = high - 2, delay_component2 = low - 6 - if (high < 2) { - report.logError("MODE0: SCLK High Width must be at least 2 cycles (overhead compensation for delay_component1)", inst, "sclk high pulse width (in PRU cycles)"); + // delay_component1 = high - 1, delay_component2 = low - 6 - dataSetup + if (high < 1) { + report.logError("MODE0: SCLK High Width must be at least 1 cycle (overhead compensation for delay_component1)", inst, "sclk high pulse width (in PRU cycles)"); } - if (low < 6) { - report.logError("MODE0: SCLK Low Width must be at least 6 cycles (overhead compensation for delay_component2)", inst, "sclk low pulse width (in PRU cycles)"); + if (low < 6 + dataSetup) { + report.logError(`MODE0: SCLK Low Width must be at least ${6 + dataSetup} cycles (6 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); } } else if (mode === "MODE1") { - // delay_component1 = high - 4, delay_component2 = low - 3 - if (high < 4) { - report.logError("MODE1: SCLK High Width must be at least 4 cycles (overhead compensation for delay_component1)", inst, "sclk high pulse width (in PRU cycles)"); + // delay_component1 = high - 4 - dataSetup, delay_component2 = low - 3 + if (high < 4 + dataSetup) { + report.logError(`MODE1: SCLK High Width must be at least ${4 + dataSetup} cycles (4 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); } if (low < 3) { report.logError("MODE1: SCLK Low Width must be at least 3 cycles (overhead compensation for delay_component2)", inst, "sclk low pulse width (in PRU cycles)"); } } else if (mode === "MODE2") { - // delay_component1 = low - 1, delay_component2 = high - 6 + // delay_component1 = low - 1, delay_component2 = high - 6 - dataSetup if (low < 1) { report.logError("MODE2: SCLK Low Width must be at least 1 cycle (overhead compensation for delay_component1)", inst, "sclk low pulse width (in PRU cycles)"); } - if (high < 6) { - report.logError("MODE2: SCLK High Width must be at least 6 cycles (overhead compensation for delay_component2)", inst, "sclk high pulse width (in PRU cycles)"); + if (high < 6 + dataSetup) { + report.logError(`MODE2: SCLK High Width must be at least ${6 + dataSetup} cycles (6 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk high pulse width (in PRU cycles)"); } } else if (mode === "MODE3") { - // delay_component1 = low - 4, delay_component2 = high - 3 - if (low < 4) { - report.logError("MODE3: SCLK Low Width must be at least 4 cycles (overhead compensation for delay_component1)", inst, "sclk low pulse width (in PRU cycles)"); + // delay_component1 = low - 4 - dataSetup, delay_component2 = high - 3 + if (low < 4 + dataSetup) { + report.logError(`MODE3: SCLK Low Width must be at least ${4 + dataSetup} cycles (4 cycles overhead + ${dataSetup} cycles Data Setup Time)`, inst, "sclk low pulse width (in PRU cycles)"); } if (high < 3) { report.logError("MODE3: SCLK High Width must be at least 3 cycles (overhead compensation for delay_component2)", inst, "sclk high pulse width (in PRU cycles)"); @@ -788,7 +795,7 @@ const spi_write1 = pru_spi_write.addInstance(); | sclk low pulse width (in PRU cycles) | Integer | 1-0xFFFFFFFF | 7 | Clock low time (Controller only) | | CS Setup Time | Integer | 0-10000 | 10 | CS setup time in nanoseconds (Controller only) | | CS Hold Time | Integer | 0-10000 | 10 | CS hold time in nanoseconds (Controller only) | -| Data Setup Time | Integer | 0-100 | 0 | Data setup time in PRU cycles (Controller only) | +| Data Setup Time | Integer | 0-10000 | 0 | Data setup time in nanoseconds, converted to PRU cycles internally (Controller only) | | CS Filter Cycles | Integer | 1-0xFFFFFFFF | 2 | CS glitch filter cycles (Peripheral only) | ### Example Configurations @@ -916,14 +923,20 @@ SPI is a synchronous serial communication protocol with: - The **SPI Clock Frequency** field below automatically calculates the actual frequency based on your configured PRU clock - Peripheral mode follows controller's clock timing -### Maximum Achievable Frequency (at 200 MHz PRU Clock) -Different SPI modes have different minimum SCLK width requirements due to timing overhead: -- **MODE0**: Min High=2, Min Low=6 → Max Frequency = 25.00 MHz (Total: 8 cycles) -- **MODE1**: Min High=4, Min Low=3 → Max Frequency = 28.57 MHz (Total: 7 cycles) -- **MODE2**: Min High=6, Min Low=1 → Max Frequency = 28.57 MHz (Total: 7 cycles) -- **MODE3**: Min High=3, Min Low=4 → Max Frequency = 28.57 MHz (Total: 7 cycles) +### Maximum Achievable Frequency +Different SPI modes have different minimum SCLK width requirements due to timing overhead. +Cycles per bit: **(4+d1) + (3+d2)** + +**Theoretical Maximum (d1=0, d2=0 — controller overhead only):** +- **MODE0**: Min High=2, Min Low=6 → 200 MHz = 25.00 MHz | 333 MHz = 41.63 MHz (Total: 8 cycles) +- **MODE1**: Min High=4, Min Low=3 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) +- **MODE2**: Min High=6, Min Low=1 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) +- **MODE3**: Min High=3, Min Low=4 → 200 MHz = 28.57 MHz | 333 MHz = 47.57 MHz (Total: 7 cycles) -**Note**: These are theoretical maximums at 200 MHz PRU clock. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. Always verify with oscilloscope and increase pulse widths if data corruption occurs. +**Practical Maximum (d1=0, d2=1 — recommended for reliable operation):** +- All modes: Min High+Low = 8 cycles → **200 MHz = 25.00 MHz** | **333 MHz = 41.63 MHz** + +**Note**: Theoretical maximums assume ideal peripheral response. Practical values (d1=0, d2=1) are recommended for reliable operation and are validated against the open-pru SPI slave macros. Actual maximum frequency depends on peripheral device specifications, signal integrity, and PCB layout. Always verify with oscilloscope and increase pulse widths if data corruption occurs. ### Setup and Hold Times (Controller Mode Only) @@ -931,9 +944,9 @@ Different SPI modes have different minimum SCLK width requirements due to timing - **CS Setup Time**: Time delay (in nanoseconds) after CS assertion before starting SPI transaction. This ensures the peripheral device is ready before data transfer begins. - **CS Hold Time**: Time delay (in nanoseconds) after the last bit is transferred before CS deassertion. This ensures the peripheral device has latched the data properly. -- **Data Setup Time**: Time delay (in PRU cycles) to hold data stable after clock edge. This provides additional hold time for data stability on slow devices. +- **Data Setup Time**: Minimum time (in nanoseconds) data must be stable before the sampling clock edge. Automatically converted to PRU cycles internally using Math.ceil. -**Note**: CS Setup Time and CS Hold Time are specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. +**Note**: CS Setup Time, CS Hold Time, and Data Setup Time are all specified in **nanoseconds** and automatically converted to PRU cycles based on the PRU Clock Frequency configured in **Simulation Settings**. Ensure the PRU Clock Frequency matches your hardware configuration for accurate timing. ### Peripheral Mode Parameters - **CS Filter Cycles**: Number of consecutive cycles CS must be stable to be considered valid. This provides glitch rejection for noisy CS signals. @@ -1035,10 +1048,18 @@ exports = { default : "TEMP_REG1", getValue: (inst) => { if (inst["Device Mode"] === "controller") { + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); // Controller mode: dataReg, PACKETSIZE, bitId, SCLK_PIN, SDO_PIN, DELAY_COMPEN_1, DELAY_COMPEN_2, CS_PIN, CS_SETUP_TIME, CS_HOLD_TIME, DATA_SETUP_TIME return inst["packetSize"] + ", TEMP_REG1.b0, " + inst["SCLK Signal"] +", " + inst["SDO Signal"] + ", " + inst["delay_component1"] + ", " + inst["delay_component2"] + ", " + inst["CS Signal"] - + ", " + inst["CS Setup Time"] + ", " + inst["CS Hold Time"] + ", " + inst["Data Setup Time"]; + + ", " + csSetupCycles + ", " + csHoldCycles + ", " + dataSetupCycles; } else { // Peripheral mode: dataReg, PACKETSIZE, bitId, SCLK_PIN, SDO_PIN, CS_PIN, CS_FILTER_CYCLES (MODE removed - now in macro name) return inst["packetSize"] + ", TEMP_REG1.b0, " + inst["SCLK Signal"] @@ -1175,15 +1196,15 @@ exports = { }, { name: "Data Setup Time", - displayName: "Data Setup Time", - description: "Time delay to hold data stable after clock edge (hold time for data stability)", + displayName: "Data Setup Time (ns)", + description: "Time data must be stable before the sampling clock edge (nanoseconds). Converted to PRU cycles internally using Math.ceil.", default: 0, - range: [0, 100], + range: [0, 10000], hidden: false }, { name: "CS Setup Time", - displayName: "CS Setup Time (nanoseconds)", + displayName: "CS Setup Time (ns)", description: "Time delay after CS assertion before starting SPI transaction", default: 10, range: [0, 10000], @@ -1191,7 +1212,7 @@ exports = { }, { name: "CS Hold Time", - displayName: "CS Hold Time (nanoseconds)", + displayName: "CS Hold Time (ns)", description: "Time delay after SPI transaction before CS deassertion", default: 10, range: [0, 10000], @@ -1213,29 +1234,34 @@ exports = { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + let value = 0; - // MODE0 (CPHA=0, CPOL=0): SHIFTING_EDGE = SET SCLK (HIGH pulse starts) - // Overhead: SET SCLK = 1 cycle + // MODE0 (CPHA=0, CPOL=0): DATA_SETUP_TIME nops sit inside the LOW half (before SET SCLK sampling edge) + // HIGH half overhead: SET SCLK (1) only — dataSetup is in the LOW half if (mode === "MODE0") { value = high - 1; } - // MODE1 (CPHA=1, CPOL=0): SHIFTING_EDGE = SET SCLK (HIGH pulse starts) - // Overhead: SET SCLK + data setup (3) = 4 cycles + // MODE1 (CPHA=1, CPOL=0): DATA_SETUP_TIME nops sit inside the HIGH half (after SET SCLK, before CLR SCLK) + // Overhead: SET SCLK + fixed overhead (3) + dataSetup = 4 + dataSetup else if (mode === "MODE1") { - value = high - 4; + value = high - 4 - dataSetup; } - // MODE2 (CPHA=0, CPOL=1): SHIFTING_EDGE = CLR SCLK (LOW pulse starts) - // Overhead: CLR SCLK = 1 cycle - // DELAY_COMPEN_1 extends LOW pulse, so use low_width + // MODE2 (CPHA=0, CPOL=1): DATA_SETUP_TIME nops sit inside the HIGH half (before CLR SCLK sampling edge) + // LOW half overhead: CLR SCLK (1) only — dataSetup is NOT here else if (mode === "MODE2") { value = low - 1; } - // MODE3 (CPHA=1, CPOL=1): SHIFTING_EDGE = CLR SCLK (LOW pulse starts) - // Overhead: CLR SCLK + data setup (3) = 4 cycles - // DELAY_COMPEN_1 extends LOW pulse, so use low_width + // MODE3 (CPHA=1, CPOL=1): DATA_SETUP_TIME nops sit inside the LOW half (after CLR SCLK, before SET SCLK) + // Overhead: CLR SCLK + fixed overhead (3) + dataSetup = 4 + dataSetup else { // MODE3 - value = low - 4; + value = low - 4 - dataSetup; } // Ensure delay component is not negative @@ -1251,28 +1277,30 @@ exports = { const high = inst["sclk high pulse width (in PRU cycles)"]; const low = inst["sclk low pulse width (in PRU cycles)"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const dataSetup = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); + let value = 0; - // MODE0 (CPHA=0, CPOL=0): CLR SCLK starts LOW pulse - // LOW overhead: CLR SCLK + loop control (2) + data setup (3) = 6 cycles - // DELAY_COMPEN_2 extends LOW pulse, so use low_width + // MODE0: DATA_SETUP_TIME is in the LOW half (before SET SCLK sampling edge) + // LOW half overhead: data output (3) + dataSetup + CLR SCLK (1) + sub+qbne (2) = 6 + dataSetup if (mode === "MODE0") { - value = low - 6; + value = low - 6 - dataSetup; } - // MODE1 (CPHA=1, CPOL=0): SAMPLING_EDGE = CLR SCLK (LOW pulse starts) - // Overhead: CLR SCLK + loop control (2) = 3 cycles + // MODE1: DATA_SETUP_TIME is in HIGH half — not here (DELAY_COMPEN_2 is in LOW half) else if (mode === "MODE1") { value = low - 3; } - // MODE2 (CPHA=0, CPOL=1): SET SCLK starts HIGH pulse - // HIGH overhead: SET SCLK + loop control (2) + data setup (3) = 6 cycles - // DELAY_COMPEN_2 extends HIGH pulse, so use high_width + // MODE2: DATA_SETUP_TIME is in HIGH half (before CLR SCLK sampling edge) — DELAY_COMPEN_2 also in HIGH half + // HIGH half overhead: SET SCLK (1) + data output (3) + dataSetup + sub+qbne (2) = 6 + dataSetup else if (mode === "MODE2") { - value = high - 6; + value = high - 6 - dataSetup; } - // MODE3 (CPHA=1, CPOL=1): SAMPLING_EDGE = SET SCLK (HIGH pulse starts) - // Overhead: SET SCLK + loop control (2) = 3 cycles - // DELAY_COMPEN_2 extends HIGH pulse, so use high_width + // MODE3: DATA_SETUP_TIME is in LOW half — not here (DELAY_COMPEN_2 is in HIGH half) else { // MODE3 value = high - 3; } @@ -1400,16 +1428,21 @@ exports = { // Controller mode: includes CS setup, bit loop, and CS hold time // Peripheral mode: includes CS filter, bit loop (no CS setup/hold) if (inst["Device Mode"] === "controller") { - const csSetupTime = inst["CS Setup Time"]; - const csHoldTime = inst["CS Hold Time"]; - const dataSetupTime = inst["Data Setup Time"]; + let pruFreqMHz = 200; + const staticMod = system.modules["/pru_blocks/common/pru_blocks_static_module"]; + if (staticMod && staticMod.$static && staticMod.$static.pruClkFreq) { + pruFreqMHz = staticMod.$static.pruClkFreq; + } + const csSetupCycles = Math.ceil(inst["CS Setup Time"] * pruFreqMHz / 1000); + const csHoldCycles = Math.ceil(inst["CS Hold Time"] * pruFreqMHz / 1000); + const dataSetupCycles = Math.ceil(inst["Data Setup Time"] * pruFreqMHz / 1000); // Cycles per bit: 7 fixed + DATA_SETUP_TIME + delay_component1 + delay_component2 - const cyclesPerBit = 7 + dataSetupTime + inst["delay_component1"] + inst["delay_component2"]; + const cyclesPerBit = 7 + dataSetupCycles + inst["delay_component1"] + inst["delay_component2"]; - return 1 + csSetupTime + 1 + + return 1 + csSetupCycles + 1 + (inst["packetSize"] * cyclesPerBit) + - csHoldTime + 1; + csHoldCycles + 1; } else { return 6 + inst["delay_component1"] + (inst["packetSize"] - 1) * (6 + inst["delay_component1"] + inst["delay_component2"]); } diff --git a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_rx_op.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_rx_op.syscfg.js index 0bae2bb..68516c1 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_rx_op.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_rx_op.syscfg.js @@ -600,8 +600,9 @@ exports = { ports: (inst) => { const dataBits = inst.rxFrameSize - 2; const outputType = dataBits >= 31 ? "output64" : "output32"; + const portName = outputType === "output64" ? "out64" : "output1" return [ - { name: "output1", type: outputType }, + { name: "output1", type: outputType, displayName: portName }, { name: "prev", type: "PREV" }, { name: "next", type: "NEXT" }, ]; diff --git a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_tx_op.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_tx_op.syscfg.js index 5f9a747..5b6d1c7 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_tx_op.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/uart_tx_op.syscfg.js @@ -960,8 +960,9 @@ exports = { ports: (inst) => { const dataBits = inst.dataBits; const inputType = dataBits > 32 ? "input64" : "input32"; + const portName = inputType === "input64" ? "in64" : "output1" return [ - { name: "input1", type: inputType }, + { name: "input1", type: inputType, displayName: portName }, { name: "prev", type: "PREV" }, { name: "next", type: "NEXT" }, ]; diff --git a/.metadata/sysconfig/.meta/pru_blocks/utils/data_splitter.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/utils/data_splitter.syscfg.js index 1a6787d..151a646 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/utils/data_splitter.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/utils/data_splitter.syscfg.js @@ -131,7 +131,7 @@ exports = { }, ], ports: (_inst) => [ - { name: "input1", type: "input64" }, + { name: "input1", type: "input64", displayName: "in64" }, { name: "output1", type: "output32" }, { name: "prev", type: "PREV" }, { name: "next", type: "NEXT" }, diff --git a/.metadata/sysconfig/.meta/pru_blocks/utils/memory_access_block.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/utils/memory_access_block.syscfg.js index a556b9f..7b87d9a 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/utils/memory_access_block.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/utils/memory_access_block.syscfg.js @@ -563,11 +563,13 @@ exports = { if (inst["operationMode"] === "write") { // Write mode: input for data to store const inputType = dataSize > 4 ? "input64" : "input32"; - ports.push({ name: "input1", displayName: "data", type: inputType }); + const portType = inputType === "input64" ? "in64" : "input1" + ports.push({ name: "input1", displayName: portType, type: inputType }); } else { // Read mode: output for loaded data const outputType = dataSize > 4 ? "output64" : "output32"; - ports.push({ name: "output1", displayName: "data", type: outputType }); + const portType = outputType === "output64" ? "out64" : "output1" + ports.push({ name: "output1", displayName: portType, type: outputType }); } // Control flow ports diff --git a/README.md b/README.md index 5511f7f..98a2634 100644 --- a/README.md +++ b/README.md @@ -159,9 +159,9 @@ Blocks for GPIO, SPI, UART, and memory operations. |-------|---------|--------|---------------------------| | PRU GPI | Read GPIO input pins (R31) | 1 | N/A | | PRU GPO | Write GPIO output pins (R30) | 1 | N/A | -| SPI Read | Read data via SPI | Variable | Up to 28.57 MHz | -| SPI Write | Write data via SPI | Variable | Up to 28.57 MHz | -| SPI Transfer | Full-duplex SPI | Variable | Up to 25.00 MHz | +| SPI Read | Read data via SPI | Variable | Up to 8.33 MHz | +| SPI Write | Write data via SPI | Variable | Up to 25.00 MHz | +| SPI Transfer | Full-duplex SPI | Variable | Up to 7.69 MHz | | UART config | configure 3 channel interface for UART transmission | Variable | N/A | | UART TX op | Transmit UART frame (up to 62 data bits) | Variable | Up to 32 Mbaud | | UART RX op | Receive UART frame (up to 64 bits) | Variable | Up to 32 Mbaud | diff --git a/docs/input-output/serial-protocol-emulation/pru_spi_read_block.md b/docs/input-output/serial-protocol-emulation/pru_spi_read_block.md index f48c698..9bf638b 100644 --- a/docs/input-output/serial-protocol-emulation/pru_spi_read_block.md +++ b/docs/input-output/serial-protocol-emulation/pru_spi_read_block.md @@ -45,12 +45,14 @@ Implements SPI (Serial Peripheral Interface) protocol to **receive** data in bot ### Minimum SCLK Widths (Controller, at 200 MHz PRU clock) -| Mode | Min High | Min Low | Max Frequency | -|------|----------|---------|---------------| -| MODE0 | 4 | 3 | 28.57 MHz | -| MODE1 | 1 | 6 | 28.57 MHz | -| MODE2 | 3 | 4 | 28.57 MHz | -| MODE3 | 6 | 1 | 28.57 MHz | +| Mode | Min High | Min Low | Theoretical Max Frequency (zero delay compensation) | Practical Max Frequency | +|------|----------|---------|---------------|---------------| +| MODE0 | 4 | 3 | 28.57 MHz | 8.33 MHz | +| MODE1 | 1 | 6 | 28.57 MHz | 8.33 MHz | +| MODE2 | 3 | 4 | 28.57 MHz | 8.33 MHz | +| MODE3 | 6 | 1 | 28.57 MHz | 8.33 MHz | + +**Note**: The theoretical column assumes zero delay compensation (d1=0, d2=0) and ideal peripheral response — not achievable in practice. The practical column uses d1=10, d2=7 (24 cycles/bit total). See "Maximum Achievable Frequency" in the block's `getAIContext()`/long description for the full breakdown. ### How It Works diff --git a/docs/input-output/serial-protocol-emulation/pru_spi_transfer_block.md b/docs/input-output/serial-protocol-emulation/pru_spi_transfer_block.md index b534969..ed98883 100644 --- a/docs/input-output/serial-protocol-emulation/pru_spi_transfer_block.md +++ b/docs/input-output/serial-protocol-emulation/pru_spi_transfer_block.md @@ -47,12 +47,14 @@ Implements full-duplex SPI (Serial Peripheral Interface) in both Controller and ### Minimum SCLK Widths (Controller, at 200 MHz PRU clock) -| Mode | Min High | Min Low | Max Frequency | -|------|----------|---------|---------------| -| MODE0 | 4 | 6 | 20.00 MHz | -| MODE1 | 2 | 6 | 25.00 MHz | -| MODE2 | 6 | 4 | 20.00 MHz | -| MODE3 | 6 | 2 | 25.00 MHz | +| Mode | Min High | Min Low | Theoretical Max Frequency (zero delay compensation) | Practical Max Frequency | +|------|----------|---------|---------------|---------------| +| MODE0 | 4 | 6 | 20.00 MHz | 7.69 MHz | +| MODE1 | 2 | 6 | 25.00 MHz | 7.69 MHz | +| MODE2 | 6 | 4 | 20.00 MHz | 7.69 MHz | +| MODE3 | 6 | 2 | 25.00 MHz | 7.69 MHz | + +**Note**: The theoretical column assumes zero delay compensation (d1=0, d2=0) and ideal peripheral response — not achievable in practice. The practical column uses d1=9, d2=7 (26 cycles/bit total) for PRU-to-PRU loopback. See "Maximum Achievable Frequency" in the block's `getAIContext()`/long description for the full breakdown. ### How It Works diff --git a/docs/input-output/serial-protocol-emulation/pru_spi_write_block.md b/docs/input-output/serial-protocol-emulation/pru_spi_write_block.md index 94c4ad3..422eab9 100644 --- a/docs/input-output/serial-protocol-emulation/pru_spi_write_block.md +++ b/docs/input-output/serial-protocol-emulation/pru_spi_write_block.md @@ -46,12 +46,14 @@ Implements SPI (Serial Peripheral Interface) protocol to **transmit** data in bo ### Minimum SCLK Widths (Controller, at 200 MHz PRU clock) -| Mode | Min High | Min Low | Max Frequency | -|------|----------|---------|---------------| -| MODE0 | 2 | 6 | 25.00 MHz | -| MODE1 | 4 | 3 | 28.57 MHz | -| MODE2 | 6 | 1 | 28.57 MHz | -| MODE3 | 3 | 4 | 28.57 MHz | +| Mode | Min High | Min Low | Theoretical Max Frequency (zero delay compensation) | Practical Max Frequency | +|------|----------|---------|---------------|---------------| +| MODE0 | 2 | 6 | 25.00 MHz | 25.00 MHz | +| MODE1 | 4 | 3 | 28.57 MHz | 25.00 MHz | +| MODE2 | 6 | 1 | 28.57 MHz | 25.00 MHz | +| MODE3 | 3 | 4 | 28.57 MHz | 25.00 MHz | + +**Note**: The theoretical column assumes zero delay compensation (d1=0, d2=0) and ideal peripheral response — not achievable in practice for MODE1–3. The practical column uses d1=0, d2=1 (8 cycles/bit total). See "Maximum Achievable Frequency" in the block's `getAIContext()`/long description for the full breakdown. ### How It Works diff --git a/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index 89de96d..160ff49 100644 --- a/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -12,7 +12,7 @@ > $(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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..93f08ca 100644 --- a/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/conditional/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -12,7 +12,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +25,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +46,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif diff --git a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index 8ea7132..0b4c32c 100644 --- a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -84,8 +84,8 @@ " linkerBuildOptions=" -lfreertos.am261x.r5f.ti-arm-clang.debug.lib - -ldrivers.am261x.r5f.ti-arm-clang.debug.lib - -lboard.am261x.r5f.ti-arm-clang.debug.lib + -ldrivers.am261x.r5f.ti-arm-clang.freertos.debug.lib + -lboard.am261x.r5f.ti-arm-clang.freertos.debug.lib -llibc.a -llibsysbm.a " @@ -96,8 +96,8 @@ " linkerBuildOptions=" -lfreertos.am261x.r5f.ti-arm-clang.release.lib - -ldrivers.am261x.r5f.ti-arm-clang.release.lib - -lboard.am261x.r5f.ti-arm-clang.release.lib + -ldrivers.am261x.r5f.ti-arm-clang.freertos.release.lib + -lboard.am261x.r5f.ti-arm-clang.freertos.release.lib -llibc.a -llibsysbm.a " diff --git a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile index 2222519..a78c902 100644 --- a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile +++ b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile @@ -29,15 +29,15 @@ OUTNAME:=empty.$(PROFILE).out COREOUTNAME:=empty.$(PROFILE).optishare.out BOOTIMAGE_PATH=$(abspath .) -BOOTIMAGE_NAME:=empty.$(PROFILE).appimage -BOOTIMAGE_NAME_XIP:=empty.$(PROFILE).appimage_xip -BOOTIMAGE_NAME_SIGNED:=empty.$(PROFILE).appimage.signed -BOOTIMAGE_RPRC_NAME:=empty.$(PROFILE).rprc -BOOTIMAGE_RPRC_NAME_XIP:=empty.$(PROFILE).rprc_xip -BOOTIMAGE_RPRC_NAME_TMP:=empty.$(PROFILE).rprc_tmp -BOOTIMAGE_NAME_HS:=empty.$(PROFILE).appimage.hs -BOOTIMAGE_NAME_HS_FS:=empty.$(PROFILE).appimage.hs_fs -TARGETS := $(BOOTIMAGE_NAME) +oeconfig?=None + +BOOTIMAGE_NAME_MCELF:=empty.$(PROFILE).mcelf +BOOTIMAGE_NAME_MCELF_HS:=empty.$(PROFILE).mcelf.hs +TARGETS := $(BOOTIMAGE_NAME_MCELF) + +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif FILES_common := \ @@ -112,8 +112,8 @@ LIBS_PATH_common = \ LIBS_common = \ -lfreertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ - -ldrivers.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ - -lboard.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + -ldrivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + -lboard.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ -llibc.a \ -llibsysbm.a \ @@ -126,8 +126,8 @@ LFLAGS_common = \ LIBS_NAME = \ freertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ - drivers.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ - board.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + drivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + board.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ libc.a \ libsysbm.a \ @@ -208,13 +208,8 @@ clean: @echo Cleaning: am261x: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) + $(RM) $(BOOTIMAGE_NAME_MCELF) + $(RM) $(BOOTIMAGE_NAME_MCELF_HS) $(RMDIR) generated/ scrub: @@ -229,6 +224,10 @@ ifeq ($(OS),Windows_NT) $(RM) \*.bin $(RM) \*.lnkxml $(RM) \*.ossr + $(RM) \*.mcelf + $(RM) \*.mcelf_xip + $(RM) \*.mcelf-enc + $(RM) \*.mcelf.hs else $(RM) *.out $(RM) *.map @@ -238,6 +237,10 @@ else $(RM) *.bin $(RM) *.lnkxml $(RM) *.ossr + $(RM) *.mcelf + $(RM) *.mcelf_xip + $(RM) *.mcelf-enc + $(RM) *.mcelf.hs endif $(RMDIR) generated @@ -274,68 +277,45 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(SYSCFG_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(SYSCFG_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -endif +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py -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_MCELF): $(OUTNAME) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) ... + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTNAME) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) --otfaConfigFile=$(oeconfig) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . -$(BOOTIMAGE_NAME): $(OUTNAME) - @echo Boot image: am261x: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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..9708db0 100644 --- a/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/empty/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -3,7 +3,6 @@ # # Below variables need to be defined outside this file or via command line -# - PRU_NO_CODE_TOOL_PATH # - MCU_PLUS_SDK_PATH # - PROFILE # - CG_TOOL_ROOT @@ -12,7 +11,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +24,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +45,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif diff --git a/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index 94dc7c4..99f006f 100644 --- a/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -12,7 +12,7 @@ > $(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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..93f08ca 100644 --- a/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/gray_encoder_4_bit/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -12,7 +12,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +25,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +46,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif diff --git a/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index 3c09af3..3262814 100644 --- a/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -12,7 +12,7 @@ > $(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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..93f08ca 100644 --- a/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/incremental_spi/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -12,7 +12,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +25,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +46,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif diff --git a/examples/makefile b/examples/makefile index fd15cde..da36ff9 100644 --- a/examples/makefile +++ b/examples/makefile @@ -8,6 +8,7 @@ SUBDIRS := \ gray_encoder_4_bit \ incremental_spi \ tamagawa_single_channel \ + spi_10mhz \ # "make" or "make all" builds projects that match $(DEVICE) set in imports.mak all: ARGUMENTS = all diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg new file mode 100644 index 0000000..56fdb78 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg @@ -0,0 +1,50 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "icss_m1_pru0" --product "PRU_NO_CODE_TOOL@01.00.01" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "icss_m1_pru0" --product "PRU_NO_CODE_TOOL@01.00.01" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const pru_blocks_static_module = scripting.addModule("/pru_blocks/common/pru_blocks_static_module"); +const load_constant_block = scripting.addModule("/pru_blocks/data_handling/load_constant_block", {}, false); +const load_constant_block1 = load_constant_block.addInstance(); +const flow_control_block = scripting.addModule("/pru_blocks/program_control/flow_control_block", {}, false); +const flow_control_block1 = flow_control_block.addInstance(); +const pru_spi_transfer = scripting.addModule("/pru_blocks/pru_io_blocks/pru_spi_transfer", {}, false); +const pru_spi_transfer1 = pru_spi_transfer.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +load_constant_block1.$name = "Load_Constant_0"; +load_constant_block1.constant1 = 2882400171; + +flow_control_block1.$name = "Flow_Control_0"; + +pru_spi_transfer1.$name = "PRU0_SPI_Transfer_0"; +pru_spi_transfer1["SPI Mode"] = "MODE1"; +pru_spi_transfer1["CS Signal"] = "2"; +pru_spi_transfer1["SDO Signal"] = "1"; +pru_spi_transfer1["SDI Signal"] = "6"; +pru_spi_transfer1["Data Setup Time"] = 50; +pru_spi_transfer1["CS Setup Time"] = 500; +pru_spi_transfer1["CS Hold Time"] = 500; +pru_spi_transfer1["sclk high pulse width (in PRU cycles)"] = 16; +pru_spi_transfer1["sclk low pulse width (in PRU cycles)"] = 6; + +/** + * Connections between modules. + */ +scripting.connect(load_constant_block1, "output1", pru_spi_transfer1, "input1"); +scripting.connect(flow_control_block1, "prev", pru_spi_transfer1, "next"); + +/** + * (x,y) coordinates for modules that are displayed in a graph. + */ +load_constant_block1.$position = [-145,155]; +flow_control_block1.$position = [150,150]; +pru_spi_transfer1.$position = [0,160]; diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec new file mode 100644 index 0000000..acb706c --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd new file mode 100644 index 0000000..5d7910e --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd @@ -0,0 +1,54 @@ +/* + * AM243x_PRU0.cmd + * + * Example Linker command file for linking assembly programs built with the TI-PRU-CGT + * on AM243x PRU0 cores + */ + +/* Specify the System Memory Map */ +MEMORY +{ + PAGE 0: + /* 12 KB PRU Instruction RAM */ + PRU_IMEM : org = 0x00000000 len = 0x00003000 + + PAGE 1: + /* Data RAMs */ + /* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU0 and reserve + * the second 4 KB for RTU0 and Tx_PRU0 */ + PRU0_DMEM_0 : org = 0x00000000 len = 0x00001000 + /* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU0, + * RTU1 and Tx_PRU0; do not use for any Slice0 cores */ + PRU0_DMEM_1 : org = 0x00002000 len = 0x00001000 + /* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1 + * split equally between the corresponding RTU and Tx_PRU cores in + * each slice */ + RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800 + TX_PRU0_DMEM_0 : org = 0x00001800 len = 0x00000800 + RTU1_DMEM_1 : org = 0x00003000 len = 0x00000800 + TX_PRU0_DMEM_1 : org = 0x00003800 len = 0x00000800 + + PAGE 2: + /* C28 needs to be programmed to point to SHAREDMEM, default is 0 */ + /* 64 KB PRU Shared RAM */ + PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 +} + +/* Specify the sections allocation into memory */ +SECTIONS { + .text:main > 0, PAGE 0 + .text > PRU_IMEM, PAGE 0 + .stack > PRU0_DMEM_0, PAGE 1 + .bss > PRU0_DMEM_0, PAGE 1 + .udmem > PRU0_DMEM_0, PAGE 1 + .initdmem > PRU0_DMEM_0, PAGE 1 + .cio > PRU0_DMEM_0, PAGE 1 + .data > PRU0_DMEM_0, PAGE 1 + .switch > PRU0_DMEM_0, PAGE 1 + .sysmem > PRU0_DMEM_0, PAGE 1 + .cinit > PRU0_DMEM_0, PAGE 1 + .rodata > PRU0_DMEM_0, PAGE 1 + .rofardata > PRU0_DMEM_0, PAGE 1 + .farbss > PRU0_DMEM_0, PAGE 1 + .fardata > PRU0_DMEM_0, PAGE 1 +} diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile new file mode 100644 index 0000000..3be589d --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile @@ -0,0 +1,55 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +# Define build outputs +OUTPUT_NAME := spi_10mhz_am261x-lp_icss_m1_pru0_fw + +# MCU+ projects: rename & move hex array output +MCU_HEX_NAME := pru0_load_bin.h +HEX_ARRAY_PREFIX := PRU0Firmware +MCU_HEX_PATH := $(PRU_NO_CODE_TOOL_PATH)/examples/spi_10mhz/firmware/am261x-lp/$(MCU_HEX_NAME) + +# which directories to search for assembly & C source files? +FILES_PATH := .. ../../.. . syscfg/ + +# Linker command file +COMMAND_FILES := linker.cmd + +# Silicon version (3: PRUSS, PRU-ICSS; 4: PRU_ICSSG) +PRU_VERSION := 4 +EXPECTED_DEVICE := am261x + +# Default values are defined in pru_rules.mak: +# - include paths (INCLUDE) +# - compiler flags (CFLAGS) +# - linker flags (LFLAGS) + +# Optional: +# Pre-define here to override default value +# OPT_LEVEL, STACK_SIZE, HEAP_SIZE, or ENTRY_POINT + +# pru_rules.mak has shared settings for all PRU/RTU/TX_PRU core makefiles +include $(PRU_NO_CODE_TOOL_PATH)/pru_rules.mak + +# Optional: +# Append values to INCLUDE, CFLAGS, or LFLAGS here. +# Values can be appended like this: +# INCLUDE += --include_path= + +# Defines (pass instance specific definitions to the program) +# see --define or -D in 'PRU Optimizing C/C++ Compiler User's Guide' +# For example, to define PRU0, ICSSG1, SOC_AM243X, and set _DEBUG_=1: +# -DPRU0 -DICSSG1 --define=SOC_AM243X -D_DEBUG_=1 +DFLAGS := -DPRU0 -DPRU1 --define=SOC_AM261X + +# Libraries +# see --library in 'PRU Optimizing C/C++ Compiler User's Guide' +LIBS := + +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru0 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru0 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec new file mode 100644 index 0000000..5f84611 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=spi_10mhz_am261x-lp_icss_m1_pru0_fw_ti-pru-cgt + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg new file mode 100644 index 0000000..b13eaed --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg @@ -0,0 +1,49 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "icss_m1_pru1" --product "PRU_NO_CODE_TOOL@01.00.01" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "icss_m1_pru1" --product "PRU_NO_CODE_TOOL@01.00.01" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const pru_blocks_static_module = scripting.addModule("/pru_blocks/common/pru_blocks_static_module"); +const load_constant_block = scripting.addModule("/pru_blocks/data_handling/load_constant_block", {}, false); +const load_constant_block1 = load_constant_block.addInstance(); +const flow_control_block = scripting.addModule("/pru_blocks/program_control/flow_control_block", {}, false); +const flow_control_block1 = flow_control_block.addInstance(); +const pru_spi_write = scripting.addModule("/pru_blocks/pru_io_blocks/pru_spi_write", {}, false); +const pru_spi_write1 = pru_spi_write.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +pru_blocks_static_module.pruClkFreq = 225; + +load_constant_block1.$name = "Load_Constant_0"; +load_constant_block1.constant1 = 3735936685; + +flow_control_block1.$name = "Flow_Control_0"; + +pru_spi_write1.$name = "PRU1_SPI_Write_0"; +pru_spi_write1["Device Mode"] = "peripheral"; +pru_spi_write1["SCLK Signal"] = "4"; +pru_spi_write1["SDO Signal"] = "5"; +pru_spi_write1["CS Signal"] = "6"; +pru_spi_write1.packetSize = 32; +pru_spi_write1.Endiness = "most significant bit first"; + +/** + * Connections between modules. + */ +scripting.connect(load_constant_block1, "output1", pru_spi_write1, "input1"); +scripting.connect(flow_control_block1, "prev", pru_spi_write1, "next"); + +/** + * (x,y) coordinates for modules that are displayed in a graph. + */ +load_constant_block1.$position = [-150,140]; +flow_control_block1.$position = [110,130]; +pru_spi_write1.$position = [-15,130]; diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec new file mode 100644 index 0000000..8d9faa5 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd new file mode 100644 index 0000000..7340f73 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd @@ -0,0 +1,54 @@ +/* + * AM243x_PRU1.cmd + * + * Example Linker command file for linking assembly programs built with the TI-PRU-CGT + * on AM243x PRU1 cores + */ + +/* Specify the System Memory Map */ +MEMORY +{ + PAGE 0: + /* 12 KB PRU Instruction RAM */ + PRU_IMEM : org = 0x00000000 len = 0x00003000 + + PAGE 1: + /* Data RAMs */ + /* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU1 and reserve + * the second 4 KB for RTU0 and Tx_PRU1 */ + PRU1_DMEM_0 : org = 0x00000000 len = 0x00001000 + /* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU1, + * RTU1 and Tx_PRU1; do not use for any Slice0 cores */ + PRU1_DMEM_1 : org = 0x00002000 len = 0x00001000 + /* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1 + * split equally between the corresponding RTU and Tx_PRU cores in + * each slice */ + RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800 + TX_PRU1_DMEM_0 : org = 0x00001800 len = 0x00000800 + RTU1_DMEM_1 : org = 0x00003000 len = 0x00000800 + TX_PRU1_DMEM_1 : org = 0x00003800 len = 0x00000800 + + PAGE 2: + /* C28 needs to be programmed to point to SHAREDMEM, default is 0 */ + /* 64 KB PRU Shared RAM */ + PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 +} + +/* Specify the sections allocation into memory */ +SECTIONS { + .text:main > 0, PAGE 0 + .text > PRU_IMEM, PAGE 0 + .stack > PRU1_DMEM_0, PAGE 1 + .bss > PRU1_DMEM_0, PAGE 1 + .udmem > PRU1_DMEM_0, PAGE 1 + .initdmem > PRU1_DMEM_0, PAGE 1 + .cio > PRU1_DMEM_0, PAGE 1 + .data > PRU1_DMEM_0, PAGE 1 + .switch > PRU1_DMEM_0, PAGE 1 + .sysmem > PRU1_DMEM_0, PAGE 1 + .cinit > PRU1_DMEM_0, PAGE 1 + .rodata > PRU1_DMEM_0, PAGE 1 + .rofardata > PRU1_DMEM_0, PAGE 1 + .farbss > PRU1_DMEM_0, PAGE 1 + .fardata > PRU1_DMEM_0, PAGE 1 +} diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile new file mode 100644 index 0000000..82830f7 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile @@ -0,0 +1,55 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +# Define build outputs +OUTPUT_NAME := spi_10mhz_am261x-lp_icss_m1_pru1_fw + +# MCU+ projects: rename & move hex array output +MCU_HEX_NAME := pru1_load_bin.h +HEX_ARRAY_PREFIX := PRU1Firmware +MCU_HEX_PATH := $(PRU_NO_CODE_TOOL_PATH)/examples/spi_10mhz/firmware/am261x-lp/$(MCU_HEX_NAME) + +# which directories to search for assembly & C source files? +FILES_PATH := .. ../../.. . syscfg/ + +# Linker command file +COMMAND_FILES := linker.cmd + +# Silicon version (3: PRUSS, PRU-ICSS; 4: PRU_ICSSG) +PRU_VERSION := 4 +EXPECTED_DEVICE := am261x + +# Default values are defined in pru_rules.mak: +# - include paths (INCLUDE) +# - compiler flags (CFLAGS) +# - linker flags (LFLAGS) + +# Optional: +# Pre-define here to override default value +# OPT_LEVEL, STACK_SIZE, HEAP_SIZE, or ENTRY_POINT + +# pru_rules.mak has shared settings for all PRU/RTU/TX_PRU core makefiles +include $(PRU_NO_CODE_TOOL_PATH)/pru_rules.mak + +# Optional: +# Append values to INCLUDE, CFLAGS, or LFLAGS here. +# Values can be appended like this: +# INCLUDE += --include_path= + +# Defines (pass instance specific definitions to the program) +# see --define or -D in 'PRU Optimizing C/C++ Compiler User's Guide' +# For example, to define PRU1, ICSSG1, SOC_AM243X, and set _DEBUG_=1: +# -DPRU1 -DICSSG1 --define=SOC_AM243X -D_DEBUG_=1 +DFLAGS := -DPRU0 -DPRU1 --define=SOC_AM261X + +# Libraries +# see --library in 'PRU Optimizing C/C++ Compiler User's Guide' +LIBS := + +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru1 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru1 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + diff --git a/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec new file mode 100644 index 0000000..e3c26c0 --- /dev/null +++ b/examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=spi_10mhz_am261x-lp_icss_m1_pru1_fw_ti-pru-cgt + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/spi_10mhz/firmware/main.asm b/examples/spi_10mhz/firmware/main.asm new file mode 100644 index 0000000..586984e --- /dev/null +++ b/examples/spi_10mhz/firmware/main.asm @@ -0,0 +1,40 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright (C) 2024-2025 Texas Instruments Incorporated - http://www.ti.com/ + +;*************************************************************************************** +; File: main.asm +; +; Brief: Empty example assembly file (asm) with halt instruction +; +; Steps to build : +; +; - Using ccs: +; - Import pru project to ccs workspace +; - main.asm file gets copied to ccs workspace +; - Modify main.asm file +; - Build the pru project, after which .out (Executable output file) and .h (Firmware header) files gets generated +; - Either .out (Executable output file) can be loaded to PRU using ccs or R5F can write to PRU IRAM using PRUICSS driver +; - Using makefile: +; - Use command gmake -all to build PRU project +; +;*************************************************************************************** + +; CCS/makefile specific settings + .retain ; Required for building .out with assembly file + .retainrefs ; Required for building .out with assembly file + + .global main + .ref sysconfig_generated_start + .global sysconfig_generated_end + .sect ".text:main" + +;******** +;* MAIN * +;******** + +main: + ; halt the program after jumping to sysconfig generated start + zero &r0,120 + JMP sysconfig_generated_start +sysconfig_generated_end: + halt diff --git a/examples/spi_10mhz/images/spi_10mhz.png b/examples/spi_10mhz/images/spi_10mhz.png new file mode 100644 index 0000000000000000000000000000000000000000..cef8f32df39623f86691e16916f21638d03f9647 GIT binary patch literal 13368 zcmeHO2~<;O+P=7f3(#X1P?k7j)mGG~D2ps{>4=IFtp!vdQBe^>2o(iPNMiLD+Cijh z1r;GGCIMcLLdRc9uPyqmhC1tbAxo$I_IBu&dfQTGvpl3JvX`cTi*A1 z-}if-@8gHPZZ3xN7S96!z;Ne|uf7I=*|Pv(MvB24_#2O9>p}RU7xJ~sRv@$1d=S2w z<+o+e768bOov%JJ8@`_#yyIX902r0){`9znv||8ZU95z5d+bYQF11%fg-C?-MLpcqh;G>*PFFvspg{uvZy=mHyeoz)F(GJupD< zBD89k`?g9CpN962(zmCDCuAA82kf-k;UC-$>NTKN zxg)u{E#ySMtOa_mzHt*b+#QWPcoG1D7q42i8%pgPnCKIk@Vj$YfWqdW$6bE>yW8ZB zTBvrnzL9rWw~{S^PUGmzf`aBl2@ZqWH6^i6wMH}qlRt6oOlRpCzi|ooCPgb=rQ8T) zDf1T~0bp~*phaqc)P5%L!0)43z#Z$MSnpKjd_iGOHdYX6ISW{OWy?pvxh#J!-5)_+ zeoMx)6Zhzyd%oa20Q}!0+oOh9R7An~F2-5KXg!gk53Dtq0n``wUBUSZ-AJLPTIOe} zi!*_Q+9d`+>F&hpG}b6S&h4cW`%=-=OW0} zfqN`lmy=zkiUYPPwSrm6@S;RzIH3Z@$pFAq#2o4E^HrPe%rb;rDQ`oB@@Ll!jP)x$U`07>+0CT^Jv=Etg-bWri$Wq%G2Rvn zLUM_VS)(1FA*_|KjcBLw4Jlkb;8De-BX%#&`OJ`;)x_8X8=>#|(zdow&?|5XN;8oN zt*#h8qgK7BvZA3z(%cz_bjV&GSeYPT^X|e9y6uch>~u!TRz6&nF|Y~`daGh&SQB*&UrWH0yeB2qG$ zb5rNn;XA!9iux-!^l%%rmBd$pOH42;7Vd>R!B3hw56Ghy0xtf^*KX`D-;b3jg~JBy(+O_Xy9J5yRnh4FP~nttT9iS^kmOxpo1H!mcVS&L}}K8o;aF zZRNtb&Wl7MF35(4|(+vwaa57GJFsi zvy!54d>?oyN9X2E3(nJ-^N~eansGGezPO#us;R;Iqa8=S0@WgvaG0Zoy0+=r#mK}0 zUWYW&Hm{u>#wsYV*Idl4e-8WLIS;*9W<$iU9zul|%2|QFW^mGZ$xmM@+|HnDzKvvX zq-FC3PcG;Slp@JVdAt0g%#%9d>C4dX9OrYWRIrt%xtUJ}&#uU{a8ik7Yz{b*&3$r0 zQ0U9OEQm6xJ0ZFq;>Pa&s};XC(LvCV?Ba!^Yr2so$;A?~1ZU!NdY>TI56y;DLxKWP zk^mY-N*0ya11tQ$rV7WB!Kk%>i2jv|_4T4Em@x!7p$HY+U3abLKS zujp%_nb{4B<{8z{!3_{(18s;vU861cDwJH85XL90gxps=kHun1Pb|t=Rv1>)BV>9J zG|bSNjl4V;OXYU9yo1EW7?)Nij7x+WjFLj~z&1ocyice=GReVxpZc82iSoPLQ+Pe1r}j#4bTXJ(~Qxoc&w0G zdzPjFp=tPmCF3_C2A;r#4mm{Djf3W(YmrFB_Lm@t`X*?(kQB*1%t@ky~96s>EKx`V>0jzVpE2jH&~8Re+9+} z6~SOG3dG`hnLd-vcSRu?>A{hmO5^1OiN$|`J!v-CSJ0Z9l}iJx0B%t;QKX{#-n_A@*`zRvj9Ju$5qc_EMKM3OB)%-P!6H7j$bAWS%$;X4p+XtJ?82leb2;pZc6)miiu9oJiMt+4$X=N;ySWS%7 zIBC^m0$tvqfdw?22`2mqID(+!*`v>`1kH3WK|;srZEP7I7bQ9RXU*&bf-H`!7IGqv zpJao>b@>j%kCQdc1PxEtdkxLh*#J+WP=1*)YMaywtK8+Fd%FJ?j=vx6)a0yqVw}%` zhDd@TctW!8jNAC3Vty;6uG5CWcpAcUFOLb}EYy)imbEq?!ttMG37%BqKC1Z{qMcu$Ntr)mu@tbKyYFCl~cPd&XGbXi>%MwN$^djVhgGoca* zS$nrwBi0wp$12J`)|QVCG$f0Sp-v79PO>CAY^XCf>yI)wQaw7aHgOh9cdsMXC3E7M zwwK!2%*uprEDH$<5ocgE0VMSZSJ32%ZNF^c&>X}T=Z8v)>!YCkx+)SWxu+S3g?6wfnz1-9RuEo0iqyWaB#$?Q_C8xGz85XayP$6j7Ytb* zDB*A{Hl04HcmN!yHw#IUVn$+E$7Pu-XFOUgqC)*LMNcdX9nnqAgKL$c@FG-p@R)D% zVL|8G$H$ab(u$}u3eBxQV~*`;i_NG#W#DcU|AMh|i*A^f6h)V;bf$LlX1HjqRyGo= z#efPfm0{sT%v-%`RUTE9N)5n*d|sqv7gf)#EIv>Ibq6j!Gg3sdM5v zPdr33^$`)liZ$c$dp3rRJdIzq0GU*SQIwhF>k4)cmxeQT%2SYK@ff1N0LDQ}4+V~6 zxOkmSA&VS@{$eFzDRdF5P|9xBwY59TvSSk!IYL52Pr{0loIYLJf=fdc-4GA=EaNGlzs! zlD5RT)W;Z}OOC53U3N|7@alyt63)eVT&$Dq0BO9z1?|nlp4)HzkRwVW1?eg~JXlgf zLIMs2M+QGR)|sCa-u=VJgj7!T)`Bh4W2-e6)jg<^WQ~fURY{wGz=iP2L{J%XJ~>VZ z{UmgMrl8nr0J{LYIZ5+0v!B&tPu%TY@;FQq0an<0K%8V;E1ap}0eI<>y+eN6%&c!! z^B?uUjC#UvHk%AsQIe)wf^^G5-hO~3lrbdez&qS7Sc?B&eJzQ9z$i@NEWYz>D5(#4n2KS z&k`Vb{VvOur(jMfuD?r)jMr;9rkelbT@J8F<;sYtS_{)+;1eAY0f2K`^M_lqdt_Zt zbKA?d;<%Tc?28tZE^ox1TQF%6qWh>HyvBs7r28_?@o);1)3ppZv6-s39v=EO>Y#h& zmS8P~`X{}GllSn~@tEu8@FErf?xb7y`x$hQ<$jUzHZ_K}MgHOb_YSr<66K9m0s=YNT9(>H2z`(RDVXH}-FwYAnt4p1Azsb>@s18}lTE`7lvWQQH%CGSET{Omig)YgG_lYqHzfxOG;JSYd}zuOT!hsmM3>)0BMz#p$( zxU-)Eyus=(*!*C;A5Qy&&fi49?;7u>K7BYq-ied?FHutlnT$ht_&TfZy$&ld@Mqqa z_6EP<6*r|GoTvUCoTolI{oHuUNbu!F#?=c;bgg}Jd@8!(UjF$jzrjX-7_$xwL{Y>U zpTC91dV?8jt=~h1&H%sDtYc%8v=y7rPvUdRj-8MO+WKxs{~Bz6gHQj3@&0q4F4496 zM}Wa}Hqa%!{|pR3nezRdxZpfced%2k{|hkaR2RLUzTvF;n9AY&_^afr1K95jv;QL4 zP8WrLUO4|SMd3daUDIftUc&r(K|H-O{55HqP6E0@_(xc2{ZEywjq*Mu_3V-GY){)Z z>4UEOjl;uilyy=Ef zHsOe58!*X+I4M@tl+f~@z|Vp$&tNs<6j~=>V04;=X;ZlqUgiWh$xVYt<`1h3g0`n7 z*i#h?&ZkzX)yFSGa}3@gbfaF8AMn%nBaH44`uZ_Bd?b*SRnO1%MH?Y!W>vn!>m9$* z={i9AO6BTu24%v%+!d%k_wJIgGa8eJ51)H((c5k}hK<#*CO5VL;EQ{`x?ROd#mD$l z`{2&P(1CiV@+u&3{iGr^DGiiteM4H;y?OFaUSY3Wz6GV-twBfbGJUy8=9oE$uMNJX z?@H?_N$9F@y(5a+DqRRzztso+zXfJfTN#Mz_A{8{J(|iv6>SJ{2_n`>7uJn|xrO7R z3eoX1#grgBYlU@np8DpXKq?oNemA5$IC05G5LgUB3sAOmohU&O7(25RtvP62eKV!^ z?w|jz@SHtyxotctJnfK+ydeSOjD#JRW;y&Y3f7nUbm9{;1*|$&tZs#&aR7_tcow(0 z5SEiM3pI(S5&p$(`(cGCC0+*{JL?Il$nS;I=c@T;`(Q6>j?a3ZsJF4|j3;L8cx!Z+ zq8~o-j^n0Ovz2cc{3l_f6nk|%v|3}jLeNWaBa_Is%pyxG_H177N|wDT`+ KUuAAReEx4{RZQOi literal 0 HcmV?d00001 diff --git a/examples/spi_10mhz/makefile b/examples/spi_10mhz/makefile new file mode 100644 index 0000000..5cd0333 --- /dev/null +++ b/examples/spi_10mhz/makefile @@ -0,0 +1,106 @@ +include ../../imports.mak + +####################### +# project information # +####################### + +PROJECT_NAME := spi_10mhz +SUPPORTED_PROCESSORS := am261x +# Does the PRU code have dependencies outside of the pru-no-code-tool repo? +PRU_DEPENDENCIES := +# Use NON_PRU_DEPENDENCIES to select which makefiles to call for non-PRU cores +NON_PRU_DEPENDENCIES := mcuplus + +################### +# Prebuild checks # +################### +BUILD_PROJECT := y +DEVICE_NON_PRU := + +# Only build project if $(DEVICE) is in $(SUPPORTED_PROCESSORS) +ifeq (,$(findstring $(DEVICE),$(SUPPORTED_PROCESSORS))) +BUILD_PROJECT := n +MESSAGE := Project $(PROJECT_NAME) does not have a build option for $(DEVICE) +endif + +# Only build project if PRU dependencies exist +ifneq (,$(PRU_DEPENDENCIES)) +# MCU+ SDK dependency? +ifeq (mcuplus,$(findstring mcuplus,$(PRU_DEPENDENCIES))) +ifneq ($(BUILD_MCUPLUS),y) +BUILD_PROJECT := n +MESSAGE ?= Project $(PROJECT_NAME) depends on MCU+ SDK, but BUILD_MCUPLUS != y. +endif +endif +# Additional PRU dependency checks go here. For example: +#ifeq (dependency,$(findstring dependency,$(PRU_DEPENDENCIES))) +#if (dependency check fails) +#BUILD_PROJECT := n +#MESSAGE ?= Project $(PROJECT_NAME) depends on dependency, but dependency does not exist. +#endif +#endif +endif + +# Only build non-PRU code if the non-PRU code is enabled in imports.mak +ifeq ($(BUILD_MCUPLUS),y) +ifeq (mcuplus,$(findstring mcuplus,$(NON_PRU_DEPENDENCIES))) +DEVICE_NON_PRU += $(DEVICE)_mcuplus +endif +endif +ifeq ($(BUILD_LINUX),y) +ifeq (linux,$(findstring linux,$(NON_PRU_DEPENDENCIES))) +DEVICE_NON_PRU += $(DEVICE)_linux +endif +endif + +########################### +# Make and clean commands # +########################### + +ifeq ($(BUILD_PROJECT),y) +# "make" or "make all" builds projects that match $(DEVICE) set in imports.mak +# "make" builds PRU firmware first, then host (non-PRU) code +all: MESSAGE = "Building $(PROJECT_NAME) for $(DEVICE)" +all: pre_build_message + $(MAKE) pru + $(MAKE) host + +# "make pru" builds only PRU firmware for $(DEVICE) +pru: ARGUMENTS_PRU = all +pru: $(DEVICE) + +# "make host" builds only host (non-PRU) code for $(DEVICE) +host: ARGUMENTS_MCUPLUS = all +host: $(DEVICE_NON_PRU) + +# "make clean" cleans projects that match $(DEVICE) set in imports.mak +clean: ARGUMENTS_PRU = clean +clean: ARGUMENTS_MCUPLUS = scrub +clean: MESSAGE = "Cleaning $(PROJECT_NAME) for $(DEVICE)" +clean: pre_build_message $(DEVICE) $(DEVICE_NON_PRU) + +else +# if a prebuild check failed, print message and exit +all clean pru host: pre_build_message +endif + +pre_build_message: + @echo $(MESSAGE) + +###################### +# Target definitions # +###################### + +# provide target definitions for each supported processor +# PRU firmware should be built before any RTOS code that includes it +am261x: +# am261x-lp + $(MAKE) -C firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt $(ARGUMENTS_PRU) + $(MAKE) -C firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt $(ARGUMENTS_PRU) + +am261x_mcuplus: +# am261x-lp + $(MAKE) -C mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang $(ARGUMENTS_MCUPLUS) + +.PHONY: all clean pru host pre_build_message $(DEVICE) $(DEVICE_NON_PRU) $(SUPPORTED_PROCESSORS) + diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg new file mode 100644 index 0000000..c9e69a2 --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg @@ -0,0 +1,327 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@11.00.00" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM261x@11.00.00" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const ioexp = scripting.addModule("/board/ioexp/ioexp", {}, false); +const ioexp1 = ioexp.addInstance(); +const i2c = scripting.addModule("/drivers/i2c/i2c", {}, false); +const i2c1 = i2c.addInstance(); +const pruicss = scripting.addModule("/drivers/pruicss/pruicss", {}, false); +const pruicss1 = pruicss.addInstance(); +const debug_log = scripting.addModule("/kernel/dpl/debug_log"); +const dpl_cfg = scripting.addModule("/kernel/dpl/dpl_cfg"); +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(); +const mpu_armv76 = mpu_armv7.addInstance(); +const default_linker = scripting.addModule("/memory_configurator/default_linker", {}, false); +const default_linker1 = default_linker.addInstance(); +const general = scripting.addModule("/memory_configurator/general", {}, false); +const general1 = general.addInstance(); +const region = scripting.addModule("/memory_configurator/region", {}, false); +const region1 = region.addInstance(); +const section = scripting.addModule("/memory_configurator/section", {}, false); +const section1 = section.addInstance(); +const section2 = section.addInstance(); +const section3 = section.addInstance(); +const section4 = section.addInstance(); +const section5 = section.addInstance(); +const section6 = section.addInstance(); +const section7 = section.addInstance(); +const section8 = section.addInstance(); +const section9 = section.addInstance(); +const section10 = section.addInstance(); +const section11 = section.addInstance(); +const section12 = section.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +ioexp1.$name = "CONFIG_IOEXP0"; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_S1_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_BO_MUX_EN_N_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_SO_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_S1_state = 1; +ioexp1.TCA6408ARGTR_port0_pinBP_BO_MUX_EN_mode = 0; + +ioexp1.peripheralDriver = i2c1; +i2c1.$name = "CONFIG_I2C2"; +i2c1.I2C.$assign = "I2C0"; +i2c1.I2C.SCL.$assign = "GPIO135"; +i2c1.I2C.SDA.$assign = "GPIO134"; +i2c1.I2C_child.$name = "drivers_i2c_v1_i2c_v1_template1"; + +pruicss1.$name = "CONFIG_PRU_ICSS0"; +pruicss1.instance = "ICSSM1"; +pruicss1.AdditionalICSSSettings[0].$name = "CONFIG_PRU_ICSS_IO0"; +pruicss1.AdditionalICSSSettings[0].PruGPIO.create(1); +pruicss1.AdditionalICSSSettings[0].PruGPIO[0].$name = "CONFIG_PRU_ICSS_GPIO0"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].$assign = "PRU-ICSS1"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO5.$assign = "GPIO54"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO5.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.$assign = "GPIO19"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO4.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO4.$assign = "GPIO15"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO4.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO0.$assign = "GPIO81"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO0.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO1.$assign = "GPIO82"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO1.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO2.$assign = "GPIO83"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO2.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO9.$assign = "GPIO80"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.$assign = "GPIO3"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO1.$assign = "GPIO72"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO1.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO2.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO2.$assign = "GPIO73"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO2.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO7.$assign = "GPIO26"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO7.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO6.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO6.$assign = "GPIO45"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO6.$used = true; + +debug_log.enableUartLog = true; +debug_log.enableSharedMemLog = true; +debug_log.enableSharedMemLogReader = true; +debug_log.uartLog.$name = "CONFIG_UART0"; +debug_log.uartLog.UART.$assign = "UART0"; +debug_log.uartLog.UART.RXD.$assign = "GPIO27"; +debug_log.uartLog.UART.TXD.$assign = "GPIO28"; +debug_log.uartLog.child.$name = "drivers_uart_v2_uart_v2_template0"; + +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 = 0x80000; +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.size = 14; +mpu_armv75.baseAddr = 0x50D00000; +mpu_armv75.allowExecute = false; +mpu_armv75.attributes = "Device"; + +mpu_armv76.$name = "CONFIG_MPU_REGION5"; +mpu_armv76.size = 14; +mpu_armv76.allowExecute = false; +mpu_armv76.attributes = "NonCached"; +mpu_armv76.baseAddr = 0x72000000; + +default_linker1.$name = "memory_configurator_default_linker0"; + +general1.$name = "CONFIG_GENERAL0"; +general1.linker.$name = "TIARMCLANG0"; + +region1.$name = "MEMORY_REGION_CONFIGURATION0"; +region1.memory_region.create(11); +region1.memory_region[0].type = "TCMA"; +region1.memory_region[0].$name = "R5F_VECS"; +region1.memory_region[0].size = 0x40; +region1.memory_region[0].auto = false; +region1.memory_region[1].type = "TCMA"; +region1.memory_region[1].$name = "R5F_TCMA"; +region1.memory_region[1].size = 0x7FC0; +region1.memory_region[2].type = "TCMB"; +region1.memory_region[2].size = 0x8000; +region1.memory_region[2].$name = "R5F_TCMB"; +region1.memory_region[3].$name = "SBL"; +region1.memory_region[3].auto = false; +region1.memory_region[3].size = 0x40000; +region1.memory_region[4].$name = "OCRAM"; +region1.memory_region[4].auto = false; +region1.memory_region[4].manualStartAddress = 0x70040000; +region1.memory_region[4].size = 0x40000; +region1.memory_region[5].type = "FLASH"; +region1.memory_region[5].auto = false; +region1.memory_region[5].manualStartAddress = 0x60100000; +region1.memory_region[5].size = 0x80000; +region1.memory_region[5].$name = "FLASH"; +region1.memory_region[6].$name = "USER_SHM_MEM"; +region1.memory_region[6].auto = false; +region1.memory_region[6].manualStartAddress = 0x70150000; +region1.memory_region[6].size = 0x4000; +region1.memory_region[6].isShared = true; +region1.memory_region[6].shared_cores = ["r5fss0-1"]; +region1.memory_region[7].$name = "LOG_SHM_MEM"; +region1.memory_region[7].auto = false; +region1.memory_region[7].manualStartAddress = 0x70154000; +region1.memory_region[7].size = 0x4000; +region1.memory_region[7].isShared = true; +region1.memory_region[7].shared_cores = ["r5fss0-1"]; +region1.memory_region[8].type = "CUSTOM"; +region1.memory_region[8].$name = "RTOS_NORTOS_IPC_SHM_MEM"; +region1.memory_region[8].auto = false; +region1.memory_region[8].manualStartAddress = 0x72000000; +region1.memory_region[8].size = 0x3E80; +region1.memory_region[8].isShared = true; +region1.memory_region[8].shared_cores = ["r5fss0-1"]; +region1.memory_region[9].type = "CUSTOM"; +region1.memory_region[9].$name = "MAILBOX_HSM"; +region1.memory_region[9].auto = false; +region1.memory_region[9].manualStartAddress = 0x44000000; +region1.memory_region[9].size = 0x3CE; +region1.memory_region[9].isShared = true; +region1.memory_region[9].shared_cores = ["r5fss0-1"]; +region1.memory_region[10].type = "CUSTOM"; +region1.memory_region[10].$name = "MAILBOX_R5F"; +region1.memory_region[10].auto = false; +region1.memory_region[10].manualStartAddress = 0x44000400; +region1.memory_region[10].size = 0x3CE; +region1.memory_region[10].isShared = true; +region1.memory_region[10].shared_cores = ["r5fss0-1"]; + +section1.load_memory = "R5F_VECS"; +section1.group = false; +section1.$name = "Vector Table"; +section1.output_section.create(1); +section1.output_section[0].$name = ".vectors"; +section1.output_section[0].palignment = true; + +section2.load_memory = "OCRAM"; +section2.$name = "Text Segments"; +section2.output_section.create(5); +section2.output_section[0].$name = ".text.hwi"; +section2.output_section[0].palignment = true; +section2.output_section[1].$name = ".text.cache"; +section2.output_section[1].palignment = true; +section2.output_section[2].$name = ".text.mpu"; +section2.output_section[2].palignment = true; +section2.output_section[3].$name = ".text.boot"; +section2.output_section[3].palignment = true; +section2.output_section[4].$name = ".text:abort"; +section2.output_section[4].palignment = true; + +section3.load_memory = "OCRAM"; +section3.$name = "Code and Read-Only Data"; +section3.output_section.create(2); +section3.output_section[0].$name = ".text"; +section3.output_section[0].palignment = true; +section3.output_section[1].$name = ".rodata"; +section3.output_section[1].palignment = true; + +section4.load_memory = "OCRAM"; +section4.$name = "Data Segment"; +section4.output_section.create(1); +section4.output_section[0].$name = ".data"; +section4.output_section[0].palignment = true; + +section5.load_memory = "OCRAM"; +section5.$name = "Memory Segments"; +section5.output_section.create(3); +section5.output_section[0].$name = ".bss"; +section5.output_section[0].output_sections_start = "__BSS_START"; +section5.output_section[0].output_sections_end = "__BSS_END"; +section5.output_section[0].palignment = true; +section5.output_section[1].$name = ".sysmem"; +section5.output_section[1].palignment = true; +section5.output_section[2].$name = ".stack"; +section5.output_section[2].palignment = true; + +section6.load_memory = "OCRAM"; +section6.$name = "Stack Segments"; +section6.output_section.create(5); +section6.output_section[0].$name = ".irqstack"; +section6.output_section[0].output_sections_start = "__IRQ_STACK_START"; +section6.output_section[0].output_sections_end = "__IRQ_STACK_END"; +section6.output_section[0].input_section.create(1); +section6.output_section[0].input_section[0].$name = ". = . + __IRQ_STACK_SIZE;"; +section6.output_section[1].$name = ".fiqstack"; +section6.output_section[1].output_sections_start = "__FIQ_STACK_START"; +section6.output_section[1].output_sections_end = "__FIQ_STACK_END"; +section6.output_section[1].input_section.create(1); +section6.output_section[1].input_section[0].$name = ". = . + __FIQ_STACK_SIZE;"; +section6.output_section[2].$name = ".svcstack"; +section6.output_section[2].output_sections_start = "__SVC_STACK_START"; +section6.output_section[2].output_sections_end = "__SVC_STACK_END"; +section6.output_section[2].input_section.create(1); +section6.output_section[2].input_section[0].$name = ". = . + __SVC_STACK_SIZE;"; +section6.output_section[3].$name = ".abortstack"; +section6.output_section[3].output_sections_start = "__ABORT_STACK_START"; +section6.output_section[3].output_sections_end = "__ABORT_STACK_END"; +section6.output_section[3].input_section.create(1); +section6.output_section[3].input_section[0].$name = ". = . + __ABORT_STACK_SIZE;"; +section6.output_section[4].$name = ".undefinedstack"; +section6.output_section[4].output_sections_start = "__UNDEFINED_STACK_START"; +section6.output_section[4].output_sections_end = "__UNDEFINED_STACK_END"; +section6.output_section[4].input_section.create(1); +section6.output_section[4].input_section[0].$name = ". = . + __UNDEFINED_STACK_SIZE;"; + +section7.load_memory = "OCRAM"; +section7.$name = "Initialization and Exception Handling"; +section7.output_section.create(3); +section7.output_section[0].$name = ".ARM.exidx"; +section7.output_section[0].palignment = true; +section7.output_section[1].$name = ".init_array"; +section7.output_section[1].palignment = true; +section7.output_section[2].$name = ".fini_array"; +section7.output_section[2].palignment = true; + +section8.load_memory = "USER_SHM_MEM"; +section8.type = "NOLOAD"; +section8.$name = "User Shared Memory"; +section8.group = false; +section8.output_section.create(1); +section8.output_section[0].$name = ".bss.user_shared_mem"; +section8.output_section[0].alignment = 0; + +section9.load_memory = "LOG_SHM_MEM"; +section9.$name = "Log Shared Memory"; +section9.group = false; +section9.type = "NOLOAD"; +section9.output_section.create(1); +section9.output_section[0].$name = ".bss.log_shared_mem"; +section9.output_section[0].alignment = 0; + +section10.load_memory = "RTOS_NORTOS_IPC_SHM_MEM"; +section10.type = "NOLOAD"; +section10.$name = "IPC Shared Memory"; +section10.group = false; +section10.output_section.create(1); +section10.output_section[0].$name = ".bss.ipc_vring_mem"; +section10.output_section[0].alignment = 0; + +section11.load_memory = "MAILBOX_HSM"; +section11.type = "NOLOAD"; +section11.$name = "SIPC HSM Queue Memory"; +section11.group = false; +section11.output_section.create(1); +section11.output_section[0].$name = ".bss.sipc_hsm_queue_mem"; +section11.output_section[0].alignment = 0; + +section12.load_memory = "MAILBOX_R5F"; +section12.$name = "SIPC R5F Queue Memory"; +section12.group = false; +section12.type = "NOLOAD"; +section12.output_section.create(1); +section12.output_section[0].$name = ".bss.sipc_secure_host_queue_mem"; +section12.output_section[0].alignment = 0; diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/main.c b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/main.c new file mode 100644 index 0000000..b8dd06a --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/main.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024-2025 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 empty_example_main(void *args); + +void freertos_main(void *args) +{ + empty_example_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/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec new file mode 100644 index 0000000..b5a26d0 --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile new file mode 100644 index 0000000..fbca04d --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile @@ -0,0 +1,336 @@ +# +# Auto generated makefile +# + +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_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 +COV=$(CG_TOOL_ROOT)/bin/tiarmcov +PROFDATA=$(CG_TOOL_ROOT)/bin/tiarmprofdata +COVERAGE_PATH=$(abspath .) +ifeq ($(OS), Windows_NT) + PYTHON=python +else + PYTHON=python3 +endif + +PROFILE?=release +ConfigName:=$(PROFILE) + +OUTNAME:=spi_10mhz.$(PROFILE).out +COREOUTNAME:=spi_10mhz.$(PROFILE).optishare.out + +BOOTIMAGE_PATH=$(abspath .) +oeconfig?=None + +BOOTIMAGE_NAME_MCELF:=spi_10mhz.$(PROFILE).mcelf +BOOTIMAGE_NAME_MCELF_HS:=spi_10mhz.$(PROFILE).mcelf.hs +TARGETS := $(BOOTIMAGE_NAME_MCELF) + +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif + + +FILES_common := \ + main.c \ + empty_example.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${MCU_PLUS_SDK_PATH}/source \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/FreeRTOS-Kernel/include \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/portable/TI_ARM_CLANG/ARM_CR5F \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/config/am261x/r5f \ + -I${MCU_PLUS_SDK_PATH}/source/pru_io/driver \ + -I${PRU_NO_CODE_TOOL_PATH}/examples/spi_10mhz/firmware/am261x-lp \ + -Igenerated \ + +DEFINES_common := \ + -DSOC_AM261X \ + -DOS_FREERTOS \ + +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-register \ + -Wno-writable-strings \ + -Wno-enum-compare \ + -Wno-reserved-user-defined-literal \ + -Wno-unused-const-variable \ + -Wno-vla-cxx-extension \ + -x c++ \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -Os \ + +LNK_FILES_common = \ + generated/linker.cmd \ + +LIBS_PATH_common = \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/kernel/freertos/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/drivers/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/board/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/pru_io/lib \ + -Wl,-i${CG_TOOL_ROOT}/lib \ + +LIBS_common = \ + -lfreertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + -ldrivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + -lboard.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + -llibc.a \ + -llibsysbm.a \ + +LFLAGS_common = \ + -Wl,--diag_suppress=10063 \ + -Wl,--ram_model \ + -Wl,--reread_libs \ + -Wl,--gen_xml_func_hash \ + + +LIBS_NAME = \ + freertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + drivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + board.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + libc.a \ + libsysbm.a \ + +LIBS_PATH_NAME = \ + ${MCU_PLUS_SDK_PATH}/source/kernel/freertos/lib \ + ${MCU_PLUS_SDK_PATH}/source/drivers/lib \ + ${MCU_PLUS_SDK_PATH}/source/board/lib \ + ${MCU_PLUS_SDK_PATH}/source/pru_io/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)) +ifeq ($(INSTRUMENTATION_MODE), yes) +CFLAGS += -fprofile-instr-generate -fcoverage-mapping +endif +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: am261x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: am261x:r5fss0-0:freertos:ti-arm-clang $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -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 + +SYSTEM_FLAG ?= false + +ifeq ($(SYSTEM_FLAG), false) + SYSTEM_COMMAND := syscfg $(SYSCFG_GEN_FILES) $(OBJS) $(LNK_FILES) $(LIBS_NAME) +else + SYSTEM_COMMAND := $(OBJS) $(LNK_FILES) $(LIBS_NAME) +endif + +$(OUTNAME): $(SYSTEM_COMMAND) + @echo . + @echo Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ ... + $(LNK) $(LNKOPTFLAGS) $(LFLAGS) $(LIBS_PATH) -Wl,-m=$(basename $@).map -o $@ $(addprefix $(OBJDIR), $(OBJS)) $(LIBS) $(LNK_FILES) -Wl,--xml_link_info=$(basename $@).lnkxml + @echo Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ Done !!! + @echo . + +coreout: $(COREOUTNAME) +$(COREOUTNAME): $(SYSTEM_COMMAND) + @echo . + @echo Relinking Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ with OptiShare SSO.. + $(LNK) $(LNKOPTFLAGS) $(LFLAGS) $(LIBS_PATH) -Wl,-m=$(basename $@).map -o $@ $(addprefix $(OBJDIR), $(OBJS)) $(LIBS) $(LNK_FILES) -Wl,--xml_link_info=$(basename $@).lnkxml -Wl,--import_sso=$(SSO_PATH) + @echo Relinking with optishare: am261x:r5fss0-0:freertos:ti-arm-clang $@ Done !!! + @echo . + +clean: + @echo Cleaning: am261x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(OUTNAME) + $(RM) $(BOOTIMAGE_NAME_MCELF) + $(RM) $(BOOTIMAGE_NAME_MCELF_HS) + $(RMDIR) generated/ + +scrub: + @echo Scrubing: am261x:r5fss0-0:freertos:ti-arm-clang spi_10mhz ... + $(RMDIR) obj +ifeq ($(OS),Windows_NT) + $(RM) \*.out + $(RM) \*.map + $(RM) \*.appimage* + $(RM) \*.rprc* + $(RM) \*.tiimage* + $(RM) \*.bin + $(RM) \*.lnkxml + $(RM) \*.ossr + $(RM) \*.mcelf + $(RM) \*.mcelf_xip + $(RM) \*.mcelf-enc + $(RM) \*.mcelf.hs +else + $(RM) *.out + $(RM) *.map + $(RM) *.appimage* + $(RM) *.rprc* + $(RM) *.tiimage* + $(RM) *.bin + $(RM) *.lnkxml + $(RM) *.ossr + $(RM) *.mcelf + $(RM) *.mcelf_xip + $(RM) *.mcelf-enc + $(RM) *.mcelf.hs +endif + $(RMDIR) generated + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + $(MKDIR) $@ + + +.NOTPARALLEL: + +.INTERMEDIATE: syscfg +$(SYSCFG_GEN_FILES): syscfg + +ifeq ($(SYSTEM_FLAG), false) +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --product $(SYSCFG_MCU_PLUS_SDK_PRODUCT) --context r5fss0-0 --part ALX --package ALX --output generated/ ../example.syscfg +endif + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --product $(SYSCFG_MCU_PLUS_SDK_PRODUCT) --device AM261x_ALX_beta --context r5fss0-0 --part 2612 --package ZFG --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 $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MCU_PLUS_SDK_PATH)/source/security/security_common/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 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 +SBL_DEV_ID=55 + +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py + +$(BOOTIMAGE_NAME_MCELF): $(OUTNAME) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) ... + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTNAME) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) --otfaConfigFile=$(oeconfig) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) +ifeq ($(DEVICE_TYPE), HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) +else + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss +endif +else +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! + @echo . +endif + + + +.PHONY: coverage +coverage: + @echo Creating Coverage Report for spi_10mhz.$(PROFILE) ... + $(MKDIR) coverage + $(PROFDATA) merge -sparse -obj-file=$(OUTNAME) $(OUTNAME).cnt -o spi_10mhz.$(PROFILE).profdata + $(COV) show --format=html --show-expansions --show-instantiations --show-branches=count --object=$(OUTNAME) -instr-profile=spi_10mhz.$(PROFILE).profdata --output-dir=$(COVERAGE_PATH)/coverage --ignore-filename-regex=build_jenkins + $(COV) export --format=text --object=$(OUTNAME) --instr-profile=spi_10mhz.$(PROFILE).profdata > coverage/spi_10mhz.$(PROFILE).profdata.json + node $(MCU_PLUS_SDK_PATH)/tools/smart_placement/clang_coverage_analyse.js --input=coverage/spi_10mhz.$(PROFILE).profdata.json --output-json=coverage/spi_10mhz.$(PROFILE).analysis.json --output=../spi_10mhz.annotations.$(PROFILE).S --top-function-count=500 + @echo Coverage Report Generated at $(COVERAGE_PATH)/coverage folder !!! + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen new file mode 100644 index 0000000..93f08ca --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -0,0 +1,95 @@ +# +# Auto generated makefile +# + +# Below variables need to be defined outside this file or via command line +# - PRU_NO_CODE_TOOL_PATH +# - MCU_PLUS_SDK_PATH +# - PROFILE +# - CG_TOOL_ROOT +# - OUTNAME +# - CCS_INSTALL_DIR +# - CCS_IDE_MODE + +CCS_PATH=$(CCS_INSTALL_DIR) +include $(MCU_PLUS_SDK_PATH)/imports.mak +include $(MCU_PLUS_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_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif + +# +# 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 $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.sh +endif +BOOTIMAGE_TEMP_OUT_FILE=$(PROFILE)/temp_stdout_$(PROFILE).txt + +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 +SBL_DEV_ID=55 + +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py + +all: +ifeq ($(CCS_IDE_MODE),cloud) +# No post build steps +else + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) +else + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss +endif +else +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! + @echo . +endif +endif diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec new file mode 100644 index 0000000..16cc4cd --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=spi_10mhz_am261x-lp_r5fss0-0_freertos_ti-arm-clang + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs new file mode 100644 index 0000000..f716f8e --- /dev/null +++ b/examples/spi_10mhz/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs @@ -0,0 +1,12 @@ +/* + * ======== syscfg_c.rov.xs ======== + * This file contains the information needed by the Runtime Object + * View (ROV) tool. + */ +var crovFiles = [ + "kernel/freertos/rov/FreeRTOS.rov.js", +]; + +var objectViewerFiles = [ + "kernel/freertos/rov_theia/FreeRTOS_Theia.rov.js", +]; diff --git a/examples/spi_10mhz/mcuplus/empty_example.c b/examples/spi_10mhz/mcuplus/empty_example.c new file mode 100644 index 0000000..f7bff9c --- /dev/null +++ b/examples/spi_10mhz/mcuplus/empty_example.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024-2025 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_drivers_open_close.h" +#include "ti_board_open_close.h" +#include + +#include +#include + + + +/* + * This is an example project to show R5F + * loading PRU firmware. + */ + +/** \brief Global Structure pointer holding PRUSS1 memory Map. */ + +PRUICSS_Handle gPruIcss0Handle; + + +void empty_example_main(void *args) +{ + Drivers_open(); // check return status + + int status; + status = Board_driversOpen(); + DebugP_assert(SystemP_SUCCESS == status); + + gPruIcss0Handle = PRUICSS_open(CONFIG_PRU_ICSS0); + + status = PRUICSS_initMemory(gPruIcss0Handle, PRUICSS_DATARAM(PRUICSS_PRU0)); + DebugP_assert(status != 0); + + status = PRUICSS_initMemory(gPruIcss0Handle, PRUICSS_DATARAM(PRUICSS_PRU1)); + DebugP_assert(status != 0); + + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_PRU1, PRU1Firmware_0, sizeof(PRU1Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + DebugP_log("----- PRU1 Firmware loaded successfully. SPI Slave initialized. \r\n"); + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_PRU0, PRU0Firmware_0, sizeof(PRU0Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + DebugP_log("----- PRU0 Firmware loaded successfully. SPI Master initialized. \r\n"); + DebugP_log("----- Check register R0 of PRU0 to view the data recieved \r\n"); + + while (1) + { + ClockP_usleep(1); + } + + Board_driversClose(); + Drivers_close(); +} diff --git a/examples/spi_10mhz/readme.md b/examples/spi_10mhz/readme.md new file mode 100644 index 0000000..991c308 --- /dev/null +++ b/examples/spi_10mhz/readme.md @@ -0,0 +1,169 @@ +# SPI Transfer at 10MHz + +## Introduction + +This example demonstrates the use of the PRU No-Code Tool to achieve a 10MHz SPI clock on the AM261x platform using a PRU core clock of 200MHz. PRU0 acts as the SPI controller using the **SPI Transfer block** (full-duplex) and PRU1 acts as the SPI peripheral using the **SPI Write block**. + +The purpose of this example is to validate both directions of the SPI Transfer block: +- **TX path (PRU0 → PRU1)**: PRU0 transmits 32-bit data over SDO. Verified using a Saleae logic analyzer. +- **RX path (PRU1 → PRU0)**: PRU1 emulates an encoder response by driving known data (0xDEADDEAD) back over its SDO using the SPI Write slave block, which PRU0 receives via its SDI pin. This allows the RX path of the SPI Transfer block to be validated without requiring actual encoder hardware. + +After running the example the data recieved by the SPI transfer block is stored in register **R0 of PRU0** + +SPI mode used: **MODE1** (CPOL=0, CPHA=1). All 4 modes are supported. + +
+spi_10mhz +
In the figure, white signal represent the clock (70ns high and 30ns low) and the red signal represent the data (1 bit = 10ns)
+
+ +--- + +## Timing Configuration + +| Parameter | Value | +|-----------|-------| +| PRU clock | 200 MHz (AM261x ZFG 400MHz variant) | +| SCLK high width | 14 PRU cycles | +| SCLK low width | 6 PRU cycles | +| SPI clock frequency | 200MHz / (14+6) = **10 MHz** | +| Data setup time | 50 ns (10 PRU cycles) | +| CS setup time | 500 ns | +| CS hold time | 500 ns | + +> **Note:** The SCLK high width of 14 cycles is the minimum achievable with a 50ns data setup time requirement. +> At 200MHz PRU clock: `ceil(50ns × 200/1000) = 10 cycles` data setup overhead, giving `high_min = 4 + 10 = 14 cycles`. + +--- + +## No-Code Tool Block Design + +### PRU0 — SPI Controller (Transfer block) + +``` +[Load Constant: Load_Constant_0] value = 0xABCDEFAB (32-bit data to transmit) + │ + ▼ +[SPI Transfer: PRU0_SPI_Transfer_0] full-duplex, controller mode, MODE1, 32-bit MSB first + │ SCLK high = 14 cycles, low = 6 cycles → 10MHz + │ Data setup = 50ns, CS setup = 500ns, CS hold = 500ns + │ SCLK → GPO0, SDO → GPO1, SDI ← GPI6, CS → GPO2 + ▼ +[Flow Control: Flow_Control_0] HALT +``` + +### PRU1 — SPI Peripheral (Write block) + +``` +[Load Constant: Load_Constant_0] value = 0xDEADDEAD (32-bit data to send back to controller) + │ + ▼ +[SPI Write: PRU1_SPI_Write_0] peripheral mode, MODE1, 32-bit MSB first + │ waits for CS assert from PRU0, then sends data on SDO + │ SCLK ← GPI4, SDI ← GPI5, SDO → GPO1, CS ← GPI6 + ▼ +[Flow Control: Flow_Control_0] HALT +``` + +--- + +## Block Configuration Details + +### PRU0 Blocks + +**Load Constant (`Load_Constant_0`)** +- Value: 2882400171 (0xABCDEFAB) — 32-bit test pattern to transmit + +**SPI Transfer (`PRU0_SPI_Transfer_0`)** +- Packet size: 32 bits +- Device mode: Controller +- SPI mode: MODE1 (CPOL=0, CPHA=1) +- Endianness: MSB first +- SCLK high pulse width: 14 PRU cycles +- SCLK low pulse width: 6 PRU cycles +- Data setup time: 50ns +- CS setup time: 500ns +- CS hold time: 500ns +- SCLK signal: GPO0 +- SDO signal: GPO1 +- SDI signal: GPI6 +- CS signal: GPO2 + +**Flow Control (`Flow_Control_0`)** +- Operation: HALT + +--- + +### PRU1 Blocks + +**Load Constant (`Load_Constant_0`)** +- Value: 3735936685 (0xDEADDEAD) — 32-bit test pattern PRU1 sends back to PRU0 to emulate the encoder response + +**SPI Write (`PRU1_SPI_Write_0`)** +- Packet size: 32 bits +- Device mode: Peripheral +- SPI mode: MODE1 (CPOL=0, CPHA=1) +- Endianness: MSB first +- SCLK signal: GPI4 +- SDI signal: GPI5 +- SDO signal: GPO1 +- CS signal: GPI6 +- CS filter cycles: 2 + +**Flow Control (`Flow_Control_0`)** +- Operation: HALT + +--- + +## Pin Connections + +PRU0 drives SCLK and CS; both PRUs drive their respective SDO lines. + +| Signal | PRU0 pin (controller) | PRU1 pin (peripheral) | +|--------|-----------------------|-----------------------| +| SCLK | GPO0 | GPI4 | +| SDO | GPO1 | GPO5 | +| SDI | GPI6 | ---- | +| CS | GPO2 | GPI6 | + +--- + +## Why SPI Write slave instead of SPI Transfer slave? + +The SPI Transfer slave (full-duplex peripheral) has a practical maximum frequency of **7.69MHz at 200MHz PRU clock** due to the polling overhead of the software-based slave. The slave needs ~13 cycles minimum in both high and low phases to detect edges reliably. + +The SPI Write slave (TX only peripheral) relaxes the low phase constraint since it does not need to sample SDI, allowing the controller's low width to go down to 6 cycles. This enables the 10MHz clock while still validating the RX path of the controller's Transfer block. + +In this example the SPI Write slave on PRU1 serves as an **encoder emulator** — it sends back a fixed known pattern (0xDEADDEAD) to simulate the response a real encoder would send over SPI. This lets the RX path of the Transfer block be fully tested at 10MHz without needing actual encoder hardware connected. + +For a full bidirectional loopback at 200MHz PRU clock, use `high=13, low=13` giving **7.69MHz**. For 333MHz PRU clock (AM243x), the practical max is **12.8MHz** with `high=13, low=13`. + +--- + +# Supported Combinations + + Parameter | Value + ---------------|----------- + ICSSM | ICSSM1 - PRU0, PRU1 (am261x only) + Toolchain | pru-cgt + Board | am261x-lp + Example folder | examples/spi_10mhz/ + +# Steps to Run the Example + +> Prerequisite: [PRU-CGT-2-3](https://www.ti.com/tool/PRU-CGT) (ti-pru-cgt) should be installed at: `C:/ti/` + +- **When using CCS projects to build**, import the CCS project from the above mentioned Example folder path for R5F and PRU. After this `main.asm`, `linker.cmd` files get copied to the CCS workspace of the PRU project. The `main.asm` contains sample code to halt the PRU program. + + - Build the PRU project using the CCS project menu (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_PROJECTS_PAGE.html)). + - Build Flow: Once you click on build in PRU project, the firmware header file generated in the release or debug folder of the CCS workspace is moved to `` + + - Build the R5F project using the CCS project menu (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_PROJECTS_PAGE.html)). + - The firmware header file path is included in R5F project include options by default. Instructions in the firmware header file can be written into PRU IRAM memory using the PRUICSS_loadFirmware API. + + - Launch a CCS debug session and run the executable (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_LAUNCH_PAGE.html)). + + - Connect the SPI controller and peripheral pins as per the pin connections table above. + +- **When using makefiles to build**: + - For steps on how to use makefiles, run `make help` from the root folder of the pru-no-code-tool repository. diff --git a/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index f72f75b..7321e38 100644 --- a/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -12,7 +12,7 @@ > $(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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..93f08ca 100644 --- a/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/spi_loopback/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -12,7 +12,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +25,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +46,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif diff --git a/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec index 7d97362..5fb8708 100644 --- a/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec +++ b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -12,7 +12,7 @@ > $(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) - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) - $(RM) $(BOOTIMAGE_TEMP_OUT_FILE) +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif - $(RM) $(BOOTIMAGE_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS) Done !!! - @echo . else -# 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_NAME) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_HS_FS) Done !!! +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif diff --git a/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen index 9c2450e..93f08ca 100644 --- a/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen +++ b/examples/uart_crc/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -12,7 +12,7 @@ # - CCS_IDE_MODE CCS_PATH=$(CCS_INSTALL_DIR) -include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_SDK_PATH)/imports.mak include $(MCU_PLUS_SDK_PATH)/devconfig/devconfig.mak STRIP=$(CG_TOOL_ROOT)/bin/tiarmstrip @@ -25,12 +25,13 @@ 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 +BOOTIMAGE_NAME_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif # # Generation of boot image which can be loaded by Secondary Boot Loader (SBL) @@ -45,69 +46,50 @@ else 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 +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 SBL_DEV_ID=55 -MULTI_CORE_IMAGE_GEN = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/multicoreImageGen/multicoreImageGen.js -OUTRPRC_CMD = $(CCS_NODE) $(MCU_PLUS_SDK_PATH)/tools/boot/out2rprc/elf2rprc.js -APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py - -ifeq ($(OS),Windows_NT) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.exe -else - UNAME_S = $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out.mac - else - XIPGEN_CMD=$(MCU_PLUS_SDK_PATH)/tools/boot/xipGen/xipGen.out -endif -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) \ +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py all: ifeq ($(CCS_IDE_MODE),cloud) # No post build steps else - @echo Boot image: am261x: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) -ifeq ($(DEVICE_TYPE),HS) + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) # Sign the appimage using appimage signing script ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_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 - $(RM) $(BOOTIMAGE_NAME) + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_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 + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss endif else -# 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_NAME) -endif - $(RM) $(BOOTIMAGE_RPRC_NAME_TMP) -ifeq ($(DEVICE_TYPE),HS) - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs Done !!! - @echo . +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc else - @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME).hs_fs Done !!! + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! @echo . endif endif From a69f359e24525338e9e5fc5d2161ae5bec410deb Mon Sep 17 00:00:00 2001 From: Ayushman Date: Tue, 4 Aug 2026 16:05:39 +0530 Subject: [PATCH 2/2] am261x : add mirror_input example signed off by: Ayushman --- .../pru_blocks/common/pru_syscfg.asm.xdt | 8 + .../pru_register_allocator.js | 39 +- .../conditional_block.syscfg.js | 148 +++++++- .../flow_control_block.syscfg.js | 194 ++++++++-- README.md | 5 + docs/program-control/conditional_block.md | 19 +- docs/program-control/flow_control_block.md | 46 ++- docs/program-control/loop_block.md | 1 + .../am243x-evm/icss_g0_pru0_fw/example.syscfg | 2 +- .../am243x-evm/icss_g0_pru1_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru0_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru1_fw/example.syscfg | 2 +- .../icss_g0_tx_pru0_fw/example.syscfg | 2 +- .../icss_g0_tx_pru1_fw/example.syscfg | 2 +- .../am243x-lp/icss_g0_pru0_fw/example.syscfg | 2 +- .../am243x-lp/icss_g0_pru1_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru0_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru1_fw/example.syscfg | 2 +- .../icss_g0_tx_pru0_fw/example.syscfg | 2 +- .../icss_g0_tx_pru1_fw/example.syscfg | 2 +- .../am261x-lp/icss_m0_pru0_fw/example.syscfg | 2 +- .../am261x-lp/icss_m0_pru1_fw/example.syscfg | 2 +- .../am261x-lp/icss_m1_pru0_fw/example.syscfg | 2 +- .../am261x-lp/icss_m1_pru1_fw/example.syscfg | 2 +- .../am64x-evm/icss_g0_pru0_fw/example.syscfg | 2 +- .../am64x-evm/icss_g0_pru1_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru0_fw/example.syscfg | 2 +- .../icss_g0_rtu_pru1_fw/example.syscfg | 2 +- .../icss_g0_tx_pru0_fw/example.syscfg | 2 +- .../icss_g0_tx_pru1_fw/example.syscfg | 2 +- examples/empty/firmware/main.asm | 2 + examples/makefile | 1 + .../am261x-lp/icss_m1_pru0_fw/example.syscfg | 82 +++++ .../ti-pru-cgt/example.projectspec | 83 +++++ .../icss_m1_pru0_fw/ti-pru-cgt/linker.cmd | 54 +++ .../icss_m1_pru0_fw/ti-pru-cgt/makefile | 55 +++ .../ti-pru-cgt/makefile_projectspec | 16 + .../am261x-lp/icss_m1_pru1_fw/example.syscfg | 85 +++++ .../ti-pru-cgt/example.projectspec | 83 +++++ .../icss_m1_pru1_fw/ti-pru-cgt/linker.cmd | 54 +++ .../icss_m1_pru1_fw/ti-pru-cgt/makefile | 55 +++ .../ti-pru-cgt/makefile_projectspec | 16 + examples/mirror_input/firmware/main.asm | 35 ++ .../images/mirror_input_capture.png | Bin 0 -> 21632 bytes examples/mirror_input/makefile | 106 ++++++ .../r5fss0-0_freertos/example.syscfg | 325 +++++++++++++++++ .../am261x-lp/r5fss0-0_freertos/main.c | 84 +++++ .../ti-arm-clang/example.projectspec | 116 ++++++ .../r5fss0-0_freertos/ti-arm-clang/makefile | 336 ++++++++++++++++++ .../ti-arm-clang/makefile.defs | 14 + .../ti-arm-clang/makefile_ccs_bootimage_gen | 95 +++++ .../ti-arm-clang/makefile_projectspec | 16 + .../ti-arm-clang/syscfg_c.rov.xs | 12 + examples/mirror_input/mcuplus/empty_example.c | 101 ++++++ examples/mirror_input/readme.md | 75 ++++ .../am243x-lp/icss_g0_pru0_fw/example.syscfg | 2 +- .../am243x-lp/icss_g0_pru1_fw/example.syscfg | 2 +- .../am261x-lp/icss_m1_pru0_fw/example.syscfg | 2 +- .../am261x-lp/icss_m1_pru1_fw/example.syscfg | 2 +- examples/spi_loopback/firmware/main.asm | 1 + .../am243x-lp/icss_g0_pru1_fw/example.syscfg | 53 +-- 61 files changed, 2367 insertions(+), 100 deletions(-) create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile create mode 100644 examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec create mode 100644 examples/mirror_input/firmware/main.asm create mode 100644 examples/mirror_input/images/mirror_input_capture.png create mode 100644 examples/mirror_input/makefile create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/main.c create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec create mode 100644 examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs create mode 100644 examples/mirror_input/mcuplus/empty_example.c create mode 100644 examples/mirror_input/readme.md diff --git a/.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.asm.xdt b/.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.asm.xdt index 1f395e1..eb5ebd6 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.asm.xdt +++ b/.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.asm.xdt @@ -108,6 +108,10 @@ sysconfig_generated_start: %if(typeof(labels[iterator]) == "string" && labels[iterator] !== "") %{ `labels[iterator]`: +%if(labels[iterator].endsWith("_end")) +%{ + +%} %} % if((!pruInstructions[iterator].includes("-1")) && (pruInstructions[iterator] != "0") && (!pruInstructions[iterator].includes("undefined"))) % { @@ -128,6 +132,10 @@ sysconfig_generated_start: %if(typeof(labels[iterator]) == "string" && labels[iterator] !== "") %{ `labels[iterator]`: +%if(labels[iterator].endsWith("_end")) +%{ + +%} %} % if((!pruInstructions[iterator].includes("-1")) && (pruInstructions[iterator] != "0") && (!pruInstructions[iterator].includes("undefined"))) % { diff --git a/.metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js b/.metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js index d224604..cd6baa3 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js +++ b/.metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js @@ -484,6 +484,7 @@ function pushInstruction(instance, parentInstance) { if (moduleInstanceRegisterMap[instanceName]?.conditionCalculated === 1) { return moduleInstanceRegisterMap[instanceName].label; } + // Process prev port if it exists and is connected let label; if (instance?.["prev"] && instance?.["prev"][0]?.["inst"]) { @@ -619,6 +620,10 @@ function pushInstruction(instance, parentInstance) { }; instruction = `LDI ${getPruRegister(byteOffset, instance.loopCountRegSize)}, ${instance.loopCount}`; addToPruRegisterAllocationSummary(label, instruction, instance, instanceName, 0); + //push _start label between LDI and LOOP so a Flow Control + //jump back here resumes with the current counter value instead of + //resetting it (jumping to before the LDI would reset the count) + addToPruRegisterAllocationSummary(`${instanceName}_start`, "0", instance, instanceName, 0); //push loop instruction instruction = `LOOP endloop_${moduleInstanceRegisterMap[instanceName].instanceNum}, ${getPruRegister(byteOffset, instance.loopCountRegSize)}`; label = 0; @@ -770,8 +775,40 @@ function pushInstruction(instance, parentInstance) { { moduleInstanceRegisterMap[instanceName]["peakCycles"] += cycleBudgetMap[instanceName]; } + // Emit a universal _start label immediately before this + // block's own instruction, as its addressable entry point for Flow + // Control jumps. Placed here (not at function entry) so it lands right + // above this instruction rather than above the whole prev-chain that + // was just recursively processed. Loop and group blocks are excluded — + // they emit their own specific start labels elsewhere (loop: between + // LDI and LOOP / startloop_N; group: _start). + if (!instance.$groupContents) { + addToPruRegisterAllocationSummary(`${instanceName}_start`, "0", instance, instanceName, 0); + } addToPruRegisterAllocationSummary(label, instruction, instance, instanceName, moduleInstanceRegisterMap[instanceName]["peakCycles"]); - + + // Emit a universal _end label immediately after this + // block's own instruction, as an addressable "done with this block" + // target for Flow Control jumps (e.g. bailing out of a loop from + // inside a nested branch). Excluded for conditional (If/Else) blocks — + // a conditional has two forward addresses (_TRUE/_FALSE), not one, so + // a single _end here would be meaningless. + if (!instance.$groupContents && !(instance.T && instance.F)) { + addToPruRegisterAllocationSummary(`${instanceName}_end`, "0", instance, instanceName, 0); + } + + // Loop blocks get their own _end at the loop's actual exit + // point — right after endloop_N (finite loops) or right after the + // infinite QBA back-edge (infinite loops, i.e. the plain fallthrough + // point past the whole loop subtree). This is a NEW, exposed label + // distinct from the internal endloop_N/startloop_N hardware labels, + // so it can be selected in Flow Control's dropdown as an early-exit + // target (e.g. jump here from inside the loop body to bail out before + // the counter/condition naturally ends the loop). + if (instance.$groupContents && 'infiniteLoop' in instance) { + addToPruRegisterAllocationSummary(`${instanceName}_end`, "0", instance, instanceName, 0); + } + return maxBytesUsed; } diff --git a/.metadata/sysconfig/.meta/pru_blocks/program_control/conditional_block.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/program_control/conditional_block.syscfg.js index e93f8ae..abc3aca 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/program_control/conditional_block.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/program_control/conditional_block.syscfg.js @@ -1,11 +1,84 @@ +const FLOW_CONTROL_MODULE = "/pru_blocks/program_control/flow_control_block"; +const CONDITIONAL_MODULE = "/pru_blocks/program_control/conditional_block"; + +/** + * Walks forward from a T/F branch head via BOTH "next" (control flow) and + * "output1" (data flow fanout) connections — matching the reachability + * model already used elsewhere for branch chains (collectBranchChain in + * pru_register_allocator.js) and cycle detection (detectControlFlowCycle + * in pru_blocks_static_module.syscfg.js). A branch head with no outgoing + * "next" of its own can still be "handled" if a data consumer of its + * output eventually reaches a Flow Control block via ITS OWN "next" chain + * (e.g. Memory_Access -> Arithmetic.input1 (data) -> Arithmetic.next -> + * Flow Control). Only a genuine dead end (no next, no output1 consumers, + * and not a Flow Control block itself) on every reachable path is an error. + * If the chain reaches a nested conditional block, both of ITS T and F + * branches must recursively terminate the same way. + * Returns an error message, or null if the branch terminates correctly. + */ +function branchTerminates(headInst, ownerName, branchLabel) { + const visited = new Set(); + + function walk(current) { + if (!current || !current.$name || visited.has(current.$name)) { + return true; // Already visited (or a cycle, reported separately) — treat as handled + } + visited.add(current.$name); + + // $module is a live object reference on the instance; round-trip + // through JSON to get the plain module path string for comparison + // (matches the pattern used elsewhere in this codebase, e.g. + // crc_block.syscfg.js). + const currentModulePath = JSON.parse(JSON.stringify(current)).$module; + + if (currentModulePath === FLOW_CONTROL_MODULE) { + return true; // This path terminates correctly + } + + if (currentModulePath === CONDITIONAL_MODULE) { + const trueHead = current.T?.[0]?.inst; + const falseHead = current.F?.[0]?.inst; + if (!trueHead || !falseHead) { + // Nested conditional with an unconnected branch is caught by + // its own validate() call; don't double-report here. + return true; + } + // Both of the nested conditional's own branches must terminate. + return walk(trueHead) && walk(falseHead); + } + + const nextInst = current.next?.[0]?.inst; + const outputConsumers = current.output1 ? current.output1.map(c => c?.inst).filter(Boolean) : []; + + if (!nextInst && outputConsumers.length === 0) { + return false; // Genuine dead end, never reached a Flow Control block + } + + let handled = false; + if (nextInst) { + handled = walk(nextInst) || handled; + } + for (const consumer of outputConsumers) { + handled = walk(consumer) || handled; + } + return handled; + } + + const terminatesOk = walk(headInst); + if (terminatesOk) { + return null; + } + return `${ownerName}'s ${branchLabel} branch does not reach a Flow Control block on any path. Without one, execution falls through into the other branch. Add a Flow Control block at the end of this branch (directly, or via a data-consuming block's own control-flow chain).`; +} + function validate(inst, report) { for(let iterator = 1; iterator <= inst["numOfInputPorts"]; iterator++) { if(inst["input"+iterator.toString()].length == 0) { - report.logWarning("input"+iterator.toString()+" port not connected to output port",inst) + report.logWarning("input"+iterator.toString()+" port not connected to output port",inst) } - } + } //verifying if true port is connected true/false port(conditional input) are not if((inst["T"].length == 0)) { @@ -16,6 +89,23 @@ function validate(inst, report) { { report.logWarning("f_next port is not connected",inst); } + + // Any branch that IS connected must terminate in a Flow Control block, + // otherwise it falls through into the other branch's code. + const trueHead = inst.T?.[0]?.inst; + if (trueHead) { + const err = branchTerminates(trueHead, inst.$name, "T"); + if (err) { + report.logError(err, inst, "T"); + } + } + const falseHead = inst.F?.[0]?.inst; + if (falseHead) { + const err = branchTerminates(falseHead, inst.$name, "F"); + if (err) { + report.logError(err, inst, "F"); + } + } } function getAIContext() { @@ -85,8 +175,40 @@ scripting.connect(if_else1, "F", false_path_block, "prev"); // Connect control flow input scripting.connect(prev_block, "next", if_else1, "prev"); + +// REQUIRED: both true_path_block's and false_path_block's chains must each +// end in a Flow Control block, or validation fails. Example (standalone +// If/Else, NOT inside a Loop block): +const flow_control_block = scripting.addModule("/pru_blocks/program_control/flow_control_block", {}, false); +const flow_true = flow_control_block.addInstance(); +flow_true.$name = "Flow_Control_True_End"; +flow_true.jumpTarget = "JMP"; // or "HALT", or any real "_start"/"_end" target to jump elsewhere +scripting.connect(true_path_block, "next", flow_true, "prev"); + +const flow_false = flow_control_block.addInstance(); +flow_false.$name = "Flow_Control_False_End"; +flow_false.jumpTarget = "JMP"; +scripting.connect(false_path_block, "next", flow_false, "prev"); \\\`\\\`\\\` +**If the If/Else block is inside a Loop block's \\\`$groupContents\\\`**, "JMP"/"HALT" would exit the loop +entirely (or halt the PRU) instead of continuing the loop — jump to the loop's own \\\`_start\\\` +target instead so the loop keeps iterating: +\\\`\\\`\\\`javascript +// if_else1 is one of the instances inside loop_block1.$groupContents +const flow_true = flow_control_block.addInstance(); +flow_true.$name = "Flow_Control_True_End"; +flow_true.jumpTarget = "Loop_0_start"; // matches loop_block1.$name + "_start" — continues the loop +scripting.connect(true_path_block, "next", flow_true, "prev"); + +const flow_false = flow_control_block.addInstance(); +flow_false.$name = "Flow_Control_False_End"; +flow_false.jumpTarget = "Loop_0_start"; +scripting.connect(false_path_block, "next", flow_false, "prev"); +\\\`\\\`\\\` +Jumping to the loop's \\\`_start\\\` (not the loop's \\\`_end\\\`) is what resumes normal looping — \\\`_end\\\` +is the dedicated early-exit/break target, for when you want to abandon the loop instead of continuing it. + ### Important Notes 1. **Two Inputs Required**: Both input1 and input2 must be connected for comparison. @@ -99,7 +221,11 @@ scripting.connect(prev_block, "next", if_else1, "prev"); 5. **Port Names**: True path uses "T" port, False path uses "F" port (displayed as t_next/f_next). -6. **Terminate Each Branch with a Flow Control Block**: The code generator places the FALSE path immediately after the branch instruction, with the TRUE path at the branch target label. If the FALSE path has no explicit terminator, execution falls through into the TRUE path — causing both branches to execute regardless of the condition. Always end each branch (T and F) with a Flow Control block (HALT or END) to prevent this fall-through. +6. **Every Connected Branch MUST Terminate in a Flow Control Block**: The code generator places the FALSE path immediately after the branch instruction, with the TRUE path at the branch target label. If a connected branch (T or F) has no explicit terminator, execution falls through into the other branch — causing both to execute regardless of the condition. This is now enforced by SysConfig validation (an error, not a warning) — any connected T or F branch that doesn't end in a Flow Control block will fail validation. A branch left entirely unconnected is still fine (nothing happens on that path). + +7. **Where the Flow Control Block Should Jump To Depends On Context**: + - **Standalone If/Else** (not inside a Loop block): jump to \\\`JMP\\\` (SysConfig Generated End), \\\`HALT\\\`, or any other block's \\\`_start\\\`/\\\`_end\\\` target. + - **If/Else nested inside a Loop block**: jump to that Loop's own \\\`_start\\\` target, so execution resumes the loop instead of exiting it. Using \\\`JMP\\\`/\\\`HALT\\\` here ends the whole program early instead of continuing the loop — only do that if that's actually the intent (e.g. an early-exit condition that should stop everything, not just this iteration). To break out of the loop early without ending the whole program, jump to the Loop's \\\`_end\\\` target instead. `; } @@ -132,12 +258,14 @@ Implements conditional logic (IF/ELSE statements) to control program flow based **Generated Assembly**: - ; Example: Greater Than Input2 (QBGT) -- QBGT TRUE_LABEL, input1_reg, input2_reg ; Branch if input1 > input2 (1 cycle) +- FalseBranchHead_start: +- QBGT If_Else_0_TRUE, input1_reg, input2_reg ; Branch if input1 > input2 (1 cycle) - ; FALSE path code here -- QBA END_LABEL ; Jump to end -- TRUE_LABEL: +- ; FALSE branch MUST end in a Flow Control block (e.g. JMP sysconfig_generated_end) +- If_Else_0_TRUE: +- TrueBranchHead_start: - ; TRUE path code here -- END_LABEL: +- ; TRUE branch MUST end in a Flow Control block **PRU Branch Instructions**: - **QBGT**: Quick Branch if Greater Than (unsigned comparison) @@ -170,7 +298,11 @@ Implements conditional logic (IF/ELSE statements) to control program flow based - The conditional check happens instantly (1 cycle) - Code on both branches is generated, only one path executes at runtime - This block does not produce an output value - it only controls flow -- **Always terminate each branch (T and F) with a Flow Control block**: The FALSE path falls through to the TRUE path in the generated assembly unless explicitly stopped. Without a terminator on the FALSE branch, both branches execute sequentially regardless of the condition result. +- **Any connected branch (T or F) MUST terminate in a Flow Control block**: The FALSE path falls through to the TRUE path in the generated assembly unless explicitly stopped, and vice versa. SysConfig validation now enforces this as an error — connect a Flow Control block at the end of every connected branch. Leaving a branch entirely unconnected is fine; only connected-but-unterminated branches are rejected. +- **What that Flow Control block should jump to depends on where the If/Else block lives**: + - **Standalone If/Else** (not inside a Loop block): jump to Sysconfig Generated End, Halt, or any other block's \`_start\`/\`_end\` target. + - **If/Else nested inside a Loop block**: jump to that Loop's \`_start\` target so execution resumes the loop instead of exiting the whole program. Jumping to Sysconfig Generated End or Halt from inside a loop's branch ends the entire program early rather than just this iteration — only intentional if that's really the goal. To break out of the loop early (without ending the whole program), jump to the Loop's \`_end\` target instead. +- Every block, including this one and every block on either branch, has an addressable \`_start\` entry point that a Flow Control block elsewhere in the design can jump to (e.g. to re-run this comparison, or to re-enter a Loop block from inside a branch). ### Terminology - **Conditional branching**: Changing program flow based on a condition diff --git a/.metadata/sysconfig/.meta/pru_blocks/program_control/flow_control_block.syscfg.js b/.metadata/sysconfig/.meta/pru_blocks/program_control/flow_control_block.syscfg.js index 37fc906..2e56b8c 100644 --- a/.metadata/sysconfig/.meta/pru_blocks/program_control/flow_control_block.syscfg.js +++ b/.metadata/sysconfig/.meta/pru_blocks/program_control/flow_control_block.syscfg.js @@ -1,3 +1,86 @@ +/** + * Enumerates every real, user-meaningful label in the current design that + * a Flow Control block can validly jump to: every block's _start + * (entry point) and, for ordinary and loop blocks, _end (exit + * point — for loops this is a dedicated early-exit target, not the + * natural end-of-loop position). Conditional (If/Else) blocks only expose + * _start, since they have two forward addresses (_TRUE/_FALSE) rather + * than one "end". Excludes internal hardware labels (endloop_N; the + * startloop_N numeric suffix is kept since it's the only re-entry point + * infinite loops have, but conditional branch labels + * If_Else_x_TRUE/FALSE are excluded since those are branch-instruction + * targets, not block entry/exit points). + * @returns {{name: string, displayName: string}[]} + */ +function getValidJumpTargets() { + const targets = []; + + for (const moduleName in system.modules) { + if (!moduleName.startsWith("/pru_blocks/")) continue; + const module = system.modules[moduleName]; + if (!module || !module.$instances) continue; + + for (let i = 0; i < module.$instances.length; i++) { + const inst = module.$instances[i]; + if (!inst || typeof inst !== 'object' || !inst.$name) continue; + + if (inst.$groupContents) { + // Group block: exposed target is _start + if ('infiniteLoop' in inst) { + // Loop block + if (inst.infiniteLoop === true) { + targets.push({ + name: `startloop_${i}`, + displayName: `${inst.$name} (loop start)` + }); + } else { + targets.push({ + name: `${inst.$name}_start`, + displayName: `${inst.$name} (loop start)` + }); + } + // _end: exposed early-exit target, distinct from + // the internal endloop_N/startloop_N hardware labels — + // lands right after the loop's body finishes (or right + // after the infinite loop's back-edge), for bailing out + // of the loop from anywhere inside it. + targets.push({ + name: `${inst.$name}_end`, + displayName: `${inst.$name} (loop end / exit)` + }); + } else { + // Group block + const groupName = inst.groupName || inst.$name; + targets.push({ + name: `${groupName}_start`, + displayName: `${inst.$name} (group start)` + }); + } + } else if (inst.T && inst.F) { + // Conditional (If/Else) block: only _start is exposed — a + // conditional has two forward addresses (_TRUE/_FALSE), not + // a single "end", so no _end target is offered for it. + targets.push({ + name: `${inst.$name}_start`, + displayName: inst.$name + }); + } else { + // Ordinary block: universal _start and _end + targets.push({ + name: `${inst.$name}_start`, + displayName: inst.$name + }); + targets.push({ + name: `${inst.$name}_end`, + displayName: `${inst.$name} (end)` + }); + } + } + } + + return targets; +} + function validate(inst, report) { for(let iterator = 1; iterator <= inst["numOfInputPorts"]; iterator++) { @@ -6,6 +89,11 @@ function validate(inst, report) { report.logWarning("input"+iterator.toString()+" port not connected to output port",inst) } } + + const validNames = new Set(["JMP", "HALT", ...getValidJumpTargets().map(t => t.name)]); + if (!validNames.has(inst["jumpTarget"])) { + report.logError(`"${inst["jumpTarget"]}" is not a valid jump target in the current design. Re-select a target — it may have been renamed or removed.`, inst, "jumpTarget"); + } } function getAIContext() { @@ -26,27 +114,52 @@ const flow1 = flow_control_block.addInstance(); | Parameter | Type | Valid Values | Default | Description | |-----------|------|--------------|---------|-------------| -| opCode | String | "JMP", "HALT" | "JMP" | Jump target: end of generated code or halt | +| jumpTarget | String | "JMP", "HALT", or the name of any real _start/_end target in the design | "JMP" | Single dropdown covering every jump target — end of generated code, halt, or any block's entry/exit point. Validated against the current design, not free text | -### Valid Values for opCode +### Valid Values for jumpTarget | Value | Display Name | Description | |-------|--------------|-------------| | "JMP" | Sysconfig Generated End | Jump to end label of generated code | | "HALT" | Halt | Immediately stop PRU execution | +| "\_start" | \ | Jump to that block's entry point | +| "\_end" | \ (end) | Jump to that block's exit point (ordinary blocks), or the loop's dedicated early-exit target (loop blocks) | + +### _start vs _end targets + +- Every block exposes \`_start\` — jump here to (re-)run that block from its entry point. +- Ordinary blocks also expose \`_end\` — the position immediately after that block's own instruction (equivalent to jumping just past it). +- Loop blocks expose \`_end\` — a dedicated **early-exit** target for bailing out of the loop from anywhere inside its body (e.g. from a conditional branch nested inside the loop), landing right after the loop's normal exit point without waiting for the counter/condition to finish naturally. +- If/Else (Conditional) blocks only expose \`_start\` — a conditional has two forward addresses (\`_TRUE\`/\`_FALSE\`), not a single "end". ### Example Configurations **Jump to end (normal exit):** \\\`\\\`\\\`javascript flow1.$name = "Flow_Control_End"; -flow1.opCode = "JMP"; +flow1.jumpTarget = "JMP"; \\\`\\\`\\\` **Halt PRU immediately:** \\\`\\\`\\\`javascript flow1.$name = "Flow_Control_Halt"; -flow1.opCode = "HALT"; +flow1.jumpTarget = "HALT"; +\\\`\\\`\\\` + +**Jump to another block's entry point (e.g. re-entering a loop):** +\\\`\\\`\\\`javascript +flow1.$name = "Flow_Control_Custom"; +flow1.jumpTarget = "Loop_0_start"; // Must match a real "_start" target in the design — validated by SysConfig +\\\`\\\`\\\` + +**Early-exit a loop from inside a nested condition (break-like pattern):** +\\\`\\\`\\\`javascript +// Inside Loop_0's body, an If/Else checks some exit condition. +// Its TRUE branch jumps straight to Loop_0_end instead of letting the +// loop continue — bailing out before the counter naturally finishes. +flow_break.$name = "Flow_Control_Break"; +flow_break.jumpTarget = "Loop_0_end"; +scripting.connect(if_else_check, "T", flow_break, "prev"); \\\`\\\`\\\` ### Connecting to Other Blocks @@ -65,9 +178,11 @@ scripting.connect(if_else1, "T", flow1, "prev"); // Exit on true condition 2. **No Next Port**: Cannot connect anything to this block's output - execution ends here. -3. **JMP vs HALT**: Use JMP for normal exits (allows cleanup code), HALT for immediate stops. +3. **JMP vs HALT vs a block target**: Use "SysConfig Generated End" for normal exits (allows cleanup code), "Halt" for immediate stops, or select any other block's entry/exit point directly from the same dropdown (e.g. an If/Else block's own \`_start\` to re-evaluate it, or a Loop block's \`_start\`/\`_end\` to re-enter or bail out of it). + +4. **Single Cycle**: All jumpTarget options execute in 1 PRU cycle. -4. **Single Cycle**: Both JMP and HALT execute in 1 PRU cycle. +5. **jumpTarget is validated against the current design**: Every block gets an addressable \`_start\` entry point (and \`_end\` where applicable), and the dropdown lists all of them alongside SysConfig Generated End / Halt — SysConfig rejects any value that doesn't correspond to a real target. If a referenced block is renamed or removed, re-select the target; SysConfig will flag it as invalid at validation time, not at the assembler build step. `; } @@ -76,44 +191,47 @@ function getLongDescription() { ## Flow Control Block ### Purpose -Controls PRU program flow by either jumping to the end of generated code or halting the PRU. +Controls PRU program flow by jumping to the end of generated code, halting the PRU, or jumping to the entry point of any other block in the design. ### How It Works 1. **Place in Flow**: Position this block where you want to control program flow -2. **Select Jump Target**: Choose between END or HALT +2. **Select Jump Target**: Pick from a single dropdown — Sysconfig Generated End, Halt, or the entry/exit point of any block in the design 3. **Execution**: When reached, performs the selected jump 4. **No Output**: This is a **terminating block** - no next connections ### Configuration -**Jump To**: Select where the program should jump +**Jump To**: A single dropdown listing every valid jump target in the current design: -**Option 1: Sysconfig Generated End** -- Jumps to the end label of the SysConfig-generated code -- Allows any cleanup code or epilogue to execute -- Recommended for normal program completion -- Generated instruction: JMP sysconfig_generated_end +- **Sysconfig Generated End**: Jumps to the end label of the SysConfig-generated code. Allows any cleanup code or epilogue to execute. Recommended for normal program completion. Generated instruction: \`JMP sysconfig_generated_end\` +- **Halt**: Immediately stops the PRU execution. Puts PRU into halt state, no cleanup or epilogue runs. Generated instruction: \`HALT\`. Use for emergency stops or when no cleanup needed. +- **Any block's \`_start\` or \`_end\`**: Every block in the design — ordinary blocks, If/Else blocks, Loop blocks, Group blocks — has an addressable \`_start\` entry point; ordinary and Loop blocks also expose \`_end\` (see "_start vs _end targets" below). The dropdown only lists real, currently-existing targets — SysConfig rejects the field if a previously-selected target no longer exists (e.g. the referenced block was renamed or deleted). -**Option 2: Halt** -- Immediately stops the PRU execution -- Puts PRU into halt state -- No cleanup or epilogue runs -- Generated instruction: HALT -- Use for emergency stops or when no cleanup needed +### _start vs _end targets + +- Every block exposes \`_start\` — jump here to (re-)run that block from its entry point. +- Ordinary blocks also expose \`_end\` — the position immediately after that block's own instruction. +- Loop blocks expose \`_end\` — a dedicated **early-exit** target for bailing out of the loop from anywhere inside its body (e.g. a break-like pattern from a nested conditional), landing right after the loop's normal exit point without waiting for the counter/condition to finish naturally. +- If/Else (Conditional) blocks only expose \`_start\` — a conditional has two forward addresses (\`_TRUE\`/\`_FALSE\`), not a single "end". ### Technical Details (Additional Information) -**Generated Assembly** (END): +**Generated Assembly** (Sysconfig Generated End): \`\`\`asm JMP sysconfig_generated_end ; Jump to end label (1 cycle) \`\`\` -**Generated Assembly** (HALT): +**Generated Assembly** (Halt): \`\`\`asm HALT ; Halt immediately (1 cycle) \`\`\` -**Performance**: Both options execute in 1 PRU cycle +**Generated Assembly** (block target): +\`\`\`asm +JMP Loop_0_start ; Jump to the selected block's entry/exit point (1 cycle) +\`\`\` + +**Performance**: Every jumpTarget option executes in 1 PRU cycle ### Block Appearance - **Shape**: Circle (distinct from square data processing blocks) @@ -122,15 +240,18 @@ HALT ; Halt immediately (1 cycle) ### Usage Notes - This is a **terminating block** - it has no output connections -- Use END for normal program exits (recommended default) -- Use HALT for emergency stops or when cleanup isn't needed +- Use Sysconfig Generated End for normal program exits (recommended default) +- Use Halt for emergency stops or when cleanup isn't needed +- Select any other block's entry/exit point directly from the same dropdown — no separate free-text field - Multiple FLOW_CONTROL blocks can exist in different program paths +- **Every If/Else (Conditional) branch that is connected MUST end in a Flow Control block**: An If/Else block's TRUE and FALSE branches are NOT mutually exclusive in the generated assembly unless each branch is explicitly terminated — without a terminator, execution falls from one branch straight into the other and runs both. SysConfig now enforces this as a validation error, not just a warning — connect a Flow Control block (any jumpTarget) at the end of every connected T/F branch. ### Terminology - **Flow control**: Directing program execution path - **Terminating block**: Block with no output - ends execution path - **HALT**: PRU instruction that stops core execution - **JMP**: Jump instruction that transfers control to a label +- **jumpTarget**: The single dropdown selecting where this block jumps to — Sysconfig Generated End, Halt, or any real \`_start\`/\`_end\` target in the design, validated against the current design, not free text --- `; } @@ -157,10 +278,11 @@ exports = { default: "", }, { - name: "opCode", + name: "jumpTarget", displayName: "Jump To", + description: "Where to jump when this block is reached. Includes every real, currently-existing block entry (_start) and exit (_end) point in the design — validated, not free text.", default: "JMP", - options: [ + options: (inst) => [ { name: "JMP", displayName: "SysConfig Generated End", @@ -168,19 +290,31 @@ exports = { { name: "HALT", displayName: "Halt", - } + }, + ...getValidJumpTargets() ], }, + { + name: "opCode", + hidden: true, + default: "JMP", + getValue: (inst) => { + return (inst["jumpTarget"] === "HALT") ? "HALT" : "JMP"; + } + }, { name: "constant1", default: "sysconfig_generated_end", getValue: (inst) => { - if(inst["opCode"] == "JMP"){ + if(inst["jumpTarget"] == "JMP"){ return "sysconfig_generated_end"; } - else{ + else if(inst["jumpTarget"] == "HALT"){ return ""; } + else{ + return inst["jumpTarget"]; + } }, hidden: true }, diff --git a/README.md b/README.md index 98a2634..79d65fd 100644 --- a/README.md +++ b/README.md @@ -304,6 +304,11 @@ done: | sysconfig_generated_start | Entry point for ungrouped blocks | | sysconfig_generated_end | Exit point for ungrouped blocks | | _start | Entry point for a Group block | +| _start | Entry point for any individual block — addressable by a [Flow Control block](docs/program-control/flow_control_block.md) to (re-)run that block | +| _end | Exit point for any ordinary block (position right after that block's own instruction) | +| _end | Dedicated early-exit target for a Loop block — jump here from inside the loop's body to break out before its counter/condition finishes naturally | + +If/Else (Conditional) blocks only expose `_start` — they have two forward addresses (`_TRUE`/`_FALSE`), not a single "end". Every one of these labels appears directly in a [Flow Control block](docs/program-control/flow_control_block.md)'s "Jump To" dropdown — no manual label-name entry required. --- diff --git a/docs/program-control/conditional_block.md b/docs/program-control/conditional_block.md index 177ed80..b0b2edf 100644 --- a/docs/program-control/conditional_block.md +++ b/docs/program-control/conditional_block.md @@ -51,12 +51,12 @@ Implements conditional logic to control program flow based on comparing two inpu ### Generated Assembly ```assembly -QBGT TRUE_LABEL, input1_reg, input2_reg ; Branch if input1 > input2 (1 cycle) +QBGT If_Else_0_TRUE, input1_reg, input2_reg ; Branch if input1 > input2 (1 cycle) ; FALSE path blocks here -QBA END_LABEL ; Jump past true path -TRUE_LABEL: +; FALSE branch MUST end in a Flow Control block (see "Flow Control Requirement" below) +If_Else_0_TRUE: ; TRUE path blocks here -END_LABEL: +; TRUE branch MUST end in a Flow Control block ``` ### Technical Details @@ -64,6 +64,16 @@ END_LABEL: - **Performance**: 1 PRU cycle for the comparison and branch - **Comparison type**: All comparisons are **unsigned** — values treated as positive integers - Both `t_next` and `f_next` ports should be connected (warnings issued if not) +- Every block, including this one, has an addressable `_start` entry point that a [Flow Control block](flow_control_block.md) elsewhere in the design can jump to (e.g. to re-run this comparison) + +### Flow Control Requirement + +The FALSE path is placed immediately after the branch instruction, with the TRUE path at the branch target label. **Any connected branch (t_next or f_next) that has no explicit terminator falls through into the other branch — causing both to execute regardless of the condition.** SysConfig validation enforces this as an error: every connected branch must end in a [Flow Control block](flow_control_block.md). Leaving a branch entirely unconnected is fine; only connected-but-unterminated branches are rejected. + +**Where that Flow Control block should jump to depends on where the If/Else block lives:** + +- **Standalone If/Else** (not inside a Loop block): jump to Sysconfig Generated End, Halt, or any other block's `_start`/`_end` target. +- **If/Else nested inside a Loop block**: jump to that Loop's own `_start` target so execution resumes the loop instead of exiting the whole program. Jumping to Sysconfig Generated End or Halt from inside a loop's branch ends the entire program early rather than just this iteration — only do that if that's genuinely the intent. To break out of the loop early without ending the whole program, jump to the Loop's `_end` target instead. ### Common Use Cases @@ -71,5 +81,6 @@ END_LABEL: - Zero detection (`notEqualToInput2` with input2 = 0) - Range validation - State machine transitions +- Loop early-exit / break (nested inside a Loop block, jumping to `_end` on some exit condition) --- diff --git a/docs/program-control/flow_control_block.md b/docs/program-control/flow_control_block.md index f9fa02e..9152b2e 100644 --- a/docs/program-control/flow_control_block.md +++ b/docs/program-control/flow_control_block.md @@ -4,20 +4,21 @@ ### Purpose -Controls PRU program flow by either jumping to the end of SysConfig-generated code or halting the PRU immediately. This is a terminating block — it has no output port. +Controls PRU program flow by jumping to the end of SysConfig-generated code, halting the PRU immediately, or jumping to the entry (`_start`) or exit (`_end`) point of any other block in the design. This is a terminating block — it has no output port. ### Features -- Two modes: jump to generated end label, or halt the PRU +- Single dropdown listing every valid jump target in the current design - Single-cycle execution - Terminating block — no next connection - Distinct circular shape in the UI +- Target list is validated against the live design — renamed/removed blocks are flagged as errors, not silently broken ### Configuration | Parameter | Description | Options | |-----------|-------------|---------| -| Jump To | What to do when this block is reached | Sysconfig Generated End, Halt | +| Jump To | Where to jump when this block is reached | Sysconfig Generated End, Halt, or any block's `_start`/`_end` target in the current design | ### Options @@ -31,27 +32,47 @@ Controls PRU program flow by either jumping to the end of SysConfig-generated co - No cleanup or epilogue code runs - Use for emergency stops or when no further cleanup is needed +**Any block's `_start`/`_end` target**: +- Every block in the design exposes an addressable `_start` entry point +- Ordinary blocks and Loop blocks also expose `_end` (see "`_start` vs `_end`" below); If/Else blocks only expose `_start` (they have two forward addresses, `_TRUE`/`_FALSE`, not a single "end") +- Select the target directly from the same dropdown — no separate free-text field +- If the referenced block is later renamed or deleted, SysConfig flags this block as invalid at validation time instead of silently generating a broken jump + +### `_start` vs `_end` + +- **`_start`**: jump here to (re-)run that block from its entry point. For a Loop block, jumping here resumes the loop with its current counter value (not a reset). +- **`_end`**: for ordinary blocks, the position immediately after that block's own instruction. For Loop blocks, a dedicated **early-exit** target — jump here from anywhere inside the loop's body to break out of the loop before its counter/condition finishes naturally. +- If/Else blocks only expose `_start` — no `_end` is offered for them. + ### Generated Assembly ```assembly -; Sysconfig Generated End mode: +; Sysconfig Generated End: JMP sysconfig_generated_end ; Jump to end label (1 cycle) -; Halt mode: +; Halt: HALT ; Stop PRU execution (1 cycle) + +; Jump to a block's start (e.g. re-entering a Loop): +JMP Loop_0_start ; Jump to that block's entry point (1 cycle) + +; Jump to a Loop's dedicated early-exit target: +JMP Loop_0_end ; Break out of the loop (1 cycle) ``` ### Technical Details -- **Performance**: 1 PRU cycle +- **Performance**: 1 PRU cycle for any option - **Shape**: Circle (distinct from square data blocks) - **No output ports** — execution ends here - Multiple Flow Control blocks can exist in different paths of the same design +- The dropdown only lists real, currently-existing targets in the design — it is rebuilt live from every block's `$name`, so it always reflects the current design state ### Common Use Cases -- Exiting from a conditional branch early (e.g., error detected → jump to end) -- Ending the true or false path of an If/Else block +- Ending the true or false path of an If/Else block (see [If/Else block](conditional_block.md)) +- Re-entering a Loop block from inside a nested branch (jump to `_start`) +- Breaking out of a Loop early from inside its body (jump to `_end`) - Stopping the PRU after one-shot initialization completes - Emergency halt on fault conditions @@ -63,4 +84,13 @@ If/Else (error != 0) └── f_next → [continue normal flow] ``` +### Example: Continuing a Loop from a Nested If/Else + +``` +Loop_0 + └── If/Else (check exit condition) + ├── t_next → Flow Control (Jump To = "Loop_0_end") ; break out of the loop + └── f_next → Flow Control (Jump To = "Loop_0_start") ; continue looping +``` + --- diff --git a/docs/program-control/loop_block.md b/docs/program-control/loop_block.md index 4bf84c3..d9f8193 100644 --- a/docs/program-control/loop_block.md +++ b/docs/program-control/loop_block.md @@ -113,5 +113,6 @@ Example: 100 iterations, body = 11 cycles → 3 + (100 × 11) = 1103 cycles = 5. - Infinite loops **never exit** — the `next` port is hidden and no code after the loop is reachable - Loop counter occupies a register during loop execution - Pre-init blocks are still visually inside the container but their instructions are hoisted out +- A **Flow Control** block elsewhere in the design can jump directly to this loop's generated label (`endloop_label` for a fixed loop, `startloop_label` for an infinite loop) by selecting this Loop block as its "Loop Block" target — see [flow_control_block.md](flow_control_block.md) --- diff --git a/examples/empty/firmware/am243x-evm/icss_g0_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_pru0_fw/example.syscfg index f0512d0..83f0251 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-evm/icss_g0_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_pru1_fw/example.syscfg index 744916d..5254db1 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru0_fw/example.syscfg index 759b026..9c9eec5 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru1_fw/example.syscfg index e877806..5a70796 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_rtu_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-evm/icss_g0_tx_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_tx_pru0_fw/example.syscfg index 304eb44..e0a86f1 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_tx_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_tx_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-evm/icss_g0_tx_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-evm/icss_g0_tx_pru1_fw/example.syscfg index 3a11887..0ff47c3 100644 --- a/examples/empty/firmware/am243x-evm/icss_g0_tx_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-evm/icss_g0_tx_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg index 8e623df..9a1aaba 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg @@ -16,7 +16,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg index 949409c..d95f39e 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru0_fw/example.syscfg index 2f05320..ff493ec 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru1_fw/example.syscfg index 2cc601d..a5333f3 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_rtu_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_tx_pru0_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_tx_pru0_fw/example.syscfg index fb4f638..ce37f79 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_tx_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_tx_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am243x-lp/icss_g0_tx_pru1_fw/example.syscfg b/examples/empty/firmware/am243x-lp/icss_g0_tx_pru1_fw/example.syscfg index fe37c16..c96c552 100644 --- a/examples/empty/firmware/am243x-lp/icss_g0_tx_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am243x-lp/icss_g0_tx_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am261x-lp/icss_m0_pru0_fw/example.syscfg b/examples/empty/firmware/am261x-lp/icss_m0_pru0_fw/example.syscfg index 15a2303..29984ee 100644 --- a/examples/empty/firmware/am261x-lp/icss_m0_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am261x-lp/icss_m0_pru0_fw/example.syscfg @@ -16,7 +16,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am261x-lp/icss_m0_pru1_fw/example.syscfg b/examples/empty/firmware/am261x-lp/icss_m0_pru1_fw/example.syscfg index 71ba22c..ca44d9d 100644 --- a/examples/empty/firmware/am261x-lp/icss_m0_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am261x-lp/icss_m0_pru1_fw/example.syscfg @@ -16,7 +16,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg b/examples/empty/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg index 5e187d1..4d67adc 100644 --- a/examples/empty/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg @@ -16,7 +16,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg b/examples/empty/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg index 99fdb98..81c99aa 100644 --- a/examples/empty/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg @@ -16,7 +16,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_pru0_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_pru0_fw/example.syscfg index 39a894b..7042b60 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_pru1_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_pru1_fw/example.syscfg index 6c8e4c7..1de0c89 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru0_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru0_fw/example.syscfg index b78470e..9a93bd5 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru1_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru1_fw/example.syscfg index dec587d..114ba80 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_rtu_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_tx_pru0_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_tx_pru0_fw/example.syscfg index 69af09f..e6f4f59 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_tx_pru0_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_tx_pru0_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/am64x-evm/icss_g0_tx_pru1_fw/example.syscfg b/examples/empty/firmware/am64x-evm/icss_g0_tx_pru1_fw/example.syscfg index e17610c..40ada58 100644 --- a/examples/empty/firmware/am64x-evm/icss_g0_tx_pru1_fw/example.syscfg +++ b/examples/empty/firmware/am64x-evm/icss_g0_tx_pru1_fw/example.syscfg @@ -15,7 +15,7 @@ const flow_control_block1 = flow_control_block.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + /** * (x,y) coordinates for modules that are displayed in a graph. diff --git a/examples/empty/firmware/main.asm b/examples/empty/firmware/main.asm index 63eff57..cac8041 100644 --- a/examples/empty/firmware/main.asm +++ b/examples/empty/firmware/main.asm @@ -25,6 +25,7 @@ .global main .ref sysconfig_generated_start + .global sysconfig_generated_end .sect ".text:main" ;******** @@ -34,3 +35,4 @@ main: ; halt the program after jumping to sysconfig generated start JMP sysconfig_generated_start +sysconfig_generated_end: diff --git a/examples/makefile b/examples/makefile index da36ff9..0587888 100644 --- a/examples/makefile +++ b/examples/makefile @@ -9,6 +9,7 @@ SUBDIRS := \ incremental_spi \ tamagawa_single_channel \ spi_10mhz \ + mirror_input \ # "make" or "make all" builds projects that match $(DEVICE) set in imports.mak all: ARGUMENTS = all diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg new file mode 100644 index 0000000..1aa683e --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg @@ -0,0 +1,82 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "icss_m1_pru0" --product "PRU_NO_CODE_TOOL@01.00.01" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "icss_m1_pru0" --product "PRU_NO_CODE_TOOL@01.00.01" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const pru_blocks_static_module = scripting.addModule("/pru_blocks/common/pru_blocks_static_module"); +const load_constant_block = scripting.addModule("/pru_blocks/data_handling/load_constant_block", {}, false); +const load_constant_block1 = load_constant_block.addInstance(); +const conditional_block = scripting.addModule("/pru_blocks/program_control/conditional_block", {}, false); +const conditional_block1 = conditional_block.addInstance(); +const flow_control_block = scripting.addModule("/pru_blocks/program_control/flow_control_block", {}, false); +const flow_control_block1 = flow_control_block.addInstance(); +const flow_control_block2 = flow_control_block.addInstance(); +const loop_block = scripting.addModule("/pru_blocks/program_control/loop_block", {}, false); +const loop_block1 = loop_block.addInstance(); +const pru_gpi_block = scripting.addModule("/pru_blocks/pru_io_blocks/pru_gpi_block", {}, false); +const pru_gpi_block1 = pru_gpi_block.addInstance(); +const pru_gpo_block = scripting.addModule("/pru_blocks/pru_io_blocks/pru_gpo_block", {}, false); +const pru_gpo_block1 = pru_gpo_block.addInstance(); +const pru_gpo_block2 = pru_gpo_block.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +pru_blocks_static_module.pruClkFreq = 225; + +load_constant_block1.$name = "Load_Constant_0"; + +conditional_block1.$name = "If_Else_0"; +conditional_block1.conditionToCheck = "equalToInput2"; + +flow_control_block1.$name = "Flow_Control_0"; +flow_control_block1.jumpTarget = "startloop_0"; + +flow_control_block2.$name = "Flow_Control_1"; +flow_control_block2.jumpTarget = "startloop_0"; + +loop_block1.$name = "Loop_0"; +loop_block1.infiniteLoop = true; +loop_block1.$size = [690,375]; + +pru_gpi_block1.$name = "PRU0_GPI_INSTANCE_0"; + +pru_gpo_block1.$name = "PRU0_GPO_INSTANCE_0"; +pru_gpo_block1.constant1 = "R30, 1"; + +pru_gpo_block2.$name = "PRU0_GPO_INSTANCE_1"; +pru_gpo_block2.constant1 = "R30, 1"; +pru_gpo_block2.opCode = "CLR"; + +/** + * References between modules. + */ +loop_block1.$groupContents = [pru_gpi_block1, conditional_block1, load_constant_block1, pru_gpo_block1, pru_gpo_block2, flow_control_block1, flow_control_block2]; + +/** + * Connections between modules. + */ +scripting.connect(load_constant_block1, "output1", conditional_block1, "input2"); +scripting.connect(conditional_block1, "input1", pru_gpi_block1, "output1"); +scripting.connect(conditional_block1, "T", pru_gpo_block2, "prev"); +scripting.connect(conditional_block1, "F", pru_gpo_block1, "prev"); +scripting.connect(flow_control_block1, "prev", pru_gpo_block1, "next"); +scripting.connect(flow_control_block2, "prev", pru_gpo_block2, "next"); + +/** + * (x,y) coordinates for modules that are displayed in a graph. + */ +load_constant_block1.$position = [70,205]; +conditional_block1.$position = [195,105]; +flow_control_block1.$position = [445,155]; +flow_control_block2.$position = [430,50]; +loop_block1.$position = [0,0]; +pru_gpi_block1.$position = [75,110]; +pru_gpo_block1.$position = [315,165]; +pru_gpo_block2.$position = [310,70]; diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec new file mode 100644 index 0000000..989307d --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/example.projectspec @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd new file mode 100644 index 0000000..5d7910e --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd @@ -0,0 +1,54 @@ +/* + * AM243x_PRU0.cmd + * + * Example Linker command file for linking assembly programs built with the TI-PRU-CGT + * on AM243x PRU0 cores + */ + +/* Specify the System Memory Map */ +MEMORY +{ + PAGE 0: + /* 12 KB PRU Instruction RAM */ + PRU_IMEM : org = 0x00000000 len = 0x00003000 + + PAGE 1: + /* Data RAMs */ + /* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU0 and reserve + * the second 4 KB for RTU0 and Tx_PRU0 */ + PRU0_DMEM_0 : org = 0x00000000 len = 0x00001000 + /* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU0, + * RTU1 and Tx_PRU0; do not use for any Slice0 cores */ + PRU0_DMEM_1 : org = 0x00002000 len = 0x00001000 + /* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1 + * split equally between the corresponding RTU and Tx_PRU cores in + * each slice */ + RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800 + TX_PRU0_DMEM_0 : org = 0x00001800 len = 0x00000800 + RTU1_DMEM_1 : org = 0x00003000 len = 0x00000800 + TX_PRU0_DMEM_1 : org = 0x00003800 len = 0x00000800 + + PAGE 2: + /* C28 needs to be programmed to point to SHAREDMEM, default is 0 */ + /* 64 KB PRU Shared RAM */ + PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 +} + +/* Specify the sections allocation into memory */ +SECTIONS { + .text:main > 0, PAGE 0 + .text > PRU_IMEM, PAGE 0 + .stack > PRU0_DMEM_0, PAGE 1 + .bss > PRU0_DMEM_0, PAGE 1 + .udmem > PRU0_DMEM_0, PAGE 1 + .initdmem > PRU0_DMEM_0, PAGE 1 + .cio > PRU0_DMEM_0, PAGE 1 + .data > PRU0_DMEM_0, PAGE 1 + .switch > PRU0_DMEM_0, PAGE 1 + .sysmem > PRU0_DMEM_0, PAGE 1 + .cinit > PRU0_DMEM_0, PAGE 1 + .rodata > PRU0_DMEM_0, PAGE 1 + .rofardata > PRU0_DMEM_0, PAGE 1 + .farbss > PRU0_DMEM_0, PAGE 1 + .fardata > PRU0_DMEM_0, PAGE 1 +} diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile new file mode 100644 index 0000000..6063f9f --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile @@ -0,0 +1,55 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +# Define build outputs +OUTPUT_NAME := mirror_input_am261x-lp_icss_m1_pru0_fw + +# MCU+ projects: rename & move hex array output +MCU_HEX_NAME := pru0_load_bin.h +HEX_ARRAY_PREFIX := PRU0Firmware +MCU_HEX_PATH := $(PRU_NO_CODE_TOOL_PATH)/examples/mirror_input/firmware/am261x-lp/$(MCU_HEX_NAME) + +# which directories to search for assembly & C source files? +FILES_PATH := .. ../../.. . syscfg/ + +# Linker command file +COMMAND_FILES := linker.cmd + +# Silicon version (3: PRUSS, PRU-ICSS; 4: PRU_ICSSG) +PRU_VERSION := 4 +EXPECTED_DEVICE := am261x + +# Default values are defined in pru_rules.mak: +# - include paths (INCLUDE) +# - compiler flags (CFLAGS) +# - linker flags (LFLAGS) + +# Optional: +# Pre-define here to override default value +# OPT_LEVEL, STACK_SIZE, HEAP_SIZE, or ENTRY_POINT + +# pru_rules.mak has shared settings for all PRU/RTU/TX_PRU core makefiles +include $(PRU_NO_CODE_TOOL_PATH)/pru_rules.mak + +# Optional: +# Append values to INCLUDE, CFLAGS, or LFLAGS here. +# Values can be appended like this: +# INCLUDE += --include_path= + +# Defines (pass instance specific definitions to the program) +# see --define or -D in 'PRU Optimizing C/C++ Compiler User's Guide' +# For example, to define PRU0, ICSSG1, SOC_AM243X, and set _DEBUG_=1: +# -DPRU0 -DICSSG1 --define=SOC_AM243X -D_DEBUG_=1 +DFLAGS := -DPRU0 -DPRU1 --define=SOC_AM261X + +# Libraries +# see --library in 'PRU Optimizing C/C++ Compiler User's Guide' +LIBS := + +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru0 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru0 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec new file mode 100644 index 0000000..f8b0e55 --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=mirror_input_am261x-lp_icss_m1_pru0_fw_ti-pru-cgt + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg new file mode 100644 index 0000000..fb6e2b0 --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg @@ -0,0 +1,85 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "icss_m1_pru1" --product "PRU_NO_CODE_TOOL@01.00.01" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "icss_m1_pru1" --product "PRU_NO_CODE_TOOL@01.00.01" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const loop_block = scripting.addModule("/pru_blocks/program_control/loop_block", {}, false); +const loop_block1 = loop_block.addInstance(); +const pru_gpo_block = scripting.addModule("/pru_blocks/pru_io_blocks/pru_gpo_block", {}, false); +const pru_gpo_block1 = pru_gpo_block.addInstance(); +const pru_gpo_block2 = pru_gpo_block.addInstance(); +const pru_gpo_block3 = pru_gpo_block.addInstance(); +const pru_gpo_block4 = pru_gpo_block.addInstance(); +const delay_block = scripting.addModule("/pru_blocks/utils/delay_block", {}, false); +const delay_block1 = delay_block.addInstance(); +const delay_block2 = delay_block.addInstance(); +const delay_block3 = delay_block.addInstance(); +const delay_block4 = delay_block.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +loop_block1.$name = "Loop_0"; +loop_block1.infiniteLoop = true; +loop_block1.$size = [1105,415]; + +pru_gpo_block1.$name = "PRU1_GPO_INSTANCE_0"; +pru_gpo_block1.constant1 = "R30, 4"; + +pru_gpo_block2.$name = "PRU1_GPO_INSTANCE_1"; +pru_gpo_block2.constant1 = "R30, 4"; +pru_gpo_block2.opCode = "CLR"; + +pru_gpo_block3.$name = "PRU1_GPO_INSTANCE_2"; +pru_gpo_block3.constant1 = "R30, 4"; + +pru_gpo_block4.$name = "PRU1_GPO_INSTANCE_3"; +pru_gpo_block4.opCode = "CLR"; +pru_gpo_block4.constant1 = "R30, 4"; + +delay_block1.$name = "Delay_0"; +delay_block1.delayCount = 40; + +delay_block2.$name = "Delay_1"; +delay_block2.delayCount = 20; + +delay_block3.$name = "Delay_2"; +delay_block3.delayCount = 40; + +delay_block4.$name = "Delay_3"; +delay_block4.delayCount = 20; + +/** + * References between modules. + */ +loop_block1.$groupContents = [pru_gpo_block1, delay_block1, pru_gpo_block2, delay_block2, pru_gpo_block3, delay_block3, pru_gpo_block4, delay_block4]; + +/** + * Connections between modules. + */ +scripting.connect(pru_gpo_block1, "next", delay_block1, "prev"); +scripting.connect(pru_gpo_block2, "prev", delay_block1, "next"); +scripting.connect(pru_gpo_block2, "next", delay_block2, "prev"); +scripting.connect(pru_gpo_block3, "prev", delay_block2, "next"); +scripting.connect(pru_gpo_block3, "next", delay_block3, "prev"); +scripting.connect(pru_gpo_block4, "prev", delay_block3, "next"); +scripting.connect(pru_gpo_block4, "next", delay_block4, "prev"); + +/** + * (x,y) coordinates for modules that are displayed in a graph. + */ +loop_block1.$position = [0,0]; +pru_gpo_block1.$position = [140,180]; +pru_gpo_block2.$position = [370,180]; +pru_gpo_block3.$position = [575,180]; +pru_gpo_block4.$position = [810,185]; +delay_block1.$position = [250,165]; +delay_block2.$position = [465,165]; +delay_block3.$position = [695,170]; +delay_block4.$position = [935,180]; diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec new file mode 100644 index 0000000..653e590 --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/example.projectspec @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd new file mode 100644 index 0000000..7340f73 --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd @@ -0,0 +1,54 @@ +/* + * AM243x_PRU1.cmd + * + * Example Linker command file for linking assembly programs built with the TI-PRU-CGT + * on AM243x PRU1 cores + */ + +/* Specify the System Memory Map */ +MEMORY +{ + PAGE 0: + /* 12 KB PRU Instruction RAM */ + PRU_IMEM : org = 0x00000000 len = 0x00003000 + + PAGE 1: + /* Data RAMs */ + /* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU1 and reserve + * the second 4 KB for RTU0 and Tx_PRU1 */ + PRU1_DMEM_0 : org = 0x00000000 len = 0x00001000 + /* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU1, + * RTU1 and Tx_PRU1; do not use for any Slice0 cores */ + PRU1_DMEM_1 : org = 0x00002000 len = 0x00001000 + /* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1 + * split equally between the corresponding RTU and Tx_PRU cores in + * each slice */ + RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800 + TX_PRU1_DMEM_0 : org = 0x00001800 len = 0x00000800 + RTU1_DMEM_1 : org = 0x00003000 len = 0x00000800 + TX_PRU1_DMEM_1 : org = 0x00003800 len = 0x00000800 + + PAGE 2: + /* C28 needs to be programmed to point to SHAREDMEM, default is 0 */ + /* 64 KB PRU Shared RAM */ + PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 +} + +/* Specify the sections allocation into memory */ +SECTIONS { + .text:main > 0, PAGE 0 + .text > PRU_IMEM, PAGE 0 + .stack > PRU1_DMEM_0, PAGE 1 + .bss > PRU1_DMEM_0, PAGE 1 + .udmem > PRU1_DMEM_0, PAGE 1 + .initdmem > PRU1_DMEM_0, PAGE 1 + .cio > PRU1_DMEM_0, PAGE 1 + .data > PRU1_DMEM_0, PAGE 1 + .switch > PRU1_DMEM_0, PAGE 1 + .sysmem > PRU1_DMEM_0, PAGE 1 + .cinit > PRU1_DMEM_0, PAGE 1 + .rodata > PRU1_DMEM_0, PAGE 1 + .rofardata > PRU1_DMEM_0, PAGE 1 + .farbss > PRU1_DMEM_0, PAGE 1 + .fardata > PRU1_DMEM_0, PAGE 1 +} diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile new file mode 100644 index 0000000..f43114c --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile @@ -0,0 +1,55 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +# Define build outputs +OUTPUT_NAME := mirror_input_am261x-lp_icss_m1_pru1_fw + +# MCU+ projects: rename & move hex array output +MCU_HEX_NAME := pru1_load_bin.h +HEX_ARRAY_PREFIX := PRU1Firmware +MCU_HEX_PATH := $(PRU_NO_CODE_TOOL_PATH)/examples/mirror_input/firmware/am261x-lp/$(MCU_HEX_NAME) + +# which directories to search for assembly & C source files? +FILES_PATH := .. ../../.. . syscfg/ + +# Linker command file +COMMAND_FILES := linker.cmd + +# Silicon version (3: PRUSS, PRU-ICSS; 4: PRU_ICSSG) +PRU_VERSION := 4 +EXPECTED_DEVICE := am261x + +# Default values are defined in pru_rules.mak: +# - include paths (INCLUDE) +# - compiler flags (CFLAGS) +# - linker flags (LFLAGS) + +# Optional: +# Pre-define here to override default value +# OPT_LEVEL, STACK_SIZE, HEAP_SIZE, or ENTRY_POINT + +# pru_rules.mak has shared settings for all PRU/RTU/TX_PRU core makefiles +include $(PRU_NO_CODE_TOOL_PATH)/pru_rules.mak + +# Optional: +# Append values to INCLUDE, CFLAGS, or LFLAGS here. +# Values can be appended like this: +# INCLUDE += --include_path= + +# Defines (pass instance specific definitions to the program) +# see --define or -D in 'PRU Optimizing C/C++ Compiler User's Guide' +# For example, to define PRU1, ICSSG1, SOC_AM243X, and set _DEBUG_=1: +# -DPRU1 -DICSSG1 --define=SOC_AM243X -D_DEBUG_=1 +DFLAGS := -DPRU0 -DPRU1 --define=SOC_AM261X + +# Libraries +# see --library in 'PRU Optimizing C/C++ Compiler User's Guide' +LIBS := + +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru1 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --device AM261x_ZFG --context icss_m1_pru1 --part AM2612 --package ZFG --output syscfg/ ../example.syscfg + diff --git a/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec new file mode 100644 index 0000000..a3b8358 --- /dev/null +++ b/examples/mirror_input/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=mirror_input_am261x-lp_icss_m1_pru1_fw_ti-pru-cgt + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/mirror_input/firmware/main.asm b/examples/mirror_input/firmware/main.asm new file mode 100644 index 0000000..c307146 --- /dev/null +++ b/examples/mirror_input/firmware/main.asm @@ -0,0 +1,35 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright (C) 2024-2025 Texas Instruments Incorporated - http://www.ti.com/ + +;*************************************************************************************** +; File: main.asm +; +; Brief: Empty example assembly file (asm) with halt instruction +; +; Steps to build : +; +; - Using ccs: +; - Import pru project to ccs workspace +; - main.asm file gets copied to ccs workspace +; - Modify main.asm file +; - Build the pru project, after which .out (Executable output file) and .h (Firmware header) files gets generated +; - Either .out (Executable output file) can be loaded to PRU using ccs or R5F can write to PRU IRAM using PRUICSS driver +; - Using makefile: +; - Use command gmake -all to build PRU project +; +;*************************************************************************************** + +; CCS/makefile specific settings + .retain ; Required for building .out with assembly file + .retainrefs ; Required for building .out with assembly file + + .global main + .ref sysconfig_generated_start + .sect ".text:main" + +;******** +;* MAIN * +;******** + +main: + JMP sysconfig_generated_start diff --git a/examples/mirror_input/images/mirror_input_capture.png b/examples/mirror_input/images/mirror_input_capture.png new file mode 100644 index 0000000000000000000000000000000000000000..907174d2b1032cb8f563c8224fdb690cf75a5a6d GIT binary patch literal 21632 zcmeHv2UL^k)@~dNHe?hV(nLoTX(}qx$BK%8ibyXOM5KfsS`rl%1r#eNRYgSv5_%{J z0g1_X&I1 z_$TqQ3o8*R57s-Z`Z1UI;_1B7O!#g|;Li?{>&;|THg2C^x*%IWZp%-lBBjxD&&$5p znDXFmgG_wU`=2Ky)|<`msGONvx^%VG+O>~2Z+LhA)%I-;NL%Z>S^hs7n3U${Q$OS< z5AE1Dn5Nah2tFI&>UQ+OGt3XSMqcz@Uoh8h_xjK?Bj-NaI-j@RqNlX`>g#qFYinx~ zhsU#(U$9`}$kL@)_%n~x$K#QMt_)`ti((Tlmxp98EIjLM>-+=4^SYkvHij_l4`Pw?VG}n5Vp$>ozd0qy*XI$4^@t+} z_MY;J9BlRWddSM=joL~#pWh^PZIkGap~p=Q$o_D3$@49Nfrky>kuow_kqU7^8iv@6 zB#R0cdsbwEVQypeo2)C(Z`P)YoW6JPKxp!&pMG4C%6Naice3PSsa{R@lS(D(Bz?d} z>YBQeH^(FENUwyEscFu91mYua27^T*r^W@Y@EBaJB#J`r*3GuHwxmrdNQ%_F!SSE9d0Xge3+=Veg#RU5U>f(lW!ov{I-)UQZlgl&j#4 z^FkHb_vGjg-ZwG`<~UEDy36y6@R_t|-{G<+H1hbTAdA^q5v2>pp&1_Zx_q&=mu<%$ zKkINi#+lRW7l_!iFm?|Dksmjc*PDb?#`_gpnb{TAy1Keb>qYMI8Sfh$bcw?5Qd9G- zd3{1qP>^1aOztQiU%zc`(A}Kvh>`5=fpZZE<4~KaJHvKf*7?bvY@EsJ=H+{V9I z^^|O2M4L}ju3H8-48!BfKakd4x8r;%c9w?qoUQHb6gDGZta(WTPbVwuhK&@7Bl~{D zFGHXy;$L>j(8iJ1I4x^6zF%2+H;F^Y(RQN8sLa%q(`OZo8Kg-|6j`f}8omtCx7p87 z41stY_pEO0UFIO$sOy8)v}~Ziuh|5H%A;HH-guIjkAy>1RSTg4GSOIoiKKp<3eA`V-Syd+&n*-Ms@ z>=BnMgHOOJ_Z*~Kj<&Z2S0|<@yo#!1fO%&>U z#6lOGs8iOi2ErT!;+h5qnly)2dU_@eblTSZ{A{UJh(;eut`G zKc||I$vf&r*KhW_LTU}s;-Ztt7b@kED1Wue?pC4h(=@B=D(VvY$BrF4b?QYWP0OY8 z09{mI>DnJ9B-%cGI(h2Uc($fP&E+|_mM>o(YU52RH#DsE@bH)`AnmPQCAV zAB7qHB)#nBty>>w&m&R=}X1- zY}>l^LyxOBsVy)t@WzcBnnaPyuku8SHg4Q#TOQ6zLZaOU8&a-cFTu=o`A!bEq8KEt za4l>erRS1^gWo`W-0XOqR*XlT37K6~siYKO7WybA21P|rl6kWnv@4YB<^3LOiF1+k zvF0i@!4C1b(fknA^6u7tu3M?^E{VyJj8V&_-5TmcVp6iIs?*{2xV)J$%4Yp&^V6q2 zM~l+tB8dZUyiru{ZCEeKcd{%7J49obuCY?*2xzhQUb^(gW=d98HU=~OWRp&)`uNBF zX||P4c6Khgg>4w$o=WU&5Qjl#q*4@^Q+}{_qRLK0MjmJJk`PvhII;iLK~#&2w)McB zpdhA~I+oK+we%fgEfd~*;zZTC5DitkPfsvpd}88EM}VYdj=P;?+tQy6*w+>buUoh7 z2ka6wMilN>q9(Zg%+hKCQZe3(pT zMEE*+O86d^PV^-Ar%g5^Y7Ao9h4S#$T&=u;HwmldjE|o@IR?l`^`?nKM=;aVtFSszr4J>z_M=0K51#`>{eXw z1;+aan{{;b7cdQ=ndNOGlbLt>2QXWQM|9$%H?;K&oTlLeV)P`1axEN9=$^u6?L4)a zbgocNmUkIVsyA4v!kFka`gE_%`}glxty*;@Z;h4Ts6J*)n9$7qAghSCB0qB+fAQjl z0?%2~y)QXmdyAahLLzOjagDaNHhFqLRw2y3>iNMXYb;Tn?`{PtJAvH|wc;jkG7=^L#i%gc$7Xl#vyh1)WZSlDb0p!3{ytUY1WGTyI-EJXjqa z9rx}n*VQdAxg!pFTwYpwGb99+omgD_>i+%vfq|}+)aS9W)zwNZPN*|y&gkl9*qF$k zCT1Y17(%nSq$G-2P6!qaBiT?wD}?vj*wj9hF=+Euq~%|kt4t-bi$#&fDQ6E_e>kk8 zqjU7=Rz*ccIXN*6pJT?x#(VefJ%9c{Sd2iv$y=%)^LAl?5Im%iggUz`L`!0ub$)w+ ze^5{mna7np7O{Kij+ztF!6Eq8t;S5pX6_`_>iF@CCUuRrFKY_W5cVHQ0$8q zmOn^YS4L~_7(A|f+2id(8skeSsXw6cIhWdC>*{e9x$ga`kav6i7euL>tn=cTIb~;1 zv?8gV&5ndtPx@F7vc;D{x-#iE(MV1*&B)2io4v1dL3!s+2^H5DP}qrya&mISH*Y@C zS*HyR(IW+!@@APoNlWkAwJS3{{o$iWJv}`FPKASwX;@Z*RcKh4@~&Mk~s|pfV^VA$GEsQ;M`x0DE6SGs5*y%1w-g%SL7kWoF$M|j7y?Y`+Yo-cz zN{;fOl7A88=uP&t5J(H#%4qB?Gs<^3JFf76^H}%$(9lreL_>{fG{B{bGBHip?ou>o z0_Yrxfkr}VS8DNQgfJt8w$a|IQc@kw)Y*zK@=T9{meA$2EP2Y<)QrC7lor&^x#D1x zl+L7~WkL1d+NMpLWw&lkOH0FN_lEEFzdx6;dinCInwnD<7UFC>NFO1B z!$3`Zb)3GeygZs&uB;!q=idDtTefa}L)H|8cCKKtHsJiMPIRXKK&xktX9k(kibnb9$B0=TR3ERYuV*x*#1@8yAG*D+XOg3R zdmU@MT3=(bMawC>r>@RwU|5J|mg!&uIB7jC*pOjww0CcT#-yM9a7(tX?rqWC4lM*E zHCn@0KuB+@j*z#@I{z|6%z>K6B~7}frj@io=Kvhb&dzQoAd$X0&{Huy4wXiug#bgP z*CpB4B_7d}*yGqVuHx2vEPQ7_5NHOGspsKgc=SViJ_lZjHy*7MMH0Q)BORHNo28{M zR79!(?gQrIr>CbYgs+rz+1c62C@KmOH*MYO`tj*r4ZpS=jyj^EGgFS<{r*07rc3hC zqeqZ>@PV>hwm4^-1D3!iE6B)XkAKqHxM4$Gk{JQTXv=5FY}qo?qljg_6V^}1JRBKu zrlfifP4}ggNI>;xb>DB)z9Z&6J4K_@MTfJxCZzV?@FKNMPpigMGCTtg9y&A+6IM?j z>Im)Wm1sz}ODpNh?!K=R7!(BP9|fzOo!$w&{zNM#1jSiI42sX?3iLC18ErQeXv|C{ zZvufFqGh;n(U~(H7&5jzd>5pn-+=?~091;Lix*(xbG0JzmZa%C&M&<_avE0jyh0 z#G=t$By?6Q-gJFQh$NEZ^6J==9X1~x5{bloU(e`;rlzJqefv*A0HW6szAv_AoGe+6GujpZwYTcc;LWb8!4A1G}O^?hDoz}@c40--_#fc z&p5Q!djqU=p^#8zg+%?Q&Y<96b=YRmW6hT6{LAlLx{41T^p>MQy3&W4h&?*ZCy1@o zszV38opS6(*`u~Z&M^7Sn>Pb=I&h)6Wc3SW4KY9$0m`W}y~=Z`W~pb3%pPox+2z<& zbEfb{aY+fXCCiRCi*9UebfZ~DM`_@mKX-k9e^bCRanoGSa-a*eN^-h=Rg8Jdbgt~8cm|~G$o(u(&9~3 zTwi1P_|YTQgP0jx&<|JU3V04RdC;Oz%f$9LPmeP}Mg#wOHreKjr$p3r+@?jV_1qA3 z+T%HBeB#6jM@L7y{>}O}`bR`&VkNoT6cmP`n0X_GLUWN~T9~(h^GA>B<&73cTp_qe zFZ}S~!>eN|wC6zzk$YUOHV?HWpV?2R=gfC1d~rk=aLreEMW?;JeQa#(8U^!)9@-q| z&}4`wvN?0eUno;>-Oeq_lli^n5oV^umoH!1*W+4=-fn2L#eoCoEiK#lPZPKbnUS7u z9Qr6SGV<<^*zt=6kht`L0Xd4Qd*5+gT@SZ3LS7!GInz-wkA2q3$q9=4(xrg{e}Pa1 zi-{(CJiNQRN8Ik>Yvjd?(34C_KDDVf6jN?s`b1bd=_jwefa>CkRj z*W*IgiHgou^vJ_-r(f!XWz0_S8)M|2j(4|&`FbtejaCt*W`wsyx94B^g_fK&sJ@B@ z_LCYa=Pi}ImkY{f(S#!iRW5~EYs#EJs zgf-O{0u=oSQ)l8d9EY$*G{sxZ&mugW#51!z*e+{OEk$BZOT(JQmrL|BM|)bL4;;8g zqe-@=+ns|XN=7dESYmEx*I$swXE1wW`j>P?wUL;N;jymy+5vc16huidN~`Y4W2Ziip@$jG4?u; zjQk;IwTOrctZ#5|@Y()=Vd%+lpPRRLc1hPLhntb%Q6}oyIlA{~ zfHu=4?LsSt<5(CFvR2i-R2EPCP?c=etj&}$cs0Wz^URJO{Qw+QT0c56!neKj9`Q%7 zimSt0G?8t@C5pt0{hy4ieEMw&%_RGJZLm8VpqxSAg#llL2Yk43D62C_ z2h1XcoWAFd&6$c;d45&TMM1cVu3qgqcD_HCk(UeEXib%}jo4}Tsh*6fpXFwQh&kRa z4;DtWlC7Sx@#A{BBPSZw%E|zeg)>R(g`}vr!tUR{zYyGsOzVQHX%(unJ9a$J$+-Y+ zo?b_)uRZwDOxzW;lWAxM=v)A8#Za61mi6ncJKkP5cooT<<(OGvrh0hn5Z;KFx?*0| zPckxg6_Jz`D>?zMv}U~~6YvTExl8NNi{_Y^m{4aY$UuG2K*T{RL2m*72jlHs1iCj9 zi*;&Wb@7LsvgNB+^Ear#-v9uAnS^>ekciIC&i2-b5q#6AHf^&j^N-; zO-<~tj*CIHc|&ve0oszE8-<=|thZDn6N#O`pUtwIJ3uaHfHy)U`nirLc{6)0oC~gl z3xWoG6%ai7{=)~*cs^WK4`}y2N=k0yeN|UZ_|?2lq~px`COKB#Jw3}e9x97eaVxnK z1qE)N+};F2lhABoYMSZP+N5u#^O70%E(vETT2_HHW{lE%<2V?P1WtS+lBbF;p~TpGVlRF*^qhJ&snv5;`E|&E>_)k zLN)MF5+Z)>8au3Gt+LcLVUvM!Mzsu}ALdM(m!?Xxn4y>N=)Ei!?Aa6leDX znO-3*3=NM~mhDg+ERtY^H_3LjX%EXO+iqL&l1Z!Nwfj5D$oPY7GdXc$^n)yZ9;5Br z)kVU^`qAoB8TFO~xdiYF($m2~NBVUQv)Sx0OCOn$K($bt+hQtXvQ|?cQqGk~`VOXm zE23cTWnp466)d7uT19Bm3?h%vc&vycN?U!vTxAgt)RyVp)CsHKUaW*9M)7{uufjYQ9M ze2{RIEQkL5Aj0=)a`HA6mBy~ohoPapy~9Gph*-(;RobIqjtziapv4(XD}4JFM;!YA zV35b1_)u?Uh3PK6H$Lu;CwPMi0@4}m$HC!^?@CGp^7M=WHGygnsF>#B2+2#SX=xyp z?<^9Q2K@j(*I?C1P7Jq-E?@p6N@IA67DEQ(RV}zP>LB=9U<`x!mXbOH^Z`PDwH`Cm zl2hi=_ptz^@9LE+mxAozV}`IW70csFXdXU!@}!^N4D90K#dkn)u%H=aw$6TJw)<;E z?QuB^7l=gzeQpOdD$q8b+2$a$BtmQ_27}U4Q(+y=g~|sv|HQwRitNZrPj{z;P6GM1 z>na!81x6?ZVpx1zls4)$3=aW7+%C!Ua$@$DKLDx*oZH1^6v!cKW_f8cU}h7?iL zN7->mMu%A+$Ke!xtm9mHcm|=xm10Epi3326s?05nRoQ1u(`E`t&X{~-qWq<7Q z%oSd-f@q1SGLTMA;2DakxOUrwl^;2Jln87G<^>uOl}34~BVgh74R7=V#;dPB`mRJ0 z8wtk7nYZsmlq%>W8bf`g3YD|xxk%~Zv? zJs=xt~GAjWtMD*-4s2(!+sOB9kd#rK%;`aQ8@W7c5S_<~^y zY7~r7HJ8qJZWU8wagw>^vNt^_HXL3~wm7aX%$(lY*fmksaavhOvQm>X2=f7^VZv#! zLQFzyr^O8|I;+H_5}C16w%ji<)wKKc!k59Vg2V;;yNCxAfj&jnf{+@C6&WR&vLMA< zNt|XxkjrJ8lfzNWtk{Gb>peNsvkoRi8A`lHT4kIgz=^6ul@KE36 zkTNW_dHWfouUd3yJQQ^Foz2 zs?yj%u6BT-72#yM6Chj>-LC^$Gm32C3`1NnNx+o=b+l_2YoZxh`Qd|Uo}agkO;7jx z2jDvTyBO_z_W)eY7PrdU+FIZ|8YB60;rs43k}rhP$ET?#-r(HXvmpC{ayHF|W~#_h za+nor6{_^a$Ve85Y7s5WO!s?RPY?0&4^XuH8)%2D-nnZRX{t8@21)yY&#qPTESsWL zCdS8m!(c#7%QbxCnUF7M0XA>iq+m((g4JG$xgRT(f!;|adNV6A6YZd&*nYEMlkgu{ zWXHQ6*NoZ8t=l}o57UiO-KFMh?&Xz5>B#}8!)Kj!vg>~@C|U&a!Q=TDAm^pADKCMPEoiE^5nPVk{UJ*%KLFLBJgb_S>b*u+c_MgkIM ztEZ}nINUIpz!NI8V~sg1|9q>3ui^;4dz}I_!(}o4KES5n!eH6}6`)Ss+=Nb@I#ux) zES+Ex+enu~$Bvb~F-!mx`g$gLlWJ2MxO18@cpNS-JKGyXs3jf+R*$Z(E83)Ae$4&>>aa6ksU9VRyAU1_*{xJleol^zMBERte1N z)le8?3kwY>6`)CM?(Ae6#ZHaTrPLo;n3`A~p{yUVn>$S>cQU8+qUDC1Rplt_v}S|H z$J1dinwpw`TU@>R7E)f`Jj*%%@*J30RJ?z`sMuoBa*!23^&rw9-UYk)=@$Ozkq1aA zz(znmMU&JQg*PfQRfv{I@D%_c+>2JZ0c3$qP><{J$kZgm&EcAvAwur*eZu;DMh^WA ztTPdSz3|4Jh#U|Z$BxYmqsYP%5|(CW%`Ghl?r7FP2tY9hu9EGoB=@ROr}W(2$3e1$ z%A3_q&w{}xE$ss=oQnZd(!ZWwUS1BR31;L`aQMKcoMwrd<0LGvBvOzDVb!gKcmg&i zk1S-N>1Q13QEO-f#(ivh`Z$4%_N#s4iPwcTP*ycnHIvRRH01TqT%2X$sk_bhmlM?%uz@qG9hUwh$UfEX)m?hbE@{z?)6- zMO`R+Jeo`8?p9alPaPLIT#tYK8j4(0)%~Kmc_d6;otzZl0tdS{$|Vmr=;6Zx2xn5v z)aC8x4g~~ggEK^A%}TpkRC7(Xc zr!nUE(T`qRH%(1g#^d(y&<0bwy+G#Py%WDorIVBI?mBFB9EP_g zU0}H`6T1dtP*7}7@|!nfeN|U88J?{k_1v*AA%GY7Q~g|hZ+Ur*#+JcN+SGxOi_ze5 zMn;NBNWhpC?y+R?;<-Go3XmHK-@z&{KS4J-a3+S}vp|0(COVYfm2z=O3H`irpmmsM zZ?}@%pFAJ7Y)gzl4VRF0`erU_o_%){geZ)_0gaPF#8-#(W-eSJqiY159ftGSDUUfA5G|-10IeePZ$e^&a(a1 zW|sI#@S%Mt2JO%~mX?;hHqF9QM)m3FYfg`V{4x1i>EiMpnsm!_XeOR^O%b>M4%At6 z%p5aI%RF#%G8tGHN@0lT8}WENBl%Ghjc4gmdS>+G2s){7GY=XR`0I?}DA9H6-dEvO z)x%M2J2Oc75%dNinJ|3LoyvE#%1O)>9N1gUT)>jRp5tM3$;?=9A)QU$I|EJtmYIbb z8XGrwE<^@tnX?F)A-z}d4<<({mZ5jnbKiJfx^$zGCcAZDnmT(LS_as}>2e8)iN}~o zwS9&8SNzqZ`_7fqUhc8SViSjT%U|Pgi8#%2>{Vckz%0#7O?@m4uPbiZwJY}J%bs_)oOrHV z*KggrRYvB0Y9ioger&dtZF1&y4ZLk=r23Yvf!c1X{0z+nLwZl1G*Ei;W~=?BeN$ED zlL?)Wd6vj(J8BY8uK-2VQ~b5-*NaLfFFiSbWD#~_1H)Wl@~%{&57Rb&Y|K?+v%}qc z+h^Y0s^$gUgoPbFic8Yq>U^w$epg%D=uM%2 z6Wrl=;XJD?x2dgX3VvztkK*08-~v zqgJ5k&1$KlYhurM@@yC^ArObp@DCJ$rFQxZKmxdH7EDgko2>%G9l0u7He44wSt`Z< z^6bV2)0xw5%zmrfH52Xbhqp@wz;IFH^XVaYw|^h>wnN3G*3^0F`=8eCtn`^$ppc}*bPU?|+0B)%hou5Oe_0oJ_}1-nE7!d3zk7DyvR3|4 zCO9>6_XWp%G}`Lua8FFjr+|7>b^>{FBmwQ4RBef?#FvuNhFm=@U3$xc$i92SHR>hGotZ*yE>=U)r+aB@U;` z&jV-G7mx4mN3EZB_5OKr`vVuLxNExzhxV#`^?{2;YhM1gq|$|d zwWMQ9zbpxsEvczKuEnX?_tnBgOSUNd&B~*0y z=ktpQgtctziI!_Gy}y2lw+lREBA3ZXcYhQw(lrjJ$*sKiYx2uc9wEf#+d8*I>jGHmJ_H;%`| zGrkV&_U(y|!e2rQZr4ZN;GgSKEH>+xT!Vc49Jy;h@!=dUhnH%B5y?9%O}@&&hNlYG ze=XLmMLNvL>wg4<>w*I(zd)(&g&VUVNwvfp_7U!eFmp5XsG zto*Mnx^IN$TZ!@CpW0p+OrMqk^=n)jxMb2S{Y$eB?(CEQV_SY`ddOwdzuX1?zKQ<1 z(^XQI{1wA+6#N~-(DK>&7YyU1(eD_>w?gxc$o}Vx?jP1HABzzG$$s*U4fxjn{r9K# zx1Qi1ZooI*{yl-d!DqfF(BJdH?+NtpC6FPTqLsa=f$+?XO3HuLe1W;S;8_^GXWjmQ zHnnm}qu;^dR$ASZ`?U%3lg=>CRW+j`MpPPZZ5B8-C&Rj`T4sNJO>t~?P0ul}ohX=( zPfqE6ZcvEUD((W0Z%E^B(B)r*z`hl~s`AXmI)@K0oN(+5ry}71|2)p=_LYBZv#ZIq zEiEetMX%`pqV)v_KKFozK;-dXnQ4cTt)8}I zf7%uu`7<{5kJ2nYf$q67fcr(=eWROvtC#&5OlPNdzmDa72hs*FIa z80P<8fPZSne5Y0a9~_ zr8e@bfz9uY|Ig&_f3wPe-b8f0{_N@g_JM1Qs?5IPlfN5z{Mlk2otgP7kGQ5b^@~UR z7kA7E?mYU17ulY__E)aA^o=jB_rEn{{Db)&{b!f|w`V!zGQRqcQ@7tnH!$G(hvELK zQPcnZtmvC#sK4h7e@^D_2HbCh>fa9-KNs3}1MdGgp#4ub{qK$bTcYnjt{ML!?fZvs z|DHhKIO6aff&N~#{J%}0<(A3q32=m}HDX1&Z1a>|idF$Fw{xUpqgDx3Po<}=-zp(U zc7i$QnFWK@>%M2QE#4xuJ7S_mw>er$FO36_vo@uaQN+9D>34tA0)qDH%B_DJgJ5 z?J;Dq7MBm2T`~CMxdZ;`E;oZ@aA; zBR{)Thy@+LIgV@iznp|WWB>enx8P4^zn#DNa&V&P%Xx(_=L1%KF;IUS(0@55^P7SB z{U)dXQ+qOt<#@>PW3;W5>a#lc!v;7T^^$KGC!gf|SH|&tJ)L-p&-_nsG=Ng?>qB73I6@^m~$(&lofc((+-LXapa)h0o*?8tN#n8PSe}~ literal 0 HcmV?d00001 diff --git a/examples/mirror_input/makefile b/examples/mirror_input/makefile new file mode 100644 index 0000000..3327dae --- /dev/null +++ b/examples/mirror_input/makefile @@ -0,0 +1,106 @@ +include ../../imports.mak + +####################### +# project information # +####################### + +PROJECT_NAME := mirror_input +SUPPORTED_PROCESSORS := am261x +# Does the PRU code have dependencies outside of the pru-no-code-tool repo? +PRU_DEPENDENCIES := +# Use NON_PRU_DEPENDENCIES to select which makefiles to call for non-PRU cores +NON_PRU_DEPENDENCIES := mcuplus + +################### +# Prebuild checks # +################### +BUILD_PROJECT := y +DEVICE_NON_PRU := + +# Only build project if $(DEVICE) is in $(SUPPORTED_PROCESSORS) +ifeq (,$(findstring $(DEVICE),$(SUPPORTED_PROCESSORS))) +BUILD_PROJECT := n +MESSAGE := Project $(PROJECT_NAME) does not have a build option for $(DEVICE) +endif + +# Only build project if PRU dependencies exist +ifneq (,$(PRU_DEPENDENCIES)) +# MCU+ SDK dependency? +ifeq (mcuplus,$(findstring mcuplus,$(PRU_DEPENDENCIES))) +ifneq ($(BUILD_MCUPLUS),y) +BUILD_PROJECT := n +MESSAGE ?= Project $(PROJECT_NAME) depends on MCU+ SDK, but BUILD_MCUPLUS != y. +endif +endif +# Additional PRU dependency checks go here. For example: +#ifeq (dependency,$(findstring dependency,$(PRU_DEPENDENCIES))) +#if (dependency check fails) +#BUILD_PROJECT := n +#MESSAGE ?= Project $(PROJECT_NAME) depends on dependency, but dependency does not exist. +#endif +#endif +endif + +# Only build non-PRU code if the non-PRU code is enabled in imports.mak +ifeq ($(BUILD_MCUPLUS),y) +ifeq (mcuplus,$(findstring mcuplus,$(NON_PRU_DEPENDENCIES))) +DEVICE_NON_PRU += $(DEVICE)_mcuplus +endif +endif +ifeq ($(BUILD_LINUX),y) +ifeq (linux,$(findstring linux,$(NON_PRU_DEPENDENCIES))) +DEVICE_NON_PRU += $(DEVICE)_linux +endif +endif + +########################### +# Make and clean commands # +########################### + +ifeq ($(BUILD_PROJECT),y) +# "make" or "make all" builds projects that match $(DEVICE) set in imports.mak +# "make" builds PRU firmware first, then host (non-PRU) code +all: MESSAGE = "Building $(PROJECT_NAME) for $(DEVICE)" +all: pre_build_message + $(MAKE) pru + $(MAKE) host + +# "make pru" builds only PRU firmware for $(DEVICE) +pru: ARGUMENTS_PRU = all +pru: $(DEVICE) + +# "make host" builds only host (non-PRU) code for $(DEVICE) +host: ARGUMENTS_MCUPLUS = all +host: $(DEVICE_NON_PRU) + +# "make clean" cleans projects that match $(DEVICE) set in imports.mak +clean: ARGUMENTS_PRU = clean +clean: ARGUMENTS_MCUPLUS = scrub +clean: MESSAGE = "Cleaning $(PROJECT_NAME) for $(DEVICE)" +clean: pre_build_message $(DEVICE) $(DEVICE_NON_PRU) + +else +# if a prebuild check failed, print message and exit +all clean pru host: pre_build_message +endif + +pre_build_message: + @echo $(MESSAGE) + +###################### +# Target definitions # +###################### + +# provide target definitions for each supported processor +# PRU firmware should be built before any RTOS code that includes it +am261x: +# am261x-lp + $(MAKE) -C firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt $(ARGUMENTS_PRU) + $(MAKE) -C firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt $(ARGUMENTS_PRU) + +am261x_mcuplus: +# am261x-lp + $(MAKE) -C mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang $(ARGUMENTS_MCUPLUS) + +.PHONY: all clean pru host pre_build_message $(DEVICE) $(DEVICE_NON_PRU) $(SUPPORTED_PROCESSORS) + diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg new file mode 100644 index 0000000..2a6c9ac --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/example.syscfg @@ -0,0 +1,325 @@ +/** + * 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 "AM261x_ZFG" --part "AM2612" --package "ZFG" --context "r5fss0-0" --product "PRU_NO_CODE_TOOL@01.00.01" --product "MCU_PLUS_SDK_AM261x@11.00.00" + * @v2CliArgs --device "AM2612" --package "NFBGA (ZFG)" --variant "500MHz" --context "r5fss0-0" --product "PRU_NO_CODE_TOOL@01.00.01" --product "MCU_PLUS_SDK_AM261x@11.00.00" + * @versions {"tool":"1.27.0+4565"} + */ + +/** + * Import the modules used in this configuration. + */ +const ioexp = scripting.addModule("/board/ioexp/ioexp", {}, false); +const ioexp1 = ioexp.addInstance(); +const i2c = scripting.addModule("/drivers/i2c/i2c", {}, false); +const i2c1 = i2c.addInstance(); +const pruicss = scripting.addModule("/drivers/pruicss/pruicss", {}, false); +const pruicss1 = pruicss.addInstance(); +const debug_log = scripting.addModule("/kernel/dpl/debug_log"); +const dpl_cfg = scripting.addModule("/kernel/dpl/dpl_cfg"); +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(); +const mpu_armv76 = mpu_armv7.addInstance(); +const default_linker = scripting.addModule("/memory_configurator/default_linker", {}, false); +const default_linker1 = default_linker.addInstance(); +const general = scripting.addModule("/memory_configurator/general", {}, false); +const general1 = general.addInstance(); +const region = scripting.addModule("/memory_configurator/region", {}, false); +const region1 = region.addInstance(); +const section = scripting.addModule("/memory_configurator/section", {}, false); +const section1 = section.addInstance(); +const section2 = section.addInstance(); +const section3 = section.addInstance(); +const section4 = section.addInstance(); +const section5 = section.addInstance(); +const section6 = section.addInstance(); +const section7 = section.addInstance(); +const section8 = section.addInstance(); +const section9 = section.addInstance(); +const section10 = section.addInstance(); +const section11 = section.addInstance(); +const section12 = section.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +ioexp1.$name = "CONFIG_IOEXP0"; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_S1_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_BO_MUX_EN_N_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_SO_mode = 0; +ioexp1.TCA6408ARGTR_port0_pinBP_MUX_SW_S1_state = 1; +ioexp1.TCA6408ARGTR_port0_pinBP_BO_MUX_EN_mode = 0; + +ioexp1.peripheralDriver = i2c1; +i2c1.$name = "CONFIG_I2C2"; +i2c1.I2C.$assign = "I2C0"; +i2c1.I2C_child.$name = "drivers_i2c_v1_i2c_v1_template1"; + +pruicss1.$name = "CONFIG_PRU_ICSS0"; +pruicss1.instance = "ICSSM1"; +pruicss1.AdditionalICSSSettings[0].$name = "CONFIG_PRU_ICSS_IO0"; +pruicss1.AdditionalICSSSettings[0].PruGPIO.create(1); +pruicss1.AdditionalICSSSettings[0].PruGPIO[0].$name = "CONFIG_PRU_ICSS_GPIO0"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].$assign = "PRU-ICSS1"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO5.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO5.$assign = "GPIO54"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO5.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.$assign = "GPIO19"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO6.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO4.$assign = "GPIO15"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO4.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO0.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO0.$assign = "GPIO81"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO0.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO1.$assign = "GPIO82"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO1.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO2.$assign = "GPIO83"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO9.$assign = "GPIO80"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.rx = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.$used = true; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO7.$assign = "GPIO26"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU0_GPIO7.$used = true; + +debug_log.enableUartLog = true; +debug_log.enableSharedMemLog = true; +debug_log.enableSharedMemLogReader = true; +debug_log.uartLog.$name = "CONFIG_UART0"; +debug_log.uartLog.UART.$assign = "UART0"; +debug_log.uartLog.UART.RXD.$assign = "GPIO27"; +debug_log.uartLog.UART.TXD.$assign = "GPIO28"; +debug_log.uartLog.child.$name = "drivers_uart_v2_uart_v2_template0"; + +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 = 0x80000; +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.size = 14; +mpu_armv75.baseAddr = 0x50D00000; +mpu_armv75.allowExecute = false; +mpu_armv75.attributes = "Device"; + +mpu_armv76.$name = "CONFIG_MPU_REGION5"; +mpu_armv76.size = 14; +mpu_armv76.allowExecute = false; +mpu_armv76.attributes = "NonCached"; +mpu_armv76.baseAddr = 0x72000000; + +default_linker1.$name = "memory_configurator_default_linker0"; + +general1.$name = "CONFIG_GENERAL0"; +general1.linker.$name = "TIARMCLANG0"; + +region1.$name = "MEMORY_REGION_CONFIGURATION0"; +region1.memory_region.create(11); +region1.memory_region[0].type = "TCMA"; +region1.memory_region[0].$name = "R5F_VECS"; +region1.memory_region[0].size = 0x40; +region1.memory_region[0].auto = false; +region1.memory_region[1].type = "TCMA"; +region1.memory_region[1].$name = "R5F_TCMA"; +region1.memory_region[1].size = 0x7FC0; +region1.memory_region[2].type = "TCMB"; +region1.memory_region[2].size = 0x8000; +region1.memory_region[2].$name = "R5F_TCMB"; +region1.memory_region[3].$name = "SBL"; +region1.memory_region[3].auto = false; +region1.memory_region[3].size = 0x40000; +region1.memory_region[4].$name = "OCRAM"; +region1.memory_region[4].auto = false; +region1.memory_region[4].manualStartAddress = 0x70040000; +region1.memory_region[4].size = 0x40000; +region1.memory_region[5].type = "FLASH"; +region1.memory_region[5].auto = false; +region1.memory_region[5].manualStartAddress = 0x60100000; +region1.memory_region[5].size = 0x80000; +region1.memory_region[5].$name = "FLASH"; +region1.memory_region[6].$name = "USER_SHM_MEM"; +region1.memory_region[6].auto = false; +region1.memory_region[6].manualStartAddress = 0x70150000; +region1.memory_region[6].size = 0x4000; +region1.memory_region[6].isShared = true; +region1.memory_region[6].shared_cores = ["r5fss0-1"]; +region1.memory_region[7].$name = "LOG_SHM_MEM"; +region1.memory_region[7].auto = false; +region1.memory_region[7].manualStartAddress = 0x70154000; +region1.memory_region[7].size = 0x4000; +region1.memory_region[7].isShared = true; +region1.memory_region[7].shared_cores = ["r5fss0-1"]; +region1.memory_region[8].type = "CUSTOM"; +region1.memory_region[8].$name = "RTOS_NORTOS_IPC_SHM_MEM"; +region1.memory_region[8].auto = false; +region1.memory_region[8].manualStartAddress = 0x72000000; +region1.memory_region[8].size = 0x3E80; +region1.memory_region[8].isShared = true; +region1.memory_region[8].shared_cores = ["r5fss0-1"]; +region1.memory_region[9].type = "CUSTOM"; +region1.memory_region[9].$name = "MAILBOX_HSM"; +region1.memory_region[9].auto = false; +region1.memory_region[9].manualStartAddress = 0x44000000; +region1.memory_region[9].size = 0x3CE; +region1.memory_region[9].isShared = true; +region1.memory_region[9].shared_cores = ["r5fss0-1"]; +region1.memory_region[10].type = "CUSTOM"; +region1.memory_region[10].$name = "MAILBOX_R5F"; +region1.memory_region[10].auto = false; +region1.memory_region[10].manualStartAddress = 0x44000400; +region1.memory_region[10].size = 0x3CE; +region1.memory_region[10].isShared = true; +region1.memory_region[10].shared_cores = ["r5fss0-1"]; + +section1.load_memory = "R5F_VECS"; +section1.group = false; +section1.$name = "Vector Table"; +section1.output_section.create(1); +section1.output_section[0].$name = ".vectors"; +section1.output_section[0].palignment = true; + +section2.load_memory = "OCRAM"; +section2.$name = "Text Segments"; +section2.output_section.create(5); +section2.output_section[0].$name = ".text.hwi"; +section2.output_section[0].palignment = true; +section2.output_section[1].$name = ".text.cache"; +section2.output_section[1].palignment = true; +section2.output_section[2].$name = ".text.mpu"; +section2.output_section[2].palignment = true; +section2.output_section[3].$name = ".text.boot"; +section2.output_section[3].palignment = true; +section2.output_section[4].$name = ".text:abort"; +section2.output_section[4].palignment = true; + +section3.load_memory = "OCRAM"; +section3.$name = "Code and Read-Only Data"; +section3.output_section.create(2); +section3.output_section[0].$name = ".text"; +section3.output_section[0].palignment = true; +section3.output_section[1].$name = ".rodata"; +section3.output_section[1].palignment = true; + +section4.load_memory = "OCRAM"; +section4.$name = "Data Segment"; +section4.output_section.create(1); +section4.output_section[0].$name = ".data"; +section4.output_section[0].palignment = true; + +section5.load_memory = "OCRAM"; +section5.$name = "Memory Segments"; +section5.output_section.create(3); +section5.output_section[0].$name = ".bss"; +section5.output_section[0].output_sections_start = "__BSS_START"; +section5.output_section[0].output_sections_end = "__BSS_END"; +section5.output_section[0].palignment = true; +section5.output_section[1].$name = ".sysmem"; +section5.output_section[1].palignment = true; +section5.output_section[2].$name = ".stack"; +section5.output_section[2].palignment = true; + +section6.load_memory = "OCRAM"; +section6.$name = "Stack Segments"; +section6.output_section.create(5); +section6.output_section[0].$name = ".irqstack"; +section6.output_section[0].output_sections_start = "__IRQ_STACK_START"; +section6.output_section[0].output_sections_end = "__IRQ_STACK_END"; +section6.output_section[0].input_section.create(1); +section6.output_section[0].input_section[0].$name = ". = . + __IRQ_STACK_SIZE;"; +section6.output_section[1].$name = ".fiqstack"; +section6.output_section[1].output_sections_start = "__FIQ_STACK_START"; +section6.output_section[1].output_sections_end = "__FIQ_STACK_END"; +section6.output_section[1].input_section.create(1); +section6.output_section[1].input_section[0].$name = ". = . + __FIQ_STACK_SIZE;"; +section6.output_section[2].$name = ".svcstack"; +section6.output_section[2].output_sections_start = "__SVC_STACK_START"; +section6.output_section[2].output_sections_end = "__SVC_STACK_END"; +section6.output_section[2].input_section.create(1); +section6.output_section[2].input_section[0].$name = ". = . + __SVC_STACK_SIZE;"; +section6.output_section[3].$name = ".abortstack"; +section6.output_section[3].output_sections_start = "__ABORT_STACK_START"; +section6.output_section[3].output_sections_end = "__ABORT_STACK_END"; +section6.output_section[3].input_section.create(1); +section6.output_section[3].input_section[0].$name = ". = . + __ABORT_STACK_SIZE;"; +section6.output_section[4].$name = ".undefinedstack"; +section6.output_section[4].output_sections_start = "__UNDEFINED_STACK_START"; +section6.output_section[4].output_sections_end = "__UNDEFINED_STACK_END"; +section6.output_section[4].input_section.create(1); +section6.output_section[4].input_section[0].$name = ". = . + __UNDEFINED_STACK_SIZE;"; + +section7.load_memory = "OCRAM"; +section7.$name = "Initialization and Exception Handling"; +section7.output_section.create(3); +section7.output_section[0].$name = ".ARM.exidx"; +section7.output_section[0].palignment = true; +section7.output_section[1].$name = ".init_array"; +section7.output_section[1].palignment = true; +section7.output_section[2].$name = ".fini_array"; +section7.output_section[2].palignment = true; + +section8.load_memory = "USER_SHM_MEM"; +section8.type = "NOLOAD"; +section8.$name = "User Shared Memory"; +section8.group = false; +section8.output_section.create(1); +section8.output_section[0].$name = ".bss.user_shared_mem"; +section8.output_section[0].alignment = 0; + +section9.load_memory = "LOG_SHM_MEM"; +section9.$name = "Log Shared Memory"; +section9.group = false; +section9.type = "NOLOAD"; +section9.output_section.create(1); +section9.output_section[0].$name = ".bss.log_shared_mem"; +section9.output_section[0].alignment = 0; + +section10.load_memory = "RTOS_NORTOS_IPC_SHM_MEM"; +section10.type = "NOLOAD"; +section10.$name = "IPC Shared Memory"; +section10.group = false; +section10.output_section.create(1); +section10.output_section[0].$name = ".bss.ipc_vring_mem"; +section10.output_section[0].alignment = 0; + +section11.load_memory = "MAILBOX_HSM"; +section11.type = "NOLOAD"; +section11.$name = "SIPC HSM Queue Memory"; +section11.group = false; +section11.output_section.create(1); +section11.output_section[0].$name = ".bss.sipc_hsm_queue_mem"; +section11.output_section[0].alignment = 0; + +section12.load_memory = "MAILBOX_R5F"; +section12.$name = "SIPC R5F Queue Memory"; +section12.group = false; +section12.type = "NOLOAD"; +section12.output_section.create(1); +section12.output_section[0].$name = ".bss.sipc_secure_host_queue_mem"; +section12.output_section[0].alignment = 0; + +/** + * 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. + */ +i2c1.I2C.SCL.$suggestSolution = "GPIO135"; +i2c1.I2C.SDA.$suggestSolution = "GPIO134"; +pruicss1.AdditionalICSSSettings[0].PruGPIO[0]["PRU-ICSS1"].PR1_PRU1_GPIO11.$suggestSolution = "GPIO3"; diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/main.c b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/main.c new file mode 100644 index 0000000..b8dd06a --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/main.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024-2025 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 empty_example_main(void *args); + +void freertos_main(void *args) +{ + empty_example_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/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec new file mode 100644 index 0000000..f737860 --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile new file mode 100644 index 0000000..4e3cae4 --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile @@ -0,0 +1,336 @@ +# +# Auto generated makefile +# + +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak +include $(MCU_PLUS_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 +COV=$(CG_TOOL_ROOT)/bin/tiarmcov +PROFDATA=$(CG_TOOL_ROOT)/bin/tiarmprofdata +COVERAGE_PATH=$(abspath .) +ifeq ($(OS), Windows_NT) + PYTHON=python +else + PYTHON=python3 +endif + +PROFILE?=release +ConfigName:=$(PROFILE) + +OUTNAME:=mirror_input.$(PROFILE).out +COREOUTNAME:=mirror_input.$(PROFILE).optishare.out + +BOOTIMAGE_PATH=$(abspath .) +oeconfig?=None + +BOOTIMAGE_NAME_MCELF:=mirror_input.$(PROFILE).mcelf +BOOTIMAGE_NAME_MCELF_HS:=mirror_input.$(PROFILE).mcelf.hs +TARGETS := $(BOOTIMAGE_NAME_MCELF) + +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif + + +FILES_common := \ + main.c \ + empty_example.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${MCU_PLUS_SDK_PATH}/source \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/FreeRTOS-Kernel/include \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/portable/TI_ARM_CLANG/ARM_CR5F \ + -I${MCU_PLUS_SDK_PATH}/source/kernel/freertos/config/am261x/r5f \ + -I${MCU_PLUS_SDK_PATH}/source/pru_io/driver \ + -I${PRU_NO_CODE_TOOL_PATH}/examples/mirror_input/firmware/am261x-lp \ + -Igenerated \ + +DEFINES_common := \ + -DSOC_AM261X \ + -DOS_FREERTOS \ + +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-register \ + -Wno-writable-strings \ + -Wno-enum-compare \ + -Wno-reserved-user-defined-literal \ + -Wno-unused-const-variable \ + -Wno-vla-cxx-extension \ + -x c++ \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -Os \ + +LNK_FILES_common = \ + generated/linker.cmd \ + +LIBS_PATH_common = \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/kernel/freertos/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/drivers/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/board/lib \ + -Wl,-i${MCU_PLUS_SDK_PATH}/source/pru_io/lib \ + -Wl,-i${CG_TOOL_ROOT}/lib \ + +LIBS_common = \ + -lfreertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + -ldrivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + -lboard.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + -llibc.a \ + -llibsysbm.a \ + +LFLAGS_common = \ + -Wl,--diag_suppress=10063 \ + -Wl,--ram_model \ + -Wl,--reread_libs \ + -Wl,--gen_xml_func_hash \ + + +LIBS_NAME = \ + freertos.am261x.r5f.ti-arm-clang.${ConfigName}.lib \ + drivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + board.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \ + libc.a \ + libsysbm.a \ + +LIBS_PATH_NAME = \ + ${MCU_PLUS_SDK_PATH}/source/kernel/freertos/lib \ + ${MCU_PLUS_SDK_PATH}/source/drivers/lib \ + ${MCU_PLUS_SDK_PATH}/source/board/lib \ + ${MCU_PLUS_SDK_PATH}/source/pru_io/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)) +ifeq ($(INSTRUMENTATION_MODE), yes) +CFLAGS += -fprofile-instr-generate -fcoverage-mapping +endif +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: am261x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: am261x:r5fss0-0:freertos:ti-arm-clang $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -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 + +SYSTEM_FLAG ?= false + +ifeq ($(SYSTEM_FLAG), false) + SYSTEM_COMMAND := syscfg $(SYSCFG_GEN_FILES) $(OBJS) $(LNK_FILES) $(LIBS_NAME) +else + SYSTEM_COMMAND := $(OBJS) $(LNK_FILES) $(LIBS_NAME) +endif + +$(OUTNAME): $(SYSTEM_COMMAND) + @echo . + @echo Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ ... + $(LNK) $(LNKOPTFLAGS) $(LFLAGS) $(LIBS_PATH) -Wl,-m=$(basename $@).map -o $@ $(addprefix $(OBJDIR), $(OBJS)) $(LIBS) $(LNK_FILES) -Wl,--xml_link_info=$(basename $@).lnkxml + @echo Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ Done !!! + @echo . + +coreout: $(COREOUTNAME) +$(COREOUTNAME): $(SYSTEM_COMMAND) + @echo . + @echo Relinking Linking: am261x:r5fss0-0:freertos:ti-arm-clang $@ with OptiShare SSO.. + $(LNK) $(LNKOPTFLAGS) $(LFLAGS) $(LIBS_PATH) -Wl,-m=$(basename $@).map -o $@ $(addprefix $(OBJDIR), $(OBJS)) $(LIBS) $(LNK_FILES) -Wl,--xml_link_info=$(basename $@).lnkxml -Wl,--import_sso=$(SSO_PATH) + @echo Relinking with optishare: am261x:r5fss0-0:freertos:ti-arm-clang $@ Done !!! + @echo . + +clean: + @echo Cleaning: am261x:r5fss0-0:freertos:ti-arm-clang $(OUTNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(OUTNAME) + $(RM) $(BOOTIMAGE_NAME_MCELF) + $(RM) $(BOOTIMAGE_NAME_MCELF_HS) + $(RMDIR) generated/ + +scrub: + @echo Scrubing: am261x:r5fss0-0:freertos:ti-arm-clang mirror_input ... + $(RMDIR) obj +ifeq ($(OS),Windows_NT) + $(RM) \*.out + $(RM) \*.map + $(RM) \*.appimage* + $(RM) \*.rprc* + $(RM) \*.tiimage* + $(RM) \*.bin + $(RM) \*.lnkxml + $(RM) \*.ossr + $(RM) \*.mcelf + $(RM) \*.mcelf_xip + $(RM) \*.mcelf-enc + $(RM) \*.mcelf.hs +else + $(RM) *.out + $(RM) *.map + $(RM) *.appimage* + $(RM) *.rprc* + $(RM) *.tiimage* + $(RM) *.bin + $(RM) *.lnkxml + $(RM) *.ossr + $(RM) *.mcelf + $(RM) *.mcelf_xip + $(RM) *.mcelf-enc + $(RM) *.mcelf.hs +endif + $(RMDIR) generated + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + $(MKDIR) $@ + + +.NOTPARALLEL: + +.INTERMEDIATE: syscfg +$(SYSCFG_GEN_FILES): syscfg + +ifeq ($(SYSTEM_FLAG), false) +syscfg: ../example.syscfg + @echo Generating SysConfig files ... + $(SYSCFG_NODE) $(SYSCFG_CLI_PATH)/dist/cli.js --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --product $(SYSCFG_MCU_PLUS_SDK_PRODUCT) --context r5fss0-0 --part ALX --package ALX --output generated/ ../example.syscfg +endif + +syscfg-gui: + $(SYSCFG_NWJS) $(SYSCFG_PATH) --product $(SYSCFG_PRU_NO_TOOL_PRODUCT) --product $(SYSCFG_MCU_PLUS_SDK_PRODUCT) --device AM261x_ALX_beta --context r5fss0-0 --part 2612 --package ZFG --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 $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MCU_PLUS_SDK_PATH)/source/security/security_common/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 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 +SBL_DEV_ID=55 + +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py + +$(BOOTIMAGE_NAME_MCELF): $(OUTNAME) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) ... + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTNAME) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) --otfaConfigFile=$(oeconfig) + @echo Boot MulticoreELF image: $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +$(BOOTIMAGE_NAME_MCELF_HS): $(BOOTIMAGE_NAME_MCELF) +ifeq ($(DEVICE_TYPE), HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) +else + @echo Boot image signing: Encryption is disabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss +endif +else +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSAPSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! + @echo . +endif + + + +.PHONY: coverage +coverage: + @echo Creating Coverage Report for mirror_input.$(PROFILE) ... + $(MKDIR) coverage + $(PROFDATA) merge -sparse -obj-file=$(OUTNAME) $(OUTNAME).cnt -o mirror_input.$(PROFILE).profdata + $(COV) show --format=html --show-expansions --show-instantiations --show-branches=count --object=$(OUTNAME) -instr-profile=mirror_input.$(PROFILE).profdata --output-dir=$(COVERAGE_PATH)/coverage --ignore-filename-regex=build_jenkins + $(COV) export --format=text --object=$(OUTNAME) --instr-profile=mirror_input.$(PROFILE).profdata > coverage/mirror_input.$(PROFILE).profdata.json + node $(MCU_PLUS_SDK_PATH)/tools/smart_placement/clang_coverage_analyse.js --input=coverage/mirror_input.$(PROFILE).profdata.json --output-json=coverage/mirror_input.$(PROFILE).analysis.json --output=../mirror_input.annotations.$(PROFILE).S --top-function-count=500 + @echo Coverage Report Generated at $(COVERAGE_PATH)/coverage folder !!! + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs new file mode 100644 index 0000000..4f41ac3 --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile.defs @@ -0,0 +1,14 @@ +GEN_FILES__QUOTED += \ +*.appimage* \ +*.appimage_xip \ +*.rprc* \ +*.rprc_xip \ +*.tiimage* \ +*.bin \ +*.lnkxml \ +*.map \ +*.ossr + +GEN_FILES__QUOTED += \ +*.mcelf* \ +*.mcelf_xip diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen new file mode 100644 index 0000000..93f08ca --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen @@ -0,0 +1,95 @@ +# +# Auto generated makefile +# + +# Below variables need to be defined outside this file or via command line +# - PRU_NO_CODE_TOOL_PATH +# - MCU_PLUS_SDK_PATH +# - PROFILE +# - CG_TOOL_ROOT +# - OUTNAME +# - CCS_INSTALL_DIR +# - CCS_IDE_MODE + +CCS_PATH=$(CCS_INSTALL_DIR) +include $(MCU_PLUS_SDK_PATH)/imports.mak +include $(MCU_PLUS_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_MCELF:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf +BOOTIMAGE_NAME_MCELF_HS:=$(BOOTIMAGE_PATH)/$(OUTNAME).mcelf.hs +TARGETS += $(BOOTIMAGE_NAME_MCELF) +TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +ifeq ($(DEVICE_TYPE), HS) + TARGETS += $(BOOTIMAGE_NAME_MCELF_HS) +endif + +# +# 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 $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.ps1 +else + BOOTIMAGE_CERT_GEN_CMD=$(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/x509CertificateGen.sh +endif +BOOTIMAGE_TEMP_OUT_FILE=$(PROFILE)/temp_stdout_$(PROFILE).txt + +BOOTIMAGE_CORE_ID_r5fss0-0 = 0 +BOOTIMAGE_CORE_ID_r5fss0-1 = 1 +BOOTIMAGE_CORE_ID_r5fss1-0 = 2 +BOOTIMAGE_CORE_ID_r5fss1-1 = 3 +SBL_RUN_ADDRESS=0x70002000 +SBL_DEV_ID=55 + +APP_IMAGE_SIGN_CMD = $(MCU_PLUS_SDK_PATH)/source/security/security_common/tools/boot/signing/mcu_appimage_x509_cert_gen.py +MCELF_IMAGE_GEN = $(MCU_PLUS_SDK_PATH)/tools/boot/multicore-elf/genimage.py + +all: +ifeq ($(CCS_IDE_MODE),cloud) +# No post build steps +else + + @echo Boot multi-core ELF image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_NAME_MCELF) ... + + $(PYTHON) $(MCELF_IMAGE_GEN) --core-img=$(BOOTIMAGE_CORE_ID_r5fss0-0):$(OUTFILE) --output=$(BOOTIMAGE_NAME_MCELF) --merge-segments=$(MCELF_MERGE_SEGMENTS_FLAG) --tolerance-limit=$(MCELF_MERGE_SEGMENTS_TOLERANCE_LIMIT) --ignore-context=$(MCELF_IGNORE_CONTEXT_FLAG) --xip=$(MCELF_XIP_RANGE) --xlat=$(MCELF_ADDR_TRANSLATION_PATH) --max-segment-size=$(MCELF_MAX_SEGMENT_SIZE) + + @echo Boot multi-core ELF image: $(BOOTIMAGE_NAME_MCELF) Done !!! + @echo . + +ifeq ($(DEVICE_TYPE), HS) +# Sign the appimage using appimage signing script +ifeq ($(ENC_ENABLED),no) +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is disabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) +else + @echo Boot image signing: Encryption is disabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss +endif +else +ifeq ($(RSASSAPSS_ENABLED),no) + @echo Boot image signing: Encryption is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --output $(BOOTIMAGE_NAME_MCELF_HS) + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +else + @echo Boot image signing: Encryption is enabled. RSASSA-PSS is enabled. + $(PYTHON) $(APP_IMAGE_SIGN_CMD) --bin $(BOOTIMAGE_NAME_MCELF) --key $(APP_SIGNING_KEY) --enc y --enckey $(APP_ENCRYPTION_KEY) --kd-salt $(KD_SALT) --sign_key_id $(APP_SIGNING_KEY_KEYRING_ID) --enc_key_id $(APP_ENCRYPTION_KEY_KEYRING_ID) --hash_algo $(APP_SIGNING_HASH_ALGO) --pss_saltlen $(APP_SIGNING_SALT_LENGTH) --output $(BOOTIMAGE_NAME_MCELF_HS) --rsassa_pss + $(RM) $(BOOTIMAGE_NAME_MCELF)-enc +endif +endif + @echo Boot image: am261x:r5fss0-0:freertos:ti-arm-clang $(BOOTIMAGE_PATH)/$(BOOTIMAGE_NAME_MCELF_HS) Done !!! + @echo . +endif +endif diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec new file mode 100644 index 0000000..af5f4c1 --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec @@ -0,0 +1,16 @@ +export PRU_NO_CODE_TOOL_PATH?=$(abspath ../../../../../..) +include $(PRU_NO_CODE_TOOL_PATH)/imports.mak + +PROFILE?=Release + +PROJECT_NAME=mirror_input_am261x-lp_r5fss0-0_freertos_ti-arm-clang + +all: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) + +clean: + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean + +export: + $(MKDIR) $(PRU_NO_CODE_TOOL_PATH)/ccs_projects + $(CCS_ECLIPSE) -noSplash -data $(PRU_NO_CODE_TOOL_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full diff --git a/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs new file mode 100644 index 0000000..f716f8e --- /dev/null +++ b/examples/mirror_input/mcuplus/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs @@ -0,0 +1,12 @@ +/* + * ======== syscfg_c.rov.xs ======== + * This file contains the information needed by the Runtime Object + * View (ROV) tool. + */ +var crovFiles = [ + "kernel/freertos/rov/FreeRTOS.rov.js", +]; + +var objectViewerFiles = [ + "kernel/freertos/rov_theia/FreeRTOS_Theia.rov.js", +]; diff --git a/examples/mirror_input/mcuplus/empty_example.c b/examples/mirror_input/mcuplus/empty_example.c new file mode 100644 index 0000000..092fa88 --- /dev/null +++ b/examples/mirror_input/mcuplus/empty_example.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2024-2025 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_drivers_open_close.h" +#include "ti_board_open_close.h" +#include + +#include +#include +#if defined(SOC_AM64X) || defined(SOC_AM243X) +#include +#include +#include +#include +#endif + + + +/* + * This is an example project to show R5F + * loading PRU firmware. + */ + +/** \brief Global Structure pointer holding PRUSS1 memory Map. */ + +PRUICSS_Handle gPruIcss0Handle; + + +void empty_example_main(void *args) +{ + Drivers_open(); // check return status + + int status; + status = Board_driversOpen(); + DebugP_assert(SystemP_SUCCESS == status); + + gPruIcss0Handle = PRUICSS_open(CONFIG_PRU_ICSS0); + + status = PRUICSS_initMemory(gPruIcss0Handle, PRUICSS_DATARAM(PRUICSS_PRU0)); + DebugP_assert(status != 0); + + status = PRUICSS_initMemory(gPruIcss0Handle, PRUICSS_DATARAM(PRUICSS_PRU1)); + DebugP_assert(status != 0); + + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_PRU0, PRU0Firmware_0, sizeof(PRU0Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + ClockP_usleep(5); + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_PRU1, PRU1Firmware_0, sizeof(PRU1Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + + #if defined(SOC_AM64X) || defined(SOC_AM243X) + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_RTU_PRU0, RTUPRU0Firmware_0, sizeof(RTUPRU0Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_RTU_PRU1, RTUPRU1Firmware_0, sizeof(RTUPRU1Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_TX_PRU0, TXPRU0Firmware_0, sizeof(TXPRU0Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_TX_PRU1, TXPRU1Firmware_0, sizeof(TXPRU1Firmware_0)); + DebugP_assert(SystemP_SUCCESS == status); + #endif + + while (1) + { + ClockP_usleep(1); + } + + Board_driversClose(); + Drivers_close(); +} diff --git a/examples/mirror_input/readme.md b/examples/mirror_input/readme.md new file mode 100644 index 0000000..f374470 --- /dev/null +++ b/examples/mirror_input/readme.md @@ -0,0 +1,75 @@ +# SPI Transfer at 10MHz + +## Introduction + +This example demonstrates replicating the input (GPI) signals and producing the same waveform on the output (GPO) pins + +
+mirror_input +
In the figure, yellow signal represent the input signal and the red signal represents the output waveform produced
+
+ +## No-Code Tool Block Design + +This example uses two PRU cores running concurrently inside ICSSM1. The core demonstration is on **PRU0** — it reads an input signal on a GPI pin and mirrors it in real time onto a GPO pin using the No-Code Tool blocks. PRU1 is a helper that simply generates a repeating signal and feeds it as input to PRU0, so there is something to mirror. + +**PRU1 — Signal Generator (helper only)** + +PRU1 continuously produces a square wave on GPO bit 4 using an infinite Loop block: +- SET GPO bit 4 → wait 40 cycles → CLR GPO bit 4 → wait 20 cycles → repeat + +No inputs are needed. The block design is a single infinite Loop containing four alternating GPO (SET/CLR) and Delay blocks, with Flow Control jumping back to the loop start. + +**PRU0 — Input Mirror (main example)** + +PRU0 reads GPI bit 0 (connected to PRU1's GPO bit 4 output) and reproduces the same signal on GPO bit 1 using an If/Else block inside an infinite Loop: + +1. **PRU_GPI** — read R31 bit 0 into a register +2. **Load_Constant** — load the value 0 into a second register +3. **If/Else** — compare GPI reading to 0: + - **FALSE branch** (input is non-zero / HIGH): SET GPO bit 1 → Flow Control jumps back to loop start + - **TRUE branch** (input is zero / LOW): CLR GPO bit 1 → Flow Control jumps back to loop start + +Both Flow Control blocks jump to `Loop_0_start` so the loop keeps iterating on every cycle regardless of which branch was taken. + +**Generated Assembly (PRU0)** + +```asm +startloop_0: + AND R0.b0, R31, 1 << 0 ; read GPI bit 0 + LDI R0.b1, 0 ; constant 0 + QBEQ If_Else_0_TRUE, R0.b1, R0.b0 ; branch if input == 0 (LOW) + SET R30, R30, 1 ; FALSE: input HIGH → set GPO bit 1 + JMP startloop_0 +If_Else_0_TRUE: + CLR R30, R30, 1 ; TRUE: input LOW → clear GPO bit 1 + JMP startloop_0 +``` + +# Supported Combinations + + Parameter | Value + ---------------|----------- + ICSSM | ICSSM1 - PRU0, PRU1 (am261x only) + Toolchain | pru-cgt + Board | am261x-lp + Example folder | examples/mirror_input/ + +# Steps to Run the Example + +> Prerequisite: [PRU-CGT-2-3](https://www.ti.com/tool/PRU-CGT) (ti-pru-cgt) should be installed at: `C:/ti/` + +- **When using CCS projects to build**, import the CCS project from the above mentioned Example folder path for R5F and PRU. After this `main.asm`, `linker.cmd` files get copied to the CCS workspace of the PRU project. The `main.asm` contains sample code to halt the PRU program. + + - Build the PRU project using the CCS project menu (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_PROJECTS_PAGE.html)). + - Build Flow: Once you click on build in PRU project, the firmware header file generated in the release or debug folder of the CCS workspace is moved to `` + + - Build the R5F project using the CCS project menu (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_PROJECTS_PAGE.html)). + - The firmware header file path is included in R5F project include options by default. Instructions in the firmware header file can be written into PRU IRAM memory using the PRUICSS_loadFirmware API. + + - Launch a CCS debug session and run the executable (see [for AM261x](https://software-dl.ti.com/mcu-plus-sdk/esd/AM261X/latest/exports/docs/api_guide_am261x/CCS_LAUNCH_PAGE.html)). + + - Connect the SPI controller and peripheral pins as per the pin connections table above. + +- **When using makefiles to build**: + - For steps on how to use makefiles, run `make help` from the root folder of the pru-no-code-tool repository. diff --git a/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg b/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg index c8272eb..a71db23 100644 --- a/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg +++ b/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru0_fw/example.syscfg @@ -26,7 +26,7 @@ load_constant_block1.$name = "Load_Constant_0"; load_constant_block1.constant1 = 2882382797; flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + pru_spi_write1.$name = "PRU_SPI_Write_0"; pru_spi_write1.packetSize = 32; diff --git a/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg b/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg index dce012a..f600106 100644 --- a/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg +++ b/examples/spi_loopback/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg @@ -18,7 +18,7 @@ const pru_spi_read1 = pru_spi_read.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + pru_spi_read1.$name = "PRU_SPI_Read_0"; pru_spi_read1.packetSize = 32; diff --git a/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg b/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg index 31a0958..06ff9bd 100644 --- a/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg +++ b/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru0_fw/example.syscfg @@ -26,7 +26,7 @@ load_constant_block1.$name = "Load_Constant_0"; load_constant_block1.constant1 = 3735928559; flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + pru_spi_write1.$name = "PRU0_SPI_Write_0"; pru_spi_write1.packetSize = 32; diff --git a/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg b/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg index 46d0fcb..12ffff5 100644 --- a/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg +++ b/examples/spi_loopback/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg @@ -18,7 +18,7 @@ const pru_spi_read1 = pru_spi_read.addInstance(); * Write custom configuration values to the imported modules. */ flow_control_block1.$name = "Flow_Control_0"; -flow_control_block1.opCode = "HALT"; + pru_spi_read1.$name = "PRU1_SPI_Read_0"; pru_spi_read1["SCLK Signal"] = "4"; diff --git a/examples/spi_loopback/firmware/main.asm b/examples/spi_loopback/firmware/main.asm index dcd1f1e..0e4e88f 100644 --- a/examples/spi_loopback/firmware/main.asm +++ b/examples/spi_loopback/firmware/main.asm @@ -34,3 +34,4 @@ main: JMP sysconfig_generated_start +sysconfig_generated_end: diff --git a/examples/tamagawa_single_channel/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg b/examples/tamagawa_single_channel/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg index 57cc415..33af280 100644 --- a/examples/tamagawa_single_channel/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg +++ b/examples/tamagawa_single_channel/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg @@ -11,9 +11,12 @@ */ const load_constant_block = scripting.addModule("/pru_blocks/data_handling/load_constant_block", {}, false); const load_constant_block1 = load_constant_block.addInstance(); -const load_constant_block3 = load_constant_block.addInstance(); +const load_constant_block2 = load_constant_block.addInstance(); const conditional_block = scripting.addModule("/pru_blocks/program_control/conditional_block", {}, false); const conditional_block1 = conditional_block.addInstance(); +const flow_control_block = scripting.addModule("/pru_blocks/program_control/flow_control_block", {}, false); +const flow_control_block1 = flow_control_block.addInstance(); +const flow_control_block2 = flow_control_block.addInstance(); const loop_block = scripting.addModule("/pru_blocks/program_control/loop_block", {}, false); const loop_block1 = loop_block.addInstance(); const uart_config = scripting.addModule("/pru_blocks/pru_io_blocks/uart_config", {}, false); @@ -22,12 +25,11 @@ const uart_rx_op = scripting.addModule("/pru_blocks/pru_io_blocks/ua const uart_rx_op1 = uart_rx_op.addInstance(); const uart_tx_op = scripting.addModule("/pru_blocks/pru_io_blocks/uart_tx_op", {}, false); const uart_tx_op1 = uart_tx_op.addInstance(); -const delay_block = scripting.addModule("/pru_blocks/utils/delay_block", {}, false); -const delay_block1 = delay_block.addInstance(); const memory_access_block = scripting.addModule("/pru_blocks/utils/memory_access_block", {}, false); const memory_access_block1 = memory_access_block.addInstance(); const memory_access_block2 = memory_access_block.addInstance(); const memory_access_block3 = memory_access_block.addInstance(); +const memory_access_block4 = memory_access_block.addInstance(); const memory_variable_block = scripting.addModule("/pru_blocks/utils/memory_variable_block", {}, false); const memory_variable_block1 = memory_variable_block.addInstance(); @@ -37,11 +39,17 @@ const memory_variable_block1 = memory_variable_block.addInstance(); load_constant_block1.constant1 = 1; load_constant_block1.$name = "trigger_true"; -load_constant_block3.$name = "trigger_clear_value"; +load_constant_block2.$name = "trigger_clear_value"; conditional_block1.$name = "If_Else_0"; conditional_block1.conditionToCheck = "equalToInput2"; +flow_control_block1.$name = "Flow_Control_0"; +flow_control_block1.jumpTarget = "startloop_0"; + +flow_control_block2.$name = "Flow_Control_1"; +flow_control_block2.jumpTarget = "startloop_0"; + loop_block1.infiniteLoop = true; loop_block1.$name = "repeat_always"; loop_block1.$size = [1000,515]; @@ -63,8 +71,6 @@ uart_config1.rxBaudRate = 2.5; uart_config1.rxStartBitPolarity = 0; uart_config1.$name = "config"; -delay_block1.$name = "Delay_0"; - memory_access_block1.$name = "trigger"; memory_access_block1.dataSize = 1; @@ -77,10 +83,9 @@ memory_access_block3.operationMode = "write"; memory_access_block3.$name = "clear_trigger"; memory_access_block3.dataSize = 1; -const memory_access_block4 = memory_access_block.addInstance(); -memory_access_block4.$name = "read_command"; -memory_access_block4.offsetValue = 0x1; -memory_access_block4.dataSize = 1; +memory_access_block4.$name = "read_command"; +memory_access_block4.offsetValue = 0x1; +memory_access_block4.dataSize = 1; memory_variable_block1.$name = "Memory_Variable_0"; memory_variable_block1.sizeInBytes = 16; @@ -93,38 +98,40 @@ memory_access_block4.memVar = memory_variable_block1; /** * References between modules. */ -loop_block1.$groupContents = [memory_access_block1, conditional_block1, load_constant_block1, uart_config1, memory_access_block4, uart_tx_op1, uart_rx_op1, memory_access_block2, memory_access_block3, load_constant_block3, delay_block1]; +loop_block1.$groupContents = [memory_access_block1, conditional_block1, load_constant_block1, uart_config1, memory_access_block4, uart_tx_op1, uart_rx_op1, memory_access_block2, memory_access_block3, load_constant_block2, flow_control_block1, flow_control_block2]; /** * Connections between modules. */ scripting.connect(load_constant_block1, "output1", conditional_block1, "input2"); -scripting.connect(memory_access_block4, "output1", uart_tx_op1, "input1"); -scripting.connect(memory_access_block4, "prev", uart_config1, "next"); -scripting.connect(memory_access_block4, "next", uart_tx_op1, "prev"); -scripting.connect(load_constant_block3, "output1", memory_access_block3, "input1"); -scripting.connect(load_constant_block3, "prev", memory_access_block2, "next"); -scripting.connect(load_constant_block3, "next", memory_access_block3, "prev"); +scripting.connect(load_constant_block2, "output1", memory_access_block3, "input1"); +scripting.connect(load_constant_block2, "prev", memory_access_block2, "next"); +scripting.connect(load_constant_block2, "next", memory_access_block3, "prev"); scripting.connect(conditional_block1, "input1", memory_access_block1, "output1"); scripting.connect(conditional_block1, "T", uart_config1, "prev"); -scripting.connect(conditional_block1, "F", delay_block1, "prev"); +scripting.connect(conditional_block1, "F", flow_control_block1, "prev"); +scripting.connect(flow_control_block2, "prev", memory_access_block3, "next"); scripting.connect(uart_rx_op1, "prev", uart_tx_op1, "next"); scripting.connect(uart_rx_op1, "next", memory_access_block2, "prev"); scripting.connect(uart_rx_op1, "output1", memory_access_block2, "input1"); +scripting.connect(uart_tx_op1, "input1", memory_access_block4, "output1"); +scripting.connect(uart_tx_op1, "prev", memory_access_block4, "next"); +scripting.connect(uart_config1, "next", memory_access_block4, "prev"); /** * (x,y) coordinates for modules that are displayed in a graph. */ load_constant_block1.$position = [30,240]; -load_constant_block3.$position = [825,190]; -memory_access_block4.$position = [405,305]; +load_constant_block2.$position = [825,190]; conditional_block1.$position = [150,180]; -loop_block1.$position = [-510,-40]; +flow_control_block1.$position = [360,180]; +flow_control_block2.$position = [900,415]; +loop_block1.$position = [-565,-65]; uart_rx_op1.$position = [655,320]; uart_tx_op1.$position = [540,310]; uart_config1.$position = [300,280]; -delay_block1.$position = [385,185]; memory_access_block1.$position = [35,165]; memory_access_block2.$position = [790,355]; -memory_access_block3.$position = [905,145]; +memory_access_block3.$position = [805,430]; +memory_access_block4.$position = [405,305]; memory_variable_block1.$position = [-805,-60];