Menu

GPIO control with MK2

2017-03-22
2017-03-22
  • Antoine Roy-Gobeil

    Hello,

    I am trying to control the GPIO on the MK2-A810 but I can't get it to work. I'm basically using the following Python script which reuses functions from "mk2_spm_control.py". What am I missing?

    Thank you for your help,
    Antoine

    import sys
    import struct
    
    # Set here the SRanger dev to be used:
    sr_dev_path = "/dev/sranger_mk2_1"
    magic_address = 0x5000
    magic_fmt = "<HHHHHHHHHHHHHHHHHHHHHHHHHH"
    i_CR_generic_io = 21
    
    # open SRanger, read magic offsets (look at FB_spm_dataexchange.h -> SPM_MAGIC_DATA_LOCATIONS)
    def open_sranger():
        sr = open (sr_dev_path, "rw")
        sr.seek (magic_address, 1)
        magic = struct.unpack (magic_fmt, sr.read (struct.calcsize (magic_fmt)))
        sr.close ()
        return magic
    
    magic = open_sranger()
    print ("Magic:", magic)
    
    # Copied from "mk2_spm_contro.py"
    def CoolRunnerIOWritePort(data):
        sr = open (sr_dev_path, "wb")
        sr.seek (magic[i_CR_generic_io]+4, 1)
        sr.write (struct.pack ("<H", data)) # Start (code what 1: WR, 2: RD, 3: DirReconf), Stop, Dir-, In-, Out-data
        sr.seek (magic[i_CR_generic_io], 1)
        sr.write (struct.pack ("<hh", 1,0)) # Start (code what 1: WR, 2: RD, 3: DirReconf), Stop, Dir-, In-, Out-data
        sr.close ()
        return 1
    
    # Copied from "mk2_spm_contro.py"
    def CoolRunnerIOWrite(s):
        data = int (s, 16) # Hex
        CoolRunnerIOWritePort (data)
        print "GPIO WR: 0x%04X" %data
    
    # Copied from "mk2_spm_contro.py"
    def CoolRunnerIOWriteDirection(s):
        dirdata = int (s, 16) # Hex
        sr = open (sr_dev_path, "wb")
        sr.seek (magic[i_CR_generic_io], 1)
        sr.write (struct.pack ("<hhH", 3,0, dirdata)) # Start (code what 1: WR, 2: RD, 3: DirReconf), Stop, Dir-, In-, Out-data
        sr.close ()
        print ("GPIO CONF DIRECTION: 0x%04X" %dirdata)
        return 1
    
    # Set direction of all pins to OUTPUT
    CoolRunnerIOWriteDirection("0xFFFF")
    # Set all pins to ON
    CoolRunnerIOWrite("0xFFFF")
    
     
  • Thorsten Wagner

    Thorsten Wagner - 2017-03-23

    Dear Antoine.

    Please check line 5 of your skript: The mk2 card might be connected to the block device /dev/sranger_mk23_0.

    Thorsten :-)

     
  • Antoine Roy-Gobeil

    Dear Thorsten,

    I should have mentionned that the hardware is working properly and is connected to the block device "/dev/sranger_mk2_1" in my setup. I can get the MK2 card to output pulses (using the script "mk2_spm_control.py") but I can't simply turn them ON using "CoolRunnerIOWrite("0xFFFF")". Why is that?

    Thank you,
    Antoine

     
  • Percy Zahl

    Percy Zahl - 2017-03-24

    Hey Antoine,

    so what exactly is not working, any error? Or just nothing is happening? May be simply the output is "inverted" from what you expect -- using any possibly inverting driver or just a meter to check? Try to toggle 0/1 and see! But I be leave "high" (TTL on) on the GPIO port should be digital 1 also.

    One note -- you may need to introduce a few ms delay between both commands to make sure the are both executed.

    for example add this line:
    add on top:
    import time

    and use this between dir and data write:
    time.sleep(.05)

    You may also want to use "os" for read/write -- it seam to be more efficient and I remember some kind of trouble with the other method under some circuimstances I just do not recall, like this:

    sr = open (sr_dev_path, "wb")
    os.lseek (sr.fileno(), magic[...], 0)
    os.write (sr.fileno(), struct.pack ("<h", 0))
    ...

    FYI also:
    The GPIO action (R/W/Dir) is executed when you write the "start" flag in the structure.
    It is always goingto GPIO Port 0:

    From FB_spm_statemaschine.c

                    /* Do CoolRunner generic IO ? */
                    if (CR_generic_io.start){
                            switch (CR_generic_io.start){
                            case 1: WR_GPIO (GPIO_Data_0, &CR_generic_io.gpio_data_out, 1); break; // write port
                            case 2: WR_GPIO (GPIO_Data_0, &CR_generic_io.gpio_data_in, 0); break; // read port
                            case 3: WR_GPIO (GPIO_Dir_0, &CR_generic_io.gpio_direction_bits, 1); break; // reconfigure port
                            default: break;
                            }
                            CR_generic_io.start=0;
                    }
    

    PS: If I find a moment I'll test it tomorrow real quick and see, I have a nice LED dongle for that.... only have a MK3 prototype at home right now ;)

    -P

     

    Last edit: Percy Zahl 2017-03-24
  • Percy Zahl

    Percy Zahl - 2017-03-24

    Dear Antoine, I made you a simplified script, tested it also and it works just fine this way:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #!/usr/bin/python
    
    import sys
    import time
    import struct
    
    # Set here the SRanger dev to be used:
    sr_dev_path = "/dev/sranger_mk2_1"
    magic_address = 0x5000
    magic_fmt = "<HHHHHHHHHHHHHHHHHHHHHHHHHH"
    i_CR_generic_io = 21
    
    # open SRanger, read magic offsets (look at FB_spm_dataexchange.h -> SPM_MAGIC_DATA_LOCATIONS)
    def open_sranger():
        sr = open (sr_dev_path, "rw")
        sr.seek (magic_address, 1)
        magic = struct.unpack (magic_fmt, sr.read (struct.calcsize (magic_fmt)))
        sr.close ()
        return magic
    
    def GPIO_setup(dir):
        sr = open (sr_dev_path, "wb")
        sr.seek (magic[i_CR_generic_io], 1)
        sr.write (struct.pack ("<hhHHH", 3,0,dir,0,0)) # Start (code what 1: WR, 2: RD, 3: DirReconf), Stop, Dir-, In-, Out-data
        sr.close ()
        return 1
    
    def GPIO_write(data):
        sr = open (sr_dev_path, "wb")
        sr.seek (magic[i_CR_generic_io], 1)
        sr.write (struct.pack ("<hhHHH", 1,0,0,0,data)) # Start (code what 1: WR, 2: RD, 3: DirReconf), Stop, Dir-, In-, Out-data
        sr.close ()
        return 1
    
    print ("Open SR at ", sr_dev_path)
    
    magic = open_sranger()
    print ("Magic:", magic)
    GPIO_setup (0x00ff)
    
    for bits in range(0, 0xff):
        time.sleep (0.1)
        GPIO_write (bits)
    
     

    Last edit: Percy Zahl 2017-03-24
  • Antoine Roy-Gobeil

    Dear Percy,

    Thank you very much for this script! It works now!

    Have a very nice day,
    Antoine

     

Log in to post a comment.