ISA interrupt help

The basic story is that I have a PC104 board interfacing with a single board computer. The board is configured to a test state where I can toggle ISA interrupt lines at will through an IO port. The IRQs the board is wired up to are 4, 6, 9, 11, 14, 15. As far as I can tell, 6, 9, 11, and 14 should be free on the single board computer. So far i have had no luck in getting an interrupt to respont properly. Below is the code I’m using to excersize the board and interrupts. Any help is greatly appreciated.

-Nick

UINT8 interruptHandledFlag;

const struct sigevent* intHandler(void *arg, int id)
{
(UINT8)arg = 1;
switch(id)
{
case 4:
{
out16(0x0182, ~0x0001);
break;
}
case 6:
{
out16(0x0182, ~0x0002);
break;
}
case 9:
{
out16(0x0182, ~0x0004);
break;
}
case 11:
{
out16(0x0182, ~0x0008);
break;
}
case 14:
{
out16(0x0182, ~0x0010);
break;
}
case 15:
{
out16(0x0182, ~0x0020);
break;
}
}
return NULL;
}

int runAnInterrupt(DSP_CLASS* DSP, int num, UINT32 dspStuff)
{
int retVal = PASS;
int intId;
int maskCount;
int timeoutcount = 0;

interruptHandledFlag = 0;

intId = InterruptAttach(num, intHandler, &interruptHandledFlag, sizeof(UINT8), 0);
InterruptEnable();
maskCount = InterruptUnmask(num, intId);

printf("interrupt %d mask count: %d\n", num, maskCount);

for(int s = 0; s < 10; s++)
{
	//DSP->WriteData(DSP->EPLDControlReg2, clearInterruptsOnTheDsp | dspIRQ6);
	DSP->WriteData(DSP->EPLDControlReg2, dspStuff);

	int count = 0;
	while(!interruptHandledFlag)
	{
		usleep(500);
		count++;
		if(count > 2000);
		{
			timeoutcount++;
			DSP->WriteData(DSP->EPLDControlReg2, ~dspStuff);
			retVal = FAIL;
			break;
		}
	}

	DSP->WriteData(DSP->EPLDControlReg2, ~dspStuff);
}

InterruptDetach(intId);

char printfStuffs[300];
sprintf(printfStuffs, "time out IRQ %d x %d", num, timeoutcount);
td_out(printfStuffs, VB_ERROR_ONLY);

return retVal;

}

static int intIsaTest (DSP_CLASS* DSP)
{
const UINT32 dspIRQ4 = 0x0001;
const UINT32 dspIRQ6 = 0x0002;
const UINT32 dspIRQ9 = 0x0004;
const UINT32 dspIRQ11 = 0x0008;
const UINT32 dspIRQ14 = 0x0010;
const UINT32 dspIRQ15 = 0x0020;

interruptHandledFlag = 0;

ThreadCtl(_NTO_TCTL_IO, 0);

// clear interrupts so that they can be transitioned high
DSP->WriteData(DSP->EPLDControlReg2, ~(dspIRQ4 | dspIRQ6 | dspIRQ9 | dspIRQ11 | dspIRQ14 | dspIRQ15));

sleep(1);

runAnInterrupt(DSP, 4, dspIRQ4);
runAnInterrupt(DSP, 6, dspIRQ6);
runAnInterrupt(DSP, 9, dspIRQ9);
runAnInterrupt(DSP, 11, dspIRQ11);
runAnInterrupt(DSP, 14, dspIRQ14);
runAnInterrupt(DSP, 15, dspIRQ15);

// set all interrupts high / tristate
DSP->WriteData(DSP->EPLDControlReg2, 0xffff);

return PASS;

}

check your bios, if all irq do you want to use are free - ecept irq 11 ist most network, 14/15 for ide e.g. - disable these hardware in the bios

If this is a x86 arch machine, then 6 is floppy, 9 is cascade (i.e. you can attach a handler to 9, but your board needs to raise IRQ 2), and 14 is EIDE controller; so the only interrupt that might work is 11 (unless it is being used as well).

You are saying you can trigger interrupt via IO port, how do you write it. Can you check with a scope if the interrupt is really triggered.

Does anyone knows how I can write to the SA<11:0> of the PC104 interface in C code??

Regards,

Gijs

What’s SA<11:0>?

PC/104 Bus Interface
· Standard configuration provides base address selection through a rotary switch

