/* * Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "resource_table.h" #include "intc_map_0.h" volatile register uint32_t __R30; volatile register uint32_t __R31; /* Host-0 Interrupt sets bit 30 in register R31 */ #define HOST_INT ((uint32_t) 1 << 30) /* * The PRU-ICSS system events used for RPMsg are defined in the Linux device tree * PRU0 uses system event 16 (To ARM) and 17 (From ARM) * PRU1 uses system event 18 (To ARM) and 19 (From ARM) */ #define TO_ARM_HOST 16 #define FROM_ARM_HOST 17 /* * Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found * at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c */ #define CHAN_NAME "rpmsg-pru" #ifndef CHAN_PORT #error "CHAN_PORT not defined, must be passed using the compiler CFLAGS" #endif #define XSTR(x) #x #define CHAN_DESC(x) "Channel "XSTR(x) /* * Used to make sure the Linux drivers are ready for RPMsg communication * Found at linux-x.y.z/include/uapi/linux/virtio_config.h */ #define VIRTIO_CONFIG_S_DRIVER_OK 4 uint8_t payload[RPMSG_MESSAGE_SIZE]; /* * main.c */ void main(void) { struct pru_rpmsg_transport transport; uint16_t src, dst, len; volatile uint8_t *status; volatile uint32_t gpio; gpio = 0xFFFFFFFF; /* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */ CT_INTC.STATUS_CLR_INDEX_REG_bit.STATUS_CLR_INDEX = FROM_ARM_HOST; /* Make sure the Linux drivers are ready for RPMsg communication */ status = &resourceTable.rpmsg_vdev.status; while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK)); /* Initialize the RPMsg transport structure */ pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST); /* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */ while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC(CHAN_PORT), CHAN_PORT) != PRU_RPMSG_SUCCESS); while (1) { /* Check bit 30 of register R31 to see if the ARM has kicked us */ if (__R31 & HOST_INT) { /* Clear the event status */ CT_INTC.STATUS_CLR_INDEX_REG_bit.STATUS_CLR_INDEX = FROM_ARM_HOST; /* Receive all available messages, multiple messages can be sent per kick */ while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) { //toggle gpios __R30 ^= gpio; /* Echo the message back to the same address from which we just received */ pru_rpmsg_send(&transport, dst, src, payload, len); } } } }