Hi !
I'm using custom board with 21065L.
I've connected 2 sharcs via serial ports and i'm sending single 32bit
words. Transmision is interrupt driven:
1) IRQ0I- every 150us; here variable is being written to TX register and sent 2) SPR0I (SPORT0 receive)- here variable is being read from RX 3) SPT0I (SPORT0 transmit)- not important code at the moment (like incrementing a varible) 1- has got highest priority; 3-
lowest
I wrote the program in C mostly and i'm
using 'interrupts' function (EE-134) wchich DISABLES interrupt
nesting (30 cycle counts; alternate register set is used; noting
saved)
And the thing is that the main code executes
about 7000 times per second.. and if diable transmit interrupt 3) the code
executes about 146000 times per second- so 20 times more.. disableing other
interrups makes no difference, only this one..
So is there something i'm missing out
??
I don't need this interrupt service at the
moment, but i may need it in the future.
I also tried interruptf() and interrupt() and
it doesn't work at all.. even if i disable interrup nesting.. it's
strange for me because i thought that it should work pretty the same way, coz
only more work is being done with preserving some registers and
stuff..
So i don't fully understand what's
happening :( but i don't have much experience with programing processors on
the other hand :)
Anyway has some of You got any idea why is it
working this way ??
I would like to solve this problem coz i
may need transmit interrupt in the future, as well as interrupt nesting.. and i
don't think i'll write interrup services in asembler, coz i have even
less experience with that..
i can send my code if someone would be
interested :).. it's fairly short and simple.
regards,
Artur
|
|
SPORT sh65L
Started by ●July 6, 2004
Reply by ●July 7, 20042004-07-07
Hi, --- arTh <> wrote: > Hi ! > > I'm using custom board with 21065L. I've connected 2 > sharcs via serial ports and i'm sending single 32bit > words. Transmision is interrupt driven: > 1) IRQ0I- every 150us; here variable is being > written to TX register and sent > 2) SPR0I (SPORT0 receive)- here variable is being > read from RX > 3) SPT0I (SPORT0 transmit)- not important code at > the moment (like incrementing a varible) > 1- has got highest priority; 3- lowest > > I wrote the program in C mostly and i'm using > 'interrupts' function (EE-134) wchich DISABLES > interrupt nesting (30 cycle counts; alternate > register set is used; noting saved) > > And the thing is that the main code executes about > 7000 times per second.. and if diable transmit > interrupt 3) the code executes about 146000 times > per second- so 20 times more.. disableing other > interrups makes no difference, only this one.. Are there any events that generate the interrupt 3)? Which ones? How often do they happen? > So is there something i'm missing out ?? > I don't need this interrupt service at the moment, > but i may need it in the future. > > I also tried interruptf() and interrupt() and it > doesn't work at all.. even if i disable interrup > nesting.. it's strange for me because i thought that > it should work pretty the same way, coz only more > work is being done with preserving some registers > and stuff.. > > So i don't fully understand what's happening :( but > i don't have much experience with programing > processors on the other hand :) > Anyway has some of You got any idea why is it > working this way ?? > > I would like to solve this problem coz i may need > transmit interrupt in the future, as well as > interrupt nesting.. and i don't think i'll write > interrup services in asembler, coz i have even less > experience with that.. With 1st generation SHARCs (and generally, all the way throughout the family) it is VERY simple, I think it's worth giving a try (if you have some time to play around) > > i can send my code if someone would be interested > :).. it's fairly short and simple. That would certainly help. > > regards, > > Artur JaaC ===== Jaime Andr Aranguren Cardona __________________________________ |
Reply by ●July 7, 20042004-07-07
Make sure you are reading the SPORT Rx register to clear the interrupt, otherwise I believe you will get interrupted again as soon as you exit. At 01:07 PM 7/6/2004, arTh wrote: >Hi ! > >I'm using custom board with 21065L. I've connected 2 sharcs via serial >ports and i'm sending single 32bit words. Transmision is interrupt driven: >1) IRQ0I- every 150us; here variable is being written to TX register and sent >2) SPR0I (SPORT0 receive)- here variable is being read from RX >3) SPT0I (SPORT0 transmit)- not important code at the moment (like >incrementing a varible) >1- has got highest priority; 3- lowest > >I wrote the program in C mostly and i'm using 'interrupts' function >(EE-134) wchich DISABLES interrupt nesting (30 cycle counts; alternate >register set is used; noting saved) > >And the thing is that the main code executes about 7000 times per second.. >and if diable transmit interrupt 3) the code executes about 146000 times >per second- so 20 times more.. disableing other interrups makes no >difference, only this one.. >So is there something i'm missing out ?? >I don't need this interrupt service at the moment, but i may need it in >the future. > >I also tried interruptf() and interrupt() and it doesn't work at all.. >even if i disable interrup nesting.. it's strange for me because i thought >that it should work pretty the same way, coz only more work is being done >with preserving some registers and stuff.. > >So i don't fully understand what's happening :( but i don't have much >experience with programing processors on the other hand :) >Anyway has some of You got any idea why is it working this way ?? > >I would like to solve this problem coz i may need transmit interrupt in >the future, as well as interrupt nesting.. and i don't think i'll write >interrup services in asembler, coz i have even less experience with that.. > >i can send my code if someone would be interested :).. it's fairly short >and simple. > >regards, > >Artur >_____________________________________ >Note: If you do a simple "reply" with your email client, only the author >of this message will receive your answer. You need to do a "reply all" if >you want your answer to be distributed to the entire group. > >_____________________________________ >About this discussion group: > >To Join: Send an email to > >To Post: Send an email to > >To Leave: Send an email to > >Archives: ><http://groups.yahoo.com/group/adsp" target="_blank" rel="nofollow">http://groups.yahoo.com/group/adsp>http://groups.yahoo.com/group/adsp > >Other Groups: ><http://www.dsprelated.com/groups.php3" target="_blank" rel="nofollow">http://www.dsprelated.com/groups.php3>http://www.dsprelated.com/groups.php3 > > >---------- >Yahoo! Groups Links > * To Steve Holle Link Communications, Inc. 1035 Cerise Rd. Billings, MT 59101 |
Reply by ●July 7, 20042004-07-07
> Are there any events that generate the interrupt 3)?
> Which ones? How often do they happen? Yes .. Serial Port generates an interrupt after
it sends data.. unfortunatelly i didn't chcek yet how often this
interrupt happens.. will do this as soon as i can..
> Make sure you are reading the SPORT Rx register to clear the
interrupt,
> otherwise I believe you will get interrupted again as soon as you exit. I am.. in the receive interrupt service routine
'irq_odebrano_dana()'. I read somewhere that while writting code in
assembler one has to check what kind of interrupt occured, right ?. C does it
for me.
I would be greatfull for any interesting
sugestions. Cheers.
************************************ shortly:
main
{
var_init()
// initialization of variables
SPRT_enable(); // enabling and setting up
SPORT0
interrupts(SIG_IRQ0, irq0_isr); /* main
interrup occuring every 150us- data is being written here to TX and
sent */
interrupts(SIG_SPR0I, irq_odebrano_dana); // interrupt after receiving data- data is being read here from RX to internal memory interrupts(SIG_SPT0I,
irq_wyslano_dana); // interrupt
after sending data
do
{
checking some
registers
do_PC(); // PC reads data from
external memory
z_PC() // PC writes data to external memory }
}
*****************************
//===============================================================
//================================================================
#include <21065L.h>
#include <def21065L.h> #include <signal.h> #include <macros.h> #include <math.h> //#include "def21065L_j.h"
#include "io_def.c" #include "sh65_ios.c" //--------------MAKRA---------------------------- #define testuj_bit_tx(in,out) \ asm("r9 = dm(0xe0);r8 = %1; btst r9 by r8; r9=0; if sz %0=r9; " : "=d"(out) : "d"(in) : "r9","r8"); #define testuj_bit_rx(in,out) \
asm("r9 = dm(0xe1);r8 = %1; btst r9 by r8; r9=1; if not sz %0=r9; " : "=d"(out) : "d"(in) : "r9","r8"); #define Cycle_Count_START(cntr) \
asm("r0 = emuclk; %0 = r0;" : "=k"(cntr) : "d"(cntr) : "r0"); #define Cycle_Count_STOP(cntr) \
asm("r0 = emuclk; r1=%1; r2=4; r0=r0-r2; r0=r0-r1; %0=r0;" : "=k"(cntr) : "d"(cntr) : "r0", "r1"); #define read_reg(in,out) \
asm("r0=%1; %0=r0;" : "=d"(out) : "d"(in) : "r0"); #define read_reg_IRPTL(out) \ asm("r0 = IRPTL; %0=r0;" : "=d"(out) : : "r0" ); #define read_reg_IMASK(out) \ asm("r0 = IMASK; %0=r0;" : "=d"(out) : : "r0" ); #define read_reg_MODE1(out) \ asm("r0 = MODE1; %0=r0;" : "=d"(out) : : "r0" ); #define read_reg_MODE2(out) \ asm("r0 = MODE2; %0=r0;" : "=d"(out) : : "r0" ); //------------
float ssps2003,ssps2004,odebrano,wyslano;
int allow_send, allow_receive; int
RecIrqAsserted,TsmIrqAsserted,allowSend,forbidSend,allowReceive,forbidReceive,mainRoutine,mainRout;
float tmp, cycles, cntr0; int R_imask,R_irptl,R_srctl,R_stctl,R_mode1,R_mode2; short tmp_int; void z_PC(void); // przesyl danych z i do Konsoli operatora
void do_PC(void); void var_init (void); void SPRT_disable(void); void SPRT_enable(void); /*--*/
void irq0_isr(void) // you could call it timer
interrupt service routine, coz it occures every 150us
{ allow_send = 1; testuj_bit_tx(31,allow_send); if (allow_send == 0) { if (allowSend > 1000000) allowSend = 1; else allowSend++; wyslano = ssps2003; *(long int *) TX0_A = wyslano; } else { if (forbidSend > 1000000) forbidSend = 1; else forbidSend++; } } void irq_odebrano_dana(void) // receive interrupt service
routine
{ RecIrqAsserted++; if (RecIrqAsserted > 1000000) RecIrqAsserted = 1; odebrano = *(long int *) RX0_A;
ssps2004 = odebrano; } void irq_wyslano_dana(void) // transmit interrupt service
routine
{ TsmIrqAsserted++; if (TsmIrqAsserted > 1000000) TsmIrqAsserted = 1; } //*********************************
// PROGRAM GLOWNY //********************************* void main() { var_init(); //sport_reg_init(); SPRT_enable(); interrupts(SIG_IRQ0, irq0_isr); /* Glowne przerwanie przeksztaltnika
*/
interrupts(SIG_SPR0I, irq_odebrano_dana);//Przerwanie po odbioze danej z portu interrupts(SIG_SPT0I, irq_wyslano_dana);//Przerwanie po wyslaniu danej z portu asm("BIT CLR MODE1 NESTM;"); // nesting disabled, 11 bit
asm("BIT SET MODE2 FLG0O;"); // flag0 output, 15 bit // asm("BIT CLR IMASK SPR0I;"); // SPORT0 receive interrupt masked (disabled) asm("BIT CLR IMASK SPT0I;"); // SPORT0 transmit interrup masked (disabled) // asm("BIT SET IMASK SPR0I;");
// asm("BIT SET IMASK IRQ0I;"); /***********Petla*glowna*****************/
do
{ if (mainRout == 20000) // zeby zbyt czesto nie wykonywac odczytu ramu niepotrzebnie { rds_data16(100,tmp_int); if (tmp_int == 51) SPRT_enable(); if (tmp_int == 56) SPRT_disable(); } // Cycle_Count_START(cntr0);
/* allow_receive = 0; testuj_bit_rx(30,allow_receive); if (allow_receive == 1) { allowReceive ++; if (allowReceive > 1000000) allowReceive=1; odebrano = *(long int *) RX0_A; ssps2004 = odebrano; } else { if (forbidReceive > 1000000) forbidReceive = 1; else forbidReceive++; }*/ mainRout++;
mainRoutine++; if (mainRout > 40000) set_flag(SET_FLAG0,SET_FLAG);
// if (mainRout > 10000) asm("BIT SET ASTAT FLG0;"); else set_flag(SET_FLAG0,CLR_FLAG); if (mainRout>80000) mainRout = 0; // cycles = (float)cntr0; if (mainRoutine > 1000000) mainRoutine = 1;
else mainRoutine++; read_reg(*(long int *)SRCTL0,R_srctl);
read_reg(*(long int *)STCTL0,R_stctl); read_reg_IRPTL(R_irptl); read_reg_IMASK(R_imask); read_reg_MODE1(R_mode1); read_reg_MODE2(R_mode2); // asm ("BIT CLR IRPTL SPT0I;"); // bit10 0x28 SPR0I DMA Channel 0 – SPORT0 Receive /* anomalia jesli korzysta sie z ramu zew. bezposrednio po
operacji na bitach z ramu wew. */
do_PC();
z_PC(); // Cycle_Count_STOP(cntr0); } while(1); } /*-*/
/* Funkcje Pomocnicze */ /*uzyte w pelti glownej lub przerwaniu */ /*-*/ void var_init (void)
{ allow_receive = 0; RecIrqAsserted = 0;
TsmIrqAsserted = 0; // allowReceive = 0; // forbidReceive = 0; allowSend = 0; forbidSend = 0; mainRoutine = 0; mainRout = 0; } void SPRT_disable(void)
{ *(long int *) STCTL0 = 0x00000000; *(long int *) SRCTL0 = 0x00000000; *(long int *) RDIV0 = 0x00000000; *(long int *) TDIV0 = 0x00000000; tmp = 0; wrs_data32(100,tmp); } void SPRT_enable(void)
{ *(long int *) RDIV0 = 0x00000000; *(long int *) TDIV0 = 0x0028001d; *(long int *) STCTL0 = 0x000075f1; *(long int *) SRCTL0 = 0x000021f1;
tmp = 0; wrs_data32(100,tmp); } void z_PC(void)
{ rds_data32(0,ssps2003); } void do_PC(void)
{ wrs_data32(8,ssps2004); tmp = (float)allowSend;
wrs_data32(12,tmp); tmp = (float)forbidSend;
wrs_data32(16,tmp); tmp = (float)mainRoutine;
wrs_data32(20,tmp); // tmp = (float)allowReceive; // wrs_data32(24,allowReceive); // tmp = (float)forbidReceive; // wrs_data32(28,forbidReceive); wrs_data32(32,R_stctl);
wrs_data32(36,R_srctl); wrs_data32(40,R_imask); wrs_data32(44,R_irptl); wrs_data32(48,R_mode1); wrs_data32(52,R_mode2); // wrs_data32(56,cycles); } //===============================================================
//================================================================
>I'm using custom board with 21065L. I've connected 2 sharcs
via serial
>ports and i'm sending single 32bit words. Transmision is interrupt driven: >1) IRQ0I- every 150us; here variable is being written to TX register and sent >2) SPR0I (SPORT0 receive)- here variable is being read from RX >3) SPT0I (SPORT0 transmit)- not important code at the moment (like >incrementing a varible) >1- has got highest priority; 3- lowest > >I wrote the program in C mostly and i'm using 'interrupts' function >(EE-134) wchich DISABLES interrupt nesting (30 cycle counts; alternate >register set is used; noting saved) > >And the thing is that the main code executes about 7000 times per second.. >and if diable transmit interrupt 3) the code executes about 146000 times >per second- so 20 times more.. disableing other interrups makes no >difference, only this one.. >So is there something i'm missing out ?? >I don't need this interrupt service at the moment, but i may need it in >the future. > >I also tried interruptf() and interrupt() and it doesn't work at all.. >even if i disable interrup nesting.. it's strange for me because i thought >that it should work pretty the same way, coz only more work is being done >with preserving some registers and stuff.. > >So i don't fully understand what's happening :( but i don't have much >experience with programing processors on the other hand :) >Anyway has some of You got any idea why is it working this way ?? > >I would like to solve this problem coz i may need transmit interrupt in >the future, as well as interrupt nesting.. and i don't think i'll write >interrup services in asembler, coz i have even less experience with that.. |
Reply by ●July 15, 20042004-07-15
ok i found the problem..
i've checked how many times transmit
interrupt occurs.. about 140 000 times per sec., while receive int. about 7000
times p/s... i thought that it should be the same amount of interrupts since i
only send data 7000 times/s, and according to adi's help chapter 10 (Serial
Ports):
"the SPORT generates an interrupt every time it
has received a data word or has started to transmit a data word"
but one should read it several times (wchich i did of course :])
and very carefully too...
this one gives some clue but can be misleading.. well was for me
anyway: "An interrupt is generated when the output
shifter has been loaded, signifying that the TX buffer is ready to accept the
next word (i.e. the TX buffer is “not full”)"
and this sentence clarifies the whole
thing:
"..whenever a complete 32-bit word has been
received in the RX buffer,or whenever the TX buffer is not
full."
IMHO it should be
generated ONLY- i.e.- when "output shifter has been loaded", but than
again i'm just a student with little practice :]
i still don't know why my
program doesn't work with "interrupt" and "interrupf" only with
"interrupts" C function..
regards
artur
|
|
Reply by ●July 15, 20042004-07-15
On Thursday 15 July 2004 02:17, arTh wrote: > ok i found the problem.. > i've checked how many times transmit interrupt occurs.. about 140 > 000 times per sec., while receive int. about 7000 times p/s... i > thought that it should be the same amount of interrupts since i > only send data 7000 times/s, and according to adi's help chapter 10 > (Serial Ports): "the SPORT generates an interrupt every time it has > received a data word or has started to transmit a data word" > ... > i still don't know why my program doesn't work with "interrupt" and > "interrupf" only with "interrupts" C function.. > regards > > artur Take it serious, that strange feeling which bothers you. Several times I found a bigger and more important issue behind it, when I had the courage to keep on investigating, although the problem seemed to have disappeared. I don't have an answer around, but I'd like to encourage you: try to thoroughly understand what's happening, it might help you - and it might help those who work with that compiler - as I do. It might help if you trace the interrupt handler (that function __z3_int_determiner which calls the dispatcher after occurrence of an interrupt). In case you detect any abnormal or strange behaviour, contact mailto: They are usually very quick and thorough in checking the issue - I guess they'll assist you. Good luck Bernhard |