Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
12409 Discussions

Problem with reboot of DE2i-150 Development kit

Altera_Forum
Honored Contributor II
834 Views

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
Reply