Thanks for the info Frank. My PC104 daughterboard is actually a home
brew FPGA board. If you wouldn't mind sharing the source to your hack
that would give me something to try as I'm running out of ideas...
Regards,
-Elliot
--- In "Frank Pagliughi" <>
wrote:
>
> I was able to write a device driver for a proprietary PC/104
> co-processor board for use with a TS-7260, but I could never get it
to
> work reliably with the standard speed for accessing the 104 bus. I
had
> similar problems to what you're reporting in that individual reads
and
> writes were sometime (often) incorrect.
>
> Then I tried using the "fast" mode to access the board. This is a
> non-standard extension of the TS-72xx boards that clocks the bus at
a
> faster rate (requiring a wait state setup in the EBI). Then my
driver
> worked fine. But this probably wouldn't work with off-the-self
PC/104
> peripheral boards.
>
> I chalked it up to a problem with the default implementation of the
> PC/104 support in the boards's CPLD, but never did resolve the
issue.
>
> - Frank
>
> --- In "elliotbuller" <ebuller@> wrote:
> >
> > Is it possible I'm am accessing the PC104 memory at the wrong
> > location? Does the kernel access 16bit mem-mapped pc104 at
0x21A00000?
> >
> > -Elliot
> >
> > --- In "elliotbuller" <ebuller@> wrote:
> > >
> > > I'm having an issue reading data over the pc104 bus from a
kernel
> > > module. I am able to read just fine from a userspace app using
mmap.
> > > Please tell me what the difference is between the access I am
doing in
> > > userspace and kernel space. The externel hardware generates the
> > > interrupt and I see it trap to the interrupt handler. At that
point it
> > > tries to do a read over the bus but it is not latching the data
right.
> > > I get random results as if I'm just reading random memory
although I
> > > do see the mem_r line strobe low. I know you can't use mmap in a
> > > kernel module but from what I've read it sounded like the ISA
memory
> > > region could be accessed using __ioremap(). Any suggestions
would be
> > > great.
> > > -Elliot
> > > TS7300 - 2.4.26-ts11 #35
> > >
> > > Here is my userspace app:
> > >
> > > #include <unistd.h>
> > > #include <sys/mman.h>
> > > #include <stdio.h>
> > > #include <fcntl.h>
> > > #include <time.h>
> > > #include "stdtypes.h"
> > > #include "peekpoke.h"
> > >
> > > /*
> > > Other possible bases
> > > 0x21810000
> > > 0x21A00000
> > > 0x21A10000
> > > */
> > >
> > > #define PC104_BASE 0x21A00000L
> > >
> > > int passed=0, failed=0, reads=0;
> > > uint16 expected=0x0;
> > > int t_delay = 0;
> > > clock_t begin, end;
> > >
> > > delay( volatile int x )
> > > {
> > > volatile int k=0;
> > > while( k < x ) k++;
> > > }
> > > int main(int argc, char **argv){
> > > uint16 reading;
> > > volatile uint16 *start;
> > > long seconds;
> > > uint32 count = 0;
> > > int fd = open("/dev/mem", O_RDWR|O_SYNC);
> > > start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
> MAP_SHARED,
> > >
> > > reading = PEEK16((long)start);
> > > expected = reading + 1;
> > >
> > > while(count < 10000000)
> > > {
> > > reading = PEEK16((long)start);
> > > if(reading == expected)
> > > {
> > > passed++;
> > > expected++;
> > > }
> > > else
> > > {
> > > failed++;
> > > expected=reading+1;
> > > }
> > > count++;
> > > }
> > > printf("%d READS\n---------\nPASSED: %d FAILED: %
d\n",
> > > count, passed, failed);
> > >
> > > close(fd);
> > > return 0;
> > > }
> > >
> > > /***********************************/
> > >
> > > Here is my kernel module:
> > > // Linux Device Driver Template/Skeleton
> > > // Kernel Module
> > >
> > > #include <linux/module.h>
> > > #include <linux/errno.h>
> > > #include <linux/fs.h>
> > > #include <linux/mm.h>
> > > #include <linux/interrupt.h>
> > > #include <linux/sched.h>
> > > #include <linux/init.h>
> > > #include <linux/ioport.h>
> > >
> > > #include <asm/uaccess.h>
> > > #include <asm/io.h>
> > > #include "peekpoke.h"
> > >
> > > #define PC104_MAJOR 63
> > > #define PC104_NAME "PC104"
> > > #define PC104_INTERRUPT 22 // Corresponds to
IRQ5
> > > #define PC104_BASE 0x21A00000L
> > > #define PC104_MEM_SIZE 4
> > >
> > >
> > > MODULE_AUTHOR("Elliot Buller: Colorado State 2007");
> > > MODULE_LICENSE("GPL");
> > > MODULE_DESCRIPTION("PC104 Data Acquisition Card Driver");
> > >
> > > extern void disable_irq (unsigned int irq);
> > > static unsigned int counter = 0;
> > > static int interruptcount = 0;
> > > static volatile uint16_t *base;
> > > static char string[150];
> > > DECLARE_WAIT_QUEUE_HEAD(pc104_wait);
> > > static int data_not_ready = 1;
> > >
> > > static int pc104_open (struct inode *inode, struct file *file) {
> > > printk("pc104_open\n");
> > > return 0;
> > > }
> > >
> > > static int pc104_release (struct inode *inode, struct file
*file) {
> > > printk("pc104_release\n");
> > > return 0;
> > > }
> > >
> > > static ssize_t pc104_read (struct file *file, char *buf,
> > > size_t count, loff_t *ppos) {
> > > int len, err;
> > >
> > > // check if we have data - if not, sleep
> > > // wake up in interrupt_handler
> > > while (data_not_ready) {
> > > interruptible_sleep_on(&pc104_wait);
> > > }
> > > data_not_ready = 1;
> > >
> > > /* Add read code here */
> > > return len;
> > > }
> > >
> > > // write function called when to /dev/skeleton is written
> > > static ssize_t pc104_write (struct file *file, const char *buf,
> > > size_t count, loff_t *ppos) {
> > > int err;
> > > err = copy_from_user(string,buf,count);
> > > if (err != 0)
> > > return -EFAULT;
> > > counter += count;
> > > return count;
> > > }
> > >
> > >
> > > // interrupt handler
> > > static int interrupt_handler(void)
> > > {
> > >
> > > interruptcount++;
> > > printk(">>> PC104 BUS INT: interruptcount=%d\n",
interruptcount);
> > >
> > > printk("PC104 Samples: 0x%04X\n", PEEK16(base));
> > >
> > > /* Data ready. Wake up userspace process */
> > > data_not_ready = 0;
> > > wake_up_interruptible(&pc104_wait);
> > >
> > > return IRQ_HANDLED;
> > > }
> > >
> > > // define which file operations are supported
> > > struct file_operations pc104_fops = {
> > > .owner = THIS_MODULE,
> > > .llseek = NULL,
> > > .read = pc104_read,
> > > .write = pc104_write,
> > > .readdir = NULL,
> > > .poll = NULL,
> > > .ioctl = NULL,
> > > .mmap = NULL,
> > > .open = pc104_open,
> > > .flush = NULL,
> > > .release = pc104_release,
> > > .fsync = NULL,
> > > .fasync = NULL,
> > > .lock = NULL,
> > > .readv = NULL,
> > > .writev = NULL,
> > > };
> > >
> > > // initialize module (and interrupt)
> > > static int pc104_init_module (void) {
> > > int i;
> > > int ret;
> > > printk("<1>Initializing PC104 module\n");
> > >
> > > i = register_chrdev (PC104_MAJOR, PC104_NAME, &pc104_fops);
> > > if (i != 0) return - EIO;
> > >
> > > // INIT INTERRUPT
> > > ret = request_irq(PC104_INTERRUPT, &interrupt_handler,
> > > SA_INTERRUPT, "pc104_driver", NULL);
> > >
> > > /* Check to see if ISA memory in use */
> > > if (check_mem_region(PC104_BASE, PC104_MEM_SIZE)) {
> > > printk("pc104: memory already in use\n");
> > > return -EBUSY;
> > > }
> > >
> > > /* Request memory space */
> > > request_mem_region(PC104_BASE, PC104_MEM_SIZE, PC104_NAME);
> > >
> > > /* Warning: Cannot use ioremap as it adds offset */
> > > base = (volatile uint16_t*)__ioremap(PC104_BASE,
PC104_MEM_SIZE, 0);
> > > if(base == NULL)
> > > {
> > > printk("Error mapping memory!\n");
> > > return -EBUSY;
> > > }
> > >
> > > printk("Memory mapped: 0x%08X\n", base);
> > > return 0;
> > > }
> > >
> > >
> > > // close and cleanup module
> > > static void pc104_cleanup_module (void) {
> > > printk("<1>Cleaning up PC104 module\n");
> > >
> > > iounmap((void*)base);
> > > release_mem_region(base, PC104_MEM_SIZE);
> > > unregister_chrdev (PC104_MAJOR, PC104_NAME);
> > > disable_irq(PC104_INTERRUPT);
> > > free_irq(PC104_INTERRUPT, NULL);
> > >
> > > }
> > >
> > > module_init(pc104_init_module);
> > > module_exit(pc104_cleanup_module);
> > >
> >
>
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|