RM different behavior on photon and on text mode

Hi.

something weird is happening with my resource manager.

I wrote a resource manager for a data acquisition board. The ISR uses the 8254 timer of ad_board (not motherboard).
I program the timer with the needed frequency, and to see if the program is ok i use an osciloscope reading signals on the LPT port. Every Interrupt signal I go up (0xff) or down (0x00) to see a square waveform.
Ok, then the problem is, when I test the program over photon, the waveform shows little changes and the osciloscope is able to trigger and show me everything is ok.
But, when I do the same on the terminal (shutdown photon) the waveform is completely wrong and the osciloscope is unable to trigger.

Strange…

Any ideas?

Tested on 6.1 and on 6.3

Thanx
Leandro Colen

Have you disable the parallel port driver. However I don’t see how that relate to running Photon or not, but that’s all I can think of.

What IRQ is your ad board using? What IRQ is your video card using?

Post the code from your IRQ setup and ISR as well.

The only think I can think of is you are inadvertently using the video interrupt - or they are sharing the same IRQ and it is related to that somehow.

Rick…

I’ve tried irqs 3, 4, 5, 6 and 7. All of them show the same problem. I’m not sure about video IRQ. I’m using a Gene-4310 SBC.
My ad board is a PCM-3718H.

Here’s my source codes (sorry, they have some portuguese expressions)

ad board configuration :

int init_placa(int divisor1, int divisor2)
{	

	if (reset_placa() == EXIT_FAILURE)
		return EXIT_FAILURE;

	// Configura Multiplexer pg 27
	out8((BASE+2), 0x00);
   
	// Configura range pg 26
	out8((BASE+1), 0x05);

	// Configura Multiplexer pg 27
	out8((BASE+2), 0x00);

	// Control Register pg 31
	// 0xF3 = irq 7
	// 0xA3 = irq 2
	// 0xB3 = irq 3
	out8((BASE+9), 0xB3);

	if (ANALISE)
		fprintf(stdout, "\n%s : Valor do status : %#x\n",NOME_FONTE, in8(BASE+8));
	
	if (cfg_timer_placa(divisor1, divisor2) != EXIT_SUCCESS) {
		perror("Erro na inicializacao do timer...");
		return EXIT_FAILURE;
	}

	// Enable no pacer pg 32
	out8(BASE+10, 0x00);
		
	return EXIT_SUCCESS;
}

/* Reset */
int reset_placa(void)
{
	// Stop timer 0
	out8((BASE+15), 0x34);
	out8((BASE+12),0x01);
	out8((BASE+12),0x00);
	
	// Stop timer 1
	out8((BASE+15), 0x74);
	out8((BASE+13),0x01);
	out8((BASE+13),0x00);
	
	// Stop timer 2
	out8((BASE+15), 0xb0);
	out8((BASE+14),0x01);
	out8((BASE+14),0x00);


	// desabilitando interrupcao 
	DISABLE_INTERRUPT;
	
	// Clear Interrupt
	CLEAR_INTERRUPT;

	return EXIT_SUCCESS;
}

/* Configura timer */
int cfg_timer_placa(int divisor1, int divisor2)
{

	// Configura timer pag 52
	out8(BASE+15, 0x76);
	out8(BASE+13, divisor1 );
	out8(BASE+13, divisor1 >> 8);
	out8(BASE+15, 0xB6);
	out8(BASE+14, divisor2);
	out8(BASE+14, divisor2 >> 8);

	return EXIT_SUCCESS;
}

and the ISR :

void *devc_irq(void *arg) 
{
    struct sigevent event;
	int interr;
    	int i=0, a=0;
    	int idx[MAX_CANAIS];

    CONTADOR_PLACA=0;
    TEMPO_PLACA = 0;

	for (i=0; i<MAX_CANAIS; i++)
		idx[i] = 0;
		
    /* fill in "event" structure */
    memset(&event, 0, sizeof(event));
    event.sigev_notify = SIGEV_INTR;

    /* intNum is the desired interrupt level */
    interr = InterruptAttachEvent (IRQ, &event, 0);
    
    if (MEDIDAS) PAR0;

	while (1) {
		aguarda_irq();
		
		if (MEDIDAS) {
			if (a == 0) {
				PAR1;
				a=1;
			} else {
				PAR0;
				a=0;
			}
		}

		// Verificando contadores dos canais para conversao do dado
		for (i=0; i<NUMERO_CANAIS; i++) {
			// Quando estiver no momento da conversao 
			if (cont_canal[i] == CONTADOR_PLACA) {
				// conversao do sinal
				converte(i, idx[i], TEMPO_PLACA);

				// Atualiza contadores..
				cont_canal[i] += aux_canal[i];
				idx[i]++;
			}
		}
		
		CONTADOR_PLACA ++;
		TEMPO_PLACA += BASE_TEMPO;

		// Clear Interrupt
		CLEAR_INTERRUPT;

		if (InterruptUnmask(IRQ, interr) == -1) 
			perror("\nErro no InterruptUnmask...");
			
		if (TEMPO_PLACA > MAX_TA) {
			DISABLE_INTERRUPT;
			for (i=0; i<NUMERO_CANAIS; i++) {
				if (grava_arq_dados(NUM_PONTO, idx[i], NUMERO_CANAIS) == EXIT_FAILURE)
					fprintf(stderr, "\ndevc - irq : Erro na geracao dos arquivos de saida\n");
				idx[i] = 0;
				CONTADOR_PLACA = 0;
				TEMPO_PLACA = 0;
			}
		}

	}
 	
 	return ((int *) EXIT_SUCCESS);

}

