Advertisement
botsnlinux

libmetal R5 receiver

Apr 2nd, 2018
779
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.52 KB | None | 0 0
  1.  
  2. #include <metal/sys.h>
  3. #include <metal/device.h>
  4. #include <metal/io.h>
  5. #include <metal/alloc.h>
  6.  
  7. #define BUS_NAME        "generic"
  8. #define SHM_DEV_NAME    "3e800000.shm"
  9.  
  10. #define SHM_BASE_ADDR   0x3E800000
  11. /* Each I/O region can contain multiple pages.
  12.  * In baremetal system, the memory mapping is flat, there is no
  13.  * virtual memory.
  14.  * We can assume there is only one page in the whole baremetal system.
  15.  */
  16. #define DEFAULT_PAGE_SHIFT (-1UL)
  17. #define DEFAULT_PAGE_MASK  (-1UL)
  18.  
  19. // This stuff will eventually live in its own header
  20. typedef struct {
  21.   uint8_t status;
  22.   uint8_t value;
  23. } msgblock;
  24.  
  25. const int MSGBUF_LEN = 10;
  26.  
  27. const int LED_GPIO_BASE = 0x80000000;
  28.  
  29. int main(int argc, char* argv[])
  30. {
  31.   uint32_t* leds = (uint32_t*)LED_GPIO_BASE;
  32.   *leds = 0x55;
  33.  
  34.   struct metal_init_params metal_param = METAL_INIT_DEFAULTS;
  35.   metal_init(&metal_param);
  36.  
  37.   // Shared memory device
  38.   struct metal_device dev = {
  39.     .name = SHM_DEV_NAME,
  40.     .bus = NULL,
  41.     .num_regions = 1,
  42.     .regions = {
  43.       {
  44.         .virt = (void *)SHM_BASE_ADDR,
  45.         .physmap = (metal_phys_addr_t*)SHM_BASE_ADDR,
  46.         .size = 0x800000,
  47.         .page_shift = DEFAULT_PAGE_SHIFT,
  48.         .page_mask = DEFAULT_PAGE_MASK,
  49.         .mem_flags = NORM_SHARED_NCACHE |
  50.             PRIV_RW_USER_RW,
  51.         .ops = {NULL},
  52.       }
  53.     },
  54.     .node = {NULL},
  55.     .irq_num = 0,
  56.     .irq_info = NULL,
  57.   };
  58.  
  59.  
  60.   // This isn't needed in the new version
  61.   metal_bus_register(&metal_generic_bus);
  62.  
  63.   int err = metal_register_generic_device(&dev);
  64.   if(err){
  65.       print("Failed to register device\n");
  66.   }
  67.  
  68.   struct metal_device* shm_dev;
  69.   err = metal_device_open(BUS_NAME, SHM_DEV_NAME, &shm_dev);
  70.   if(err){
  71.       print("Failed to open device\n");
  72.   }
  73.  
  74.   // Now get the I/O region
  75.   struct metal_io_region *io = NULL;
  76.   io = metal_device_io_region(shm_dev, 0);
  77.   if(!io){
  78.     print("Failed to get I/O region\n");
  79.   }
  80.  
  81.   int msgcount = 0;
  82.  
  83.   union {
  84.       msgblock msg;
  85.       uint16_t raw;
  86.   } message;
  87.  
  88.   while(1){
  89.     Xil_DCacheInvalidateRange((uint32_t)SHM_BASE_ADDR, 0x100);
  90.  
  91.     // Get a message from the queue
  92.     message.raw = metal_io_read16(io, msgcount*sizeof(msgblock));
  93.  
  94.     // If the message is valid, set the LEDs accordingly
  95.     // Otherwise, just keep spinning
  96.     if(message.msg.status == 0x01){
  97.       *leds = message.msg.value;
  98.       metal_io_write16(io, msgcount*sizeof(msgblock), 0); // Clear this message
  99.       msgcount = (msgcount + 1) % MSGBUF_LEN;
  100.     }
  101.     sleep(1);
  102.   }
  103.  
  104.   metal_device_close(shm_dev);
  105.   metal_finish();
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement