1. PPI
1.1. PPI Feature Introduction
Supports 4 CS ports, each of which can be configured separately: address range (base address needs to be aligned with 1MB), port bit width (supports 8/16/32 bits) and command sequence (start/end index of command)
There is a 32 bits data/address bus that supports: 32 bits data + 32 bits address (multiplexing mode), 16 bits data + 32 bits address (multiplexing mode), 8 bits data + 32 bits address (multiplexing mode), 16 bits data + 16 bits address (non multiplexing mode), 8 bits data + 24 bits address (non multiplexing mode)
There are 4 valid byte selection ports (DM signal, used for SRAM’s UB/LB and other signals)
There are 8 control lines (used for SRAM’s WE/OE/ADV signals)
There is 1 clock line output (supporting clock always output and following instruction sequence output)

1.2. PPI Configuration Introduction
CS Configuration The CS configuration structure is as follows:
typedef struct { ppi_port_size_t port_size; uint16_t addr_start_high_12bits; /* address space: 0xF8000000 ~ 0xFFFFFFFF */ uint16_t addr_end_high_12bits; /* address space: 0xF8000000 ~ 0xFFFFFFFF */ uint16_t addr_mask; bool sync_clk_en; uint8_t sync_clk_sel; uint8_t interval_cycle; uint8_t rcmd_start0; uint8_t rcmd_end0; uint8_t rcmd_start1; uint8_t rcmd_end1; uint8_t wcmd_start0; uint8_t wcmd_end0; uint8_t wcmd_start1; uint8_t wcmd_end1; #if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS ppi_dm_valid_polarity_t dm_polarity; #endif } ppi_cs_pin_config_t; /**< ppi_cs_pin_config_t */
The PPI address space is from 0xF800000 to 0xFFFFFFFF,which is Noncacheable attribute.
port_sizeis the port bit width,addr_start_high_12bitsandaddr_end_high_12bitsare the top 12 bits of the start address and the top 12 bits of the end address, andaddr_maskis the top 16 bit address mask.sync_clk_enis whether to enable synchronization of the clock,sync_clk_selis the time selection for CS output effective level (range from 0 to clkpin_cfg. cycle), andinterval_cycleis the command interval time (unit: system clock cycle).rcmd_start0andrcmd_end0are the start/end indexes of the first read command, whilewcmd_start0andwcmd_end0are the start/end indexes of the first write command;rcmd_start1andrcmd_end1are the start/end indexes for the second and subsequent read commands, whilewcmd_sart1andwcmd_end1are the start/end indexes for the second and subsequent write commands. For example, some devices that support burst transmission may have different timing for first and subsequent access, so each device can configure different command sequences for first and subsequent access. The start/end index corresponds to an index of 64 command words, ranging from 0 to 63.
CMD Configuration
There are a total of 64 command words, shared by 4 CS.
Each data transmission can be divided into several segments, each described by a command word. For example, in the following chapter “Introduction to PPI Components”, read/write instructions are divided into four segments.
For each segment, the duration (
cmd_cycle), output level of CS pin (cs_pin_value), DQ pin function (ad_func_sel, data/address, 1 byte per group), DQ pin direction (ad_pin_dir, input/output, 1 byte per group), source of output bytes (byte_sel), level of 8 control lines (ctrl_pin_value), clock output enable (clk_output, clock pin is effective in cmd control output mode) can be configured. The structure of the CMD command word is as follows:
typedef struct { bool cs_pin_value; bool clk_output; uint8_t cmd_cycle; ppi_ad_func_t ad_func_sel[4]; ppi_ad_pin_dir_t ad_pin_dir[4]; ppi_byte_sel_t byte_sel[4]; bool ctrl_pin_value[8]; } ppi_cmd_config_t; /**< ppi_cmd_config_t */
Control Pins Configuration
There are a total of 8 control signal pins.
The direction and polarity of each control pin can be independently configured, and the configured APIs are as follows:
static inline void ppi_config_ctrl_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_ctrl_polarity_t pol); static inline void ppi_set_ctrl_pin_dir(PPI_Type *ppi, uint8_t index, ppi_ctrl_pin_dir_t dir);
Clock Pin Configuration
There is a total of 1 clock signal output.
The clock has two working modes: (1) always output; (2) The output is controlled by CMD, that is, ppi_cmdunconfig.clk_output controls the clock output.
The structure of clock pin configuration is as follows:
typedef struct { uint8_t cycle_num; uint8_t high_num; uint8_t low_num; ppi_clk_output_mode_t mode; bool revert; } ppi_clk_pin_config_t; /**< ppi_clk_pin_config_t */
Among them, the three parameters of
cycle_num,high_num, andlow_numcontrol the cycle of the output clock, themodeconfigures the working mode, and therevertcontrols whether the clock output is reversed.
1.3. PPI Component
At present, PPI components have implemented asynchronous SRAM read and write timing, supporting address/data multiplexing mode and non multiplexing mode. The corresponding pins for each mode are as follows:
AD multiplexing |
Data |
Address |
Address Latch |
|---|---|---|---|
32 bits data + 32 bits address |
D0 - D31 : DQ0 - DQ31 |
A0 - A31 : DQ0 - DQ31 |
DQ0 - DQ31 need address latch |
16 bits data + 32 bits address |
D0 - D15 : DQ0 - DQ15 |
A0 - A31 : DQ0 - DQ31 |
DQ0 - DQ15 need address latch, while DQ15 - DQ31 don’t need address latch |
8 bits data + 32 bits address |
D0 - D7 : DQ0 - DQ7 |
A0 - A31 : DQ0 - DQ31 |
DQ0 - DQ7 need address latch, while DQ8 - DQ31 don’t need address latch |
AD Non multiplexing |
Data |
Address |
|---|---|---|
16 bits data + 16 bits address |
D0 - D15 : DQ0 - DQ15 |
A0 - A15 : DQ16 - DQ31 |
8 bits data + 24 bits address |
D0 - D7 : DQ0 - DQ7 |
A0 - A23 : DQ8 - DQ31 |
The structure of asynchronous SRAM configuration is as follows:
typedef struct {
uint32_t base_address; /**< external SRAM base address, should be 1MB aligned */
uint32_t size_in_byte; /**< external SRAM size in byte */
ppi_port_size_t port_size; /**< port size */
bool ad_mux_mode; /**< addr and data mux mode */
bool cs_valid_polarity; /**< cs valid polarity */
bool dm_valid_polarity; /**< dm valid polarity */
bool addr_valid_polarity; /**< addr valid polarity */
uint8_t adv_ctrl_pin; /**< adv ctrl pin number, 0 - 7 */
uint8_t rel_ctrl_pin; /**< rel ctrl pin number, 0 - 7 */
uint8_t wel_ctrl_pin; /**< wel ctrl pin number, 0 - 7 */
uint8_t as_in_ns; /**< address setup time */
uint8_t ah_in_ns; /**< address hold time */
uint8_t rel_in_ns; /**< RE low time */
uint8_t reh_in_ns; /**< RE high time */
uint8_t wel_in_ns; /**< WE low time */
uint8_t weh_in_ns; /**< WE high time */
} ppi_async_sram_config_t;
The corresponding read and write timing diagram is:

Among them, CS is the chip selection signal and ADV, RE, and WE are control signals (selected from 8 control lines). The valid polarity of CS, ADV, and DM can be configured.
The API for configuring asynchronous SRAM in PPI components is as follows. Each CS configuration will occupy 8 CMD command words, so cmd_start_index needs to be set to a multiple of 8, such as 0, 8, 16, 24, etc.
/**
* @brief config async sram
*
* @param[in] ppi PPI base address
* @param[in] cs_index cs index, value: 0 - 3
* @param[in] cmd_index cmd start index, should be a multiple of 8, such as 0, 8, 16, 24 ...
* @param[in] config async sram config structure pointer, @ref ppi_async_sram_config_t
*/
void ppi_config_async_sram(PPI_Type *ppi, uint8_t cs_index, uint8_t cmd_start_index, ppi_async_sram_config_t *config);