int aguarda_irq(void)
{

	while(1) {
		InterruptWait(NULL, NULL);
		
		return EXIT_SUCCESS;
	}

	return EXIT_FAILURE;		
}

int converte (int numcanal, int idx, float tempo)
{

	canal_mem[numcanal]->num_canal = numcanal;
	canal_mem[numcanal]->valor_ad[idx] = in8(BASE+1)*256+in8(BASE);
	canal_mem[numcanal]->tempo[idx] = tempo;
	
	return 0;
}

int grava_arq_dados(int num, int max, int num_canais)
{
// write the data to a binary file 
}


Hum I don’t see anything wrong. Try this, don’t enable the interrupt (at the hardware level)and see if you still get interrupts. 3,4,5,6,7 are interrupts which typicaly have some devices attached to them, make sure they are disabled in the BIOS.

Some generial tips, if you care for such thing

The return ((int*)EXIT_SUCCESS) is weird although not a problem per se.
Use macro SIGEV_INTR_INIT() instead of setting event manualy.
Usage of EXIT_FAILURE is typicaly use for exit(), not a problem but unusual.

Is devc_irq() a thread? Do you ever check to see if the InterruptAttachEvent() fails? If this is a thread, you need to do a ThreadCtl() to give your thread access to attach to interrupts.

Also it is not clear to me that you determine if you are the source of the interrupt before you unmask it. In the case of a shared interrupt, you may get called even though your board didn’t generate the interrupt. You should only “react” to the interrupt if you are the source of it.

Rick…

Yes. It is a thread and yes… I forgot to do ThreadCtl(). Now is fixed! :slight_smile:

OK! Another mistake, fixed too!

Even after this changes (ThreadCtl() and Check status register), the problem continues. Yesterday I tried something different, I’m reading the irq signal from the PC104, pin 25 (for irq 3) and I see the same waveform I’ve seen when I read on paralel port (with minor differences of course).
I’m not sure, but the signal should be very stable right (triggered)? I’m reading the 8254 waveform (mode 3) directly on the pc104. I still have to do more tests! I’m writing this just to keep the discussion alive!

Now with some help from my professor, I’ll try to get a better picture of the problem, and later I’ll give more news.

Ah! And Mario, yes, I did everything you said, disabled the irqs from bios, test if even disabled this irqs are generated by someone else, and no. Everything looks fine but the problem persists.
And thanx for the tips. You can see I’m not a good programmer, here we said “I’m a fireman, my job is to put down the fire” :smiley:

Any tips will be nice ;)

Yes the signal should be stable. I assume the signal from the 8254 is ok. One thing you might try is measure the timing between the pulse on the 8254 and the CS (chip select signal). That should tell you how long it takes before the pulse and the first access to the chip in your code. Maybe it will give us a clue.

What is the rate of the pulse on the 8254.

By the way, although not wrong, symbol in capital are typicaly use to represent #define or macro, not variable. That makes the code a little harder to understand for the rest of the world ;-)

I notice code in init_placa() is use to select interrupt. Are you sure it matches the IRQ specifed in InterruptAttachEvent.

One other thing you might try is use a real ISR handler with InterruptAttach(). The handler could return a SIGV_INTR event keeping your code the same, but if you toggle a bit on the parallel port in the ISR, you might get more information. Does the delay comes from latency between the IRQ and ISR being called or is the the thread that is prevented to run.

Hi everyone,

well… after 4 days of hard work, testing, asking questions in this forum (by the way, thanx Rick and Mario for all help), new implementations, new tests, changes on approachs and everything else, I finally found the problem.

In these days, I could learn much more about data acquisition, x86 architecture, 8254 timer, 8259 interrupt, QNX, ISRs, threads, etc… Something I’m sure every device driver developer knows, but for me, I only have the possibility to learn something when the problem occurs, as most of the people from Brazil, because here is “impossible” (strong word, I know, but is quite true) to learn about such specialized job as device drivers, robotics systems and intrumentation. I don’t even know anyone else who works with QNX and how did they learn about it. I’m pretty sure they learned like me… Using, testing and looking for solutions by yourself. Using this forum, asking question on qnx inn server, etc.

Well. I’ll describe all history. It is a big text with lots of english mistakes (sorry guys) but I think is a helpful information.

