DSPRelated.com
Forums

SPORT sh65L

Started by arTh July 6, 2004
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



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

__________________________________


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



> 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..
 
 
 
 

 


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
 



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