Skip to content

Am263x: PRU-I2S - #8

Open
rajul-bhambay wants to merge 4 commits into
mainfrom
a0497643_PINDSW-8487_PRU_I2S
Open

Am263x: PRU-I2S#8
rajul-bhambay wants to merge 4 commits into
mainfrom
a0497643_PINDSW-8487_PRU_I2S

Conversation

@rajul-bhambay

@rajul-bhambay rajul-bhambay commented Apr 17, 2025

Copy link
Copy Markdown
Collaborator

User description

  • Firmware changes
  • Application changes
  • Restructured driver apis

Fixes: PINDSW-8487


PR Type

Enhancement


Description

• Complete PRU I2S driver implementation with comprehensive API for initialization, open/close, read/write operations
• Support for both I2S and TDM4 modes with interleaved/non-interleaved data format conversion
• PRU firmware binaries and assembly code for both TX and RX operations on PRU0 and PRU1
• Interrupt handling with callback mechanisms for Tx, Rx, and error events
• Hardware abstraction layer for PRU firmware loading, ICSS INTC configuration, and GPIO setup
• Diagnostic application with FreeRTOS support for AM263X and AM261X platforms
• TCA6416 IO expander driver for hardware configuration
• Build system integration with makefiles, linker scripts, and project configurations
• Runtime Object View (ROV) configuration for debugging support


Diagram Walkthrough

flowchart LR
  A["PRU I2S Driver"] --> B["I2S Firmware"]
  A --> C["TDM4 Firmware"]
  B --> D["PRU0 TX Binary"]
  B --> E["PRU1 RX Binary"]
  C --> F["PRU0 TDM TX Binary"]
  C --> G["PRU1 TDM RX Binary"]
  A --> H["Diagnostic App"]
  H --> I["AM263X Platform"]
  H --> J["AM261X Platform"]
  H --> K["TCA6416 IO Expander"]
  A --> L["PRUSS INTC Mapping"]
  A --> M["Hardware Abstraction"]
Loading

File Walkthrough

Relevant files
Enhancement
20 files
pru_i2s_drv.c
Complete PRU I2S driver implementation with hardware abstraction

source/pru_i2s/driver/pru_i2s_drv.c

• Complete PRU I2S driver implementation with initialization,
open/close, read/write operations
• Support for both interleaved and
non-interleaved data formats with conversion functions
• Interrupt
handling for Tx, Rx, and error events with callback mechanisms

Hardware abstraction for PRU firmware loading, ICSS INTC
configuration, and GPIO setup

+2379/-0
main.c
FreeRTOS main application for AM263x PRU I2S diagnostic   

examples/pru_i2s_diagnostic/single_channel/am263x-cc/r5fss0-0_freertos/main.c

• FreeRTOS main application entry point for AM263x platform
• Task
creation and scheduler initialization for PRU I2S diagnostic example

System and board initialization with proper task stack allocation

+84/-0   
pru_i2s_drv.h
PRU I2S Driver Header Implementation                                         

source/pru_i2s/include/pru_i2s_drv.h

• Complete PRU I2S driver header file with comprehensive API
definitions
• Defines data structures for configuration, parameters,
and I/O buffers
• Includes function declarations for driver
initialization, open/close, read/write operations
• Contains
hardware-specific constants and register definitions for AM263X and
AM261X SoCs

+1053/-0
pru_i2s_diagnostic.c
PRU I2S Diagnostic Application Implementation                       

examples/pru_i2s_diagnostic/pru_i2s_diagnostic.c

• Complete diagnostic application for PRU I2S functionality testing

Implements Tx/Rx interrupt handlers with error handling and statistics
tracking
• Supports both TDM and I2S modes with configurable firmware
selection
• Includes I2C IO expander configuration for AM263X hardware
setup

+679/-0 
icss_pru_i2s_fw.h
TDM4 Firmware Register Definitions                                             

source/pru_i2s/firmware/TDM4/icss_pru_i2s_fw.h

• Firmware register definitions and bit field mappings for TDM4 mode

Defines register offsets, addresses, and bit field masks for PRU I2S
firmware
• Includes ping-pong buffer control and error status register
definitions

+197/-0 
icss_pru_i2s_fw.h
I2S Firmware Register Definitions                                               

source/pru_i2s/firmware/I2S/icss_pru_i2s_fw.h

• Firmware register definitions and bit field mappings for standard
I2S mode
• Identical structure to TDM4 version with same register
layout and definitions
• Provides firmware interface constants for I2S
protocol implementation

+197/-0 
ioexp_tca6416.c
TCA6416 IO Expander Driver Implementation                               

examples/pru_i2s_diagnostic/board/ioexp_tca6416.c

• I2C IO expander driver implementation for TCA6416 chip
• Provides
functions for opening, configuring, and controlling GPIO pins

Includes I2C transaction handling and register read/write operations

+287/-0 
pru_i2s_interface.h
New I2S firmware interface header with pin configurations

source/pru_i2s/firmware/I2S/pru_i2s_interface.h

• Added new assembly header file defining I2S interface constants and
pin configurations
• Includes conditional compilation for different
SoCs (AM263X, AM261X) and PRU instances
• Defines pin mappings, buffer
addresses, error positions, and interrupt event numbers
• Contains
configuration for both TX and RX I2S instances with different pin
assignments

+213/-0 
pru_i2s_interface.h
New TDM4 firmware interface header with TDM-specific configurations

source/pru_i2s/firmware/TDM4/pru_i2s_interface.h

• Added TDM4 variant of I2S interface header with similar structure to
I2S version
• Includes same SoC and PRU conditional compilation
support
• Defines TDM-specific constants like TDM_CHANNELS and
MAX_TDM_CHANNELS
• Contains different BYTES_TO_LOAD value (2) and
samples per channel (16) for TDM mode

+209/-0 
data.h
I2S diagnostic example data definitions and buffer configurations

examples/pru_i2s_diagnostic/data.h

• Added comprehensive data definitions for I2S diagnostic example

Defines buffer sizes, constants for audio processing, and error
handling
• Includes ping-pong buffer configurations and memory layout
definitions
• Contains pre-initialized TX buffer data with test
patterns

+99/-0   
ioexp_tca6416.h
TCA6416 IO expander driver header with complete API           

examples/pru_i2s_diagnostic/board/ioexp_tca6416.h

• Added complete TCA6416 IO expander driver header file
• Defines API
functions for opening, configuring, and controlling IO expander

Includes data structures for configuration parameters and attributes

Provides constants for input/output modes and pin states

+210/-0 
pru_i2s_tdm4_pru0_array.h
PRU0 TDM4 firmware binary array                                                   

source/pru_i2s/firmware/TDM4/pru_i2s_tdm4_pru0_array.h

• Added compiled PRU0 firmware binary array for TDM4 mode
• Contains
both instruction array (pru_prupru_i2s0_image_0_0) and data array

Provides pre-compiled firmware ready for loading into PRU0

+191/-0 
pru_i2s_pru0_array.h
PRU0 I2S firmware binary array                                                     

source/pru_i2s/firmware/I2S/pru_i2s_pru0_array.h

• Added compiled PRU0 firmware binary array for standard I2S mode

Contains instruction and data arrays for PRU0 I2S firmware
• Provides
pre-compiled firmware binary ready for deployment

+187/-0 
pru_i2s_tdm4_pru1_array.h
PRU1 TDM4 firmware binary array                                                   

source/pru_i2s/firmware/TDM4/pru_i2s_tdm4_pru1_array.h

• Added compiled PRU1 firmware binary array for TDM4 mode
• Contains
instruction array and data array for PRU1 TDM4 firmware
• Provides
pre-compiled firmware for PRU1 in TDM4 configuration

+184/-0 
pru_i2s_pru1_array.h
PRU1 I2S firmware binary array                                                     

source/pru_i2s/firmware/I2S/pru_i2s_pru1_array.h

• Added compiled PRU1 firmware binary array for standard I2S mode

Contains instruction and data arrays for PRU1 I2S firmware
• Provides
pre-compiled firmware binary for PRU1 deployment

+174/-0 
pru_i2s_regs.h
TDM4 PRU register definitions and mappings                             

source/pru_i2s/firmware/TDM4/pru_i2s_regs.h

• Added TDM4-specific register definitions and assignments
• Defines
PRU register mappings for TX/RX operations, counters, and buffers

Includes conditional compilation for different I2S modes (TX/RX)

Contains register assignments for ping-pong buffers and status
tracking

+114/-0 
pru_i2s_regs.h
I2S PRU register definitions and mappings                               

source/pru_i2s/firmware/I2S/pru_i2s_regs.h

• Added I2S-specific register definitions and assignments
• Defines
PRU register mappings similar to TDM4 but for standard I2S
• Includes
register assignments for audio data, buffers, and control
• Contains
conditional compilation for TX/RX modes and profiling

+113/-0 
main.c
AM261X I2S diagnostic main application with FreeRTOS         

examples/pru_i2s_diagnostic/single_channel/am261x-lp/r5fss0-0_freertos/main.c

• Added main application file for AM261X LaunchPad I2S diagnostic

Implements FreeRTOS-based main function with task creation
• Calls
pru_i2s_diagnostic_main function and handles task management

Includes standard system and board initialization

+84/-0   
fw_regs.asm
I2S firmware register initialization assembly                       

source/pru_i2s/firmware/I2S/fw_regs.asm

• Added firmware register initialization assembly file for I2S

Defines firmware register section with configuration values
• Includes
conditional compilation for different TX configurations
• Sets up pin
numbers, buffer addresses, and system event numbers

+113/-0 
fw_regs.asm
TDM4 firmware register initialization assembly                     

