Troubles testing UART3 on Exynos5

Reinier Millo Sánchez rmillo at
Mon Feb 23 01:31:29 CET 2015

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

    #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
       void setup_wait(L4::Ipc::Istream &istr, bool)
         istr << L4::Ipc::Small_buf(srv_rcv_cap.cap(),
         l4_utcb_br_u(istr.utcb())->bdr = 0;

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

    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
       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);

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

       : Icu_cap_array_svr<GPS_server>(1, &_irq),
         _running(false), _uart(0), _uart_irq(L4_INVALID_CAP),
       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;
       // if there still some data available send this info to the client
       if (_uart->char_avail())
       return i;

    int GPS_server::handle_irq()
       if (_irq.cap().is_valid())

       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

       // Inicializando UART
       _uart = new (malloc(sizeof(L4::Uart_s5pv210))) L4::Uart_s5pv210;

        * 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 */
           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;

        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;

    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);
           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);
       tmp = gps_srv.vcon_read(buffer,11);
           printf("Readed data: %s\n",buffer);
       // Wait for client requests
       return 0;

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

    -- 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
         caps = {
             sigma0       = L4.cast(L4.Proto.Factory,
             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/");

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

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

    local Hw = Io.Hw
    local Res = Io.Res
         UART3 = Hw.Device
             hid = "UART3";
             Res.mmio(0x12C30000, 0x12C3ffff);


         -- 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"));

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

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"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rmillo.vcf
Type: text/x-vcard
Size: 517 bytes
Desc: not available
URL: <>

More information about the l4-hackers mailing list