Hi
I'm testing Fiasco.OC+L4re on YSE5250 (Exynos 5250) Board. I have compiled and tested some examples. I'm testing a GPS Driver for the board. The GPS is conected over UART3 at 9600 baudrate, first I'm testing UART3 port comunicating the UART1 serial output with UART3. I'm following as example the serial-drv package on L4re.
I have adapted the source code to my uart driver
>>> gps_drv.cc

   #include <l4/drivers/uart_s3c2410.h>
   #include <l4/io/io.h>
   #include <l4/re/env>
   #include <l4/re/error_helper>
   #include <l4/re/namespace>
   #include <l4/re/util/cap_alloc>
   #include <l4/re/util/object_registry>
   #include <l4/re/util/icu_svr>
   #include <l4/re/util/vcon_svr>
   #include <l4/sys/irq>
   #include <l4/util/util.h>

   #include <cstdlib>
   #include <cstdio>

   #define IRQ_NUM 86
   #define UART_BASE 0x12C30000

   static L4::Cap<void> srv_rcv_cap;

   class Loop_hooks :
      public L4::Ipc_svr::Ignore_errors,
      public L4::Ipc_svr::Default_timeout,
      public L4::Ipc_svr::Compound_reply
   {
   public:
      void setup_wait(L4::Ipc::Istream &istr, bool)
      {
        istr.reset();
        istr << L4::Ipc::Small_buf(srv_rcv_cap.cap(),
   L4_RCV_ITEM_LOCAL_ID);
        l4_utcb_br_u(istr.utcb())->bdr = 0;
      }
   };

   using L4Re::Env;
   using L4Re::Util::Registry_server;
   static Registry_server<Loop_hooks> server(l4_utcb(),
                                      Env::env()->main_thread(),
                                      Env::env()->factory());

   using L4Re::Util::Vcon_svr;
   using L4Re::Util::Icu_cap_array_svr;

   class GPS_server :
      public Vcon_svr<GPS_server>,
      public Icu_cap_array_svr<GPS_server>,
      public L4::Server_object
   {
   public:
      GPS_server();
      virtual ~GPS_server() throw() {}

      bool running() const { return _running; }

      int vcon_write(const char *buffer, unsigned size);
      unsigned vcon_read(char *buffer, unsigned size);

      L4::Cap<void> rcv_cap() { return srv_rcv_cap; }

      int handle_irq();

      bool init();
      int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);

   private:
      bool _running;
      L4::Uart *_uart;
      L4::Cap<L4::Irq> _uart_irq;
      Icu_cap_array_svr<GPS_server>::Irq _irq;
   };

   GPS_server::GPS_server()
      : Icu_cap_array_svr<GPS_server>(1, &_irq),
        _running(false), _uart(0), _uart_irq(L4_INVALID_CAP),
        _irq()
   {
      if (init())
        _running = true;
   }

   int GPS_server::vcon_write(const char *buffer, unsigned size)
   {
      _uart->write(buffer, size);
      return -L4_EOK;
   }

   unsigned GPS_server::vcon_read(char *buffer, unsigned size)
   {
      unsigned i = 0;
      while (_uart->char_avail() && size)
        {
          int c = _uart->get_char(false);
          if (c >= 0)
        {
          buffer[i++] = (char)c;
          size--;
        }
          else
        break;
        }
      // if there still some data available send this info to the client
      if (_uart->char_avail())
        i++;
      else
        _uart_irq->unmask();
      return i;
   }

   int GPS_server::handle_irq()
   {
      if (_irq.cap().is_valid())
        _irq.cap()->trigger();

      return L4_EOK;
   }

   bool GPS_server::init()
   {
      l4_addr_t virt_base = 0;

      // Mapeando memoria de registros del UART
      if (l4io_request_iomem((l4_addr_t)UART_BASE, 0x1000,
   L4IO_MEM_NONCACHED, &virt_base))
        {
          printf("gps-drv: request io-memory from l4io failed.\n");
          return false;
        }
      printf("gps-drv: virtual base at:%lx\n", virt_base);

      // Inicializando memoria de los registros del UART
      L4::Io_register_block_mmio *regs = new
   L4::Io_register_block_mmio(virt_base);

      // Inicializando UART
      _uart = new (malloc(sizeof(L4::Uart_s5pv210))) L4::Uart_s5pv210;
      _uart->startup(regs);

      /**
       * FIX - Ajustando el BaudRate del UART
       * Valores calculados experimentalmente a través del UART1
       *   SCLK_UART = 100 MHz
       * TODO - Hacer el ajuste del BaudRate en el propio UART
       */
       regs->write<unsigned int>(0x28,0x28a);
       regs->write<unsigned int>(0x2C,0x0);


      _uart_irq = L4Re::Util::cap_alloc.alloc<L4::Irq>();
      if (!_uart_irq.is_valid())
        {
          printf("gps-drv: Alloc capability for uart-irq failed.\n");
          return false;
        }

      if (l4io_request_irq(IRQ_NUM, _uart_irq.cap()))
        {
          printf("gps-drv: request uart-irq from l4io failed\n");
          return false;
        }

     /* setting IRQ type to L4_IRQ_F_POS_EDGE seems to be wrong place */
      if
   (l4_error(_uart_irq->attach((l4_umword_t)static_cast<L4::Server_object
   *>(this),
        L4Re::Env::env()->main_thread())))
        {
          printf("gps-drv: attach to uart-irq failed.\n");
          return false;
        }

      if ((l4_ipc_error(_uart_irq->unmask(), l4_utcb())))
        {
          printf("gps-drv: unmask uart-irq failed.\n");
          return false;
        }
      _uart->enable_rx_irq(true);

       srv_rcv_cap = L4Re::Util::cap_alloc.alloc<void>();
      if (!srv_rcv_cap.is_valid())
        {
          printf("serial-drv: Alloc capability for rcv-cap failed.\\n");
          return false;
        }

      return true;
   }

   int
   GPS_server::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
   {
      l4_msgtag_t tag;
      ios >> tag;
      switch (tag.label())
        {
        case L4_PROTO_IRQ:
          if (!L4Re::Util::Icu_svr<GPS_server>::dispatch(obj, ios))
        return handle_irq();
        case L4_PROTO_LOG:
          return L4Re::Util::Vcon_svr<GPS_server>::dispatch(obj, ios);
        default:
          return -L4_EBADPROTO;
        }
   }

   int main()
   {
      char buffer[100];
      int tmp;
      static GPS_server gps_srv;

      // Register calculation server
      if (!server.registry()->register_obj(&gps_srv, "gps_srv").is_valid())
      {
        printf("Could not register GPS service, is there a 'gps_srv' in
   the caps table?\n");
        return 1;
      }

      if (!gps_srv.running())
      {
          printf("Failed to initialize serial driver; Aborting.\n");
          return 1;
      }

      gps_srv.vcon_write("Hola Mundo\n",11);
   while(1){
      tmp = gps_srv.vcon_read(buffer,11);
      if(tmp>0)
          printf("Readed data: %s\n",buffer);
   }
      // Wait for client requests
      server.loop();
      return 0;
   }

I have created my run config file
>>> gps-drv.cfg

   require("L4");
   -- Shortcuts
   local ld = L4.default_loader;
   local vbus_uart03 = ld:new_channel();
   local platform_ctl = ld:new_channel();
   local gps_srv = ld:new_channel();
   -- Start the IO Server
   ld:start(
   {
        caps = {
            sigma0       = L4.cast(L4.Proto.Factory,
   L4.Env.sigma0):create(L4.Proto.Sigma0);
            icu          = L4.Env.icu;
            platform_ctl = platform_ctl:svr();
            uart03        = vbus_uart03:svr();
        },
        log = { "IO Server", "green" },
        l4re_dbg = L4.Dbg.Warn,
   }, "rom/io rom/yse5250.devs rom/yse5250.io");

   -- Start the GPS Driver Server conected to UART3
   ld:start(
   {
        caps = {
            gps_srv = gps_srv:svr();
            vbus =  vbus_uart03;
        },
        log = {"GPS Driver","blue"}
   }, "rom/gps_drv");

And have created the yse5250.devs and yse5250.io to put the UART3 on a virtual BUS
>>> yse5250.devs

   local Hw = Io.Hw
   local Res = Io.Res
   Io.hw_add_devices
   {
        UART3 = Hw.Device
        {
            hid = "UART3";
            Res.irq(86);
            Res.mmio(0x12C30000, 0x12C3ffff);
        }
   }

>>> yse5250.io

   Io.add_vbusses
   {
        -- Create a virtual bus for a client and give access to UART3
        uart03 = Io.Vi.System_bus(function ()
            dev = wrap(Io.system_bus():match("UART3"));
        end);
   }

On modules.list have added an entry for my example

   entry GPS-Driver
   kernel fiasco -serial_esc
   roottask moe rom/gps-drv.cfg
   module l4re
   module ned
   module gps-drv.cfg
   module gps_drv
   module io
   module yse5250.devs
   module yse5250.io

After that i have compiled and uploaded the example to the board. At runtime, i got the "Hola Mundo" over UART3 but when I write in the UART3 I never read the written information.
Something is wrong with my code?

--
Lic. Reinier Millo Sánchez
Centro de Estudios de Informática
Universidad Central "Marta Abreu" de Las Villas

"antes de discutir ... respira;
  antes de hablar ... escucha;
 antes de escribir ... piensa;
  antes de herir ... siente;
 antes de rendirte ... intenta;
  antes de morir ... vive"

<<attachment: rmillo.vcf>>

_______________________________________________
l4-hackers mailing list
l4-hackers@os.inf.tu-dresden.de
http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers

Reply via email to