diff --git a/Tools/Linux_HAL_Essentials/pru/aiopru/Makefile b/Tools/Linux_HAL_Essentials/pru/aiopru/Makefile
new file mode 100644
index 0000000000..99a5a5e8f6
--- /dev/null
+++ b/Tools/Linux_HAL_Essentials/pru/aiopru/Makefile
@@ -0,0 +1,8 @@
+RcAioPRU: RcAioPRU.p
+ pasm -V3 -c RcAioPRU.p
+
+test: RcAioPRUTest.c
+ gcc -g -o RcAioPRUTest RcAioPRUTest.c
+
+clean:
+ rm RcAioPRU_bin.h RcAioPRUTest
diff --git a/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU.p b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU.p
new file mode 100644
index 0000000000..661c7a2987
--- /dev/null
+++ b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU.p
@@ -0,0 +1,385 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+// RC AllInOnePRU
+//
+// 1 channel RCInput with 5ns accuracy
+// 12 channel RCOutput with 1us accuracy
+
+// Timer
+#define TICK_PER_US 200
+#define TICK_PER_MS 200000
+
+// PWM
+
+// 920 us
+#define PWM_PULSE_DEFAULT (920 * TICK_PER_US)
+
+// 50 Hz
+#define PWM_FREQ_DEFAULT (20 * TICK_PER_MS)
+
+// Ringbuffer size
+#define RCIN_RINGBUFFERSIZE 300
+
+// PRU Constants Table
+#define ECAP C3
+#define RAM C24
+#define IEP C26
+
+// IEP
+#define IEP_TMR_GLB_CFG 0x0
+#define IEP_TMR_GLB_STS 0x4
+#define IEP_TMR_CNT 0xc
+
+#define IEP_CNT_ENABLE 0x0
+#define IEP_DEFAULT_INC 0x4
+
+// ECAP
+#define ECAP_TSCTR 0x0
+#define ECAP_CTRPHS 0x4
+#define ECAP_CAP1 0x8
+#define ECAP_CAP2 0xc
+#define ECAP_CAP3 0x10
+#define ECAP_CAP4 0x14
+#define ECAP_ECCTL1 0x28
+#define ECAP_ECCTL2 0x2a
+#define ECAP_ECEINT 0x2c
+#define ECAP_ECFLG 0x2e
+#define ECAP_ECCLR 0x30
+#define ECAP_ECFRC 0x32
+#define ECAP_REVID 0x5c
+
+// ECCTL1
+#define ECAP_CAP1POL 0
+#define ECAP_CTRRST1 1
+#define ECAP_CAP2POL 2
+#define ECAP_CTRRST2 3
+#define ECAP_CAP3POL 4
+#define ECAP_CTRRST3 5
+#define ECAP_CAP4POL 6
+#define ECAP_CTRRST4 7
+#define ECAP_CAPLDEN 8
+#define ECAP_PRESCALE 9
+#define ECAP_FREE_SOFT 14
+
+// ECCTL2
+#define ECAP_CONT_ONESHT 0
+#define ECAP_STOP_WRAP 1
+#define ECAP_RE_ARM 3
+#define ECAP_TSCTRSTOP 4
+#define ECAP_SYNCI_EN 5
+#define ECAP_SYNCO_SEL 6
+#define ECAP_SWSYNC 8
+#define ECAP_CAP_APWM 9
+#define ECAP_APWMPOL 10
+
+// ECEINT, ECFLG
+#define ECAP_INT 0
+#define ECAP_CEVT1 1
+#define ECAP_CEVT2 2
+#define ECAP_CEVT3 3
+#define ECAP_CEVT4 4
+#define ECAP_CNTOVF 5
+#define ECAP_PRDEQ 6
+#define ECAP_CMPEQ 7
+
+// RAM
+#define CH_ENABLE_RAM_OFFSET (0 * 4)
+#define CH_1_PULSE_TIME_RAM_OFFSET (1 * 4)
+#define CH_1_T_TIME_RAM_OFFSET (2 * 4)
+#define CH_2_PULSE_TIME_RAM_OFFSET (3 * 4)
+#define CH_2_T_TIME_RAM_OFFSET (4 * 4)
+#define CH_3_PULSE_TIME_RAM_OFFSET (5 * 4)
+#define CH_3_T_TIME_RAM_OFFSET (6 * 4)
+#define CH_4_PULSE_TIME_RAM_OFFSET (7 * 4)
+#define CH_4_T_TIME_RAM_OFFSET (8 * 4)
+#define CH_5_PULSE_TIME_RAM_OFFSET (9 * 4)
+#define CH_5_T_TIME_RAM_OFFSET (10 * 4)
+#define CH_6_PULSE_TIME_RAM_OFFSET (11 * 4)
+#define CH_6_T_TIME_RAM_OFFSET (12 * 4)
+#define CH_7_PULSE_TIME_RAM_OFFSET (13 * 4)
+#define CH_7_T_TIME_RAM_OFFSET (14 * 4)
+#define CH_8_PULSE_TIME_RAM_OFFSET (15 * 4)
+#define CH_8_T_TIME_RAM_OFFSET (16 * 4)
+#define CH_9_PULSE_TIME_RAM_OFFSET (17 * 4)
+#define CH_9_T_TIME_RAM_OFFSET (18 * 4)
+#define CH_10_PULSE_TIME_RAM_OFFSET (19 * 4)
+#define CH_10_T_TIME_RAM_OFFSET (20 * 4)
+#define CH_11_PULSE_TIME_RAM_OFFSET (21 * 4)
+#define CH_11_T_TIME_RAM_OFFSET (22 * 4)
+#define CH_12_PULSE_TIME_RAM_OFFSET (23 * 4)
+#define CH_12_T_TIME_RAM_OFFSET (24 * 4)
+
+#define MAX_CYCLE_TIME_OFFSET (25 * 4)
+
+#define RCIN_RING_HEAD_OFFSET 0x1000
+#define RCIN_RING_TAIL_OFFSET 0x1002
+#define RCIN_RINGBUFFER_RAM_OFFSET 0x1004
+
+// RCOut pins
+#define RC_CH_1_PIN r30.t10
+#define RC_CH_2_PIN r30.t8
+#define RC_CH_3_PIN r30.t11
+#define RC_CH_4_PIN r30.t9
+#define RC_CH_5_PIN r30.t7
+#define RC_CH_6_PIN r30.t6
+#define RC_CH_7_PIN r30.t5
+#define RC_CH_8_PIN r30.t4
+#define RC_CH_9_PIN r30.t3
+#define RC_CH_10_PIN r30.t2
+#define RC_CH_11_PIN r30.t1
+#define RC_CH_12_PIN r30.t0
+
+// RCOut enable bits
+#define RC_CH_1_ENABLE register.ch_enable.t0
+#define RC_CH_2_ENABLE register.ch_enable.t1
+#define RC_CH_3_ENABLE register.ch_enable.t2
+#define RC_CH_4_ENABLE register.ch_enable.t3
+#define RC_CH_5_ENABLE register.ch_enable.t4
+#define RC_CH_6_ENABLE register.ch_enable.t5
+#define RC_CH_7_ENABLE register.ch_enable.t6
+#define RC_CH_8_ENABLE register.ch_enable.t7
+#define RC_CH_9_ENABLE register.ch_enable.t8
+#define RC_CH_10_ENABLE register.ch_enable.t9
+#define RC_CH_11_ENABLE register.ch_enable.t10
+#define RC_CH_12_ENABLE register.ch_enable.t11
+
+// Register struct
+.struct RegisterStruct
+ .u32 ch_enable
+ .u32 ch_1_next_time
+ .u32 ch_2_next_time
+ .u32 ch_3_next_time
+ .u32 ch_4_next_time
+ .u32 ch_5_next_time
+ .u32 ch_6_next_time
+ .u32 ch_7_next_time
+ .u32 ch_8_next_time
+ .u32 ch_9_next_time
+ .u32 ch_10_next_time
+ .u32 ch_11_next_time
+ .u32 ch_12_next_time
+ .u32 time
+ .u32 time_max
+ .u32 time_cycle
+ .u32 rcin_ram_pointer
+ .u32 rcin_ram_pointer_index
+ .u32 rcin_ram_pointer_index_max
+ .u32 rcin_ram_pointer_head
+ .u32 rcin_ram_pointer_tail
+ .u32 temp
+ .u32 temp1
+ .u32 test
+ .ends
+ .assign RegisterStruct, R4, *, register
+
+.macro RCOUT_PWM
+.mparam RC_CH_X_PIN, CH_X_NEXT_TIME, CH_X_ENABLE, CH_X_PULSE_TIME_RAM_OFFSET, CH_X_T_TIME_RAM_OFFSET
+pwm:
+ // Handle arithmetic and counter overflow, check if there is something to do
+ sub register.temp, CH_X_NEXT_TIME, register.time
+ mov register.temp1, 0xF0000000
+ qbgt pwmend, register.temp, register.temp1
+
+ mov CH_X_NEXT_TIME, register.time
+
+ // Set pin or clear pin?
+ qbbs pwmclear, RC_CH_X_PIN
+
+ // Load pulse duration
+ lbco register.temp, RAM, CH_X_PULSE_TIME_RAM_OFFSET, 4
+
+ // Calculate time to next event
+ add CH_X_NEXT_TIME, CH_X_NEXT_TIME, register.temp
+
+ // Check if channel is enabled
+ qbbc pwmend, CH_X_ENABLE
+
+ // Set pin
+ set RC_CH_X_PIN
+ jmp pwmend
+
+ pwmclear:
+ // Load pulse time
+ lbco register.temp1, RAM, CH_X_PULSE_TIME_RAM_OFFSET, 4
+
+ // Load T time
+ lbco register.temp, RAM, CH_X_T_TIME_RAM_OFFSET, 4
+
+ // Calculate time to next event (T - pulse duration)
+ sub register.temp, register.temp, register.temp1
+ add CH_X_NEXT_TIME, CH_X_NEXT_TIME, register.temp
+
+ // Clear pin
+ clr RC_CH_X_PIN
+pwmend:
+.endm
+
+.macro RCIN_ECAP_INIT
+ // Initialize ECAP
+ mov register.temp, (1 << ECAP_CTRRST1) | (1 << ECAP_CAP1POL) | (1 << ECAP_CTRRST2) | (1 << ECAP_CAPLDEN)
+ sbco register.temp, ECAP, ECAP_ECCTL1, 4
+ mov register.temp, (1 << ECAP_STOP_WRAP) | (1 << ECAP_TSCTRSTOP) | (2 << ECAP_SYNCO_SEL)
+ sbco register.temp, ECAP, ECAP_ECCTL2, 4
+.endm
+
+.macro RCIN_ECAP
+ // New value?
+ lbco register.temp, ECAP, ECAP_ECFLG, 4
+ qbbc rcin_ecap_end, register.temp.t2
+
+ // Copy S0 and S1 duration to temp and temp1
+ lbco register.temp, ECAP, ECAP_CAP1, 8
+
+ // Copy S0 and S1 duration to RAM
+ sbbo register.temp, register.rcin_ram_pointer, 0, 8
+
+ // Clear event flags
+ mov register.temp, (1 << ECAP_CEVT1) | (1 << ECAP_CEVT2)
+ sbco register.temp, ECAP, ECAP_ECCLR, 4
+
+ // Set new tail value
+ RCIN_WRITE_TAIL register.rcin_ram_pointer_index
+
+ // Update pointer
+ add register.rcin_ram_pointer_index, register.rcin_ram_pointer_index, 1
+ add register.rcin_ram_pointer, register.rcin_ram_pointer, 8
+
+ // Check end of ringbuffer
+ qblt rcin_ecap_end, register.rcin_ram_pointer_index_max, register.rcin_ram_pointer_index
+ mov register.rcin_ram_pointer, RCIN_RINGBUFFER_RAM_OFFSET
+ mov register.rcin_ram_pointer_index, 0
+rcin_ecap_end:
+.endm
+
+.macro RCIN_WRITE_HEAD
+.mparam RCIN_HEAD
+ sbbo RCIN_HEAD, register.rcin_ram_pointer_head, 0, 2
+.endm
+
+.macro RCIN_WRITE_TAIL
+.mparam RCIN_TAIL
+ sbbo RCIN_TAIL, register.rcin_ram_pointer_tail, 0, 2
+.endm
+
+.macro MAX_CYCLE_TIME
+ lbco register.temp1, IEP, IEP_TMR_CNT, 4
+ sub register.temp, register.temp1, register.time_cycle
+ mov register.time_cycle, register.temp1
+ max register.time_max, register.time_max, register.temp
+ sbco register.time_max, RAM, MAX_CYCLE_TIME_OFFSET, 4
+.endm
+
+.macro INIT
+ // Reset PWM pins
+ mov r30, 0x0
+
+ // Clear register
+ zero ®ister, SIZE(register)
+
+ // Initialize max cycle time
+ mov register.temp, 0
+ sbco register.temp, RAM, MAX_CYCLE_TIME_OFFSET, 4
+
+ // Initialize ringbuffer
+ mov register.rcin_ram_pointer, RCIN_RINGBUFFER_RAM_OFFSET
+ mov register.rcin_ram_pointer_index_max, RCIN_RINGBUFFERSIZE
+ mov register.rcin_ram_pointer_head, RCIN_RING_HEAD_OFFSET
+ mov register.rcin_ram_pointer_tail, RCIN_RING_TAIL_OFFSET
+ mov register.temp, 0
+ RCIN_WRITE_HEAD register.temp
+ RCIN_WRITE_TAIL register.temp
+
+ // Load balancing
+ mov register.ch_1_next_time, 1000
+ mov register.ch_2_next_time, 2000
+ mov register.ch_3_next_time, 3000
+ mov register.ch_4_next_time, 4000
+ mov register.ch_5_next_time, 5000
+ mov register.ch_6_next_time, 6000
+ mov register.ch_7_next_time, 7000
+ mov register.ch_8_next_time, 8000
+ mov register.ch_9_next_time, 9000
+ mov register.ch_10_next_time, 10000
+ mov register.ch_11_next_time, 11000
+ mov register.ch_12_next_time, 12000
+
+ // Disable all PWMs
+ mov register.ch_enable, 0x0
+ sbco register.ch_enable, RAM, CH_ENABLE_RAM_OFFSET, 4
+
+ // Initialize PWM pulse (920us)
+ mov register.temp, PWM_PULSE_DEFAULT
+ sbco register.temp, RAM, CH_1_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_2_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_3_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_4_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_5_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_6_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_7_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_8_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_9_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_10_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_11_PULSE_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_12_PULSE_TIME_RAM_OFFSET, 4
+
+ // Initialize PWM frequency (50Hz)
+ mov register.temp, PWM_FREQ_DEFAULT
+ sbco register.temp, RAM, CH_1_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_2_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_3_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_4_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_5_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_6_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_7_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_8_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_9_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_10_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_11_T_TIME_RAM_OFFSET, 4
+ sbco register.temp, RAM, CH_12_T_TIME_RAM_OFFSET, 4
+
+ // Initialize counter (1 step = 5ns)
+ mov register.temp, 1 << IEP_DEFAULT_INC
+ sbco register.temp, IEP, IEP_TMR_GLB_CFG, 4
+
+ // Reset counter
+ mov register.temp, 0xffffffff
+ sbco register.temp, IEP, IEP_TMR_CNT, 4
+
+ // Start counter
+ lbco register.temp, IEP, IEP_TMR_GLB_CFG, 4
+ or register.temp, register.temp, 1 << IEP_CNT_ENABLE
+ sbco register.temp, IEP, IEP_TMR_GLB_CFG, 4
+.endm
+
+.origin 0
+init:
+ INIT
+ RCIN_ECAP_INIT
+mainloop:
+ lbco register.ch_enable, RAM, CH_ENABLE_RAM_OFFSET, 4
+ lbco register.time, IEP, IEP_TMR_CNT, 4
+ RCOUT_PWM RC_CH_1_PIN, register.ch_1_next_time, RC_CH_1_ENABLE, CH_1_PULSE_TIME_RAM_OFFSET, CH_1_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_2_PIN, register.ch_2_next_time, RC_CH_2_ENABLE, CH_2_PULSE_TIME_RAM_OFFSET, CH_2_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_3_PIN, register.ch_3_next_time, RC_CH_3_ENABLE, CH_3_PULSE_TIME_RAM_OFFSET, CH_3_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_4_PIN, register.ch_4_next_time, RC_CH_4_ENABLE, CH_4_PULSE_TIME_RAM_OFFSET, CH_4_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_5_PIN, register.ch_5_next_time, RC_CH_5_ENABLE, CH_5_PULSE_TIME_RAM_OFFSET, CH_5_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_6_PIN, register.ch_6_next_time, RC_CH_6_ENABLE, CH_6_PULSE_TIME_RAM_OFFSET, CH_6_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_7_PIN, register.ch_7_next_time, RC_CH_7_ENABLE, CH_7_PULSE_TIME_RAM_OFFSET, CH_7_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_8_PIN, register.ch_8_next_time, RC_CH_8_ENABLE, CH_8_PULSE_TIME_RAM_OFFSET, CH_8_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_9_PIN, register.ch_9_next_time, RC_CH_9_ENABLE, CH_9_PULSE_TIME_RAM_OFFSET, CH_9_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_10_PIN, register.ch_10_next_time, RC_CH_10_ENABLE, CH_10_PULSE_TIME_RAM_OFFSET, CH_10_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_11_PIN, register.ch_11_next_time, RC_CH_11_ENABLE, CH_11_PULSE_TIME_RAM_OFFSET, CH_11_T_TIME_RAM_OFFSET
+ RCOUT_PWM RC_CH_12_PIN, register.ch_12_next_time, RC_CH_12_ENABLE, CH_12_PULSE_TIME_RAM_OFFSET, CH_12_T_TIME_RAM_OFFSET
+ RCIN_ECAP
+// MAX_CYCLE_TIME
+jmp mainloop
diff --git a/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRUTest.c b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRUTest.c
new file mode 100644
index 0000000000..60a33733d0
--- /dev/null
+++ b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRUTest.c
@@ -0,0 +1,158 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include
+#include
+#include
+#include
+
+#include "RcAioPRU_bin.h"
+
+#define NUM_RING_ENTRIES 300
+#define RCOUT_PRUSS_RAM_BASE 0x4a302000
+#define RCOUT_PRUSS_CTRL_BASE 0x4a324000
+#define RCOUT_PRUSS_IRAM_BASE 0x4a338000
+#define RCIN_PRUSS_RAM_BASE 0x4a303000
+
+struct ring_buffer {
+ volatile uint16_t ring_head;
+ volatile uint16_t ring_tail;
+ struct {
+ uint32_t s1;
+ uint32_t s0;
+ } buffer[NUM_RING_ENTRIES];
+};
+
+struct pwm {
+ volatile uint32_t enable;
+ volatile uint32_t ch1_hi_time;
+ volatile uint32_t ch1_t_time;
+ volatile uint32_t ch2_hi_time;
+ volatile uint32_t ch2_t_time;
+ volatile uint32_t ch3_hi_time;
+ volatile uint32_t ch3_t_time;
+ volatile uint32_t ch4_hi_time;
+ volatile uint32_t ch4_t_time;
+ volatile uint32_t ch5_hi_time;
+ volatile uint32_t ch5_t_time;
+ volatile uint32_t ch6_hi_time;
+ volatile uint32_t ch6_t_time;
+ volatile uint32_t ch7_hi_time;
+ volatile uint32_t ch7_t_time;
+ volatile uint32_t ch8_hi_time;
+ volatile uint32_t ch8_t_time;
+ volatile uint32_t ch9_hi_time;
+ volatile uint32_t ch9_t_time;
+ volatile uint32_t ch10_hi_time;
+ volatile uint32_t ch10_t_time;
+ volatile uint32_t ch11_hi_time;
+ volatile uint32_t ch11_t_time;
+ volatile uint32_t ch12_hi_time;
+ volatile uint32_t ch12_t_time;
+ volatile uint32_t max_cycle_time;
+};
+
+volatile struct ring_buffer *ring_buffer;
+volatile struct pwm *pwm;
+
+int main (void)
+{
+ unsigned int ret, i, a, s0, s1, min_s0, min_s1, max_s0, max_s1;
+ uint32_t mem_fd;
+ uint32_t *iram;
+ uint32_t *ctrl;
+
+ mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
+
+ ring_buffer = (struct ring_buffer*) mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, RCIN_PRUSS_RAM_BASE);
+ pwm = (struct pwm*) mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, RCOUT_PRUSS_RAM_BASE);
+ iram = (uint32_t*)mmap(0, 0x2000, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, RCOUT_PRUSS_IRAM_BASE);
+ ctrl = (uint32_t*)mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, RCOUT_PRUSS_CTRL_BASE);
+
+ close(mem_fd);
+
+ // Reset PRU 1
+ *ctrl = 0;
+ usleep(5 * 1000);
+
+ // Load firmware
+ for(i = 0; i < sizeof(PRUcode); i++) {
+ *(iram + i) = PRUcode[i];
+ }
+
+ usleep(5 * 1000);
+ // Start PRU 1
+ *ctrl = 3;
+
+ i = 1;
+ a = 0;
+ min_s0 = 0xffffffff;
+ min_s1 = 0xffffffff;
+ max_s0 = 0;
+ max_s1 = 0;
+
+ pwm->ch1_t_time = 200 * 2200;
+ pwm->ch2_t_time = 200 * 2300;
+ pwm->ch3_t_time = 200 * 2400;
+ pwm->ch4_t_time = 200 * 2500;
+ pwm->ch5_t_time = 200 * 2600;
+ pwm->ch6_t_time = 200 * 2700;
+ pwm->ch7_t_time = 200 * 2800;
+ pwm->ch8_t_time = 200 * 2900;
+ pwm->ch9_t_time = 200 * 3000;
+ pwm->ch10_t_time = 200 * 3100;
+ pwm->ch11_t_time = 200 * 3200;
+ pwm->ch12_t_time = 200 * 3300;
+ pwm->enable=0xffffffff;
+
+ while(1) {
+ for(a = 0; a < NUM_RING_ENTRIES; a++) {
+ s0 = ring_buffer->buffer[a].s0;
+ s1 = ring_buffer->buffer[a].s1;
+ if((s0 > max_s0) && (s0 != 1001)) {max_s0 = s0;}
+ if((s1 > max_s1) && (s1 != 1001)) {max_s1 = s1;}
+ if((s0 < min_s0) && (s0 != 1001)) {min_s0 = s0;}
+ if((s1 < min_s1) && (s1 != 1001)) {min_s1 = s1;}
+ }
+ s0 = ring_buffer->buffer[ring_buffer->ring_tail].s0;
+ s1 = ring_buffer->buffer[ring_buffer->ring_tail].s1;
+ printf("max ct: %u ns head: %u tail: %3u s0: %7u s1: %7u s01: %7u jitter_s0 %u ns jitter_s1 %u ns\n", pwm->max_cycle_time * 5, ring_buffer->ring_head, ring_buffer->ring_tail, s0/200, s1/200, (s0+s1)/200, ((max_s0-min_s0) * 5), ((max_s1-min_s1) * 5));
+// pwm->ch1_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch2_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch1_hi_time = 1000 * 200;
+// pwm->ch2_hi_time = 1500 * 200;
+ pwm->ch3_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch4_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch5_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch6_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch7_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch8_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch9_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch10_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch11_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+ pwm->ch12_hi_time = (uint32_t)((rand() % 1001 + 900) * 200);
+
+ usleep(50 * 1000);
+
+ if(i < 100) {
+ min_s0 = 0xffffffff;
+ min_s1 = 0xffffffff;
+ max_s0 = 0;
+ max_s1 = 0;
+ i++;
+ }
+ else if(((max_s1 - min_s1) * 5) > 1001000) {
+ i = 500;
+ }
+ }
+ return 0;
+}
diff --git a/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU_bin.h b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU_bin.h
new file mode 100644
index 0000000000..292cd8301f
--- /dev/null
+++ b/Tools/Linux_HAL_Essentials/pru/aiopru/RcAioPRU_bin.h
@@ -0,0 +1,280 @@
+
+
+/* This file contains the PRU instructions in a C array which are to */
+/* be downloaded from the host CPU to the PRU instruction memory. */
+/* This file is generated by the PRU assembler. */
+
+const unsigned int PRUcode[] = {
+ 0x240000fe,
+ 0x2effaf84,
+ 0x240000f9,
+ 0x81643899,
+ 0x241004f4,
+ 0x24012cf6,
+ 0x241000f7,
+ 0x241002f8,
+ 0x240000f9,
+ 0xe1001799,
+ 0xe1001899,
+ 0x2403e8e5,
+ 0x2407d0e6,
+ 0x240bb8e7,
+ 0x240fa0e8,
+ 0x241388e9,
+ 0x241770ea,
+ 0x241b58eb,
+ 0x241f40ec,
+ 0x242328ed,
+ 0x242710ee,
+ 0x242af8ef,
+ 0x242ee0f0,
+ 0x240000e4,
+ 0x81003884,
+ 0x240002d9,
+ 0x24cec099,
+ 0x81043899,
+ 0x810c3899,
+ 0x81143899,
+ 0x811c3899,
+ 0x81243899,
+ 0x812c3899,
+ 0x81343899,
+ 0x813c3899,
+ 0x81443899,
+ 0x814c3899,
+ 0x81543899,
+ 0x815c3899,
+ 0x24003dd9,
+ 0x24090099,
+ 0x81083899,
+ 0x81103899,
+ 0x81183899,
+ 0x81203899,
+ 0x81283899,
+ 0x81303899,
+ 0x81383899,
+ 0x81403899,
+ 0x81483899,
+ 0x81503899,
+ 0x81583899,
+ 0x81603899,
+ 0x240010f9,
+ 0x81003a99,
+ 0x24ffffd9,
+ 0x24ffff99,
+ 0x810c3a99,
+ 0x91003a99,
+ 0x1301f9f9,
+ 0x81003a99,
+ 0x24010bf9,
+ 0x81282399,
+ 0x240092f9,
+ 0x812a2399,
+ 0x91003884,
+ 0x910c3a91,
+ 0x04f1e5f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1e5,
+ 0xd10afe06,
+ 0x91043899,
+ 0x00f9e5e5,
+ 0xc900e408,
+ 0x1f0afefe,
+ 0x21005300,
+ 0x9104389a,
+ 0x91083899,
+ 0x04faf9f9,
+ 0x00f9e5e5,
+ 0x1d0afefe,
+ 0x04f1e6f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1e6,
+ 0xd108fe06,
+ 0x910c3899,
+ 0x00f9e6e6,
+ 0xc901e408,
+ 0x1f08fefe,
+ 0x21006300,
+ 0x910c389a,
+ 0x91103899,
+ 0x04faf9f9,
+ 0x00f9e6e6,
+ 0x1d08fefe,
+ 0x04f1e7f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1e7,
+ 0xd10bfe06,
+ 0x91143899,
+ 0x00f9e7e7,
+ 0xc902e408,
+ 0x1f0bfefe,
+ 0x21007300,
+ 0x9114389a,
+ 0x91183899,
+ 0x04faf9f9,
+ 0x00f9e7e7,
+ 0x1d0bfefe,
+ 0x04f1e8f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1e8,
+ 0xd109fe06,
+ 0x911c3899,
+ 0x00f9e8e8,
+ 0xc903e408,
+ 0x1f09fefe,
+ 0x21008300,
+ 0x911c389a,
+ 0x91203899,
+ 0x04faf9f9,
+ 0x00f9e8e8,
+ 0x1d09fefe,
+ 0x04f1e9f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1e9,
+ 0xd107fe06,
+ 0x91243899,
+ 0x00f9e9e9,
+ 0xc904e408,
+ 0x1f07fefe,
+ 0x21009300,
+ 0x9124389a,
+ 0x91283899,
+ 0x04faf9f9,
+ 0x00f9e9e9,
+ 0x1d07fefe,
+ 0x04f1eaf9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1ea,
+ 0xd106fe06,
+ 0x912c3899,
+ 0x00f9eaea,
+ 0xc905e408,
+ 0x1f06fefe,
+ 0x2100a300,
+ 0x912c389a,
+ 0x91303899,
+ 0x04faf9f9,
+ 0x00f9eaea,
+ 0x1d06fefe,
+ 0x04f1ebf9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1eb,
+ 0xd105fe06,
+ 0x91343899,
+ 0x00f9ebeb,
+ 0xc906e408,
+ 0x1f05fefe,
+ 0x2100b300,
+ 0x9134389a,
+ 0x91383899,
+ 0x04faf9f9,
+ 0x00f9ebeb,
+ 0x1d05fefe,
+ 0x04f1ecf9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1ec,
+ 0xd104fe06,
+ 0x913c3899,
+ 0x00f9ecec,
+ 0xc907e408,
+ 0x1f04fefe,
+ 0x2100c300,
+ 0x913c389a,
+ 0x91403899,
+ 0x04faf9f9,
+ 0x00f9ecec,
+ 0x1d04fefe,
+ 0x04f1edf9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1ed,
+ 0xd103fe06,
+ 0x91443899,
+ 0x00f9eded,
+ 0xc908e408,
+ 0x1f03fefe,
+ 0x2100d300,
+ 0x9144389a,
+ 0x91483899,
+ 0x04faf9f9,
+ 0x00f9eded,
+ 0x1d03fefe,
+ 0x04f1eef9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1ee,
+ 0xd102fe06,
+ 0x914c3899,
+ 0x00f9eeee,
+ 0xc909e408,
+ 0x1f02fefe,
+ 0x2100e300,
+ 0x914c389a,
+ 0x91503899,
+ 0x04faf9f9,
+ 0x00f9eeee,
+ 0x1d02fefe,
+ 0x04f1eff9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1ef,
+ 0xd101fe06,
+ 0x91543899,
+ 0x00f9efef,
+ 0xc90ae408,
+ 0x1f01fefe,
+ 0x2100f300,
+ 0x9154389a,
+ 0x91583899,
+ 0x04faf9f9,
+ 0x00f9efef,
+ 0x1d01fefe,
+ 0x04f1f0f9,
+ 0x24f000da,
+ 0x2400009a,
+ 0x60faf90d,
+ 0x10f1f1f0,
+ 0xd100fe06,
+ 0x915c3899,
+ 0x00f9f0f0,
+ 0xc90be408,
+ 0x1f00fefe,
+ 0x21010300,
+ 0x915c389a,
+ 0x91603899,
+ 0x04faf9f9,
+ 0x00f9f0f0,
+ 0x1d00fefe,
+ 0x912e2399,
+ 0xc902f90b,
+ 0x91086399,
+ 0xe1007499,
+ 0x240006f9,
+ 0x81302399,
+ 0xe1001895,
+ 0x0101f5f5,
+ 0x0108f4f4,
+ 0x48f5f603,
+ 0x241004f4,
+ 0x240000f5,
+ 0x21004100 };
+