This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Quick question regarding using UART with linux on omap-l137

Other Parts Discussed in Thread: OMAP-L138, OMAP-L137, DA8XX

How do I enable UART1 in the kernel? Is this done through kernel configuration in which case I would have to rebuild the kernel, or can uarts be enable at run time?

Thanks,

-Seb

  • Hi Seb,

    Below wiki describes the steps to enable UART1 on OMAP-L138. Please check "enabling uart1" section for modification required in kernel.

    Thanks,

    Prakash

  • Hi Seb,

    Below wiki describes the steps to enable UART1 on OMAP-L138. Please check "enabling uart1" section for modification required in kernel.

    http://processors.wiki.ti.com/index.php/Enabling_UART1_on_AM18X/DA850/OMAP-L138_running_Linux

    Thanks,

    Prakash

  • Great, I'll give that a try.

    Thanks!

  • I found what seemed like an option to enable serial ports in the kernal configuration, but it didn't seem to make a difference.

    I'm probing UART1 and using minicom and/or tty commands to try to get the port to talk, but it's been silent. I pretty sure I have the hardware setup ok (multiplexers are setup for the OMAP-l137 evm). I'm wondering if there's something I need to do for internal multiplexing, but wouldn't the kernel take care of that?

    Thanks for any help,

    -Seb

  • Seb,

    The patch specified in the wiki will enable UART1 on OMAP-L138 not for OMAP-L137. So please keep them as a reference.

    Please do pinmuxing for UART1 in board-da830.c similar to the way its done in patch 1 specified in wiki. Since UART2 pinmuxing is done by bootloader it is functional, otherwise it should have been also taken care here.

    Thanks,

    Prakash

  • hmmm, can't find a board-da*.c file.

    I recalled that I had run an example GPIO app, which handled some muxing. It was an external module which include asm/arch/mux.h and asm/arch/harware.h. I think these were written by MaxiVista. Anyway, I tried making a module that would do the muxing, here's the code:

     

    #include <linux/module.h>
    #include <linux/version.h>
    #include <linux/delay.h>
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/arch/hardware.h>
    #include <asm/arch/mux.h>
    static int uart_rx_pin = DA8XX_UART1_RXD;
    static int uart_tx_pin = DA8XX_UART1_TXD;
    int init_module()
    {
    	int status;
    	status = davinci_cfg_reg(uart_tx_pin, PINMUX_RESV);
    	if(status < 0){
    		printk("TX pin could not be muxed for UART functionality");
    		return status;
    	}
    	status = davinci_cfg_reg(uart_rx_pin, PINMUX_RESV);
    	if(status < 0){
    		printk("RX pin could not be muxed for UART functionality");
    		return status;
    	}
    	return 0;
    }
    void cleanup_module(void){
    	davinci_cfg_reg(uart_tx_pin, PINMUX_FREE);
    	davinci_cfg_reg(uart_rx_pin, PINMUX_FREE);
    }

    However, upon the insmod command, I get this output:

    Pin UART1_TXD already used for GPIO3_10.
    TX pin could not be muxed for UART functionalityinsmod: error inserting 'setup_uart.ko': -1 Device or resource busy
    

    Is there a way I can free those GPIOs?

     

    Thanks,

    -Seb

  • Hi Seb,

    I have attached the patch which does the pinmuxing for UART1 on OMAP-L137 and applies on 03.20.00.14 release. Can you give it a try?

     

  • Certainly, thank you. Sorry to ask, but I'm still new at this, to patch do I simply run the text file as a script? Should I run the script from a specific pwd? Then I rebuild the kernel, correct?

    Thanks

  • From top of your kernel dir run patch -p1 < temp_patch.txt. It should succeed without any error as shown below, then rebuild the kernel.

    $ patch -p1 < temp_patch.txt
    patching file arch/arm/mach-davinci/board-da830-evm.c
    $

    Regards,

    Prakash

  • Didn't work. Like I said before, there's no board-da830-evm.c in my directory tree, I may have outdated stuff. I'm currently just using the SDK provided by ti specifically for the omap-l137.

    ~/workdir/lsp/ti-davinci/linux-2.6.18_pro500$ patch -p1 < ../../../../temp_patch.txt
    can't find file to patch at input line 5
    Perhaps you used the wrong -p or --strip option?
    The text leading up to this was:
    --------------------------
    |diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
    |index 6569aa5..562f8a9 100755
    |--- a/arch/arm/mach-davinci/board-da830-evm.c
    |+++ b/arch/arm/mach-davinci/board-da830-evm.c
    --------------------------
    File to patch:
    

     

    There is however similar files like board-dm355-evm.c, board-dm6467-evm.c and board-evm.c

    -Seb

  • There's also a arch/arm/mach-davinci/mux_cfg.c which seems to setup all mux registers

    and a arch/arm/mach-da8xx/mux_cfg.c that seems to do the same

  • Now that I look at it, there's a bunch of object files in arch/arm/mach-da8xx so the kernel must build from this. There's a board-evm.c in addition to mux_cfg.c here.

  • As i have mentioned earlier please use latest 03.20.00.14 release from DaVinci PSP releases.

    Regards,

    Prakash

  • I think you need to copy values from mux_cfg.c:da8xx_uart1_pins to board-evm.c:evm_uart1_pins.

    static const short evm_uart1_pins[] = {
        DA8XX_UART1_RXD, DA8XX_UART1_TXD,
        -1
    };

    You must demux some other peripheral to avoid conflict. I think you do that by removing values from that peripheral's pin list in board-evm.c.

     

  • I played with this file a bit. If I leave the GPIO3_10 (Which is multiplexed with Tx of uart1) value in, I can control the port with GPIO, this gave me a chance to check the hardware, and seems ok.

    Next I tried adding the values as you suggested, and I also removed the conflicting values. I tried using minicom to open the serial port, but still nothing. However, if I try loading that little module I wrote (see post 7), it seems to be able to reserve the mux for uart. I haven't yet tried using the port from the module. I did try using minicom after installing the module, but doesn't make a difference. I'm not even all that sure what the module does exactly.

  • I've never had much success with minicom. Always get stuck in some screen I can't escape from. I usually test serial devices using HyperTerminal on the PC side and a shell on the target.

    I believe by default all 3 UARTs are enabled. They're just not MUX'ed to the outside world. You should see this line in the boot messages.

    serial8250.0: ttyS1 at MMIO map 0x1c20400 mem 0xfed0c000 (irq = 53) is a 16550A

    I use this command on the attach a shell to a serial device

    /sbin/getty -n  -l /bin/sh /dev/ttyS1 115200

    Double check that your serial cable, ie. null vs straight through, is correct for your situation.

  • Yes, all three UARTs are there, you can see them on bootup, also there's ttyS0 ttyS1 and ttyS2 (default shell) in /dev.

    In board-evm.c I can successfully mux the GPIO and toggle the line. But nothing is coming out when I mux UART1_TXD from either minicom or attaching the shell as you suggested. I'm pretty sure Linux does configure the line for output, it goes high at some point during boot, regardless of if I muxed for GPIO or UART.

    I must be missing something...

  • Here's an interesting observation, there's both a evm_uart0_pins and evm_uart1_pins arrays, but no evm_uart2_pins.

    The only reference I can see to uart2 in board-evm.c is a little section of code that I can only guess sets up uart2 as the default shell:

    #ifdef CONFIG_SERIAL_8250_CONSOLE
    static int __init da8xx_evm_console_init(void)
    {
    	return add_preferred_console("ttyS", 2, "115200");
    }
    console_initcall(da8xx_evm_console_init);
    #endif

    Another thing is that there's a function that overrides something. I had commented out the part with uart1, but maybe it should still be there. Guess I could always try.

    static void da8xx_evm_pinmux_override(void)
    {
    	da8xx_psc0_pins[DA8XX_LPSC0_EMIF25] = evm_emif25_pins;
    	da8xx_psc0_pins[DA8XX_LPSC0_MMC_SD] = evm_mmc_sd_pins;
    	da8xx_psc0_pins[DA8XX_LPSC0_UART0] = evm_uart0_pins;
    	//Seb - Let's not override UART1
    	//da8xx_psc1_pins[DA8XX_LPSC1_UART1] = evm_uart1_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_USB20] = evm_usb20_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_USB11] = evm_usb11_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_McASP0] = evm_mcasp0_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_McASP1] = evm_mcasp1_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_McASP2] = evm_mcasp2_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_SPI1] = evm_spi1_pins;
    	da8xx_psc1_pins[DA8XX_LPSC1_I2C] = evm_i2c_pins;
    }

  • It's a mystery. Not much I can suggest. UART2 will have been MUX'ed in by U-Boot for it's console messages. The bootargs passed to Linux from U-Boot specfies ttyS2 to be console. Seems the kernel code is expecting that by the absence of the evm_uart2_pins pin array.

  • I got uart 1 to work with a stand-alone program (code composer on the DSP). In addition to usual UART registers, I had to set the PINMUX11 register. Is there anyway I can check to see if Linux is or isn't setting this specific register?

  • In other threads on this forum, I've seen mention of the debugfs. Never got it to work for me. My kernel probably isn't configured for debugfs. Might not be available on the older kernels.

    mount -t debugfs debug /sys/kernel/debug
    cd /sys/kernel/debug/omap_mux

    Parts of PINMUX11 should be set when you pass the evm_uart1_pins array to the config function. For example, the value DA8XX_UART1_RXD will be eventually used as in index into that huge array in mux_cfg.c. The array entry will specify which MUX register/bitfield to modify and what value to write.

    I guess you could printk the value of PINMUX11 at the bottom of your board init function. Dig around the pin mux config functions to figure out the virtual address of PINMUX11. Or maybe put a printk in the pin mux config function itself. Not at my work-station. Can't say where is the exact spot.

  • Hi,

    You can use devmem utility($devmem <physical_address>) to dump pinmux register contents. Below is the sample log(dumps pinmux0 register) on OMAP-L138.

    root@da850-omapl138-evm:~# ./devmem 0x01c14120
    /dev/mem opened.
    Memory mapped at address 0x4025a000.
    Value at address 0x1C14120 (0x4025a120): 0x21101111

    root@da850-omapl138-evm:~#

    Note: You cannot use same utility for setting the pinmux registers.

    Regards,

    Prakash

     

  • Doesn't look like I have the devmem utility.

    I'll have to try what Norman said sometime later.

     

    root@(none):~# ls /dev
    MAKEDEV  mem        port     stdout  tty19  tty31  tty44  tty57  urandom
    bus      mmcblk0    ppp      tts     tty2   tty32  tty45  tty58  usbdev1.1_ep00
    console  mmcblk0p1  ptmx     tty     tty20  tty33  tty46  tty59  usbdev1.1_ep81
    core     mtd0       pts      tty0    tty21  tty34  tty47  tty6   usbdev2.1_ep00
    fd       mtd0ro     ram0     tty1    tty22  tty35  tty48  tty60  usbdev2.1_ep81
    full     mtd1       random   tty10   tty23  tty36  tty49  tty61  vc
    i2c      mtd1ro     rd       tty11   tty24  tty37  tty5   tty62  vcc
    i2c-0    mtd2       rtc      tty12   tty25  tty38  tty50  tty63  vcs
    initctl  mtd2ro     rtc0     tty13   tty26  tty39  tty51  tty7   vcsa
    input    mtdblock0  shm      tty14   tty27  tty4   tty52  tty8   watchdog
    kmem     mtdblock1  snd      tty15   tty28  tty40  tty53  tty9   zero
    kmsg     mtdblock2  sndstat  tty16   tty29  tty41  tty54  ttyS0
    log      net        stderr   tty17   tty3   tty42  tty55  ttyS1
    loop     null       stdin    tty18   tty30  tty43  tty56  ttyS2
    root@(none):~# ls /bin
    awk             date           grep      mktemp         rm         tcsh
    bash            dd             gunzip    more           rmdir      tempfile
    busybox         df             gzip      mount          rpm        touch
    busybox.static  dir            hostname  mountpoint     run-parts  true
    cat             dircolors      install   mv             sed        umount
    chgrp           dmesg          ip        netstat        setserial  uname
    chmod           dnsdomainname  kill      nice           sh         uncompress
    chown           domainname     link      nisdomainname  shred      unlink
    chroot          du             ln        pidof          sleep      usleep
    cp              echo           loadkeys  ping           sort       vdir
    cpio            ed             login     ping6          stat       vi
    csh             egrep          ls        ps             stty       which
    cut             false          mkdir     pwd            su         ypdomainname
    dash            fgrep          mkfifo    readlink       sync       zcat
    dash.static     fuser          mknod     red            tar
    root@(none):~# ls /sbin
    MAKEDEV                 getty              mgetty         resize2fs
    agetty                  halt               mii-tool       restore
    badblocks               hdparm             mkcramfs       rmmod
    blkid                   hotplug            mkdosfs        rmt
    blockdev                hwclock            mke2fs         route
    bootlogd                ide_info           mkfs           rrestore
    bootpc                  ifconfig           mkfs.cramfs    rtacct
    brctl                   ifdown             mkfs.ext2      rtmon
    cardctl                 ifport             mkfs.ext3      runlevel
    cardmgr                 ifrename           mkfs.jffs      scsi_id
    cfdisk                  ifup               mkfs.jffs2     setpcaps
    debugfs                 ifuser             mkfs.jfs       setpci
    depmod                  init               mkfs.minix     sfdisk
    dhcpcd                  insmod             mkfs.msdos     shutdown
    dhcpcd-bin              insmod.static      mkfs.vfat      slattach
    dosfsck                 install-info       mkfs.xfs       sln
    dump                    ip                 mksquashfs     start-stop-daemon
    dump_cardbus            ip6tables          mkswap         sucap
    dump_cis                ip6tables-restore  mkyaffs2image  sulogin
    dump_cisreg             ip6tables-save     mkyaffsimage   swapoff
    dump_exca               ipmaddr            modinfo        swapon
    dumpe2fs                iptables           modprobe       sysctl
    e2fsck                  iptables-restore   mount.nfs      syslogd
    e2image                 iptables-save      mount.nfs4     syslogd-ipv6
    e2label                 iptables-xml       mount.smb      tc
    execcap                 iptunnel           mount.smbfs    telinit
    fbgetty                 iscsi_discovery    nameif         tune2fs
    fdisk                   iscsiadm           pack_cis       udev
    findfs                  iscsid             pccardctl      udev.static
    fsck                    iwconfig           pcic_probe     udevcontrol
    fsck.cramfs             iwevent            pcinitrd       udevd
    fsck.ext2               iwgetid            pivot_root     udevsettle
    fsck.ext3               iwlist             plipconfig     udevstart
    fsck.jfs                iwpriv             pmap_dump      udevstart.static
    fsck.minix              iwspy              pmap_set       udevtrigger
    fsck.msdos              jfs_fsck           portmap        umount.nfs
    fsck.nfs                jfs_mkfs           poweroff       umount.nfs4
    fsck.vfat               killall5           quotacheck     unix_chkpwd
    fsck.xfs                klogd              quotaoff       unsquashfs
    ftl_check               ldconfig           quotaon        update-pciids
    ftl_format              logsave            rarp           vconfig
    fwparam_ibft            losetup            raw            vol_id
    generate-modprobe.conf  lspci              rdump          xfs_repair
    getpcaps                lspcmcia           reboot

  • Please copy attached devmem2 binary to your target filesystem and use it.

    Or

    build attached devmem2.c with same cross toolchain which you used to build kernel and copy binary to target filesystem.

    Regards,

    Prakash

    devmem.zip
  • I'm getting permission denied. Tried using sudo, if there's such a thing, but I get

    sudo: can't stat /etc/sudoers: No such file or directory

  • You will get "permission denied" if you haven't made it executable. I think you forgot to "chmod +x devmem2". I tried the pre-compiled binary and got an "Illegal instruction". It works if I compile it using the same cross-compiler as used on my kernel.

    root@da830-omapl137-evm:~# ./devmem2 0x01C14120
    /dev/mem opened.
    Memory mapped at address 0x4023a000.
    Value at address 0x1C14120 (0x4023a120): 0x11111100

     

  • Oh ya I forgot to add executable flag.

    Well anyway, I get "Illegal instruction" even after using my cross-compiler. Something to do with permissions?

    ls -al /dev/:

    crw-r-----  1 root kmem   1,    1 Feb 25 06:49 mem

    crw-r-----  1 root kmem   1,    2 Feb 25 06:49 kmem

  • My permissions on "/dev/mem" are the same as yours. Maybe try cross-compiling a "hello world" program to double check your setup. I use the CodeSourcery toolchain and my compile line is:

    arm-none-linux-gnueabi-gcc -o devmem2 devmem2.c

    My path includes the path to the CodeSourcery bin "/opt/arm-2009q1/bin". Your toolchain is probably different.

     

  • No problems with compiling. I have a couple of programs, including some that use the audio drivers, that work just fine.

  • Might be a kernel version difference. I am using DVSDK-3.21 aka linux-2.6.37. Was using the 2.6.18 kernel but needed all the USB bug fixes. Maybe the default config for 2.6.37 enabled the "/dev/mem" interface but 2.6.18 did not.

     

  • I took a more detailed look at the 2.6.18 code. In theory, three arrays need modification and add one function call in board-evm.c. Enabling UART1 will mean loss of McAsp0 and SPI1. You've probably already tried...just confirming what's been tried. Note that the code that uses McAsp and SPI1 is still included. Need to configure those out of the kernel.

    board-evm.c
    /* Remove mux of AXR0_9, AXR0_10, GPIO3_9, GPIO3_10. */
    /* Add mux of UART1_RXD, DA8XX_UART1_TXD. */

    static const short evm_mcasp0_pins[] = {
        /* DA8XX_AXR0_9, DA8XX_AFSR0, DA8XX_ACLKR0, *//* Remove these */
        -1
    };

    static const short evm_spi1_pins[] = {
        /* DA8XX_SPI1_SOMI_0, DA8XX_SPI1_SIMO_0, DA8XX_SPI1_CLK, DA8XX_GPIO3_10,*//* Remove these */
        -1
    };

    static const short evm_uart1_pins[] = {
        DA8XX_UART1_RXD, DA8XX_UART1_TXD, /* Add this */
        -1
    };

    static void da8xx_evm_pinmux_override(void)
    {
        da8xx_psc0_pins[DA8XX_LPSC0_EMIF25] = evm_emif25_pins;
        da8xx_psc0_pins[DA8XX_LPSC0_MMC_SD] = evm_mmc_sd_pins;

        da8xx_psc0_pins[DA8XX_LPSC0_UART0] = evm_uart0_pins;
        da8xx_psc1_pins[DA8XX_LPSC1_UART1] = evm_uart1_pins;// Leave this

        da8xx_psc1_pins[DA8XX_LPSC1_USB20] = evm_usb20_pins;
        da8xx_psc1_pins[DA8XX_LPSC1_USB11] = evm_usb11_pins;

        da8xx_psc1_pins[DA8XX_LPSC1_McASP0] = evm_mcasp0_pins;
        da8xx_psc1_pins[DA8XX_LPSC1_McASP1] = evm_mcasp1_pins;
        da8xx_psc1_pins[DA8XX_LPSC1_McASP2] = evm_mcasp2_pins;

        da8xx_psc1_pins[DA8XX_LPSC1_SPI1] = evm_spi1_pins;

        da8xx_psc1_pins[DA8XX_LPSC1_I2C] = evm_i2c_pins;
    }

    static void __init da8xx_evm_map_io(void)
    {
        da8xx_evm_pinmux_override();
        da8xx_map_common_io();

        /* UART clock needs to be ready otherwise kgdbwait won't work */
        da8xx_uart_clk_init(DAVINCI_DA8XX_UART_CLK);
        da8xx_kgdb_init();

        /* Initialize the DA8XX EVM board settigs */
        da8xx_init_common_hw();
        da8xx_evm_psc_init();
    }

    static __init void da8xx_evm_psc_init(void)
    {
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_TPCC, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_TPTC0, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_TPTC1, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_AINTC, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_ARM_RAM_ROM,
                   1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_SECU_MGR, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_SCR0_SS, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_SCR1_SS, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_SCR2_SS, 1);
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 0, DA8XX_LPSC0_DMAX, 1);
    #if defined(CONFIG_TI_CPPI41) || defined(CONFIG_TI_CPPI41_MODULE)
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 1, DA8XX_LPSC1_USB20, 1);
    #endif
    #ifdef    CONFIG_INPUT_EQEP
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 1, DA8XX_LPSC1_EQEP, 1);
    #endif
        davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, 1, DA8XX_LPSC1_UART1, 1); /* Add this */
    }

    The call to davinci_psc_config() might not be needed as it may be indirectly called from da8xx_clk_init().

     

  • I hadn't removed all the pins for mcasp0 and spi1. But, I just tried recompiling with the modifications you described, but didn't make a difference.

    I really appreciate the effort your putting in to help me Norman

  • After removing the mcasp0 and spi1 pins, maybe retry that loadable module code from MaxiVista that originally gave you the "Pin UART1_TXD already used for GPIO3_10." error. Hopefully those pins are no longer reserved,

     

  • I wrote that code, it's based off a GPIO example where the module configs some GPIO pins and turn them on and off a couple of times. I used this code to test the UART_TX pin (when it's configured for GPIO3_10)

    This is the original GPIO code:

    /*
     * Copyright (C) 2009 Texas Instruments Inc
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option)any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     */
    **includes**
    static int gpio_num = 12;	/* gpio_num = (bank_num * 16) + pin_num */
    static int gpio_pin = DA8XX_GPIO0_12;
    static int num_irq;
    static irqreturn_t handler (int irq, void * dev, struct pt_regs * regs)
    {
    	num_irq++;
    	return IRQ_HANDLED;
    }
    int init_module() 
    {
    	int status;
    	int i;
    	int gpio_val = 0;
    	
    	printk("Testing gpio %d (connected to LED DS1)\n", gpio_num);
    	/* init/set pinmux */
    	status = davinci_cfg_reg(gpio_pin, PINMUX_RESV);
    	if (status < 0) {
    		printk("pin could not be muxed for GPIO functionality %d\n", gpio_num);
    		return status;
    	}
    	
    	status = gpio_request(gpio_num, "gpio_test\n");
    	if (status < 0) {
    		printk("ERROR can not open GPIO %d\n", gpio_num);
    		return status;
    	}
    	status = request_irq(gpio_to_irq(gpio_num), handler, 0, "gpio_test", NULL);
    	if(status < 0) {
    		printk(KERN_ERR "error %d requesting GPIO IRQ %d\n", status, gpio_num);
    		return status;
    	}
    	set_irq_type(gpio_to_irq(gpio_num), IRQT_RISING);
    	for(i = 0; i < 10; i++) {
    		printk("Switching LED %s; ", (gpio_val) ? "OFF" : "ON");				
    		gpio_direction_output(gpio_num, gpio_val);			
    		gpio_set_value(gpio_num, gpio_val);			
    		msleep(3000);
    		printk("Current LED state: %s.\n", (gpio_get_value(gpio_num) == 0) ? "ON" : "OFF");
    		gpio_val ^= 1;
    	}
    	printk("Number of GPIO irq: %d\n", num_irq);
    	return 0;
    }
    void cleanup_module(void) {
    	
    	gpio_free(gpio_num);
    	free_irq(gpio_to_irq(gpio_num), NULL);
    	/* init/set pinmux */
    	davinci_cfg_reg(gpio_pin, PINMUX_FREE);
    }
    MODULE_LICENSE("GPL");

    Below is the code I wrote. It reserves the uart pins, but doesn't do much else. It does work, there's no errors so long the uart pins are configured in board-evm.c. I was hoping the module would allow Linux to freelly use the serial port, but maybe it just reserves it for the module only. In which case, I'll need a way to try to send/receive data with the module, instaid of Linux standard serial interfaces or something.

    #include
    
    **includes**
    static int uart_rx_pin = DA8XX_UART1_RXD;
    static int uart_tx_pin = DA8XX_UART1_TXD;
    int init_module()
    {
    	int status;
    	status = davinci_cfg_reg(uart_tx_pin, PINMUX_RESV);
    	if(status < 0){
    		printk("TX pin could not be muxed for UART functionality");
    		return status;
    	}
    	status = davinci_cfg_reg(uart_rx_pin, PINMUX_RESV);
    	if(status < 0){
    		printk("RX pin could not be muxed for UART functionality");
    		return status;
    	}
    	return 0;
    }
    void cleanup_module(void){
    	davinci_cfg_reg(uart_tx_pin, PINMUX_FREE);
    	davinci_cfg_reg(uart_rx_pin, PINMUX_FREE);
    }
    MODULE_LICENSE("GPL");

  • Took a quick look at the davinci_cfg_reg() in arch/arm/plat-davinci/mux.c. I don't think it remembers who is making a "reservation". I think "reservation" is more like "assign". If loading your module doesn't emit warnings, I think the UART1 pins are mux'ed in. When you unload the module, those pins will be "freed". I think that means the UART1 pins are unmux'ed and the pins are then high-Z. That would be bad.

    Assuming the UART1 pins are proper mux'ed in, I think you are right in thinking the serial port driver appears to not drive those pins. Directly reading and writing from the port in a module should be possible. Just a lot work. I've tried really hard to avoid coding in the kernel myself.

  • Guess I should have called this thread "Difficult question regarding UART1 on OMAP-l137 EVM" lol

    I'll try and see if I can get at least something from the module.

  • Yeah. Linux is free but expensive in time.Searched this forum a bit. This has some debug hints and possible solution.

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/29383.aspx

    The post by Paolo Cazzola mentions having manually set the power management bits on UART1.

  • That solved it! I had searched the Linux forum for my issue, but I forgot about the omap-l137 forum, nice find. Thank you very much Norman!

  • All this has got me worried about the kernel I am using, DVSDK-03.21 aka linux-2.6.37. Looks like it got fixed in the later version. The 2.6.37 version is online here.

    http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=arch/arm/mach-davinci/serial.c;h=d7602c50490343bff81999ff2eec8a6699b69d96;hb=HEAD

    The path to 2.6.18 version is arch/arm/plat-davinci/serial.c. The later version does a little more initialization. More reason to move up