diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-05-16 13:41:44 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-05-17 10:46:38 -0400 |
commit | b85755c0ff4cb31aeafc9fd0abd63094508d731b (patch) | |
tree | 984acee6d40d68c49e95894ac28dbbe670d4daec /src/pru/main.c | |
parent | b6f24e78ac2afd736102b8730b9addf53f80dc3b (diff) | |
download | kutter-b85755c0ff4cb31aeafc9fd0abd63094508d731b.tar.gz kutter-b85755c0ff4cb31aeafc9fd0abd63094508d731b.tar.xz kutter-b85755c0ff4cb31aeafc9fd0abd63094508d731b.zip |
pru: Move communication code to second PRU
Perform input and output in the second PRU so that more space is
available in the primary PRU.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/pru/main.c')
-rw-r--r-- | src/pru/main.c | 96 |
1 files changed, 83 insertions, 13 deletions
diff --git a/src/pru/main.c b/src/pru/main.c index c9c6422a..fcf66b39 100644 --- a/src/pru/main.c +++ b/src/pru/main.c @@ -7,15 +7,15 @@ #include <stdint.h> // uint32_t #include <string.h> // memset #include <pru/io.h> // read_r31 -#include <pru_cfg.h> // CT_CFG #include <pru_iep.h> // CT_IEP #include <pru_intc.h> // CT_INTC -#include "autoconf.h" // CONFIG_CLOCK_FREQ -#include "board/misc.h" // timer_from_us +#include <rsc_types.h> // resource_table +#include "board/misc.h" // alloc_chunk +#include "board/io.h" // readl #include "board/irq.h" // irq_disable #include "command.h" // shutdown #include "generic/timer_irq.h" // timer_dispatch_many -#include "internal.h" // IEP_IRQ +#include "internal.h" // SHARED_MEM #include "sched.h" // sched_main DECL_CONSTANT(MCU, "pru"); @@ -50,7 +50,6 @@ static void timer_set(uint32_t value) { CT_IEP.TMR_CMP0 = value; - CT_INTC.SECR0 = 1 << IEP_EVENT; } uint32_t @@ -62,14 +61,17 @@ timer_read_time(void) static void _irq_poll(void) { - CT_IEP.TMR_CMP_STS = 0xff; - uint32_t next = timer_dispatch_many(); - timer_set(next); + if (CT_INTC.SECR0 & (1 << IEP_EVENT)) { + CT_IEP.TMR_CMP_STS = 0xff; + uint32_t next = timer_dispatch_many(); + timer_set(next); + } + CT_INTC.SECR0 = (1 << IEP_EVENT) | (1 << KICK_PRU1_EVENT); } void irq_poll(void) { - if (read_r31() & (1 << (IEP_IRQ + R31_IRQ_OFFSET))) + if (read_r31() & (1 << (WAKE_PRU1_IRQ + R31_IRQ_OFFSET))) _irq_poll(); } @@ -87,7 +89,7 @@ DECL_SHUTDOWN(timer_shutdown); static void timer_init(void) { - timer_set(0); + CT_IEP.TMR_CNT = 0; CT_IEP.TMR_CMP_CFG = 0x01 << 1; CT_IEP.TMR_GLB_CFG = 0x11; timer_shutdown(); @@ -95,6 +97,55 @@ timer_init(void) /**************************************************************** + * Console IO + ****************************************************************/ + +// Return a buffer (and length) containing any incoming messages +char * +console_get_input(uint8_t *plen) +{ + uint32_t read_count = readl(&SHARED_MEM->read_count); + if (read_count > 64) + read_count = 64; + *plen = read_count; + return SHARED_MEM->read_data; +} + +// Remove from the receive buffer the given number of bytes +void +console_pop_input(uint8_t len) +{ + barrier(); + writel(&SHARED_MEM->read_count, 0); +} + +// Return an output buffer that the caller may fill with transmit messages +char * +console_get_output(uint8_t len) +{ + if (len > sizeof(SHARED_MEM->send_data[0].data)) + return NULL; + uint32_t send_push_pos = SHARED_MEM->send_push_pos; + if (readl(&SHARED_MEM->send_data[send_push_pos].count)) + // Queue full + return NULL; + return SHARED_MEM->send_data[send_push_pos].data; +} + +// Accept the given number of bytes added to the transmit buffer +void +console_push_output(uint8_t len) +{ + uint32_t send_push_pos = SHARED_MEM->send_push_pos; + barrier(); + writel(&SHARED_MEM->send_data[send_push_pos].count, len); + write_r31(R31_WRITE_IRQ_SELECT | (KICK_PRU0_EVENT - R31_WRITE_IRQ_OFFSET)); + SHARED_MEM->send_push_pos = ( + (send_push_pos + 1) % ARRAY_SIZE(SHARED_MEM->send_data)); +} + + +/**************************************************************** * Allocator ****************************************************************/ @@ -132,6 +183,24 @@ alloc_chunks(size_t size, size_t count, size_t *avail) /**************************************************************** + * Resource table + ****************************************************************/ + +struct my_resource_table { + struct resource_table base; + + uint32_t offset[1]; /* Should match 'num' in actual definition */ +} resourceTable __visible __section(".resource_table") = { + { + 1, /* Resource table version: only version 1 is + * supported by the current driver */ + 0, /* number of entries in the table */ + { 0, 0 }, /* reserved, must be zero */ + }, +}; + + +/**************************************************************** * Startup ****************************************************************/ @@ -139,10 +208,11 @@ alloc_chunks(size_t size, size_t count, size_t *avail) int main(void) { - // allow access to external memory - CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; + // Wait for PRU0 to initialize + while (readl(&SHARED_MEM->signal) != SIGNAL_PRU0_WAITING) + ; + writel(&SHARED_MEM->signal, SIGNAL_PRU1_READY); - console_init(); timer_init(); sched_main(); |