text: Development Demonstration of PRU of AM5718
  Forlinx OK5718-C development board is designed based on TI AM5718 processor which contains two PRU-ICSS(ProgrammableReal-Time Unit Subsystem and Industrial Communication Subsystem), here we will have a demonstration of the PRU structure and how to do development and debug work by PRU.
  PRUSS is a module that connects to L3_MAIN, similar with other modules like ARM and DSP, it can visit other peripherals.
  PRUSS contains two PRUs, it connects to subsystem interrupt controller, instruction memory, data memory, shared memory and peripherals by its 32-bitinterconnect bus.
  PRU is not an accelerator, it's a 32-bitLoad/Store RISC little-end processor, each PRU consists pf 32 registers (R0- R31), 12Kbyte instruction RAM, 8K byte data RAM and 32K byte shared RAM. Insruction RAM is separated and not accessable, but data RAM is accessiable by mapping address. Special 21 input pins and 21 output pins.
  PRU-ICSS1 and PRU-ICSS2 have below features:
  - • PD_L4PER power domain instantiation
  - • two master ports (PRU0and PRU1 core initiators) on the device L3_MAIN interconnect
  - • Non-wakeup capable - smart Standby protocol with the device PRCM
  - • Software assertion of a standby request "MStandby" (formaster port clock disable) with local (PRUICSS) monitoring of thePRCM "MWait" acknowledge.
  - • one slave(configuration) port on the L3_MAIN interconnect for device hosts(MPU, DSP1, etc.) to access various memories and registers ofPRU-ICSS
  - • Non-wakeup capable - smart Idle protocol with thedevice PRCM
  - • 10 output interrupt events from local interruptcontroller - PRUSS_INTC:
  – 2events to each PRU core (events 0 and 1)
  – 8 events mapped tothe device IRQ_CROSSBAR which further remaps them to deviceinterrupt
  controllers (events 2 through 9)
  – 2 eventsmapped to the device DMA_CROSSBAR, that remaps them to device DMAcontrollers
  (events 8 and 9)
  • 32 external interrupts aremapped via the device IRQ_CROSSBAR to the local PRUSS_INTC
  • Alocal software gating of clocks to several modules within PRUsubsystem (local clock management
  protocol), as follows:
  • 3 inputclocks obtained from device PRCM:
  – a PRU-ICSS top levelgatable interface clock
  – a PRUSS IEP functional clock
  –a PRUSS UART0
  • No memory/register retention is supported
  • One hardware non-retention (level sensitive) reset
  PART 1 PRU RAM Mapping
  1.1 Instruction space
  Separated space of each PRU is 0x00000000～0x00002FFF. The instruction space will be initialized by ARM/ DSP, program pointer on PC is a 32-bit word address, but not byte
  address, for example, PC=2, it indicates the instruction address is 0x 08
  1.2 Data space
  Data RAM space of separted 8Kbyte of each PRU is 0x 0000~ 0x 01FF. Data RAM is mounted to internal bus of PRU subsystem, so it's accessable to other modules in the subsystem,
  the mapping address of this space on the other PRU is 0x 2000- 0x 21FF. Shared interrupt controller register, PRU controller/ status register are also in the data space and have separated address spaces.
  1.3 Global address space mapping
  Base address(L3_MAINbase address) of PRU_ICSS1 local address in global address is 0x4B2A0000, and base address(L3_MAINbase address) of PRU_ICSS2 local address in global address is 0x4B28E000.
  PRU can visit data space of PRUSS by local address or global address. Take global address by L3_MAINdevice to visit data space is slower than taking local address to visit data space.
  External module of PRUSS, such as ARM and DSP can access to PRU sources by system global address space mapping port together with global address (OffsetAddress + L3_MAIN base
  address). Details please refer to 188.8.131.52PRU-ICSS Global Memory Map of AM571xTechnical Reference Manual
  PART 02 Control/ status register
  Control/ status register of PRU0 is from 0x00020000 to 0x0002_3FFF, control/ status register address of PRU1 is from 0x0002_4000 to 0x0002_5FFF
  2.1 PRU_CONTROL register
  ARM/ DSP can control PRU status by control register
  2.2 PRU_STATUS register
  status register is the program pointer regiter of PRU, it would be some latency before program running.
  Before executing SLP instruction to get into sleeping mode, enable WAKEUP bit, input 1 for R31 of the register, that means WAKEUP&R31！=0, PRU will be waken up.
  when CONTROL[ENABLE]=1 and CONTROL[COUNTENABLE]=1，CYCLECNT will count time by PRU clock cycle. When CONTROL[ENABLE]=0 or CONTROL[COUNTENABLE]=0, timing stops. Re-enable it to recover counting.
  When CONTROL[ENABLE]=1 and CONTROL[COUNTENABLE]=1, also PRU is not able to take instructions, STALLCNT will start timing by PRU cycle, its value always less or equals the
  2.6 PRUSS_DBG_GPREG 0～31
  PRUSS_DBG_GPREG0～31 are matched with R0～R31, when PRU stops, ARM/ DSP read/ writer INTGPR0～31 will directly read/ writer R0～R31.
  PART03 General register
  3.1 PRU event/ R31
  R31 is a special register with reading and writing functions. Write to R31, for example, write a channel number 0 to 15 to R31_PRU_VEC[3:0], meanwhile R31_PRU_VEC_VALID, it will generate related interrupt output event to interrupt controller event. Two PRU output same interrupt event or output to the same interrupt controller.
  Read R31, R31[29:0] indicates the status of PRU_R30[29:0]. R31[31:30] indicates status of INTR_IN and INTR_IN
  Each PUR has 32 output pins PRU0_R31[31:0] and PRU1_R31[31:0], the value wrote to R30[31:0] will be directly output to PRUn_R31[31:0]
  PART 04 PRU interrupt controller
  The PRU interrupt controller can support 64 system events, 10 interrupt channels and 10 host machine interruptions
  PRU-ICSS1_INTC/PRUSS2_INTC interrupt 0~31 are matched with events generated by PRU-ICSS. System events 16~31 is generated by writing to R31
  PRU_ICSS system events 32~55 can choose standard or MII_RT event by configuring PRUSS_MII_RT, PRUSSEVTSEL=0 to choose PRU-ICSS special IRQ_CROSSBAR output event as interrupt source, set PRUSSEVTSEL=1 to choose event generated by MII_RT as interrupt source.
  10 channels could be mapped by any 64 system events, multiple system events could map to one channel, but please don't map one system event to multiple channels.
  Set PRUSS_INTC_CMR to get maps of channels and 64 system events, PRUSS_INTC_CMRi(i is 0~15) is used for making i*4 to i*4+k system events map to same channel. Take channel
  number set y related register bit to map to related system event.
  10 host machine interrupt and 10 channels could be mapped each other, multiple system events could map to one channel, but please don't map one system event to multiple
  PRUSS_INTC_HMRi（i is 0~3）is used for mapping channel 0-9 to host machine interrupt 0- 9. Configure register bit to set host machine interrupt, build mapping between interrupt and channel.
  Host machine interrupt 0 outputs to R31.b30, interrupt 1 outputs to R31.b31, interrupt 2~ 9 output PRUSS to PRUSS_EVTOUT0～7 of ARM and DSP. Interrupt vector table is not
  supported by PRU, generated 0, 1 could be used for PRU waking up or status checking.
  PART 05 PRU code pack
  Forlinx kindly provides PRU demo source code to users
  PART 06 Software debug
  6.1 debug tool
  USBJTAG emulater XDS100V2 ,XDS100V2 are kindly recommended.
  6.2 Hardware connection
  1. Connect XDS100V2 emulater with Forlinx OK571-C development board as below
  2. Connect XDS100V2 with USB of PC via USB cable
  Here we will use Forlinx PRU demo to do PRU_LED0 debug, import the project to CCS, right click PRU_LED0 to choose Properties
  Choose related emulater and compilier version, after all settings, please click OK
  Right click PRU_LED0，choose DebugConfigurations
  Choose PRU_LED0, delete realted check box as below, click Apply and then Debug
  get into debug as below
  Below indicates compiling is successful
  Cursor will stop at the main function after getting into debug mode
  During debug, users can take below operation to check variable and register value Click view menu, choose Expressions option
  get below interface
  Choose target variable name, right click AddWatch Expression
  Add GPIO value to Expressions
  Click Addnew expression to input R30, and it will be whown on Expressions
  Get into debug interface, when program run to a certain line, right click this line, and click runto line, then it will run to this line, right click line 57
  Run to line 57 and GPIO value will change to hexadecimal as 0xffffffff
  Right click line 60, choose runto line, R30 value will change