/* * main.c */ void main(void) { struct pru_rpmsg_transport transport; uint16_t src, dst, len; volatile uint8_t *status; /* clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */ CT_INTC.SICR_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 pru_virtqueue corresponding to vring0 (PRU to ARM Host direction) */ pru_virtqueue_init(&transport.virtqueue0, &resourceTable.rpmsg_vring0, TO_ARM_HOST, FROM_ARM_HOST); /* Initialize pru_virtqueue corresponding to vring1 (ARM Host to PRU direction) */ pru_virtqueue_init(&transport.virtqueue1, &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) != PRU_RPMSG_SUCCESS); while (1) { /* Check bit 31 of register R31 to see if the ARM has kicked us */ if (__R31 & HOST_INT) { /* Clear the event status */ CT_INTC.SICR_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) { /* Echo the message back to the same address from which we just received */ pru_rpmsg_send(&transport, dst, src, payload, len); } } } }
/* * main.c */ void main(void) { struct pru_rpmsg_transport transport; uint16_t src, dst, len; volatile uint8_t *status; /* allow OCP master port access by the PRU so the PRU can read external memories */ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; /* Make sure the Linux drivers are ready for RPMsg communication */ status = &resourceTable.rpmsg_vdev.status; while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK)); /* Initialize pru_virtqueue corresponding to vring0 (PRU to ARM Host direction) */ pru_virtqueue_init(&transport.virtqueue0, &resourceTable.rpmsg_vring0, &CT_MBX.MESSAGE[MB_TO_ARM_HOST], &CT_MBX.MESSAGE[MB_FROM_ARM_HOST]); /* Initialize pru_virtqueue corresponding to vring1 (ARM Host to PRU direction) */ pru_virtqueue_init(&transport.virtqueue1, &resourceTable.rpmsg_vring1, &CT_MBX.MESSAGE[MB_TO_ARM_HOST], &CT_MBX.MESSAGE[MB_FROM_ARM_HOST]); /* Create the RPMsg channel between the PRU and ARM user space using the transport structure. * The name 'rpmsg-pru' corresponds to the rpmsg_pru driver found * at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c */ while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS); while (1) { if (CT_MBX.MESSAGE[MB_FROM_ARM_HOST] == 1) { /* Receive the message */ if (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) { /* Echo the message back to the same address from which we just received */ pru_rpmsg_send(&transport, dst, src, payload, len); } } } }
/* * main.c */ int main() { struct pru_rpmsg_transport transport; uint16_t src, dst, len; volatile uint8_t *status; /* allow OCP master port access by the PRU so the PRU can read external memories */ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; /* clear the status of event MB_INT_NUMBER (the mailbox event) and enable the mailbox event */ CT_INTC.SICR_bit.STS_CLR_IDX = MB_INT_NUMBER; CT_MBX.IRQ[MB_USER].ENABLE_SET |= 1 << (MB_FROM_ARM_HOST * 2); /* Make sure the Linux drivers are ready for RPMsg communication */ status = &resourceTable.rpmsg_vdev.status; while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK)); /* Initialize pru_virtqueue corresponding to vring0 (PRU to ARM Host direction) */ pru_virtqueue_init(&transport.virtqueue0, &resourceTable.rpmsg_vring0, &CT_MBX.MESSAGE[MB_TO_ARM_HOST], &CT_MBX.MESSAGE[MB_FROM_ARM_HOST]); /* Initialize pru_virtqueue corresponding to vring1 (ARM Host to PRU direction) */ pru_virtqueue_init(&transport.virtqueue1, &resourceTable.rpmsg_vring1, &CT_MBX.MESSAGE[MB_TO_ARM_HOST], &CT_MBX.MESSAGE[MB_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) != PRU_RPMSG_SUCCESS); while(1){ /* Check bit 31 of register R31 to see if the mailbox interrupt has occurred */ #ifdef __GNUC__ unsigned int r31 = read_r31(); #else unsigned int r31 = __R31; #endif if(r31 & HOST_INT){ /* Clear the mailbox interrupt */ CT_MBX.IRQ[MB_USER].STATUS_CLR |= 1 << (MB_FROM_ARM_HOST * 2); /* Clear the event status, event MB_INT_NUMBER corresponds to the mailbox interrupt */ CT_INTC.SICR_bit.STS_CLR_IDX = MB_INT_NUMBER; /* Use a while loop to read all of the current messages in the mailbox */ while(CT_MBX.MSGSTATUS_bit[MB_FROM_ARM_HOST].NBOFMSG > 0){ /* Check to see if the message corresponds to a receive event for the PRU */ if(CT_MBX.MESSAGE[MB_FROM_ARM_HOST] == 1){ /* Receive the message */ if(pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS){ /* Echo the message back to the same address from which we just received */ pru_rpmsg_send(&transport, dst, src, payload, len); } } } } } return 0; }
/* * main.c */ void main(void) { struct pru_rpmsg_transport transport; uint16_t src, dst, len; volatile uint8_t *status; __R30 = 0x0; /* allow OCP master port access by the PRU so the PRU can read external memories */ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; /* clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */ CT_INTC.SICR_bit.STS_CLR_IDX = 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 pru_virtqueue corresponding to vring0 (PRU to ARM Host direction) */ pru_virtqueue_init(&transport.virtqueue0, &resourceTable.rpmsg_vring0, TO_ARM_HOST, FROM_ARM_HOST); /* Initialize pru_virtqueue corresponding to vring1 (ARM Host to PRU direction) */ pru_virtqueue_init(&transport.virtqueue1, &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) != 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.SICR_bit.STS_CLR_IDX = 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) { int i; for (i = 0; i < len; i++) { if (payload[i] == 'b' || payload[i] == 'B') __R30 ^= BLUE; else if (payload[i] == 'g' || payload[i] == 'G') __R30 ^= GREEN; else if (payload[i] == 'o' || payload[i] == 'O') __R30 ^= ORANGE; else if (payload[i] == 'r' || payload[i] == 'R') __R30 ^= RED; } } } } }