TS-4200 PC104 example

From embeddedTS Manuals
Revision as of 22:42, 11 June 2013 by Mark (talk | contribs) (Created page with "With the baseboards that make use of the PC104 bus, you must first set up the MUXBUS configuration registers. From Debian, you would run this: <source lang=bash> source /ini...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

With the baseboards that make use of the PC104 bus, you must first set up the MUXBUS configuration registers. From Debian, you would run this:

source /initrd/ts4200.subr 
pc104on

NOTE: The `pc104on` command sets the MUXBUS timing config register to 0x181, which is aggressive timing. This may not work for all PC/104 devices, in which case we recommend writing a more conservative config value, something like `peekpoke 16 0x30000020 0x381`

From your application you can now talk to the MUXBUS for communication to PC104. The TS-4200 with our baseboards will implement the 8 bit PC104 address space from 0x10000400 to 0x100007ff. The 16 bit access is available from 0x30000400 to 0x300007fe. This example uses the TS-RELAY8.

#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <assert.h>

// This offset is for the TS-4200 8bit SMC (FPGA)
#define BASE_ADDRESS 0x10000000

// This assumes jumper 1 is on the TS-RELAY8
#define PLD_OFFSET 0x140

unsigned short *muxbus_base;
typedef enum {
  RLYON = 0x00,
  RLYOFF = 0xFF,
  RLY1 = 1 << 0,
  RLY2 = 1 << 1,
  RLY3 = 1 << 2,
  RLY4 = 1 << 3,
  RLY5 = 1 << 4,
  RLY6 = 1 << 5,
  RLY7 = 1 << 6,
  RLY8 = 1 << 7
} RelayFlags;

static void poke8(unsigned int adr, uint8_t val) {
        muxbus_base[adr / 2] = val;
}

void set_relays(RelayFlags bits) {
    // This adds the PLD offset to talk to the TS-RELAY8
    // the 0x400 is the offset for the MUXBUS (see the FPGA Functionality section)
    // 0x2 is added for the offset of the actual relays.  See the TS-RELAY8 wiki for more details
    poke8(PLD_OFFSET + 0x400 + 0x2, bits);
    usleep(15000);
}

int main(int argc, char **argv) {
    int mem = open("/dev/mem", O_RDWR|O_SYNC);
    assert(mem != -1);
    muxbus_base = mmap(0,
         getpagesize(),
         PROT_READ|PROT_WRITE,
         MAP_SHARED,
         mem,
         BASE_ADDRESS);
    assert(muxbus_base != MAP_FAILED);

    while(1)
    {
	set_relays(RLYOFF);
        set_relays(RLY1);
        set_relays(RLY1|RLY2);
        set_relays(RLY1|RLY2|RLY3);
        set_relays(RLY1|RLY2|RLY3|RLY4);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5|RLY6);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5|RLY6|RLY7);
        set_relays(RLYON);
    }
    return 0;
}