source/pru_i2s/firmware/TDM4/fw_regs.asm

• Added firmware register initialization assembly file for TDM4

Similar structure to I2S version with TDM4-specific configurations

Defines register section with buffer addresses and pin assignments

Includes conditional compilation for different modes and PRU instances

+113/-0 
Configuration changes
8 files
pru_i2s_pruss_intc_mapping.h
PRUSS interrupt controller mapping definitions and macros

source/pru_i2s/include/pru_i2s_pruss_intc_mapping.h

• PRUSS interrupt controller mapping definitions and constants

System event, channel, and host interrupt mapping macros
• INTC
initialization data structure template with proper MISRA C compliance

+200/-0 
syscfg_c.rov.xs
ROV configuration for AM261x FreeRTOS debugging                   

examples/pru_i2s_diagnostic/single_channel/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs

• Runtime Object View (ROV) configuration file for debugging support

FreeRTOS ROV integration for AM261x platform

+8/-0     
product.json
Product Metadata Configuration Update                                       

.metadata/product.json

• Added include path for sysconfig directory
• Added "/open_pru"
component to the components list

+2/-1     
pru_i2s_master_icss.cmd
I2S PRU firmware linker command file                                         

source/pru_i2s/firmware/I2S/pru_i2s_master_icss.cmd

• Added linker command file for I2S PRU firmware
• Defines memory
layout for ICSSG PRU with instruction and data memory sections

Includes peripheral memory mappings and section allocations

Configures firmware registers, output samples, and debug buffer
sections

+88/-0   
pru_i2s_master_icss.cmd
TDM4 PRU firmware linker command file                                       

source/pru_i2s/firmware/TDM4/pru_i2s_master_icss.cmd

• Added linker command file for TDM4 PRU firmware
• Identical
structure to I2S linker file with same memory layout
• Defines ICSSG
memory sections and peripheral mappings
• Configures section
allocations for TDM4 firmware variant

+88/-0   
syscfg_c.rov.xs
ROV configuration for FreeRTOS debugging                                 

examples/pru_i2s_diagnostic/single_channel/am263x-cc/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs

• Added Runtime Object View (ROV) configuration file
• Defines ROV
files for FreeRTOS debugging support
• Simple configuration file for
debugging tools integration

+8/-0     
makefile_ccs_bootimage_gen
Boot image generation makefile with security features       

examples/pru_i2s_diagnostic/single_channel/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen

• Added comprehensive makefile for boot image generation
• Defines
build targets for different image formats (appimage, MCELF, signed)

Includes multi-core image generation and XIP support
• Contains
security features like image signing and encryption

+141/-0 
makefile
Added I2S diagnostic example to build system                         

examples/makefile

• Added pru_i2s_diagnostic to the list of subdirectories to build

Simple one-line addition to include new example in build system

+1/-1     
Additional files
37 files
makefile +106/-0 
readme.md +304/-0 
example.syscfg +333/-0 
example.projectspec +114/-0 
makefile +370/-0 
makefile_projectspec +20/-0   
example.syscfg +313/-0 
example.projectspec +120/-0 
makefile +374/-0 
makefile_ccs_bootimage_gen +141/-0 
makefile_projectspec +20/-0   
example.projectspec +85/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +85/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +84/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +84/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
pru_i2s_main.asm +502/-0 
example.projectspec +85/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +85/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +84/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
example.projectspec +84/-0   
makefile +90/-0   
makefile_projectspec +20/-0   
pru_i2s_main.asm +517/-0 

@rajul-bhambay rajul-bhambay changed the title Am263x: PRU-I2S Am263x: PRU-I2S[WIP] Apr 17, 2025
@rajul-bhambay

rajul-bhambay commented Apr 17, 2025

Copy link
Copy Markdown
Collaborator Author
  • Firmware changes
  • Application changes
  • Restructured driver apis

Fixes: PINDSW-8487

Pending Items:
->Include Standard I2S firmware (currently its TDM4)
-> Testing
_> Documentation of code

@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch 2 times, most recently from 96bf0b7 to a27184b Compare April 24, 2025 05:41
@nsaulnier-ti

Copy link
Copy Markdown
Collaborator

Hey @rajul-bhambay, what is TDM4? I assume something to do with time-domain multiplexing, instead of a typo for TDA4?

@rajul-bhambay

Copy link
Copy Markdown
Collaborator Author

Hey @rajul-bhambay, what is TDM4? I assume something to do with time-domain multiplexing, instead of a typo for TDA4?

Hey @nsaulnier-ti , TDM4 (time division multiplexing 4 channels) is a mode of communication of audio signals. We have 2 modes, I2S and TDM4/TDM8 which is suppported by the TI's TAS6424Q1 coded (class-D amplifier).

