Advertisement
Guest User

Untitled

a guest
Jun 24th, 2013
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.69 KB | None | 0 0
  1. /*
  2.  * testpru
  3.  *
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stdarg.h>
  8. #include <stdio.h>
  9.  
  10. #include "pru_defs.h"
  11.  
  12. #include "linux_types.h"
  13. #include "remoteproc.h"
  14. #include "syscall.h"
  15.  
  16. #include "virtio_ring.h"
  17.  
  18. #include "pt.h"
  19.  
  20. /* PRU clock (200MHz) */
  21. #define PRU_CLK 200000000
  22.  
  23. /* NOTE: Do no use it for larger than 5 secs */
  24. #define PRU_sec(x)  ((u32)(((u64)(x) * PRU_CLK))
  25. #define PRU_ms(x)   ((u32)(((u64)(x) * PRU_CLK) / 1000))
  26. #define PRU_ms_err(x)   ((u32)(((u64)(x) * PRU_CLK) % 1000))
  27. #define PRU_us(x)   ((u32)(((u64)(x) * PRU_CLK) / 1000000))
  28. #define PRU_us_err(x)   ((u32)(((u64)(x) * PRU_CLK) % 1000000))
  29. #define PRU_ns(x)   ((u32)(((u64)(x) * PRU_CLK) / 1000000000))
  30. #define PRU_ns_err(x)   ((u32)(((u64)(x) * PRU_CLK) % 1000000000))
  31.  
  32. struct pru_vring {
  33.     struct vring vr;
  34.     const char *name;
  35.     u32 align;
  36.     u32 notifyid;
  37. };
  38.  
  39. static void pru_vring_init(struct pru_vring *pvr, const char *name,
  40.     const struct fw_rsc_vdev_vring *rsc_vring)
  41. {
  42.     vring_init(&pvr->vr, rsc_vring->num,
  43.         (void *)rsc_vring->da, rsc_vring->align);
  44.     pvr->align = rsc_vring->align;
  45.     pvr->notifyid = rsc_vring->notifyid;
  46. }
  47.  
  48. struct pru_vring tx_ring;
  49. struct pru_vring rx_ring;
  50.  
  51. #define BUG_ON(x) \
  52.     do { \
  53.         if (x) { \
  54.             sc_printf("BUG_ON @%s:%d", __FILE__, __LINE__); \
  55.             sc_halt(); \
  56.         } \
  57.     } while(0)
  58.  
  59. #define DELAY_CYCLES(x) \
  60.     do { \
  61.         unsigned int t = (x); \
  62.         while (--t) { \
  63.             __asm(" "); \
  64.         } \
  65.     } while(0)
  66.  
  67. void sc_vprintf(const char *fmt, va_list ap)
  68. {
  69.     static char buf[128];
  70.  
  71.     vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
  72.     buf[sizeof(buf) - 1] = '\0';
  73.     sc_puts(buf);
  74. }
  75.  
  76. void sc_printf(const char *fmt, ...)
  77. {
  78.     va_list ap;
  79.    
  80.      va_start(ap, fmt);
  81.      sc_vprintf(fmt, ap);
  82.      va_end(ap);
  83. }
  84.  
  85. void dump_vring(const char *name, struct vring *vring, unsigned int align)
  86. {
  87.     struct vring_desc *vd;
  88.     int i, sz;
  89.  
  90.     sz = vring_size(vring->num, align);
  91.     sc_printf("vring %s @0x%x num %d size %d desc=0x%x avail=0x%x used=0x%x",
  92.         name, (unsigned int)vring->desc, vring->num, sz,
  93.         (unsigned int)vring->desc, (unsigned int)vring->avail,
  94.         (unsigned int)vring->used);
  95.  
  96.     for (i = 0; i < vring->num; i++) {
  97.         vd = &vring->desc[i];
  98.         sc_printf(" d#%d: a 0x%x l 0x%x f 0x%x n 0x%x",
  99.             i, (__u32)vd->addr, vd->len, vd->flags, vd->next);
  100.     }
  101.     sc_printf(" avail: flags 0x%x idx 0x%x",
  102.         vring->avail->flags, vring->avail->idx);
  103.  
  104.     for (i = 0; i < vring->num; i++) {
  105.         sc_printf(" a#%d: ring 0x%x", i,
  106.             vring->avail->ring[i]);
  107.     }
  108.     sc_printf(" avail: used_event_idx 0x%x",
  109.         vring->avail->ring[vring->num]);
  110.  
  111.     sc_printf(" used: flags 0x%x idx 0x%x",
  112.         vring->used->flags, vring->used->idx);
  113.     for (i = 0; i < vring->num; i++) {      
  114.         sc_printf(" u#%d: id 0x%x len 0x%x", i,
  115.             vring->used->ring[i].id,
  116.                 vring->used->ring[i].len);
  117.     }
  118.  
  119. }
  120.  
  121. /* event definitions */
  122. #define SYSEV_ARM_TO_PRU0   21
  123. #define SYSEV_ARM_TO_PRU1   22
  124. #define SYSEV_PRU0_TO_ARM   19
  125. #define SYSEV_PRU0_TO_PRU1  17
  126. #define SYSEV_PRU1_TO_ARM   20
  127. #define SYSEV_PRU1_TO_PRU0  19
  128.  
  129. void *resource_get_type(struct resource_table *res, int type, int idx)
  130. {
  131.     struct fw_rsc_hdr *rsc_hdr;
  132.     int i, j;
  133.  
  134.     j = 0;
  135.     for (i = 0; i < res->num; i++) {
  136.         rsc_hdr = (void *)((char *)res + res->offset[i]);
  137.         if (type >= 0 && rsc_hdr->type != type)
  138.             continue;
  139.         if (j == idx)
  140.             return &rsc_hdr->data[0];
  141.     }
  142.  
  143.     return NULL;
  144. }
  145.  
  146. static int ring_thread(struct pt *pt)
  147. {
  148.     int i;
  149.     struct resource_table *res;
  150.     struct fw_rsc_vdev *rsc_vdev;
  151.     struct fw_rsc_vdev_vring *rsc_vring;
  152.  
  153.     PT_BEGIN(pt);
  154.  
  155.     res = sc_get_cfg_resource_table();
  156.     BUG_ON(res == NULL);
  157.  
  158.     /* get first VDEV resource */
  159.     rsc_vdev = resource_get_type(res, RSC_VDEV, 0);
  160.     BUG_ON(rsc_vdev == NULL);
  161.  
  162.     BUG_ON(rsc_vdev->num_of_vrings < 2);
  163.     for (i = 0, rsc_vring = rsc_vdev->vring; i < 2; i++, rsc_vring++) {
  164.         sc_printf("VR#%d: da=0x%x align=0x%x num=0x%x notifyid=0x%x\n",
  165.                 i, rsc_vring->da, rsc_vring->align,
  166.                 rsc_vring->num, rsc_vring->notifyid);
  167.     }
  168.  
  169.     pru_vring_init(&tx_ring, "tx", &rsc_vdev->vring[0]);
  170.     pru_vring_init(&rx_ring, "rx", &rsc_vdev->vring[1]);
  171.  
  172.     PT_YIELD(pt);
  173.  
  174.     for (;;) {
  175.  
  176.         /* wait until we get the indication */
  177.         PT_WAIT_UNTIL(pt, (__R31 & (1 << 30)) != 0);
  178.  
  179.         if (PINTC_SRSR0 & (1 << SYSEV_ARM_TO_PRU0)) {
  180.             PINTC_SICR = SYSEV_ARM_TO_PRU0;
  181.             sc_printf("ARM to PRU0 event cleared");
  182.         }
  183.         if (PINTC_SRSR0 & (1 << SYSEV_PRU1_TO_PRU0)) {
  184.             PINTC_SICR = SYSEV_PRU1_TO_PRU0;
  185.             sc_printf("PRU1 to PRU0 event cleared");
  186.         }
  187.  
  188.         /*
  189.         sc_printf("ESR0 0x%x ESR1 0x%x", PINTC_ESR0, PINTC_ESR1);
  190.         sc_printf("SECR0 0x%x SECR1 0x%x", PINTC_SECR0, PINTC_SECR1);
  191.         sc_printf("SRSR0 0x%x SRSR1 0x%x", PINTC_SRSR0, PINTC_SRSR1);
  192.         */
  193.  
  194.         // dump_vring("tx", &tx_ring.vr, tx_ring.align);
  195.         // dump_vring("rx", &rx_ring.vr, rx_ring.align);
  196.  
  197.     }
  198.  
  199.     PT_END(pt);
  200. }
  201.  
  202. static int led_thread(struct pt *pt)
  203. {
  204.     PT_BEGIN(pt);
  205.  
  206.     /* IEP timer is incrementing by one */
  207.     PIEP_GLOBAL_CFG = GLOBAL_CFG_CNT_ENABLE |
  208.               GLOBAL_CFG_DEFAULT_INC(1) |
  209.               GLOBAL_CFG_CMP_INC(1);
  210.  
  211.     /* turn on led */
  212.     __R30 |= (1 << 5);
  213.  
  214.     /* delay with the timer */
  215.     PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(0); /* clear the interrupt */
  216.     PIEP_CMP_CMP0 = PIEP_COUNT + PRU_ns(200);
  217.     PIEP_CMP_CFG |= CMP_CFG_CMP_EN(0);
  218.  
  219.     PT_YIELD(pt);
  220.  
  221.     for (;;) {
  222.  
  223.         /* wait until we get the indication */
  224.         PT_WAIT_UNTIL(pt, (PIEP_CMP_STATUS & CMD_STATUS_CMP_HIT(0)) != 0);
  225.  
  226.         /* toggle led */
  227.         __R30 ^= (1 << 5);
  228.  
  229.         PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(0);
  230.         PIEP_CMP_CMP0 += PRU_us(200);
  231.     }
  232.  
  233.     PT_END(pt);
  234. }
  235.  
  236. static struct pt pt_ring, pt_led;
  237.  
  238. int main(int argc, char *argv[])
  239. {
  240.     /* enable OCP master port */
  241.     PRUCFG_SYSCFG &= ~SYSCFG_STANDBY_INIT;
  242.  
  243.     PT_INIT(&pt_ring);
  244.     PT_INIT(&pt_led);
  245.  
  246.     for (;;) {
  247.         ring_thread(&pt_ring);
  248.         led_thread(&pt_led);
  249.     }
  250. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement