Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
759 Views

Problem with reboot of DE2i-150 Development kit

Hello, 

 

I have worked with DE2i-150 Development Kit for 2 weeks. Now, I'm writing simple Kernel driver for Intel Antom Processor to Read/Write GPIO from FPGA. When I develop driver, I'm having some trouble with my PCI driver.

My driver works something wrong when I reboot DE2i-150 Development kit. It only works well when I "Power off" and " Power on" again.You can see my result below to more clear my problem.

I created my driver with name "altera.ko" end then insert module to the Linux kernel use : insmod altera.ko. I wrote small app to write data to DO PORT and then read data from DO PORT and DI PORT. The sumaries program I attached file with name "app.c"

*Case right: The result when I " Power off" and " Power on" again. I do it again alot of time, and everytime the result well:

 

[VRD] 542 value write : 0x63 // Value is wrote in DO port

[VRD] 168 test_write : Data write to DO PORT : 0x63

[VRD] 181 test_read_do : Data read from DO PORT: 0x63

[VRD] 210 test_read _di : Data read from DI PORT: 0xffffffff

 

*Case wrong: The result when I reboot DE2i-150 the first time:

 

[VRD] 542 value write : 0x63 // Value is wrote in DO port

[VRD] 168 test_write : Data write to DO PORT : 0x63

[VRD] 181 test_read_do : Data read from DO PORT: 0xffffffff

[VRD] 210 test_read _di : Data read from DI PORT: 0x63

 

=> it seems read inverse value between DI PORT and DO PORT.

 

But the value right back when I reboot the second times

[VRD] 542 value write : 0x63 // Value is wrote in DO port

[VRD] 168 test_write : Data write to DO PORT : 0x63

[VRD] 181 test_read_do : Data read from DO PORT: 0x63

[VRD] 210 test_read _di : Data read from DI PORT: 0xffffffff

 

And it get wrong result again when I reboot the third times. End then value right back when I reboot at fourth times. ....I do it again alot of time. I see every once read right value, next once wrong value, .... I hope you can understand my case

I don't understand alot my problem. Maybe it come from "map bar address". But I see I can read right value when I power off and power on again DE2i-150 kit, so I think it ok. I also attached "probe method" code in file "probe.c", can you help me to check it.

I developed my driver in Debian 8: "Linux debian 3.16.0-4-686-pae GNU/Linux".

Can anybody help me to know where is my problem. I hope can read right value every time either "reboot" or "power off".

 

Thank your for your attention. Thank you very much.

 

Best & Regard

 

 

Bắc

 

Sorry I can't attached file app.c and probe.c so I write all here, Sorry it's very too long:

* app.c

 

int main (int argc, char *argv[])

{

int fd;

struct app_opts opts;

long value=0;

 

opts.di_addr = 0x0020;

opts.do_addr = 0x0000;

opts.dio_bar_no = ALT_DIO_BAR_NO;

opts.rw_bar_no = 0x00;

opts.port_no = 0;

 

parse_opt(argc, argv, &opts);

 

fd = open(device, O_RDWR); 

if (fd < 0) {

log_err("Open device failed");

return -ENODEV;

}

 

while(1)

{

value++; 

log_info("value: %lu", value);

 

opts.port_data = value;

 

test_write(fd, opts); // Function write data to DO PORT

 

test_read(fd,opts, PORT_IN); // Function read data from DI PORT

test_read(fd,opts, PORT_OUT); // Function read data from DO PORT

 

sleep(0.01);

if(value>=100) break; // Loop write data to DO PORT 100 times then read.

}

close(fd);

 

return 0;

}

*probe.c

static int alt_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id)

