Tool/software:
Hi,
I am using R5F0-0 and PRU1 to transfer data from PRU to R5F, when I execute my test code, it works well the first time, but fails the second time, I don't know why this happen, please help me.
Here is part of my code in R5F:
/* * Copyright (C) 2023 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 <stdio.h> #include <kernel/dpl/DebugP.h> #include "ti_drivers_config.h" #include "ti_drivers_open_close.h" #include "ti_board_open_close.h" #include <kernel/dpl/SemaphoreP.h> #include <drivers/pruicss.h> #include <pru1_load_bin.h> #include <pru_ipc.h> // PRU core setting, need to be consistent with sysconfig #define PRUICSS_PRUx PRUICSS_PRU1 #define PRUxFirmware_0 PRU1Firmware_0 #define R5F_TO_PRU_EVENT 22 #define PRUICSS_PRGM_FLOW_CNTRL_OFFSET 0xFC // PRU firmware code sections #define IDLE_SECTION 0 #define INIT_SECTION 1 #define IPC_SECTION 2 #define RESET_SECTION 3 PRUICSS_Handle gPruIcss0Handle; PRU_IPC_Handle gPruIpc0Handle; SemaphoreP_Object gPruDataRecSem; int32_t samples[CONFIG_PRU_IPC0_BUFFERS][CONFIG_PRU_IPC0_BLOCKSIZE]; void PRU_IPC_Isr(void *args); int32_t PRUICSS_goToSection(PRUICSS_Handle handle, uint32_t pruCore, uint32_t sectionId, uint32_t eventNum); void print_samples(int32_t array[CONFIG_PRU_IPC0_BUFFERS][CONFIG_PRU_IPC0_BLOCKSIZE]); void pru_io_empty_example_main(void *args) { int status; Drivers_open(); status = Board_driversOpen(); DebugP_assert(SystemP_SUCCESS == status); gPruIcss0Handle = PRUICSS_open(CONFIG_PRU_ICSS0); status = PRUICSS_intcInit(gPruIcss0Handle, &icss0_intc_initdata); DebugP_assert(SystemP_SUCCESS == status); SemaphoreP_constructBinary(&gPruDataRecSem, 0); status = PRUICSS_initMemory(gPruIcss0Handle, PRUICSS_DATARAM(PRUICSS_PRUx)); DebugP_assert(status != 0); status = PRUICSS_loadFirmware(gPruIcss0Handle, PRUICSS_PRUx, PRUxFirmware_0, sizeof(PRUxFirmware_0)); DebugP_assert(SystemP_SUCCESS == status); PRU_IPC_Params pruIpcparams = { .pruicssHandle = gPruIcss0Handle, .transferCallbackFxn = &PRU_IPC_Isr, }; gPruIpc0Handle = PRU_IPC_open(CONFIG_PRU_IPC0, &pruIpcparams); DebugP_assert(gPruIpc0Handle != NULL); PRUICSS_goToSection(gPruIcss0Handle, PRUICSS_PRUx, INIT_SECTION, R5F_TO_PRU_EVENT); ClockP_usleep(1); PRUICSS_goToSection(gPruIcss0Handle, PRUICSS_PRUx, IPC_SECTION, R5F_TO_PRU_EVENT); ClockP_usleep(1); DebugP_log("Initialization completed.\r\n"); while (1) { SemaphoreP_pend(&gPruDataRecSem, SystemP_WAIT_FOREVER); DebugP_log("Hello World!\r\n"); //print_samples(samples); PRUICSS_goToSection(gPruIcss0Handle, PRUICSS_PRUx, IPC_SECTION, R5F_TO_PRU_EVENT); ClockP_usleep(1); } Board_driversClose(); Drivers_close(); } void PRU_IPC_Isr(void *args) { PRU_IPC_getData(gPruIpc0Handle, samples); SemaphoreP_post(&gPruDataRecSem); PRUICSS_clearEvent(gPruIcss0Handle, gPruIpc0Handle->attrs->sysEventNum); } /* * This function is used to indicate PRU core to go to the specified section * It writes the specified core's DRAM memory with sectionID and creates an interrupt event to PRU as signaling mechanism. */ int32_t PRUICSS_goToSection(PRUICSS_Handle handle, uint32_t pruCore, uint32_t sectionId, uint32_t eventNum) { uintptr_t baseaddr; PRUICSS_HwAttrs const *hwAttrs; int32_t retVal = SystemP_SUCCESS; if (handle != NULL) { hwAttrs = (PRUICSS_HwAttrs const *)handle->hwAttrs; if (pruCore == PRUICSS_PRU0) baseaddr = hwAttrs->pru0DramBase; else if (pruCore == PRUICSS_PRU1) baseaddr = hwAttrs->pru1DramBase; else return SystemP_FAILURE; /* TODO: decide the final memory and offset */ CSL_REG32_WR(baseaddr + PRUICSS_PRGM_FLOW_CNTRL_OFFSET, sectionId); retVal = PRUICSS_sendEvent(handle, eventNum); } else { retVal = SystemP_FAILURE; } return retVal; } void print_samples(int32_t array[CONFIG_PRU_IPC0_BUFFERS][CONFIG_PRU_IPC0_BLOCKSIZE]) { for (uint32_t channel = 0; channel < CONFIG_PRU_IPC0_BUFFERS; channel++) { DebugP_log("----- Channel: %d ----- \r\n", channel+1); for (uint32_t sample = 0; sample < CONFIG_PRU_IPC0_BLOCKSIZE; sample++) { DebugP_log("Sample %d: %d \r\n", sample+1, array[channel][sample]); } } DebugP_log("-----------------------\r\n"); }
Here is part of my code in PRU:
; Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/ ; ; 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. ;************************************************************************************ ; File: main.asm ; ; Brief: Template asm file example ;************************************************************************************ ; CCS/makefile specific settings .retain ; Required for building .out with assembly file .retainrefs ; Required for building .out with assembly file .global main .sect ".text" ;************************************* includes ************************************* ; icss_constant_defines.inc: Defines symbols corresponding to Constant Table Entries .include "icss_constant_defines.inc" .include "ti_pru_io_config.inc" .include "icss_program_flow_macros.inc" .include "pru_ipc_macros.inc" .include "time_macros.inc" .asg R2, TEMP_REG .asg 0x16, PRGM_FLOW_EVENT .asg 31, PRGM_FLOW_EVENT_BIT .asg 5, PRU_CLK_CYC_PRD_CONST ;******** ;* MAIN * ;******** main: init: ;---------------------------------------------------------------------------- ; Clear the register space ; Before begining with the application, make sure all the registers are set ; to 0. PRU has 32 - 4 byte registers: R0 to R31, with R30 and R31 being special ; registers for output and input respectively. ;---------------------------------------------------------------------------- ; Give the starting address and number of bytes to clear. zero &r0, 120 ;---------------------------------------------------------------------------- ; Constant Table Entries Configuration ;---------------------------------------------------------------------------- ; Configure the Constant Table entry C28 to point to start of shared memory ; PRU_ICSSG Shared RAM (local-C28) : 00nn_nn00h, nnnn = c28_pointer[15:0] ; By default it is set to 0000_0000h so it will point to DMEM0 address .if $defined(PRU0) ldi TEMP_REG, 0x0100 .else ldi TEMP_REG, 0x0110 .endif sbco &TEMP_REG, ICSS_PRU_CTRL_CONST, 0x28, 2 ;---------------------------------------------------------------------------- ; SECTION: IDLE ; PRU enters the program, executes intialization and then stays in this ; section until any further command from r5f ;---------------------------------------------------------------------------- IDLE: m_prgm_flow_jump_on_intr PRGM_FLOW_EVENT, PRGM_FLOW_EVENT_BIT, 4, TEMP_REG, IDLE, main_init, main_ipc, reset qba IDLE main_init: m_pru_ipc_init R0.b0, R29, CONFIG_PRU_IPC0_CONFIG_MEM_OFFSET ; initialize ipc transfer qba IDLE main_ipc: ldi R1.b0, &R2 ; R1.b0 = &R2 m_pru_ipc_send R1.b0, R2, R0.b0, R29, CONFIG_PRU_IPC0_RX_INTR_ENABLE, CONFIG_PRU_IPC0_RX_EVENT ; send DI data to shared memory using ipc ldi R30, 0x2 ldi R30, 0x0 qba IDLE ; loop to continue collect DI data halt ; end of program reset: m_pru_ipc_init R0.b0, R29, CONFIG_PRU_IPC0_CONFIG_MEM_OFFSET ; initialize ipc transfer qba IDLE
Here are the steps in my development:
1. SOC initialization
1. OSPI boot mode, power off and then power on
2. launch selected configuration
3. connect to R5F0-0, reset CPU, load firmware
4. connect to PRU1, load firmware
5. run R5F0-0, and then it always in the below process, it seems that R5F is waiting PRU1 to send data, but PRU1 is always in IDLE process, that means PRUICSS_goToSection execute failed in the second time
I don't know why this happen, please help me, thanks.
BRs
Xiangju