· PC/104 signals connected to the FPGA:
Control: RESET, AEN, IOW, IOR
Address Data: SD<7:0>, SA<11:0>
IRQ: IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, IRQ9, IRQ10, IRQ11,
IRQ12, IRQ14, IRQ15
DMA: DRQ0, DACK0, DRQ1, DACK1, DRQ2, DACK2, DRQ3,
DACK3, TC

I hope this makes it more clear

SA<11:0> is address data in this case

PC104 is the same as ISA only with more pins, I read this somewhere

I want to write to the address data

Regards,

Gijs

I have never seen an address represented like that SA<11:0> . That’s probably FPGA related. My guess is that it means any address from 0 to - 2048, all depending on the base address. It tooks to me like SA<11:0> is actually the name of the address bus.

So if the base address is 100, then you’d do in8(100) (I’m skipping the map_device_io ).

If you want to write 53 a address 101 you would do out8( 101, 53 ).

The pinouts of the PC104 interface are like this
according to controlled.com/pc104faq/#pinouts

The name “PC/104” is derived from the fact that there are 104 pins on the two bus connectors which carry signals between modules. P1 has 64 pins and P2 has 40.


PIN J1/P1 (ROW A) J1/P1 (ROW B) J2/P2 (ROW C) J2/P2 (ROW D)

0 0V 0V
1 -IOCHCHK 0V -SBHE -MEMCS16
2 SD7 RESET LA23 -IOCS16
3 SD6 +5V LA22 IRQ10
4 SD5 IRQ9 LA21 IRQ11
5 SD4 -5V LA20 IRQ12
6 SD3 DRQ2 LA19 IRQ15
7 SD2 -12V LA18 IRQ14
8 SD1 -ENDXFR LA17 -DACK0
9 SD0 +12V -MEMR DRQ0
10 IOCHRDY KEY -MEMW -DACK5
11 AEN -SMEMW SD8 DRQ5
12 SA19 -SMEMR SD9 -DACK6
13 SA18 -IOW SD10 DRQ6
14 SA17 -IOR SD11 -DACK7
15 SA16 -DACK3 SD12 DRQ7
16 SA15 DRQ3 SD13 +5V
17 SA14 -DACK1 SD14 -MASTER
18 SA13 DRQ1 SD15 0V
19 SA12 -REFRESH KEY 0V
20 SA11 CLK
21 SA10 IRQ7
22 SA9 IRQ6
23 SA8 IRQ5
24 SA7 IRQ4
25 SA6 IRQ3
26 SA5 -DACK2
27 SA4 TC
28 SA3 BALE
29 SA2 +5V
30 SA1 OSC
31 SA0 0V
32 0V 0V

If I want to write to SA0 I need to use address 32, I would then use out8( 32, value )???

And what about IOR and IOW?

check the link above for better view.

Regards,

Gijs

Euhm, If you would write to SA0 there is no real point is there? Its 0v…

Short guess about the IOW and IOR,IO WRITE and IO READ?

After clicking on the link controlled.com/pc104faq/#pinouts

you can see that 0V (0 volts) refers to pin 31B of the PC104 interface, I’m having trouble with the TABS after pasting, its not very clear i know

The point is that SA0 (pin 31A) is connected to my FPGA so that i want to be able to write a bit to SA0
so i can use the bit inside the FPGA.

Yes IOW ans OIR concerns IO WRITE and IO READ

Do you understand my problem now?
How can I write a bit to pin 31B (SA0) in this case?

Regards,

Gijs

I would need to know what kind of hardware you are talking about. Those output pins you see are internally connected to registers, a register has a address. Lets say that SA0 is part of register A, register A has address 0x00, and its 32 bits wide. If you no want to write to ‘pin’ SA0 you would write out32(0x00,0x01) where I assume that 0x01 will map to pin one.

I think there is a total misconception here. The PC104 is simply an ISA bus that carries the data bus (SD) and address bus(SA) plus some other control signals.

You don’t write to the address bus and data bus specifically the CPU (or chipset) takes care of all these details.

The following assembly instruction:
mov $10,100
The cpu will send 10 on the data bus and 100 on the adresse bus. Whether this address is internal to the CPU card or external ( PC104/PCI/ISA/PCIe/etc) doesn’t make any difference. The CPU will also activate the MEMWRITE signal. The instruction
out 10,100 would do the same but instead would activate IOWRITE signal.

SA and SD are not devices in themselves they are extension of the CPU.

All peripheral (memory, network chip, FPGA, HD controler) will listen to these signal and decide if they are being addresses or not. In your case the FPGA would check if the addresses and control signal matches its base address. If it doesn’t match, they are simply ignore, if they do match then the device can take whatever action is appropriate.