{

struct alt_pcie_dev *alt_dev;

struct alt_pcie_pio *alt_pio;

unsigned long minor;

int i;

int ret = 0;

 

alt_dev = kzalloc(sizeof(struct alt_pcie_pio), GFP_KERNEL); //ok

if (!alt_dev) {

log_err("Can't allocate memory");

return -ENOMEM;

}

 

mutex_init(&alt_dev->buf_lock);

spin_lock_init(&alt_dev->pci_lock);

init_waitqueue_head(&alt_dev->wait_queue);

 

ret = pci_enable_device(dev);

if (ret) { 

log_err("Can't enable PCIe device");

goto err_pci_enable;

}

 

ret = pci_request_regions(dev, ALT_DRV_NAME); //ok

if (ret) {

log_err("Can't enable PCIe device");

goto err_request_region;

}

for (i = 0; i < ALT_N_PCIE_BARS; i++) {

alt_dev->bars = pci_iomap(dev, i, 0);

alt_dev->bar_size = pci_resource_len(dev, i);

if (alt_dev->bars)

}

ret = pci_enable_msi(dev);

if (ret) {

log_err("Enable MSI FAILED");

goto err_enable_msi;

}

alt_dev->irq = dev->irq;

ret = request_irq(alt_dev->irq, alt_irq_handler, IRQF_SHARED, ALT_DRV_NAME, alt_dev);

if (ret) {

log_err("Request irq failed");

goto err_request_irq;

}

alt_dev->cra_bar_no = cra_bar_no;

alt_dev->cra_base_addr = cra_base_addr;

 

alt_dev->cra_regs.status = (void __iomem *) (alt_dev->bars[alt_dev->cra_bar_no] +

alt_dev->cra_base_addr +

ALT_CRA_REG_STATUS);

alt_dev->cra_regs.ctrl = (void __iomem *) (alt_dev->bars[alt_dev->cra_bar_no] +

alt_dev->cra_base_addr +

ALT_CRA_REG_CTRL);

alt_dev->cra_regs.trans = (void __iomem *) (alt_dev->bars[alt_dev->cra_bar_no] +

alt_dev->cra_base_addr +

ALT_CRA_REG_TRANS);

 

iowrite32(0xFFFFUL, alt_dev->cra_regs.ctrl);

 

ret = pci_write_config_byte(dev, PCI_INTERRUPT_LINE, alt_dev->irq);

if (ret) {

goto err_write_config;

}

 

/* Init PIO */

alt_pio = (struct alt_pcie_pio *) alt_dev;

 

alt_pio->n_di_ports = sizeof(di_ports)/sizeof(struct alt_pio_port);

alt_pio->n_do_ports = sizeof(do_ports)/sizeof(struct alt_pio_port);

 

for (i = 0; i < alt_pio->n_di_ports; i++) {

alt_pio->di_ports = di_ports;

 

alt_pio->di_ports.regs = alt_dev->bars[ALT_DIO_BAR_NO] +

alt_pio->di_ports.base_addr;

}

 

for (i = 0; i < alt_pio->n_do_ports; i++) {

alt_pio->do_ports = do_ports;

 

alt_pio->do_ports.regs = alt_dev->bars[ALT_DIO_BAR_NO] +alt_pio->do_ports.base_addr;

}

 

INIT_LIST_HEAD(&alt_dev->device_entry);

 

mutex_lock(&device_list_lock);

 

minor = find_first_zero_bit(minors, ALT_N_PCIE_MINORS);

if (minor < ALT_N_PCIE_MINORS) {

struct device *dev;

 

alt_dev->devt = MKDEV(major, minor);

dev = device_create(alt_class, NULL, alt_dev->devt,

alt_dev, "alt_pcie_dev%lu", minor); 

if (IS_ERR(dev)) {

log_err("Create device alt_pcie_dev%lu failed", minor);

ret = PTR_ERR(dev);

}

else {

set_bit(minor, minors);

list_add(&alt_dev->device_entry, &device_list);

}

}

else {

log_err("no minor number available");

ret = -ENODEV;

}

 

mutex_unlock(&device_list_lock);

 

if (!ret)

pci_set_drvdata(dev, alt_dev);

else {

free_irq(alt_dev->irq, alt_dev);

pci_disable_msi(dev);

for (i = 0; i < ALT_N_PCIE_BARS; i++)

pci_iounmap(dev, alt_dev->bars);

pci_release_regions(dev);

pci_disable_device(dev);

kfree(alt_dev);

}

return ret;

err_write_config:

free_irq(alt_dev->irq, alt_dev);

err_request_irq:

pci_disable_msi(dev);

err_enable_msi:

for (i = 0; i < ALT_N_PCIE_BARS; i++)

[I] pci_iounmap(dev, alt_dev->bars);

pci_release_regions(dev);

err_request_region:

pci_disable_device(dev);

err_pci_enable:

kfree(alt_dev);

 

return ret;

}

 

0 Kudos
0 Replies