The work was to develop a system for instrumentation using a SBC computer and a PC-104 data acquisition board (da_board).
During the tests of timer programming for pacer trigger on the da_board, I use an osciloscope to see if the 8254 timer was programmed as I wanted. Initially, I put the osciloscope channel 1 on LPT port to see a signal generated by my ISR routine (one timer trigger - out8(PAR,0xFF), next one - out8(PAR, 0x00), and so on). This way, I could generate a square waveform with the frequency programmed (on 8254 timer) divided by 2.
Looking at osciloscope, this signal showed me too many variations, the osciloscope trigger could not be stable, the frequency had too many changes, etc.

I started to look for bugs on my IRQ thread. With RobKrten’s book at my desk ;), made some changes, tested again, etc. One interesting test was to see how the was the signal behavior under Photon and text mode.
Over Photon, the signal became more stable than on text mode. Not as stable as needed, but better. Strange… :confused:
I’ve decided to do some tests using different interrupts (IRQs 3, 4, 5, 6 and 7), but no changes at all.

I decided to go down a bit and try to see the Interrupt signal generated by timer. As the da_board have only one chip with everything integrated (PCM-3718 from advantech), I couldn’t get the signal directly from timer. Than, I choosed to get the signal on the PC-104, pin 25 (IRQ 3).

My surprise was to see the signal was unstable too :open_mouth: . The thread was working exactly as the interrupt signal. At this point, as a software developer (kind of ;)), I though about hardware problems. But I wanted to be sure, so I posted the article on the forum. With help, I made all changes to make the thread bug-free (let’s say that) and to be sure that the problem was not on software.

I ask for help with my professor, and we started to test everything again. I’ve made changes, new programs, everything to see if the problem could be with software or not. Well… the problem still persists.

Searching the net for all specifications on da_board, SBC board, someone else who had a similar problem, I found a very interesting link about the SBC board (Gene-4310 from Aaeon). The manufacturer put this link information : "Gene-4310( Not Recommended for New Design) http://na.aaeon.com/3-1-0-esbc.php?mode=viewi&i_id=20. What ?? :open_mouth:

I started to look what they mean by this and again I couldn’t find any information.

This was interesting, because it opened my mind to a possibility of problem on the SBC.

I’ve decided to go down more and look for information on 8259 interrupt controler. With all in mind, I’ve developed a tiny DOS program to use the SBC timer (timer 0 - IRQ 0) and to generate the same signal (square waveform) on the LPT port.
It showed me the same problem again.
This was critical to me.

I’ve changed the SBC (now using a vsbc-6 from versalogic, this one have the ad system on board) and tried the DOS program again and… STABLE SIGNAL! GREAT! I’ve put the PC-104 (PCM-3718) da_board, plug my HDD with QNX with the full system, and run the entire system. STABLE! AAAAAAAHHH!!! :mrgreen:

I’ve almost made a new and nice detail on the wall with the old SBC ! :smiling_imp:

After this, I learn some tips for intrumentation systems developers.
1 - be sure that your SBC is full functional. Begin with a small DOS program to program 8254 timer and 8259 interrupt controller, generate signals and see them stable on the osciloscope.
2 - be sure your data acquisition board is full functional. Make tests with function generators, use a program (MATLAB for instance) to plot the data and see if the signal generated is the same as the signal acquired, make a FFT and check the frequency.
3 - Start your system implementation.

This is a good way to be sure you’ll not loose days and days looking for a problem you can’t solve! :smiley:

Once again, I’m sorry for such big post, and thanx a lot for all the people who helped me (Rick, Mario and other users).

I’m going to have a beer now. 8)

See you,
Leandro Colen

P.S. Boards used :
Gene-4310 from Aaeon - http://na.aaeon.com/3-1-0-esbc.php?mode=viewi&i_id=20
PCM-3718 from Advantech - http://www.advantech.com/products/Model_Detail.asp?model_id=1-LFMMW&bu=
VSBC-6sr - from VersaLogic - http://www.versalogic.com/products/ds.asp?productID=75

Just one little thing.

If there’s any brazilian QNX user in this forum, or if you guys know somebody, I would like to get in contact with they. Maybe we can start a brazilian QNX-user community. ;)

My e-mail is : lcrocha@yahoo.com

Thanx.

Glad to be of help. ;-) Debugging problems over the internet is always interesting - although I can appreciate how frustrating it can be as well.

Rick…

Congratulation. And big thanks for the feedback!

Yes, a good read. The finding reminds me of warnings of the unsuitability of portable PCs due to BIOS often jumping in with a processor mode-switch and the resulting massive interruption of everything CPU related. I believe the Geode chipset is one that makes heavy use of such BIOS “features” including VGA and MDA display mode emulations.

Yeah, SMM (System management mode)… Yuch… Fortunately ACPI replaces it in most systems and it s much better approach to the same concepts - that is that the bios provides ACPI byte code and the OS provides the virtual machine to parse it.

Rick…