@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch 2 times, most recently from 26e87e1 to 29b5691 Compare May 9, 2025 10:55
@rajul-bhambay rajul-bhambay changed the title Am263x: PRU-I2S[WIP] Am263x: PRU-I2S Jun 23, 2025
@@ -0,0 +1,186 @@
%%{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this file. Can we remove?

@@ -0,0 +1,77 @@
%%{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this file. Can we remove?

@@ -0,0 +1,52 @@
/*

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this file. Can we remove?

@@ -0,0 +1,280 @@
/*
* Copyright (C) 2021 Texas Instruments Incorporated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update copyright year in all files

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this file to board sub-folder as it is not a core example function

/* Function Definitions */
/* ========================================================================== */

int32_t TCA6416_open(TCA6416_Config *config, const TCA6416_Params *params)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this code now? Is this not supported in MCU+ SDK SysConfig under IOEXP module?

#define TEST_PRUI2S0_IDX ( 0 ) /* Test PRU I2S 0 index */
#define TEST_PRUI2S1_IDX ( 1 ) /* Test PRU I2S 1 index */

#define TDM4 ( 1 ) /* TDM4 mode (change to 0 for I2S)*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we have tested both modes. Can you confirm?

*/


void i2s_i2c_io_expander(void)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's review if this can be removed - by using SysConfig

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you review this?

/* debug, increment ISR count */
gPruI2s1RxIsrCnt++;
/* debug, drive GPIO high */
GPIO_pinWriteHigh(CONFIG_GPIO_DEBUG1_BASE_ADDR, CONFIG_GPIO_DEBUG1_PIN);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put this GPIO code under some debug macro? Else it adds unnecessary latency to ISRs

@@ -0,0 +1,200 @@
/*

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to SysConfig?

@dhavaljk

Copy link
Copy Markdown
Collaborator

Can we merge commit? Don't think we need 4

@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch 3 times, most recently from cd4d050 to 172a2d0 Compare June 26, 2025 12:02

@pratheesh-ti pratheesh-ti left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complete the documentation changes to merge

Comment thread source/pru_i2s/driver/pru_i2s_drv.c Outdated
@@ -0,0 +1,2692 @@
/*
* Copyright (C) 2021 Texas Instruments Incorporated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the copyright year

Comment thread source/pru_i2s/driver/pru_i2s_drv.c Outdated

#include <stdint.h>
#include <drivers/hw_include/cslr.h>
#include <drivers\hw_include\am263x\cslr_iomux.h>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be consistent with use of "/" vs ""

Comment thread source/pru_i2s/driver/pru_i2s_drv.c Outdated
#include <kernel/dpl/SemaphoreP.h>
#include <drivers\hw_include\am263px\cslr_intr_r5fss0_core0.h>
#include <drivers\pinmux\am263x\pinmux.h>
//#include "ti_drivers_config.h"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if not relevant

Comment thread source/pru_i2s/driver/pru_i2s_drv.c Outdated
#define PRUI2S_PRU_INTC_SYSEVT2_IDX ( 2 ) /* I2S error system event index */

/* Number INTC channels per PRU */
#define PRUI2S_PRUICSS_INTC_NUM_CHANNELS_PER_PRU \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next line is not really warranted here?

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c Outdated
pSwipAttrs->rxPin[i].pinNum = temp8b;
}

/* TBD: SoC PAD address lookup */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if not relevant anymore

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2021, Texas Instruments Incorporated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the year

@@ -0,0 +1,280 @@
/*
* Copyright (C) 2021 Texas Instruments Incorporated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this file to board sub-folder as it is not a core example function

@@ -0,0 +1,113 @@
;
; Copyright (c) 2021, Texas Instruments Incorporated
; All rights reserved.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add firmware design document in md format here under firmware/I2S/docs

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check this comment @rajul-bhambay

@a1248924 a1248924 Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rajul-bhambay should we have a seperate design document for this if its covered in the readme ?

Comment thread examples/pru_i2s/pru_i2s_app/pru_i2s_diagnostic.c
@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch from 034f165 to 52e4c10 Compare July 10, 2025 11:08
pratheesh-ti
pratheesh-ti previously approved these changes Jul 11, 2025

@pratheesh-ti pratheesh-ti left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding firmware documentation. Can do dedicated PR for this

@nsaulnier-ti

Copy link
Copy Markdown
Collaborator

@dhavaljk @manojKoppolu @rajul-bhambay let's discuss the overall structure of this project and the source folder, perhaps on Wednesday's meeting?

I am trying to understand the logic of the overall project structure (e.g., not actually including any PRU code under examples, keeping it all under source), and function of different folders (especially .meta). If we want to keep the proposed structure of "source" [1], we would need to move the files a bit:

source

  • linkers
  • macros
  • defines
  • drivers
    • pru_i2s

[1] https://confluence.itg.ti.com/display/ProcSW/OpenPRU+Repository+Structure+Proposal

@nsaulnier-ti nsaulnier-ti left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to understand the logic behind the folder structures before we merge this in. Best to discuss verbally in the team meeting.

@pratheesh-ti

Copy link
Copy Markdown
Collaborator

/review

Comment on lines +60 to +68
LDI scratchreg0, I2S_TX_BUF_PING_ADD
LBBO &tx_ping_buffer_address, scratchreg0, 0, 4
LDI scratchreg0, I2S_PING_PONG_BUFSIZE_ADD
LBBO &tx_buf_size, scratchreg0, 0, 2
ADD tx_buffer_address_end, tx_ping_buffer_address, tx_buf_size
ZERO_TX_PING_PONG:
SBBO &ch0_data_tx, tx_ping_buffer_address, 0, 4
ADD tx_ping_buffer_address, tx_ping_buffer_address, 0x4
QBGT ZERO_TX_PING_PONG, tx_ping_buffer_address, tx_buffer_address_end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. zero_tx_ping_pong loop compares wrong 📘 Rule violation ≡ Correctness

The buffer-clear loop branches using QBGT with operands ordered such that the loop can become
non-terminating and write past the intended end address when tx_ping_buffer_address exceeds
tx_buffer_address_end. This can cause runaway out-of-bounds stores into arbitrary memory.
Agent Prompt
## Issue description
`ZERO_TX_PING_PONG` uses a `QBGT` compare/operand ordering that can cause non-terminating looping after the pointer passes the computed end address, resulting in out-of-bounds `SBBO`.

## Issue Context
This loop is used to clear the TX ping/pong buffer after certain error conditions; the termination condition must stop at the buffer end.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[60-68]
- examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm[59-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_interface.h
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/include/pru_i2s_drv.h Outdated
Comment on lines +262 to +326
/* Used to check status and initialization */
static Bool gPruI2sDrvInit = FALSE;

/* Number of valid configurations */
static uint8_t gPruI2sDrvNumValidCfg = 0;

/* PRU I2S objects */
static PRUI2S_Object gPruI2sObject[PRU_I2S_MAX_NUM_INST];

/* PRU I2S SW IP attributes - Minimal configuration
* All INTC, GPIO, and pinmux now managed by SysConfig.
* Only essential base configuration remains here.
*/
/* NOTE: This array is initialized with default values.
* Applications must call PRUI2S_setUserConfig() to configure ICSS instance and PRU core
* before calling PRUI2S_init().
*/
static PRUI2S_SwipAttrs gPruI2sSwipAttrs[PRU_I2S_MAX_NUM_INST] =
{
/* Configuration 0 - Set by PRUI2S_setUserConfig() */
{
.baseAddr = 0, /* Set by PRUI2S_setUserConfig() based on ICSS instance */
.icssInstId = 0, /* Set by PRUI2S_setUserConfig() */
.pruInstId = PRUICSS_PRU0, /* Set by PRUI2S_setUserConfig() */
.numTxI2s = 0, /* Detected from firmware at runtime */
.numRxI2s = 0, /* Detected from firmware at runtime */
.sampFreq = 0, /* Detected from firmware at runtime */
.bitsPerSlot = 0, /* Detected from firmware at runtime */
.i2sTxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sRxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sErrHostIntNum = 0, /* Detected from firmware at runtime */
.i2sTxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sRxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sErrIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
},
/* Configuration 1 - Set by PRUI2S_setUserConfig() */
{
.baseAddr = 0, /* Set by PRUI2S_setUserConfig() based on ICSS instance */
.icssInstId = 0, /* Set by PRUI2S_setUserConfig() */
.pruInstId = PRUICSS_PRU1, /* Set by PRUI2S_setUserConfig() */
.numTxI2s = 0, /* Detected from firmware at runtime */
.numRxI2s = 0, /* Detected from firmware at runtime */
.sampFreq = 0, /* Detected from firmware at runtime */
.bitsPerSlot = 0, /* Detected from firmware at runtime */
.i2sTxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sRxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sErrHostIntNum = 0, /* Detected from firmware at runtime */
.i2sTxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sRxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sErrIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
}
};

/* PRU I2S configurations */
static PRUI2S_Config gPruI2sConfig[PRU_I2S_NUM_CONFIG] =
{
{
&gPruI2sObject[0],
&gPruI2sSwipAttrs[0]
},
{
&gPruI2sObject[1],
&gPruI2sSwipAttrs[1]
}
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

7. Globals defined in header 🐞 Bug ⚙ Maintainability

pru_i2s_drv.h defines mutable driver globals (objects/config/state) as static variables in the
header, so every translation unit that includes it allocates its own private copy. This wastes
memory and makes driver state management error-prone (the app will have a separate unused copy from
the driver implementation).
Agent Prompt
### Issue description
The public header `pru_i2s_drv.h` defines mutable driver state as `static` globals. Every `.c` file including this header gets its own private copy, causing memory bloat and making the driver architecture fragile.

### Issue Context
Driver state should live in a single compilation unit (typically `pru_i2s_drv.c`) with `extern` declarations (or accessor APIs) exposed via the header.

### Fix Focus Areas
- examples/pru_i2s/include/pru_i2s_drv.h[262-326]
- examples/pru_i2s/driver/pru_i2s_drv.c[1-200]

### What to change
- In `pru_i2s_drv.h`: remove the `static` definitions of driver globals/config tables; keep only type definitions and function prototypes.
- In `pru_i2s_drv.c`: add the actual definitions for these globals.
- If any of these need to be visible to other modules, declare them as `extern` in the header (preferably avoid exposing internals; provide getter APIs instead).
- Ensure only one definition exists across the build (no per-TU copies).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch from 8ab787e to d9175ef Compare April 28, 2026 09:27
@qodo-code-review

qodo-code-review Bot commented Apr 28, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit d9175ef

Comment thread examples/pru_i2s/pru_i2s_app/pru_i2s_diagnostic.c
Comment on lines +42 to +73
main:
.if $isdefed("I2S_TX")
;err_stat = err_stat >> 1. Remove the Rx Overflow error bit.
LSR err_stat, err_stat, 1
;If there was an underflow/FrameSync Error, clearup thr Tx PingPong Buffer space
;err_stat is already initialized during normal operation.
; FS_ERROR UNDERFLOW_ERROR
; 0 0 No Error
; 0 1 Under Flow error
; 1 0 FS Error
; 1 1 Both errors
QBEQ CONTIUNE_INIT, err_stat, 0
;If set, this means underflow has happened.
;Below Initializations can be avoided but after power on, registers
;may contain random addresses and may result in accessing illegal addresses.
LDI ch0_data_tx, 0x0
LDI scratchreg0, 0x0
LDI tx_buf_size, 0x0
LDI scratchreg0, I2S_TX_BUF_PING_ADD
LBBO &tx_ping_buffer_address, scratchreg0, 0, 4
LDI scratchreg0, I2S_PING_PONG_BUFSIZE_ADD
LBBO &tx_buf_size, scratchreg0, 0, 2
ADD tx_buffer_address_end, tx_ping_buffer_address, tx_buf_size
ZERO_TX_PING_PONG:
SBBO &ch0_data_tx, tx_ping_buffer_address, 0, 4
ADD tx_ping_buffer_address, tx_ping_buffer_address, 0x4
QBGT ZERO_TX_PING_PONG, tx_ping_buffer_address, tx_buffer_address_end
.endif

CONTIUNE_INIT:
;Clear registers R0-R29. 4*30=120 bytes
ZERO &r0, 128

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. err_stat used before zero 📘 Rule violation ≡ Correctness

The firmware uses err_stat immediately on entry (shift/branch logic) before clearing/initializing
registers, which can make startup behavior nondeterministic. This violates the requirement to
clear/initialize registers at startup.
Agent Prompt
## Issue description
`err_stat` is read/modified before the firmware clears registers, so its value at cold start is undefined.

## Issue Context
Startup determinism is required; register zeroing should occur before any logic that depends on register contents.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[42-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +65 to +74
.if $isdefed("PRU0")
.word 0x10000 ; TX_PING_PONG_BUF_ADDR
.else
.word 0x10200 ; TX_PING_PONG_BUF_ADDR
.endif
.if $isdefed("NUMBER_OF_TX_3")
.short 264 ; PING_PONG_BUF_SZ
.else
.short 256 ; PING_PONG_BUF_SZ
.endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Hardcoded buffer addresses in fw_regs.asm 📘 Rule violation ⚙ Maintainability

fw_regs.asm encodes buffer addresses and sizes as numeric literals (e.g., 0x10000, 256, 264)
rather than named constants, reducing maintainability and increasing risk of boundary mistakes. This
violates the no-magic boundary numbers requirement.
Agent Prompt
## Issue description
`fw_regs.asm` uses numeric literals for buffer base addresses and sizes, making it hard to audit/change safely.

## Issue Context
Define these as named constants/macros (or include them from a single header) and use the names in `.word`/`.short` emissions.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/fw_regs.asm[65-74]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_regs.h
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread .metadata/product.json
@qodo-code-review

qodo-code-review Bot commented Apr 29, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit 248af3d

Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_main.asm
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment on lines +35 to +41
.sect ".text:main"
.clink
.global main

.include "pru_i2s_interface.h"
.include "pru_i2s_regs.h"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Tabs in pru assembly 📘 Rule violation ⚙ Maintainability

The added PRU assembly uses tab characters for indentation/alignment instead of the required
whitespace rules. This can create inconsistent formatting across environments and violates the
indentation/whitespace standard.
Agent Prompt
## Issue description
PRU assembly uses tab characters for indentation/alignment.

## Issue Context
Compliance requires 4-space indentation and disallows tabs in assembly sources.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[35-41]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_main.asm
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
@rajul-bhambay
rajul-bhambay force-pushed the a0497643_PINDSW-8487_PRU_I2S branch from 248af3d to 2dd5549 Compare April 29, 2026 07:13
@qodo-code-review

qodo-code-review Bot commented May 4, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit ca2034c

Comment on lines +45 to +71
LSR err_stat, err_stat, 1
;If there was an underflow/FrameSync Error, clearup thr Tx PingPong Buffer space
;err_stat is already initialized during normal operation.
; FS_ERROR UNDERFLOW_ERROR
; 0 0 No Error
; 0 1 Under Flow error
; 1 0 FS Error
; 1 1 Both errors
QBEQ CONTIUNE_INIT, err_stat, 0
;If set, this means underflow has happened.
;Below Initializations can be avoided but after power on, registers
;may contain random addresses and may result in accessing illegal addresses.
LDI ch0_data_tx, 0x0
LDI scratchreg0, 0x0
LDI tx_buf_size, 0x0
LDI scratchreg0, I2S_TX_BUF_PING_ADD
LBBO &tx_ping_buffer_address, scratchreg0, 0, 4
LDI scratchreg0, I2S_PING_PONG_BUFSIZE_ADD
LBBO &tx_buf_size, scratchreg0, 0, 2
ADD tx_buffer_address_end, tx_ping_buffer_address, tx_buf_size
ZERO_TX_PING_PONG:
SBBO &ch0_data_tx, tx_ping_buffer_address, 0, 4
ADD tx_ping_buffer_address, tx_ping_buffer_address, 0x4
QBGT ZERO_TX_PING_PONG, tx_ping_buffer_address, tx_buffer_address_end
.endif

CONTIUNE_INIT:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Uppercase opcodes in pru_i2s_main.asm 📘 Rule violation ⚙ Maintainability

PRU assembly instruction mnemonics are written in uppercase (for example LSR, LDI, LBBO,
ADD) in the newly added firmware. This violates the required opcode casing convention and reduces
consistency/readability.
Agent Prompt
## Issue description
New PRU assembly uses uppercase instruction mnemonics, violating the required lowercase opcode convention.

## Issue Context
Maintaining consistent opcode casing improves readability and reduces review friction across firmware sources.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[45-71]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread examples/pru_i2s/include/pru_i2s_drv.h Outdated
Comment on lines +262 to +326
/* Used to check status and initialization */
static Bool gPruI2sDrvInit = FALSE;

/* Number of valid configurations */
static uint8_t gPruI2sDrvNumValidCfg = 0;

/* PRU I2S objects */
static PRUI2S_Object gPruI2sObject[PRU_I2S_MAX_NUM_INST];

/* PRU I2S SW IP attributes - Minimal configuration
* All INTC, GPIO, and pinmux now managed by SysConfig.
* Only essential base configuration remains here.
*/
/* NOTE: This array is initialized with default values.
* Applications must call PRUI2S_setUserConfig() to configure ICSS instance and PRU core
* before calling PRUI2S_init().
*/
static PRUI2S_SwipAttrs gPruI2sSwipAttrs[PRU_I2S_MAX_NUM_INST] =
{
/* Configuration 0 - Set by PRUI2S_setUserConfig() */
{
.baseAddr = 0, /* Set by PRUI2S_setUserConfig() based on ICSS instance */
.icssInstId = 0, /* Set by PRUI2S_setUserConfig() */
.pruInstId = PRUICSS_PRU0, /* Set by PRUI2S_setUserConfig() */
.numTxI2s = 0, /* Detected from firmware at runtime */
.numRxI2s = 0, /* Detected from firmware at runtime */
.sampFreq = 0, /* Detected from firmware at runtime */
.bitsPerSlot = 0, /* Detected from firmware at runtime */
.i2sTxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sRxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sErrHostIntNum = 0, /* Detected from firmware at runtime */
.i2sTxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sRxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sErrIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
},
/* Configuration 1 - Set by PRUI2S_setUserConfig() */
{
.baseAddr = 0, /* Set by PRUI2S_setUserConfig() based on ICSS instance */
.icssInstId = 0, /* Set by PRUI2S_setUserConfig() */
.pruInstId = PRUICSS_PRU1, /* Set by PRUI2S_setUserConfig() */
.numTxI2s = 0, /* Detected from firmware at runtime */
.numRxI2s = 0, /* Detected from firmware at runtime */
.sampFreq = 0, /* Detected from firmware at runtime */
.bitsPerSlot = 0, /* Detected from firmware at runtime */
.i2sTxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sRxHostIntNum = 0, /* Detected from firmware at runtime */
.i2sErrHostIntNum = 0, /* Detected from firmware at runtime */
.i2sTxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sRxIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
.i2sErrIcssIntcSysEvt = 0, /* Detected from firmware at runtime */
}
};

/* PRU I2S configurations */
static PRUI2S_Config gPruI2sConfig[PRU_I2S_NUM_CONFIG] =
{
{
&gPruI2sObject[0],
&gPruI2sSwipAttrs[0]
},
{
&gPruI2sObject[1],
&gPruI2sSwipAttrs[1]
}
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Static globals in header 🐞 Bug ⚙ Maintainability

examples/pru_i2s/include/pru_i2s_drv.h defines driver state (gPruI2sDrvInit, gPruI2sObject,
gPruI2sConfig, etc.) as static, so every .c including this header allocates its own private
copy. This bloats RAM/flash and can cause state divergence or confusion as the project grows (and is
already included by multiple translation units in this PR).
Agent Prompt
### Issue description
`pru_i2s_drv.h` contains `static` definitions for driver global state. Because the header is included by multiple `.c` files, each translation unit gets its own copy, wasting memory and risking future state divergence.

### Issue Context
This driver is used by the diagnostic app and app-config code, both of which include `pru_i2s_drv.h`.

### Fix Focus Areas
- Move all driver state/storage definitions (init flags, config tables, objects, debug buffers) from the header into the implementation file and keep them `static` there.
- In the header, keep only type definitions, function prototypes, and (if absolutely required) `extern` declarations.

### Fix Focus Areas (code locations)
- examples/pru_i2s/include/pru_i2s_drv.h[262-326]
- examples/pru_i2s/driver/pru_i2s_drv.c[1-120]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
@qodo-code-review

qodo-code-review Bot commented May 4, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit b92802e

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_interface.h
Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_main.asm
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
- TDM functionality
- I2S functionality

Fixes: PINDSW-8487,9295

Signed-off-by: Rajul Bhambay <r-bhambay@ti.com>
- Build fix

Fixes: PINDSW-8487,9295

Signed-off-by: Rajul Bhambay <r-bhambay@ti.com>
- Build fix

Fixes: PINDSW-8487,9295

Signed-off-by: Rajul Bhambay <r-bhambay@ti.com>
@qodo-code-review

qodo-code-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Add PRU-based I2S and TDM4 audio support for AM26x

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Adds deterministic PRU firmware for I2S stereo and TDM4 audio streaming.
• Introduces an interrupt-driven R5F driver and diagnostic application with ping-pong buffering.
• Supports AM261x and AM263x through SysConfig, makefiles, CCS projects, and documentation.
Diagram

sequenceDiagram
    participant Codec as Audio Codec
    participant PRU1 as PRU1 RX
    participant RXBuf as RX Buffers
    participant App as R5F App
    participant TXBuf as TX Buffers
    participant PRU0 as PRU0 TX
    Codec->>PRU1: BCLK FSYNC data
    PRU1->>RXBuf: Fill active half
    PRU1-->>App: RX completion IRQ
    App->>RXBuf: Drain samples
    App->>TXBuf: Queue samples
    App-->>PRU0: Mark half ready
    PRU0->>TXBuf: Consume samples
    PRU0->>Codec: I2S or TDM data
    PRU0-->>App: TX completion IRQ
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Share protocol-neutral firmware components
  • ➕ Reduces duplicated register maps, linker scripts, pin definitions, and buffer logic.
  • ➕ Prevents the I2S and TDM implementations from drifting independently.
  • ➖ Additional assembly indirection may complicate cycle-count analysis.
  • ➖ Protocol-specific timing paths still require compile-time specialization.
2. Generate the build matrix
  • ➕ Eliminates repeated makefiles and CCS project specifications.
  • ➕ Makes adding devices, modes, or PRU roles less error-prone.
  • ➖ Introduces another generator that must integrate with TI tooling.
  • ➖ Generated CCS artifacts may be harder for users to customize directly.

Recommendation: Keep separately compiled, protocol-specific firmware paths because deterministic cycle timing is the primary constraint. However, extract the identical firmware ABI definitions and generate the repetitive device/protocol/project build matrix to reduce maintenance risk without changing runtime behavior.

Files changed (82) +13350 / -2

Enhancement (18) +7173 / -0
pru_i2s_drv.cImplement the PRU I2S host driver +2000/-0

Implement the PRU I2S host driver

• Implements configuration, lifecycle, firmware-register access, ping-pong transfers, channel conversion, interrupt control, and error handling for two PRU instances.

examples/pru_i2s/driver/pru_i2s_drv.c

fw_regs.asmDefine the I2S firmware-host register block +108/-0

Define the I2S firmware-host register block

• Emits build-time capabilities, buffer addresses, interrupt events, pin identifiers, buffer state, and error status into PRU DMEM.

examples/pru_i2s/firmware/I2S/fw_regs.asm

icss_pru_i2s_fw.hExpose the I2S firmware register ABI +197/-0

Expose the I2S firmware register ABI

• Defines host-visible firmware register offsets, addresses, masks, and ping-pong state values.

examples/pru_i2s/firmware/I2S/icss_pru_i2s_fw.h

pru_i2s_interface.hConfigure I2S pins, buffers, and events +213/-0

Configure I2S pins, buffers, and events

• Defines device- and core-specific pins, sample framing, firmware register addresses, and host interrupt events.

examples/pru_i2s/firmware/I2S/pru_i2s_interface.h

pru_i2s_main.asmImplement real-time I2S TX and RX firmware +502/-0

Implement real-time I2S TX and RX firmware

• Implements BCLK/FSYNC synchronization, serial sample transfer, ping-pong switching, host notifications, and framing, overflow, and underflow detection.

examples/pru_i2s/firmware/I2S/pru_i2s_main.asm

pru_i2s_regs.hAllocate I2S firmware registers +113/-0

Allocate I2S firmware registers

• Maps I2S transmit, receive, framing, buffer, and error state onto PRU registers.

examples/pru_i2s/firmware/I2S/pru_i2s_regs.h

fw_regs.asmDefine the TDM4 firmware-host register block +108/-0

Define the TDM4 firmware-host register block

• Emits TDM firmware capabilities and runtime buffer, interrupt, pin, and error state into PRU DMEM.

examples/pru_i2s/firmware/TDM4/fw_regs.asm

icss_pru_i2s_fw.hExpose the TDM4 firmware register ABI +197/-0

Expose the TDM4 firmware register ABI

• Defines the register offsets and bit fields shared by the TDM firmware and host driver.

examples/pru_i2s/firmware/TDM4/icss_pru_i2s_fw.h

pru_i2s_interface.hConfigure TDM4 pins, slots, and events +209/-0

Configure TDM4 pins, slots, and events

• Defines device pins, 16-bit slot timing, TDM channel counts, buffer addresses, and interrupt events.

examples/pru_i2s/firmware/TDM4/pru_i2s_interface.h

pru_i2s_main.asmImplement real-time TDM4 TX and RX firmware +517/-0

Implement real-time TDM4 TX and RX firmware

• Implements multi-slot serial transfer, channel progression, frame checks, ping-pong management, and host notifications.

examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm

pru_i2s_regs.hAllocate TDM4 firmware registers +114/-0

Allocate TDM4 firmware registers

• Maps TDM channel, sample, buffer, and error state onto PRU registers.

examples/pru_i2s/firmware/TDM4/pru_i2s_regs.h

pru_i2s_drv.hPublish the PRU I2S driver API +710/-0

Publish the PRU I2S driver API

• Declares driver objects, parameters, buffers, status codes, lifecycle APIs, transfer APIs, and interrupt controls.

examples/pru_i2s/include/pru_i2s_drv.h

main.cAdd the AM261x FreeRTOS entry point +84/-0

Add the AM261x FreeRTOS entry point

• Creates a static high-priority task that runs the shared PRU I2S diagnostic application.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/main.c

main.cAdd the AM263x FreeRTOS entry point +84/-0

Add the AM263x FreeRTOS entry point

• Creates a static high-priority task that runs the shared PRU I2S diagnostic application.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/main.c

ioexp_tca6416.cImplement AM263x audio signal routing +281/-0

Implement AM263x audio signal routing

• Adds mutex-protected I2C access for configuring TCA6416 direction and output registers used by board mux routing.

examples/pru_i2s/pru_i2s_app/board/ioexp_tca6416.c

ioexp_tca6416.hDeclare the TCA6416 board API +210/-0

Declare the TCA6416 board API

• Defines IO-expander configuration, attributes, modes, states, and public operations.

examples/pru_i2s/pru_i2s_app/board/ioexp_tca6416.h

data.hDefine diagnostic audio buffers and test data +99/-0

Define diagnostic audio buffers and test data

• Allocates RX/TX storage, ping-pong buffers, transfer sizing, timeout limits, and deterministic transmit patterns.

examples/pru_i2s/pru_i2s_app/data.h

pru_i2s_diagnostic.cAdd the interrupt-driven audio diagnostic application +1427/-0

Add the interrupt-driven audio diagnostic application

• Initializes PRU-ICSS, loads firmware, opens TX/RX instances, streams in full- or half-duplex modes, handles ISR semaphores and errors, and reports statistics.

examples/pru_i2s/pru_i2s_app/pru_i2s_diagnostic.c

Documentation (12) +488 / -0
README.mdDocument PRU I2S and TDM4 operation +488/-0

Document PRU I2S and TDM4 operation

• Documents supported boards, wiring, builds, architecture, firmware ABI, testing procedures, and performance characteristics.

examples/pru_i2s/README.md

block_diagram_am261x.jpgAdd the AM261x hardware block diagram +0/-0

Add the AM261x hardware block diagram

• Provides a visual reference for the AM261x audio test setup.

examples/pru_i2s/images/block_diagram_am261x.jpg

block_diagram_am263x.pngAdd the AM263x hardware block diagram +0/-0

Add the AM263x hardware block diagram

• Provides a visual reference for the AM263x audio test setup.

examples/pru_i2s/images/block_diagram_am263x.png

firmware_flow_rx.jpgIllustrate the RX firmware flow +0/-0

Illustrate the RX firmware flow

• Documents the PRU receive synchronization and buffer-processing workflow.

examples/pru_i2s/images/firmware_flow_rx.jpg

firmware_flow_tx.jpgIllustrate the TX firmware flow +0/-0

Illustrate the TX firmware flow

• Documents the PRU transmit synchronization and buffer-processing workflow.

examples/pru_i2s/images/firmware_flow_tx.jpg

pcm1.pngDocument PCM6260 ASI configuration +0/-0

Document PCM6260 ASI configuration

• Adds a setup image for selecting the PCM6260 external audio interface mode.

examples/pru_i2s/images/pcm1.png

pcm2.pngDocument PCM6260 jumper connections +0/-0

Document PCM6260 jumper connections

• Adds a hardware image identifying the PCM6260 audio and clock connections.

examples/pru_i2s/images/pcm2.png

pcm_channel_config.pngShow the PCM channel configuration +0/-0

Show the PCM channel configuration

• Adds a codec-tool screenshot for configuring receive channels.

examples/pru_i2s/images/pcm_channel_config.png

pcm_clock_signals.pngShow the PCM clock configuration +0/-0

Show the PCM clock configuration

• Adds a codec-tool screenshot for configuring audio clock signals.

examples/pru_i2s/images/pcm_clock_signals.png

pru_i2s_rx_arch.pngIllustrate the PRU I2S RX architecture +0/-0

Illustrate the PRU I2S RX architecture

• Visualizes the receive-side components and data path.

examples/pru_i2s/images/pru_i2s_rx_arch.png

pru_i2s_tx_arch.pngIllustrate the PRU I2S TX architecture +0/-0

Illustrate the PRU I2S TX architecture

• Visualizes the transmit-side components and data path.

examples/pru_i2s/images/pru_i2s_tx_arch.png

rx_buffer_capture.pngAdd an RX waveform verification example +0/-0

Add an RX waveform verification example

• Shows a captured receive buffer plotted for functional verification.

examples/pru_i2s/images/rx_buffer_capture.png

Other (52) +5689 / -2
product.jsonRegister the Open PRU product component +1/-1

Register the Open PRU product component

• Adds the Open PRU component identifier to product metadata for tooling discovery.

.metadata/product.json

makefileInclude PRU I2S in example builds +1/-1

Include PRU I2S in example builds

• Adds the new PRU I2S example to the repository-wide example build list.

examples/makefile

linker.cmdAdd the I2S PRU memory layout +88/-0

Add the I2S PRU memory layout

• Maps firmware code, register data, samples, and debug data into PRU instruction, data, and shared memory.

examples/pru_i2s/firmware/I2S/linker.cmd

example.projectspecAdd the AM261x I2S TX CCS project +86/-0

Add the AM261x I2S TX CCS project

• Configures a PRU0 I2S transmit firmware project and generated embedded image for AM261x.

examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/example.projectspec

makefileBuild AM261x PRU0 I2S TX firmware +91/-0

Build AM261x PRU0 I2S TX firmware

• Compiles the I2S TX assembly and exports its instruction and data images as a C header.

examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM261x I2S TX CCS project +20/-0

Automate the AM261x I2S TX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM263x I2S TX CCS project +86/-0

Add the AM263x I2S TX CCS project

• Configures a PRU0 I2S transmit firmware project and generated embedded image for AM263x.

examples/pru_i2s/firmware/I2S/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/example.projectspec

makefileBuild AM263x PRU0 I2S TX firmware +90/-0

Build AM263x PRU0 I2S TX firmware

• Compiles the I2S TX assembly and exports its instruction and data images as a C header.

examples/pru_i2s/firmware/I2S/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM263x I2S TX CCS project +20/-0

Automate the AM263x I2S TX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/I2S/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM261x I2S RX CCS project +85/-0

Add the AM261x I2S RX CCS project

• Configures a PRU1 I2S receive firmware project with overflow detection for AM261x.

examples/pru_i2s/firmware/I2S/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/example.projectspec

makefileBuild AM261x PRU1 I2S RX firmware +90/-0

Build AM261x PRU1 I2S RX firmware

• Compiles the I2S RX assembly and exports its embedded firmware arrays.

examples/pru_i2s/firmware/I2S/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM261x I2S RX CCS project +20/-0

Automate the AM261x I2S RX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/I2S/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM263x I2S RX CCS project +85/-0

Add the AM263x I2S RX CCS project

• Configures a PRU1 I2S receive firmware project with overflow detection for AM263x.

examples/pru_i2s/firmware/I2S/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/example.projectspec

makefileBuild AM263x PRU1 I2S RX firmware +90/-0

Build AM263x PRU1 I2S RX firmware

• Compiles the I2S RX assembly and exports its embedded firmware arrays.

examples/pru_i2s/firmware/I2S/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM263x I2S RX CCS project +20/-0

Automate the AM263x I2S RX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/I2S/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile_projectspec

pru_i2s_pru0_array.hEmbed the compiled PRU0 I2S image +155/-0

Embed the compiled PRU0 I2S image

• Adds generated PRU0 instruction and DMEM arrays for host-side firmware loading.

examples/pru_i2s/firmware/I2S/pru_i2s_pru0_array.h

pru_i2s_pru1_array.hEmbed the compiled PRU1 I2S image +142/-0

Embed the compiled PRU1 I2S image

• Adds generated PRU1 instruction and DMEM arrays for host-side firmware loading.

examples/pru_i2s/firmware/I2S/pru_i2s_pru1_array.h

linker.cmdAdd the TDM4 PRU memory layout +88/-0

Add the TDM4 PRU memory layout

• Maps TDM firmware code, register data, samples, and debug data into PRU memories.

examples/pru_i2s/firmware/TDM4/linker.cmd

example.projectspecAdd the AM261x TDM4 TX CCS project +86/-0

Add the AM261x TDM4 TX CCS project

• Configures the PRU0 TDM transmit firmware and image-generation steps for AM261x.

examples/pru_i2s/firmware/TDM4/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/example.projectspec

makefileBuild AM261x PRU0 TDM4 TX firmware +90/-0

Build AM261x PRU0 TDM4 TX firmware

• Compiles TDM transmit firmware and generates the host-embedded image header.

examples/pru_i2s/firmware/TDM4/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM261x TDM4 TX CCS project +20/-0

Automate the AM261x TDM4 TX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/TDM4/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM263x TDM4 TX CCS project +86/-0

Add the AM263x TDM4 TX CCS project

• Configures the PRU0 TDM transmit firmware and image-generation steps for AM263x.

examples/pru_i2s/firmware/TDM4/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/example.projectspec

makefileBuild AM263x PRU0 TDM4 TX firmware +90/-0

Build AM263x PRU0 TDM4 TX firmware

• Compiles TDM transmit firmware and generates the host-embedded image header.

examples/pru_i2s/firmware/TDM4/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM263x TDM4 TX CCS project +20/-0

Automate the AM263x TDM4 TX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/TDM4/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM261x TDM4 RX CCS project +85/-0

Add the AM261x TDM4 RX CCS project

• Configures the PRU1 TDM receive firmware and overflow detection for AM261x.

examples/pru_i2s/firmware/TDM4/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/example.projectspec

makefileBuild AM261x PRU1 TDM4 RX firmware +90/-0

Build AM261x PRU1 TDM4 RX firmware

• Compiles TDM receive firmware and generates the host-embedded image header.

examples/pru_i2s/firmware/TDM4/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM261x TDM4 RX CCS project +20/-0

Automate the AM261x TDM4 RX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/TDM4/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile_projectspec

example.projectspecAdd the AM263x TDM4 RX CCS project +85/-0

Add the AM263x TDM4 RX CCS project

• Configures the PRU1 TDM receive firmware and overflow detection for AM263x.

examples/pru_i2s/firmware/TDM4/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/example.projectspec

makefileBuild AM263x PRU1 TDM4 RX firmware +90/-0

Build AM263x PRU1 TDM4 RX firmware

• Compiles TDM receive firmware and generates the host-embedded image header.

examples/pru_i2s/firmware/TDM4/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile

makefile_projectspecAutomate the AM263x TDM4 RX CCS project +20/-0

Automate the AM263x TDM4 RX CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/firmware/TDM4/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile_projectspec

pru_i2s_tdm4_pru0_array.hEmbed the compiled PRU0 TDM4 image +159/-0

Embed the compiled PRU0 TDM4 image

• Adds generated PRU0 TDM instruction and DMEM arrays for host loading.

examples/pru_i2s/firmware/TDM4/pru_i2s_tdm4_pru0_array.h

pru_i2s_tdm4_pru1_array.hEmbed the compiled PRU1 TDM4 image +152/-0

Embed the compiled PRU1 TDM4 image

• Adds generated PRU1 TDM instruction and DMEM arrays for host loading.

examples/pru_i2s/firmware/TDM4/pru_i2s_tdm4_pru1_array.h

pru_i2s_config.hDefine portable PRU I2S user configurations +177/-0

Define portable PRU I2S user configurations

• Provides AM261x and AM263x ICSS/core presets and the user configuration structure applied before driver initialization.

examples/pru_i2s/include/pru_i2s_config.h

makefileOrchestrate firmware, library, and application builds +186/-0

Orchestrate firmware, library, and application builds

• Builds I2S and TDM firmware, host libraries, and R5F applications for AM261x and AM263x.

examples/pru_i2s/makefile

example.syscfgConfigure AM261x PRU I2S hardware +359/-0

Configure AM261x PRU I2S hardware

• Defines ICSSM1 pins, six INTC mappings, I2C resources, MPU regions, and dedicated audio buffer sections.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/example.syscfg

example.projectspecAdd the AM261x R5F CCS project +123/-0

Add the AM261x R5F CCS project

• Defines compiler, SysConfig, library, firmware, and boot-image integration for the AM261x diagnostic application.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/example.projectspec

makefileBuild the AM261x R5F application +350/-0

Build the AM261x R5F application

• Generates SysConfig sources, links the PRU I2S library, emits boot images, and supports cleanup and coverage.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile

makefile_ccs_bootimage_genGenerate AM261x CCS boot images +141/-0

Generate AM261x CCS boot images

• Creates RPRC, appimage, multicore ELF, XIP, signed, and encrypted artifacts as applicable.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen

makefile_projectspecAutomate the AM261x R5F CCS project +20/-0

Automate the AM261x R5F CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec

syscfg_c.rov.xsEnable AM261x FreeRTOS object viewing +8/-0

Enable AM261x FreeRTOS object viewing

• Registers the FreeRTOS Runtime Object View script for CCS diagnostics.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs

example.syscfgConfigure AM263x PRU I2S hardware +372/-0

Configure AM263x PRU I2S hardware

• Defines ICSSM0 pins, six INTC mappings, I2C routing, MPU regions, and dedicated audio buffer sections.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/example.syscfg

example.projectspecAdd the AM263x R5F CCS project +127/-0

Add the AM263x R5F CCS project

• Defines compiler, SysConfig, board support, library, firmware, and boot-image integration for AM263x.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/example.projectspec

makefileBuild the AM263x R5F application +352/-0

Build the AM263x R5F application

• Generates SysConfig sources, includes IO-expander support, links the driver library, and creates boot images.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/makefile

makefile_ccs_bootimage_genGenerate AM263x CCS boot images +141/-0

Generate AM263x CCS boot images

• Creates RPRC, appimage, multicore ELF, XIP, signed, and encrypted artifacts as applicable.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/makefile_ccs_bootimage_gen

makefile_projectspecAutomate the AM263x R5F CCS project +20/-0

Automate the AM263x R5F CCS project

• Adds CCS project creation, build, and clean commands.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/makefile_projectspec

syscfg_c.rov.xsEnable AM263x FreeRTOS object viewing +8/-0

Enable AM263x FreeRTOS object viewing

• Registers the FreeRTOS Runtime Object View script for CCS diagnostics.

examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/syscfg_c.rov.xs

pru_i2s_app_config.cApply board-specific PRU instance mappings +110/-0

Apply board-specific PRU instance mappings

• Maps the two driver configurations to device-specific ICSS and PRU cores before initialization.

examples/pru_i2s/pru_i2s_app/pru_i2s_app_config.c

pru_i2s_app_config.hConfigure diagnostic mode and instances +94/-0

Configure diagnostic mode and instances

• Selects TDM mode by default and defines TX/RX enable flags and driver indices.

examples/pru_i2s/pru_i2s_app/pru_i2s_app_config.h

pru_i2s.syscfg.jsAdd the PRU I2S SysConfig module +318/-0

Add the PRU I2S SysConfig module

• Exposes device, core, protocol, channel, sample, interrupt, and clock settings with configuration validation.

source/.meta/pru_i2s/pru_i2s.syscfg.js

pru_i2s_config.c.xdtGenerate legacy PRU I2S attributes +114/-0

Generate legacy PRU I2S attributes

• Adds a template for emitting firmware-detected driver configuration from selected PRUICSS instances.

source/.meta/pru_i2s/pru_i2s_config.c.xdt

pru_i2s_templates.c.xdtGenerate compile-time PRU I2S attributes +178/-0

Generate compile-time PRU I2S attributes

• Emits immutable per-instance protocol, channel, interrupt, clock, and PRU selection data from SysConfig.

source/.meta/pru_i2s/pru_i2s_templates.c.xdt

pru_i2s_templates.h.xdtGenerate PRU I2S instance declarations +140/-0

Generate PRU I2S instance declarations

• Emits instance indices, PRU identifiers, counts, and attribute declarations for application use.

source/.meta/pru_i2s/pru_i2s_templates.h.xdt

@qodo-code-review

qodo-code-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (11) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Firmware copy failures ignored 🐞 Bug ☼ Reliability ⭐ New
Description
The post-build recipe suppresses failure of the command that publishes the newly generated firmware
array, so a successful build can leave the application using a stale or missing embedded firmware
header. The parent build subsequently proceeds without detecting that the firmware source compiled
into the diagnostic application was not updated.
Code

examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile[87]

+		-$(CAT) ${OPEN_PRU_PATH}/source/firmware/pru_load_bin_copyright.h pru_i2s_pru0_array.h > ${OPEN_PRU_PATH}/examples/pru_i2s/firmware/I2S/pru_i2s_pru0_array.h
Evidence
The leading - on the publication command explicitly tells Make to ignore a nonzero exit status.
The parent makefile builds these firmware directories before RTOS code, and the diagnostic
application directly includes and embeds the published array header, so retaining an older header
produces an apparently successful build with stale firmware.

examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile[85-89]
examples/pru_i2s/makefile[138-150]
examples/pru_i2s/pru_i2s_app/pru_i2s_diagnostic.c[168-168]
examples/pru_i2s/pru_i2s_app/pru_i2s_diagnostic.c[241-245]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The firmware post-build copy command is prefixed with `-`, causing GNU Make to ignore failures and potentially retain a stale generated firmware header.

## Issue Context
The application embeds the generated array header directly, while the parent build assumes each firmware sub-build completed successfully. Apply the correction consistently to all focused I2S and TDM4 PRU firmware makefiles.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile[87-87]
- examples/pru_i2s/firmware/I2S/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/I2S/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/I2S/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/TDM4/pru0_tx/am261x-lp/icssm0-pru0_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/TDM4/pru0_tx/am263x-cc/icssm0-pru0_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/TDM4/pru1_rx/am261x-lp/icssm0-pru1_fw/ti-pru-cgt/makefile[86-86]
- examples/pru_i2s/firmware/TDM4/pru1_rx/am263x-cc/icssm0-pru1_fw/ti-pru-cgt/makefile[86-86]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Startup misdetects TX errors 🐞 Bug ☼ Reliability
Description
The firmware reads and branches on err_stat before registers are initialized, so an indeterminate
cold-start value can falsely enter TX recovery. That recovery clears the configured transmit buffer,
destroying audio queued through PRUI2S_write() before the PRU starts.
Code

examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[53]

+	qbeq CONTIUNE_INIT, err_stat, 0
Evidence
err_stat aliases r27.b2, but lines 45 and 53 consume it before the register clear at line 73. A
nonzero value enters lines 57-68, which load the configured TX allocation and overwrite it;
meanwhile, PRUI2S_write() permits the host to populate and mark a TX half full without requiring
the PRU to have been enabled.

examples/pru_i2s/firmware/I2S/pru_i2s_regs.h[99-107]
examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[45-73]
examples/pru_i2s/driver/pru_i2s_drv.c[854-918]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The I2S TX firmware tests `err_stat` before initializing the register that contains it. A cold startup can therefore be mistaken for an underflow or frame-sync recovery and erase a transmit buffer prepared by the host.

## Issue Context
`err_stat` aliases `r27.b2`, while the general register clear occurs only after the recovery branch. Preserve intentional restart recovery only when the error state comes from a validated persistent source; otherwise initialize it before testing it.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[45-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Recovery overruns TX buffer 🐞 Bug ≡ Correctness
Description
The TX recovery loop writes four bytes, increments the pointer, and repeats while the pointer is not
greater than base + pingPongBufSz, causing a final write at or beyond the allocation end. Every
recovery can corrupt adjacent PRU memory, especially because open-time validation accepts any
nonzero buffer size rather than requiring four-byte alignment.
Code

examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[R66-68]

+	sbbo	&ch0_data_tx, tx_ping_buffer_address, 0, 4
+	add		tx_ping_buffer_address, tx_ping_buffer_address, 0x4
+	qbgt	ZERO_TX_PING_PONG, tx_ping_buffer_address, tx_buffer_address_end
Evidence
The firmware interface explicitly defines the size as the complete Ping+Pong allocation. The
recovery code computes end = base + size, stores four bytes before checking, and branches until
the incremented address is strictly greater than that end; meanwhile the driver only rejects a zero
size, so even unaligned sizes reach this loop.

examples/pru_i2s/firmware/I2S/pru_i2s_interface.h[145-149]
examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[60-68]
examples/pru_i2s/driver/pru_i2s_drv.c[1674-1678]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The TX error-recovery clearing loop writes beyond the configured Ping+Pong allocation. It computes the exclusive end as `base + size`, but performs the store before its strict greater-than boundary check.

## Issue Context
`I2S_PING_PONG_BUFSIZE_ADD` contains the total Ping+Pong byte size. The loop must never issue a four-byte store unless the complete word lies inside that range; account for sizes not divisible by four or enforce alignment during parameter validation.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[64-68]
- examples/pru_i2s/driver/pru_i2s_drv.c[1674-1678]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View high (4)
4. SysConfig output cannot compile 🐞 Bug ≡ Correctness
Description
The generated header uses nonexistent PRUI2S_Attrs/gPruI2sAttrs declarations and declares a
variable whose name has already been defined as the CONFIG_PRU_I2S_NUM_INSTANCES macro. The
corresponding C template repeats both errors, so adding any PRU-I2S SysConfig instance produces
invalid C rather than a usable driver configuration.
Code

source/.meta/pru_i2s/pru_i2s_templates.h.xdt[R106-109]

+extern const PRUI2S_Attrs gPruI2sAttrs[CONFIG_PRU_I2S_NUM_INSTANCES];
+
+/* Number of instances */
+extern const uint32_t CONFIG_PRU_I2S_NUM_INSTANCES;
Evidence
The module explicitly registers these XDT files as its generated system configuration. The driver
defines only PRUI2S_SwipAttrs, while the templates emit PRUI2S_Attrs; additionally, the macro
CONFIG_PRU_I2S_NUM_INSTANCES expands inside the subsequent variable declaration and definition,
yielding invalid syntax.

source/.meta/pru_i2s/pru_i2s.syscfg.js[79-93]
source/.meta/pru_i2s/pru_i2s_templates.h.xdt[94-109]
source/.meta/pru_i2s/pru_i2s_templates.c.xdt[120-149]
examples/pru_i2s/include/pru_i2s_drv.h[227-256]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
PRU-I2S SysConfig templates generate unknown types and macro-expanded variable declarations that cannot compile.

## Issue Context
The driver exposes `PRUI2S_SwipAttrs`, not `PRUI2S_Attrs`; the templates are registered as the module's generated C and header outputs.

## Fix Focus Areas
- source/.meta/pru_i2s/pru_i2s_templates.h.xdt[94-109]
- source/.meta/pru_i2s/pru_i2s_templates.c.xdt[93-149]
- source/.meta/pru_i2s/pru_i2s.syscfg.js[79-93]
- examples/pru_i2s/include/pru_i2s_drv.h[227-256]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. TDM4 emits six slots 🐞 Bug ≡ Correctness
Description
The TDM4 interface configures both active and maximum channel counts as six, and the assembly uses
those constants to process six slots before ending a frame. This produces a six-slot wire protocol
and buffer layout instead of the documented four-channel TDM4 format.
Code

examples/pru_i2s/firmware/TDM4/pru_i2s_interface.h[R175-176]

+TDM_CHANNELS                    .set    6 ; TDM channel slots used in TDM mode
+MAX_TDM_CHANNELS                .set    6 ; Maximum TDM Slots (TDM4/TDM8)
Evidence
The public README identifies TDM4 as four-channel, but TDM_CHANNELS and MAX_TDM_CHANNELS are
six. The TX and RX assembly loops compare their channel counters against those constants, so both
directions actually process six slots.

examples/pru_i2s/README.md[423-438]
examples/pru_i2s/firmware/TDM4/pru_i2s_interface.h[172-176]
examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm[263-277]
examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm[428-497]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The TDM4 firmware processes six slots per frame instead of four.

## Issue Context
Both TX and RX assembly loops consume these constants, while the public documentation specifies four channels.

## Fix Focus Areas
- examples/pru_i2s/firmware/TDM4/pru_i2s_interface.h[172-176]
- examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm[263-277]
- examples/pru_i2s/firmware/TDM4/pru_i2s_main.asm[428-497]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Converted RX reuses stale data 🐞 Bug ≡ Correctness
Description
PRUI2S_readC() always deinterleaves from the ping base and never clears the consumed firmware
status bit. When pong is ready it therefore returns stale ping samples, while the missing ownership
release prevents correct RX buffer turnover.
Code

examples/pru_i2s/driver/pru_i2s_drv.c[R1221-1222]

+                    pDst16b++;
+                }
Evidence
All 16-bit and 32-bit converted source pointers originate at rxPingPongBuf, and the function
returns without accessing the RX selector or status registers. The plain read path instead selects
ping or pong using FW_REG_RX_PING_PONG_SEL and clears the corresponding status bit after copying.

examples/pru_i2s/driver/pru_i2s_drv.c[1202-1271]
examples/pru_i2s/driver/pru_i2s_drv.c[962-995]
examples/pru_i2s/include/pru_i2s_drv.h[500-517]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`PRUI2S_readC()` ignores the firmware-selected RX half and never releases the consumed buffer.

## Issue Context
The plain RX implementation contains the required selector lookup and status-bit clearing sequence.

## Fix Focus Areas
- examples/pru_i2s/driver/pru_i2s_drv.c[1165-1271]
- examples/pru_i2s/driver/pru_i2s_drv.c[962-995]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Converted TX corrupts buffers 🐞 Bug ≡ Correctness
Description
PRUI2S_writeC() calculates slots from the complete ping-pong allocation and always writes from the
ping base without consulting the firmware selector or marking the selected half full. Each call can
overwrite both halves, including the half currently being transmitted, while never handing ownership
back to firmware.
Code

examples/pru_i2s/driver/pru_i2s_drv.c[R1089-1090]

+                pSrc16b = (int16_t *)pIoBufC->ioBufLAddr[i];
+                pDst16b = (int16_t *)pObj->txPingPongBuf;
Evidence
The converted path derives numSlots from the full allocation and initializes every destination
pointer from txPingPongBuf; it returns without reading FW_REG_TX_PING_PONG_SEL or setting
FW_REG_TX_PING_PONG_STAT. In contrast, the plain write path selects one half, copies half the
allocation, and marks that half full.

examples/pru_i2s/driver/pru_i2s_drv.c[1079-1148]
examples/pru_i2s/driver/pru_i2s_drv.c[875-917]
examples/pru_i2s/include/pru_i2s_drv.h[481-498]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`PRUI2S_writeC()` writes the entire ping-pong allocation from the ping base and does not update firmware ownership, potentially corrupting active TX data.

## Issue Context
The non-conversion write path demonstrates the required selector and status-register protocol.

## Fix Focus Areas
- examples/pru_i2s/driver/pru_i2s_drv.c[1040-1148]
- examples/pru_i2s/driver/pru_i2s_drv.c[875-917]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

8. Buffer ownership documented backwards 🐞 Bug ⚙ Maintainability ⭐ New
Description
The register table labels the TX address and ping-pong size as firmware-to-R5F build-time constants,
but PRUI2S_open() requires these values from PRUI2S_Params and overwrites the firmware
registers. Editing the documented fw_regs.asm values therefore has no effect, while omitting the
application values makes open fail validation; the RX address row has the same ownership error.
Code

examples/pru_i2s/README.md[R373-374]

+| 0x04 | 4B | `TX_PING_PONG_BUF_ADDR` | FW→R5F (build-time constant) | Base address of the TX ping+pong buffer in PRU Shared RAM (e.g. `0x10000` for PRU0, `0x10200` for PRU1) |
+| 0x08 | 2B | `PING_PONG_BUF_SZ` | FW→R5F (build-time constant) | Combined ping+pong buffer size in bytes (each half is `PING_PONG_BUF_SZ/2`) |
Evidence
Firmware-image parsing reads channel, frequency, slot-width, and interrupt fields only. Open
validation rejects zero TX/RX addresses and buffer size, after which initialization writes all three
application values into the firmware register block.

examples/pru_i2s/README.md[373-386]
examples/pru_i2s/driver/pru_i2s_drv.c[1502-1531]
examples/pru_i2s/driver/pru_i2s_drv.c[1642-1678]
examples/pru_i2s/driver/pru_i2s_drv.c[1792-1811]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The firmware register table incorrectly describes buffer addresses and size as firmware-owned build-time constants, although the driver requires and writes application-provided values during open.

## Issue Context
Firmware image parsing reads capability and interrupt fields, not the buffer addresses or size. Clarify that firmware initializers are placeholders overwritten by the R5F driver, and document the distinct TX-offset and RX-target-address semantics.

## Fix Focus Areas
- examples/pru_i2s/README.md[373-380]
- examples/pru_i2s/README.md[386-386]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Debug profile library missing 🐞 Bug ≡ Correctness
Description
Both application makefiles select the PRU-I2S library using $(PROFILE), but the parent builders
always emit a .release.lib. Consequently, PROFILE=debug builds fail at link time because the
requested .debug.lib does not exist.
Code

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile[R117-119]

+	-ldrivers.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \
+	-lboard.am261x.r5f.ti-arm-clang.freertos.${ConfigName}.lib \
+	-lpru_i2s.am261x.r5f.ti-arm-clang.${ConfigName}.lib \
Evidence
The application makefiles request pru_i2s.<device>.r5f.ti-arm-clang.${ConfigName}.lib, where
ConfigName is the selected profile. The only library-producing rules hard-code .release.lib for
both devices, despite the applications defining a debug profile.

examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile[25-26]
examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile[98-102]
examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile[115-120]
examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/makefile[117-122]
examples/pru_i2s/makefile[152-159]
examples/pru_i2s/makefile[175-182]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The application links a profile-specific PRU-I2S library, while the parent build always creates the release variant. Debug builds therefore cannot link.

## Issue Context
The same mismatch affects both AM261X and AM263X. Either generate the library using the requested profile or make the applications consistently consume the release library.

## Fix Focus Areas
- examples/pru_i2s/pru_i2s_app/am261x-lp/r5fss0-0_freertos/ti-arm-clang/makefile[117-119]
- examples/pru_i2s/pru_i2s_app/am263x-cc/r5fss0-0_freertos/ti-arm-clang/makefile[119-121]
- examples/pru_i2s/makefile[152-159]
- examples/pru_i2s/makefile[175-182]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Deinit abandons active interrupts 🐞 Bug ☼ Reliability
Description
PRUI2S_deinit() nulls HWI handles and destroys instance locks without destructing the HWIs or
stopping an open PRU instance. Calling it with an open instance leaves active interrupt resources
behind while making subsequent PRUI2S_close() or safe reinitialization impossible.
Code

examples/pru_i2s/driver/pru_i2s_drv.c[R370-372]

+            pObj->i2sTxHwiHandle = NULL;
+            pObj->i2sRxHwiHandle = NULL;
+            pObj->i2sErrHwiHandle = NULL;
Evidence
The deinitializer destroys the mutex at lines 360-365 and then merely clears isOpen and all three
HWI handles at lines 367-372. In contrast, PRUI2S_close() explicitly disables/clears events,
destructs each HWI, and deinitializes the PRU at lines 686-775; the public deinit declaration
documents no close-first precondition.

examples/pru_i2s/driver/pru_i2s_drv.c[348-377]
examples/pru_i2s/driver/pru_i2s_drv.c[686-775]
examples/pru_i2s/include/pru_i2s_drv.h[307-312]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`PRUI2S_deinit()` discards handles for active HWIs and destroys the instance mutex without first closing an open PRU-I2S instance. Ensure all PRU, interrupt, and object resources are released before invalidating their handles.

## Issue Context
The public API does not document that every instance must be closed before deinitialization. The diagnostic application follows that order, but the driver itself currently leaves resources active when callers do not.

## Fix Focus Areas
- examples/pru_i2s/driver/pru_i2s_drv.c[348-377]
- examples/pru_i2s/driver/pru_i2s_drv.c[668-791]
- examples/pru_i2s/include/pru_i2s_drv.h[307-312]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View medium (1)
11. Odd RX sizes truncate 🐞 Bug ≡ Correctness
Description
PRUI2S_open() accepts any nonzero ping-pong size, but PRUI2S_read() silently divides an odd size
by two and copies only the truncated half. RX-only configurations can consequently lose one byte
from the configured allocation on every ping/pong cycle, whereas the TX API explicitly rejects the
same configuration.
Code

examples/pru_i2s/driver/pru_i2s_drv.c[R965-971]

+        size = pObj->prms.pingPongBufSz/2;
+        srcAddr = (uint8_t *)pObj->rxPingPongBuf;
+        if (rxPingPongSel == PING_PONG_SEL_PONG)
+        {
+            srcAddr += size;
+        }
+        memcpy((uint8_t *)pIoBuf->ioBufAddr, srcAddr, size);
Evidence
Open-time validation checks only for zero, permitting odd sizes. The read path then uses integer
division without validation, while the write path explicitly rejects zero and odd sizes before
copying.

examples/pru_i2s/driver/pru_i2s_drv.c[962-971]
examples/pru_i2s/driver/pru_i2s_drv.c[875-883]
examples/pru_i2s/driver/pru_i2s_drv.c[1674-1679]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
RX configurations accept odd ping-pong sizes that are silently truncated by `PRUI2S_read()`.

## Issue Context
Validation should be consistent for TX and RX and occur before opening the instance.

## Fix Focus Areas
- examples/pru_i2s/driver/pru_i2s_drv.c[962-971]
- examples/pru_i2s/driver/pru_i2s_drv.c[875-883]
- examples/pru_i2s/driver/pru_i2s_drv.c[1674-1679]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can turn on the rule miner and Qodo learns your standards from review history

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/firmware/TDM4/pru_i2s_interface.h
Comment thread source/.meta/pru_i2s/pru_i2s_templates.h.xdt
Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Comment thread examples/pru_i2s/firmware/I2S/pru_i2s_main.asm
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit e9fcd7d

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit c56130b

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit b3ef566

; 0 1 Under Flow error
; 1 0 FS Error
; 1 1 Both errors
qbeq CONTIUNE_INIT, err_stat, 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Startup misdetects tx errors 🐞 Bug ☼ Reliability

The firmware reads and branches on err_stat before registers are initialized, so an indeterminate
cold-start value can falsely enter TX recovery. That recovery clears the configured transmit buffer,
destroying audio queued through PRUI2S_write() before the PRU starts.
Agent Prompt
## Issue description
The I2S TX firmware tests `err_stat` before initializing the register that contains it. A cold startup can therefore be mistaken for an underflow or frame-sync recovery and erase a transmit buffer prepared by the host.

## Issue Context
`err_stat` aliases `r27.b2`, while the general register clear occurs only after the recovery branch. Preserve intentional restart recovery only when the error state comes from a validated persistent source; otherwise initialize it before testing it.

## Fix Focus Areas
- examples/pru_i2s/firmware/I2S/pru_i2s_main.asm[45-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to discuss about this comment as this might be a big change if implemented @rajul-bhambay

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit d967a77

- Fixed qodo comments

Fixes: PINDSW-8487,9295

Signed-off-by: Rajul Bhambay <r-bhambay@ti.com>
Comment thread examples/pru_i2s/README.md
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 79aff20

Comment thread examples/pru_i2s/driver/pru_i2s_drv.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants