Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * testpru
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include "pru_defs.h"
- #include "linux_types.h"
- #include "remoteproc.h"
- #include "syscall.h"
- #include "virtio_ring.h"
- #include "pt.h"
- /* PRU clock (200MHz) */
- #define PRU_CLK 200000000
- /* NOTE: Do no use it for larger than 5 secs */
- #define PRU_sec(x) ((u32)(((u64)(x) * PRU_CLK))
- #define PRU_ms(x) ((u32)(((u64)(x) * PRU_CLK) / 1000))
- #define PRU_ms_err(x) ((u32)(((u64)(x) * PRU_CLK) % 1000))
- #define PRU_us(x) ((u32)(((u64)(x) * PRU_CLK) / 1000000))
- #define PRU_us_err(x) ((u32)(((u64)(x) * PRU_CLK) % 1000000))
- #define PRU_ns(x) ((u32)(((u64)(x) * PRU_CLK) / 1000000000))
- #define PRU_ns_err(x) ((u32)(((u64)(x) * PRU_CLK) % 1000000000))
- struct pru_vring {
- struct vring vr;
- const char *name;
- u32 align;
- u32 notifyid;
- };
- static void pru_vring_init(struct pru_vring *pvr, const char *name,
- const struct fw_rsc_vdev_vring *rsc_vring)
- {
- vring_init(&pvr->vr, rsc_vring->num,
- (void *)rsc_vring->da, rsc_vring->align);
- pvr->align = rsc_vring->align;
- pvr->notifyid = rsc_vring->notifyid;
- }
- struct pru_vring tx_ring;
- struct pru_vring rx_ring;
- #define BUG_ON(x) \
- do { \
- if (x) { \
- sc_printf("BUG_ON @%s:%d", __FILE__, __LINE__); \
- sc_halt(); \
- } \
- } while(0)
- #define DELAY_CYCLES(x) \
- do { \
- unsigned int t = (x); \
- while (--t) { \
- __asm(" "); \
- } \
- } while(0)
- void sc_vprintf(const char *fmt, va_list ap)
- {
- static char buf[128];
- vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- buf[sizeof(buf) - 1] = '\0';
- sc_puts(buf);
- }
- void sc_printf(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- sc_vprintf(fmt, ap);
- va_end(ap);
- }
- void dump_vring(const char *name, struct vring *vring, unsigned int align)
- {
- struct vring_desc *vd;
- int i, sz;
- sz = vring_size(vring->num, align);
- sc_printf("vring %s @0x%x num %d size %d desc=0x%x avail=0x%x used=0x%x",
- name, (unsigned int)vring->desc, vring->num, sz,
- (unsigned int)vring->desc, (unsigned int)vring->avail,
- (unsigned int)vring->used);
- for (i = 0; i < vring->num; i++) {
- vd = &vring->desc[i];
- sc_printf(" d#%d: a 0x%x l 0x%x f 0x%x n 0x%x",
- i, (__u32)vd->addr, vd->len, vd->flags, vd->next);
- }
- sc_printf(" avail: flags 0x%x idx 0x%x",
- vring->avail->flags, vring->avail->idx);
- for (i = 0; i < vring->num; i++) {
- sc_printf(" a#%d: ring 0x%x", i,
- vring->avail->ring[i]);
- }
- sc_printf(" avail: used_event_idx 0x%x",
- vring->avail->ring[vring->num]);
- sc_printf(" used: flags 0x%x idx 0x%x",
- vring->used->flags, vring->used->idx);
- for (i = 0; i < vring->num; i++) {
- sc_printf(" u#%d: id 0x%x len 0x%x", i,
- vring->used->ring[i].id,
- vring->used->ring[i].len);
- }
- }
- /* event definitions */
- #define SYSEV_ARM_TO_PRU0 21
- #define SYSEV_ARM_TO_PRU1 22
- #define SYSEV_PRU0_TO_ARM 19
- #define SYSEV_PRU0_TO_PRU1 17
- #define SYSEV_PRU1_TO_ARM 20
- #define SYSEV_PRU1_TO_PRU0 19
- void *resource_get_type(struct resource_table *res, int type, int idx)
- {
- struct fw_rsc_hdr *rsc_hdr;
- int i, j;
- j = 0;
- for (i = 0; i < res->num; i++) {
- rsc_hdr = (void *)((char *)res + res->offset[i]);
- if (type >= 0 && rsc_hdr->type != type)
- continue;
- if (j == idx)
- return &rsc_hdr->data[0];
- }
- return NULL;
- }
- static int ring_thread(struct pt *pt)
- {
- int i;
- struct resource_table *res;
- struct fw_rsc_vdev *rsc_vdev;
- struct fw_rsc_vdev_vring *rsc_vring;
- PT_BEGIN(pt);
- res = sc_get_cfg_resource_table();
- BUG_ON(res == NULL);
- /* get first VDEV resource */
- rsc_vdev = resource_get_type(res, RSC_VDEV, 0);
- BUG_ON(rsc_vdev == NULL);
- BUG_ON(rsc_vdev->num_of_vrings < 2);
- for (i = 0, rsc_vring = rsc_vdev->vring; i < 2; i++, rsc_vring++) {
- sc_printf("VR#%d: da=0x%x align=0x%x num=0x%x notifyid=0x%x\n",
- i, rsc_vring->da, rsc_vring->align,
- rsc_vring->num, rsc_vring->notifyid);
- }
- pru_vring_init(&tx_ring, "tx", &rsc_vdev->vring[0]);
- pru_vring_init(&rx_ring, "rx", &rsc_vdev->vring[1]);
- PT_YIELD(pt);
- for (;;) {
- /* wait until we get the indication */
- PT_WAIT_UNTIL(pt, (__R31 & (1 << 30)) != 0);
- if (PINTC_SRSR0 & (1 << SYSEV_ARM_TO_PRU0)) {
- PINTC_SICR = SYSEV_ARM_TO_PRU0;
- sc_printf("ARM to PRU0 event cleared");
- }
- if (PINTC_SRSR0 & (1 << SYSEV_PRU1_TO_PRU0)) {
- PINTC_SICR = SYSEV_PRU1_TO_PRU0;
- sc_printf("PRU1 to PRU0 event cleared");
- }
- /*
- sc_printf("ESR0 0x%x ESR1 0x%x", PINTC_ESR0, PINTC_ESR1);
- sc_printf("SECR0 0x%x SECR1 0x%x", PINTC_SECR0, PINTC_SECR1);
- sc_printf("SRSR0 0x%x SRSR1 0x%x", PINTC_SRSR0, PINTC_SRSR1);
- */
- // dump_vring("tx", &tx_ring.vr, tx_ring.align);
- // dump_vring("rx", &rx_ring.vr, rx_ring.align);
- }
- PT_END(pt);
- }
- static int led_thread(struct pt *pt)
- {
- PT_BEGIN(pt);
- /* IEP timer is incrementing by one */
- PIEP_GLOBAL_CFG = GLOBAL_CFG_CNT_ENABLE |
- GLOBAL_CFG_DEFAULT_INC(1) |
- GLOBAL_CFG_CMP_INC(1);
- /* turn on led */
- __R30 |= (1 << 5);
- /* delay with the timer */
- PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(0); /* clear the interrupt */
- PIEP_CMP_CMP0 = PIEP_COUNT + PRU_ns(200);
- PIEP_CMP_CFG |= CMP_CFG_CMP_EN(0);
- PT_YIELD(pt);
- for (;;) {
- /* wait until we get the indication */
- PT_WAIT_UNTIL(pt, (PIEP_CMP_STATUS & CMD_STATUS_CMP_HIT(0)) != 0);
- /* toggle led */
- __R30 ^= (1 << 5);
- PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(0);
- PIEP_CMP_CMP0 += PRU_us(200);
- }
- PT_END(pt);
- }
- static struct pt pt_ring, pt_led;
- int main(int argc, char *argv[])
- {
- /* enable OCP master port */
- PRUCFG_SYSCFG &= ~SYSCFG_STANDBY_INIT;
- PT_INIT(&pt_ring);
- PT_INIT(&pt_led);
- for (;;) {
- ring_thread(&pt_ring);
- led_thread(&pt_led);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement