[Icc-avr] simple taskswitcher inc

BobGardner at aol.com BobGardner at aol.com
Sat Apr 30 16:35:14 PDT 2005


Skipped content of type multipart/alternative-------------- next part --------------
//file taskswitcher32.c
//try to write a task switcher in c for ere co mega32
//16Mhz xtal, 38400 baud

//Apr 23 05 Bob G iitial edit
//Apr 24 05 Bob G

//todo: fp, rf
//save joycal in eeprom

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <macros.h>
#include <iom32v.h>

#define INTR_OFF() asm("CLI")
#define INTR_ON()  asm("SEI")

//---ascii equates----------------
#define ESC  0x1b
#define CTLQ 0x11
#define CR   0x0d
#define LF   0x0a

#define PWMMAX 31
//----externs--------
extern void init_devices(void);
extern int _textmode;

//----struct used for rolling average------
#define NUMSAMP 8
typedef struct{
  char ndx;
  long int  tot;
  int  avg;
  int  dat[NUMSAMP]; //avg over NUMSAMP readings
}Trollavg;

//------vars in bss-------
Trollavg rollavg[8];
unsigned int addat[8];  //internal 10 bit
unsigned char dispon;
unsigned char *pt;
unsigned char *pf;    
unsigned char c;
signed char ch1,ch2,ch3,ch4; //+-32
unsigned char tics,ticsl;
unsigned int  tocs,tocsl;
unsigned char os100ms;
unsigned char os1sec;
unsigned char hr,min,sec;
unsigned int left,fwd,back,right;    //joystick
int fwdrise,fwdrun,backrise,backrun;
int leftrise,leftrun,rightrise,rightrun;
int fwdcen,leftcen;
int turnangdem; //+-45 deg
int turnangpos; //+-45 deg
int turnspddem; //speed demand due to turning
int throtpct; //+-100
int os100msaccum;
int os1secaccum;
int deltatms;
int deltattocs;
int deltatmsoff;
//int frntdem,frntpos,frnterr,reardem,rearpos,rearerr; //deg
//int frnterrl,rearerrl;

//------rom---------
const unsigned char banner[]={"taskswitcher32 Apr 23 05\n"};

//-------------------
void delnms(int n){
//delay n ms
int x;

  while(n--){
//    x=2400;       //empirically determined fudge factor  14.7456 mhz
    x=2600;       //empirically determined fudge factor  16 mhz
//    x=3000;       //empirically determined fudge factor  18.432 mhz
    while(x--);
  }
}

//-------------------------
void initvars(void){
//init vars

  fwdrun=1023;
  leftrun=1023;
  fwdcen=512;
  leftcen=512;
  back=0;
  fwd=1023;
  left=0;
  right=1023;
  fwdrun=back-fwd;
  leftrun=left-right;
  fwdrise= 200; //+-100
  leftrise= 90; //+-45
}

//------RS232-----------------
unsigned char kbhit(void){
//return nonzero if char waiting  polled version
unsigned char b;

  b=0;
  if(UCSRA & (1<<RXC)) b=1;
  return b;
}

//-----------------------
int getchar(void){
//polled version... 
unsigned char c;

  while(!kbhit()){}; //wait for char
  c=UDR;             //get char from usart
  return c;  
}

//-----------------------
int putc(char c){
//put char to usart0... dont add lf after cr

  while((UCSRA & 0x20)==0){};	//0x20 is UDRE0. ==0 means data register full
  UDR=c; //send char
  return c;
}

//----------------------  
int putchar(char c)	{
//adds lf after cr

  if(c=='\n'){
    putc('\r');
  }  
  putc(c);
  return c;
}

//------------------
void crlf(void){
//output cr then lf

  putchar('\n');
}

//------------
void space(void){
//output a space

  putc(' ');
}

#define ESC 0x1b
//----------------------  
void gotoxy(int x, int y){
//ansi cursor positioning sequence E[y;xH

  putc(ESC);
  putc('[');
  cprintf("%d",y);
  putc(';');
  cprintf("%d",x);
  putc('H');
}

//-------------------------
unsigned char getche(void){
//get and echo a char from rs232
char c;

  c=getchar();
  putchar(c);
  return(c);
}

//----------------------
void clrscr(void){
//clear ansi terminal screen

  putc(ESC);
  putc('[');
  putc('2');
  putc('J');
}

//------------------
void initscreen(void){
//clear screen and print banner

  clrscr();
  cprintf(banner);
}

#if 0  //used instead of printf with modifiers
//----------------------
void putnibhex(unsigned char c){
//output bin nib c in hex

  c+=0x30;           //cvt to ascii
  if(c > 0x39) c+=7; //handle a-f
  putc(c);
}

//-----------------------
void putbytehex(unsigned char c){
//output c as 2 hex chars
unsigned char nib;

  nib=(c & 0xf0) >>4;
  putnibhex(nib);
  nib=c & 0x0f;
  putnibhex(nib);
}

//-----------------------
void putwordhex(unsigned int w){
//output w as 4 hex chars

  putbytehex(w >> 8); //hi byte
  putbytehex(w);      //lo byte
}
#endif

//------debug subs-----------
void dump256ram(unsigned char *n){
//dump 16 rows of 16 bytes
unsigned char r,c,ch;
unsigned char *p;
unsigned char *pa;

  p=n;
  crlf();
  cprintf("      ");
  for(c=0; c<16; c++){
    cprintf("%02x ",c);      //header
    if(c==7) space();
  }
  crlf();
  crlf();
  for(r=0; r<16; r++){
    cprintf("%04x  ",p);     //print addr  at beg of line
    pa=p;            //remember p for ascii
    for(c=0; c<16; c++){
      cprintf("%02x ",*p++); //print hex
      if(c==7) space();
    }
    for(c=0; c<16; c++){
      ch=*pa++;
      if((ch > 0x20) && (ch !=0x0a) && (ch != 0x8a)) //if printing char
        putc(ch);   //print ascii
      else  
        putc('.'); 
      if(c==7) space();
    }
    crlf();
  }
}

//-------------------------
void dump256rom(const unsigned char *n){
//dump 16 rows of 16 bytes
unsigned char r,c,ch;
const unsigned char *p;
const unsigned char *pa;

  p=n;
  crlf();
  cprintf("      ");
  for(c=0; c<16; c++){
    cprintf("%02x ",c);      //header
    if(c==7) space();
  }
  crlf();
  crlf();
  for(r=0; r<16; r++){
    cprintf("%04x  ",p);     //print addr  at beg of line
    pa=p;            //remember p for ascii
    for(c=0; c<16; c++){
      cprintf("%02x ",*p++); //print hex
      if(c==7) space();
    }
    for(c=0; c<16; c++){
      ch=*pa++;
      if((ch > 0x20) && (ch !=0x0a) && (ch != 0x8a)) //if printing char
        putc(ch);   //print ascii
      else  
        putc('.'); 
      if(c==7) space();
    }
    crlf();
  }
}

//-------------------------
unsigned char gethex(void){
//return a hex char from rs232
unsigned char b,c;

  b=0xff; //error return value
  c=toupper(getche());
  if(isxdigit(c)) b=c-0x30; //if c ok, cvt ascii digit to binary
  if((c >= 'A') && (c <= 'F')) b-=7;     //if c hexcvt ascii A to binary 10
  return(b);
}

//---------------------------
unsigned char getbyte(void){
//get 2 nibbles, return a binary byte from rs232
unsigned char n1,n2;

  n1=gethex();
  n2=gethex();
  return((n1 << 4) + n2);
}

//----------------------------
unsigned int getaddr(void){
//return addr from rs232
unsigned int th,tl;

  th=getbyte();
  tl=getbyte();
  return((th << 8) + tl);
}

#if 0  //use these to input a dec number
//---------------------
unsigned char getdecdig(void){
//return decimal digit 0..9 from rs232
//return ff (-1) of non hex, like carriage return
unsigned char b,c;

  b=0xff; //error return value
  c=toupper(getche());
  if(isdigit(c)) b=c-0x30; //if c ok, cvt ascii digit to binary
  return(b);
}

//-----------------
void gets(char *p){
//get a string
char c;  

  do{
    c=getche();
    *p++=c;
  }while(c !=0x0d);
  p--;     //roll p back
  *p=0x00; //add null over cr
}

//-----------------------
unsigned char getnum(void){
//return number 0..255 from rs232  -1 to exit
char dig,n;

  dig=getdecdig();
  if(dig == -1) return dig; 
  n=dig;
//  if(n>2) n=2;
  dig=getdecdig();
  if(dig == -1) return dig; 
  n=n*10+dig;
//  if(n>25) n=25;
  dig=getdecdig();
  if(dig == -1) return dig; 
  n=n*10+dig;
  if(n>255) n=255;
  return(n);
}
#endif

//------------------
void examineram(void){
//ask for mem range in ram and dump
unsigned char *from;
unsigned char c;

  cprintf("from:");
  from=(unsigned char *)getaddr();
  while(c!='q'){
    dump256ram(from);
    cprintf("np or q...");
    c=getchar();
    if(c=='n') from+=0x100;
    if(c=='p') from-=0x100;
  }  
}

//------------------
void examinerom(void){
//ask for mem range in rom and dump
const unsigned char *from;
unsigned char c;

  cprintf("from:");
  from=(const unsigned char *)getaddr();
  while(c!='q'){
    dump256rom(from);
    cprintf("np or q...");
    c=getchar();
    if(c=='n') from+=0x100;
    if(c=='p') from-=0x100;
  }  
}

//------------------
void deposit(void){
//ask for addr and data
unsigned char *at;
unsigned char c;
unsigned char nh,nl;

  cprintf("at:");
  at=(unsigned char *)getaddr();
  while(1){
    cprintf(" %02x ",*at);
    nh=gethex();
    if(nh==0xff) return;
    nl=gethex();
    if(nl==0xff) return;
    c=((nh << 4) | nl);
    *at++=c;
  }
}

//------------------
void fill(void){
//ask for mem range and fill char and fill
unsigned char *from, *to, with;

  cprintf("from:");
  from=(unsigned char *)getaddr();
  cprintf(" to:");
  to=(unsigned char *)getaddr();
  cprintf(" with:");
  with=getbyte();
  memset(from,with,to-from);
}

//-----------------------------
void (* fn)(void); //fn prototype

void dojsr(void){
//ask for addr, jsr to it
const unsigned char *to;

  cprintf(" to:");
  to=(const unsigned char *)getaddr();
  fn=(void *)to;
  (*fn)();  //call function fn and returns
}

//------------------
void debugmenu(void){
//monitor cmds

  cprintf("cmds:\n"
          " e examine ram\n"
          " c examine rom\n"
          " d deposit\n"
          " f fill\n"
          " j jsr\n"
          " q quit\n");
}

//------------------
void debugloop(void){
//examine and deposit mem regs
char c;

  debugmenu();
  while(c != 'q'){
    crlf();
    cprintf("cmd:");
    c=getchar();
    crlf();
    switch(c){
      case 'e': examineram(); break;
      case 'c': examinerom(); break;
      case 'd': deposit(); break;
      case 'f': fill();    break;
      case 'j': dojsr();   break;
      default: debugmenu();
    }
  }
}
//----end of debug subs----------

//--------------------
void initrollavg(Trollavg *p){
//init rollavg struct
char i;

  p->ndx=0;
  p->tot=0;
  p->avg=0;
  for(i=0; i < NUMSAMP; i++){
    p->dat[i]=0;
  }  
}

//--------------------
int calcrollavg(Trollavg *p, int w){
//return rollavg of last NUMSAMP readings

  p->tot-=p->dat[p->ndx]; //subtract old value from tot
  p->tot+=w;              //add in new value
  p->dat[p->ndx++]=w;     //remember new value, bump ndx
  if(p->ndx==NUMSAMP) p->ndx=0; //rewind
  p->avg=p->tot >> 3;     //2^3=8=NUMSAMP; avg is tot/NUMSAMP
  return p->avg;
}

//---------------------
int readadchan(char n){
//read ch n of internal 10 bit a/d

  ADMUX=n;       //select channel n
  asm("nop");
  asm("nop");    //mux settle time?
  ADCSRA |=0x40; //init conversion
  while((ADCSRA & 0x40) !=0){}; //wait for conv complete
  return ADC;
}

//--------------------
void read2ads(void){
//read 2 a/d channels
char n;
int tmp;

  for(n=0; n < 2; n++){
    tmp=readadchan(n);
    addat[n]=calcrollavg(&rollavg[n],tmp);
  }
}

//--------------------
void readadloop(void){
//read internal 10 bit ad 0-0x3ff  0..1023
char c,n;
int tmp;

  cprintf("a/d\n");
  cprintf("0   1   2   3   4   5   6   7 \n");
  c=0;
  while(c != 'q'){
    if(kbhit()){
      c=getchar();
    }  
	  for(n=0; n < 8; n++){
      tmp=readadchan(n);
      addat[n]=calcrollavg(&rollavg[n],tmp);
      cprintf("%03x ",addat[n]);
	  }
  	cprintf("\r");  
  }
}

//-----------------
void joycal(void){
//calibrate
char c;

  cprintf("joystick centered  press a key\n");
  while(!kbhit()){
    read2ads();
	  cprintf("%5d %5d\r",addat[0],addat[1]);
	  delnms(5);
  }	
  c=getchar();
  if(c=='q') return;
  crlf();
  fwdcen=addat[0];
  leftcen=addat[1];

  cprintf("joystick fwd, press key\n");
  while(!kbhit()){
    read2ads();
	  cprintf("%5d\r",addat[0]);
	  delnms(5);
  }	
  c=getchar();
  if(c=='q') return;
  crlf();
  fwd=addat[0]; 

  cprintf("joystick back, press a key\n");
  while(!kbhit()){
    read2ads();
	  cprintf("%5d\r",addat[0]);
	  delnms(5);
  }	
  c=getchar();
  if(c=='q') return;
  crlf();
  back=addat[0]; //big

  cprintf("joystick right, press a key\n");
  while(!kbhit()){
    read2ads();
	  cprintf("%5d\r",addat[1]);
  	delnms(5);
  }	
  c=getchar();
  if(c=='q') return;
  crlf();
  right=addat[1];

  cprintf("joystick left, press a key\n");
  while(!kbhit()){
    read2ads();
	  cprintf("%5d\r",addat[1]);
  	delnms(5);
  }	
  c=getchar();
  if(c=='q') return;
  crlf();
  left=addat[1];

  fwdrun=fwd-fwdcen;     //ad
  backrun=fwdcen-back;
  leftrun=leftcen-left;
  rightrun=right-leftcen;
  fwdrise= 100; //+-100  //pct
  backrise= 100; //+-100
  leftrise= 45; //+-45   //deg
  rightrise= 45; //+-45
  cprintf("fwdrise backrise leftrise rightrise\n");
  cprintf("%8d %8d %8d %8d\n",fwdrise,backrise,leftrise,rightrise);
  cprintf("fwdrun  backrun  leftrun  rightrun\n");
  cprintf("%8d %8d %8d %8d\n",fwdrun,backrun,leftrun,rightrun);
  cprintf("fwdcen  leftcen\n");
  cprintf("%8d %8d\n",fwdcen,leftcen);
  cprintf("press a key");
  c=getchar();
}

//-------------------
void pwmclip(void){
//clip pwm dem to max
     
  if(ch1 >  PWMMAX) ch1=  PWMMAX;      
  if(ch1 < -PWMMAX) ch1= -PWMMAX;      
  if(ch2 >  PWMMAX) ch2=  PWMMAX;      
  if(ch2 < -PWMMAX) ch2= -PWMMAX;      
//  if(ch3 >  PWMMAX) ch3=  PWMMAX;      
//  if(ch3 < -PWMMAX) ch3= -PWMMAX;      
//  if(ch4 >  PWMMAX) ch4=  PWMMAX;      
//  if(ch4 < -PWMMAX) ch4= -PWMMAX;
}            

//----------------
void joycalc(void){
//compute turn angle +-45 and throt pct +-100
//outside wheel is twice as fast as inside wheel at full turn

  if(addat[0] > fwdcen){
    throtpct= fwdrise* ((long)addat[0]-fwdcen)/fwdrun;   //0-100
  }else{
    throtpct= backrise* ((long)addat[0]-fwdcen)/backrun;   //0-100
  }
  if(addat[1] > leftcen){
    turnangdem=  rightrise*((long)addat[1]-leftcen)/rightrun; //+-45
  }else{
    turnangdem=  leftrise*((long)addat[1]-leftcen)/leftrun; //+-45
  }  
//  turnangpos=
  turnspddem=turnangdem*31/45; //0 to 31
    
  //compute 4 motor speeds
  if(turnangdem > 0){ //pos
    ch1=throtpct;
  }else{
    ch1=throtpct;
  }  
  if(turnangdem > 0){ //pos
    ch2=throtpct;
  }else{
    ch2=throtpct;
  }  
  pwmclip();  
//  ch3=throtpct*turnpct;
//  ch4=throtpct*turnpct;
  
}

//----------------------
void udtime(void){
//read tics, generate oneshots, update hr,min,sec
unsigned int tmptocs;

  INTR_OFF(); //critical region
  tmptocs=tocs;             //read copy in case int hits
  INTR_ON();
  deltattocs=tmptocs-tocsl; //tocs since last pass
  tocsl=tmptocs;            //remember last pass
  
  deltatms=deltattocs/5;
  os100msaccum+=deltatms;
  os100ms=0;
  if(os100msaccum >= 100){
    os100ms=1;
    os100msaccum -= 100;
  }
  	  
  os1secaccum+=deltatms; //accumulate milliseconds
  os1sec=0;
  if(os1secaccum >= 1000){
    os1sec=1;
	  os1secaccum -= 1000;
  }
  
  if(os1sec){
    sec++;
	  if(sec > 59){
	    min++;
	    sec=0;
	    if(min > 59){
	      hr++;
	    	min=0;
		    if(hr > 23){
		      hr=0;
		    }
	    }//min
	  }//sec
  }//os1sec	  	  
}

//-------------------------
void pwmhbridge(void){
//do sw pwm on h-bridge pins, 4 pins 2 chanels 5khz it, 31 steps
//+-PWMMAX speeds
unsigned char tmp,spd;
signed char dir;

  tics++;         //pwm speed  0 to PWMMAX
  if(tics > PWMMAX){
    tics=0;
    PORTB=0;
  }
  tmp=PORTB;
  
  dir=ch1 >= 0; //0 or 1
  spd=PWMMAX-abs(ch1); //0 to PWMMAX
  if(dir){ 
    if(tics > spd) PORTB= (tmp & 0x0fc) | 0x01; //1a1b=01=fwd
  }else{  
    if(tics > spd) PORTB= (tmp & 0x0fc) | 0x02; //1a1b=02=rev
  }
  
  dir=ch2 >= 0;
  spd=PWMMAX-abs(ch2);
  if(dir){ 
    if(tics > spd) PORTB= (tmp & 0x0f3) | 0x04; //1a1b=04=fwd
  }else{  
    if(tics > spd) PORTB= (tmp & 0x0f3) | 0x08; //1a1b=08=rev
  }
#if 0  
  dir=ch3 >= 0;
  spd=PWMMAX-abs(ch3);
  if(dir){ 
    if(tics > spd) PORTB= (tmp & 0x0cf) | 0x10; //1a1b=10=fwd
  }else{  
    if(tics > spd) PORTB= (tmp & 0x0cf) | 0x20; //1a1b=20=rev
  }
  
  dir=ch4 >= 0;
  spd=PWMMAX-abs(ch4);
  if(dir){ 
    if(tics > spd) PORTB= (tmp & 0x03f) | 0x40; //1a1b=40=fwd
  }else{  
    if(tics > spd) PORTB= (tmp & 0x03f) | 0x80; //1a1b=08=rev
  }  
#endif
  
}

//-------------------------------
#pragma interrupt_handler timer0_comp_isr:11
void timer0_comp_isr(void){
//compare occured TCNT0=OCR0  5khz

  tocs++;       //time of day
  pwmhbridge();
}

//-----------------------
void pwmloop(void){
//sw pwm 8 bits 4 channels
char c;

  c=' ';
  cprintf("use wsx edc rfv tgb     space=all stop\n");  
  while(c != 'q'){
    if(kbhit()){
      c=getchar();
      switch(c){
        case 'w': ch1++; break;
        case 's': ch1=0; break;
        case 'x': ch1--; break;
        
        case 'e': ch2++; break;
        case 'd': ch2=0; break;
        case 'c': ch2--; break;
        
        case 'r': ch3++; break;
        case 'f': ch3=0; break;
        case 'v': ch3--; break;
        
        case 't': ch4++; break;
        case 'g': ch4=0; break;
        case 'b': ch4--; break;
        case ' ': ch1=ch2=ch3=ch4=0; break;
      }//switch  
//      cprintf("%02x ",tics);
      pwmclip();
      cprintf("%02x ",PORTB);
      cprintf("%3d ",ch1);
      cprintf("%3d ",ch2);
      cprintf("%3d ",ch3);
      cprintf("%3d \r",ch4);
    }//if
  }//while
}

#if 0
//-------------------------
void timing(void){
//time pwm routine
//1 million= 13 sec -> 13 usec -> 71 khz
long int n;

  INTR_OFF();
  n=100000;
  cprintf("start 1,000,000 pwms");
  while(n--){
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
    pwmhbridge();
  }
  cprintf("end\n");
  INTR_ON();
}
#endif

//----------------
void _StackOverFlowed(char n){

  cprintf("overflow! %d\n",n);
}

//-----------------------
void rtloop(void){
//rtloop
char c;

  c=' ';
  dispon=1;
  cprintf("running....     q to quit\n");
  cprintf("hr:mn:sc  mson  msof  throt turn  ch1   ch2\n");
  while(c != 'q'){    //loop forever
    if(kbhit()){      //if char waiting from pc
	    c=getchar();    //get the char
	    if(c=='p') dispon= !dispon;
    } 
	  udtime();
    read2ads();
	  joycalc();   
	 
    if(!dispon) deltatmsoff=deltatms;
    if(dispon){
  	  gotoxy(1,15);
      cprintf("%02d:%02d:%02d  %5d %5d ",hr,min,sec,deltatms,deltatmsoff);
      cprintf("%5d %5d\n",throtpct,turnangdem,ch1,ch2);
    	delnms(5);
	  }
    _StackCheck();
  } //while 1
}

char task1regs[12]; //r10 11 12 13 14 15 20 21 22 23 28 29
int  task1sp;
char task2regs[12];
int  task2sp;
char curtask;  //1 or 2;  0 means uninitialized
//---------------------
void switchtasks(void){
//switch tasks. Return addr to curtask is on stack

  INTR_OFF();
  if(curtask==1){
    asm("sts _task1regs,r10"); //save task1 regs    
    asm("sts _task1regs+1,r11");    
    asm("sts _task1regs+2,r12");    
    asm("sts _task1regs+3,r13");    
    asm("sts _task1regs+4,r14");    
    asm("sts _task1regs+5,r15");    
    asm("sts _task1regs+6,r20");    
    asm("sts _task1regs+7,r21");    
    asm("sts _task1regs+8,r22");    
    asm("sts _task1regs+9,r23");    
    asm("sts _task1regs+10,r28");    
    asm("sts _task1regs+11,r29");    
    asm("sts _task1sp,r30");   //save task1 sp
    asm("sts _task1sp+1,r31"); 

    curtask=2;
    asm("lds r10,_task2regs");  //restore task2 regs
    asm("lds r11,_task2regs+1");
    asm("lds r12,_task2regs+2");
    asm("lds r13,_task2regs+3");
    asm("lds r14,_task2regs+4");
    asm("lds r15,_task2regs+5");
    asm("lds r20,_task2regs+6");
    asm("lds r21,_task2regs+7");
    asm("lds r22,_task2regs+8");
    asm("lds r23,_task2regs+9");
    asm("lds r28,_task2regs+10");
    asm("lds r29,_task2regs+11");
    asm("lds r30,_task2sp");    //restore task2 sp
    asm("lds r31,_task2sp+1");
    INTR_ON(); 
    return;    
  }
  if(curtask==2){
    asm("sts _task2regs,r10"); //save task2 state    
    asm("sts _task2regs+1,r11");    
    asm("sts _task2regs+2,r12");    
    asm("sts _task2regs+3,r13");    
    asm("sts _task2regs+4,r14");    
    asm("sts _task2regs+5,r15");    
    asm("sts _task2regs+6,r20");    
    asm("sts _task2regs+7,r21");    
    asm("sts _task2regs+8,r22");    
    asm("sts _task2regs+9,r23");    
    asm("sts _task2regs+10,r28");    
    asm("sts _task2regs+11,r29");    
    asm("sts _task2sp,r30");   //save task2 sp
    asm("sts _task2sp+1,r31"); 

    curtask=1;
    asm("lds r10,_task1regs");  //restore task1 regs
    asm("lds r11,_task1regs+1");
    asm("lds r12,_task1regs+2");
    asm("lds r13,_task1regs+3");
    asm("lds r14,_task1regs+4");
    asm("lds r15,_task1regs+5");
    asm("lds r20,_task1regs+6");
    asm("lds r21,_task1regs+7");
    asm("lds r22,_task1regs+8");
    asm("lds r23,_task1regs+9");
    asm("lds r28,_task1regs+10");
    asm("lds r29,_task1regs+11");
    asm("lds r30,_task1sp");    //restore task1 sp
    asm("lds r31,_task1sp+1");
    INTR_ON();
    return;
  }
}

//----------------------
void task1(void){
//task1

  while(c != 'q'){
    if(kbhit()){
      c=getchar();
    }
    cprintf("task 1\n");
    delnms(500);
    switchtasks();
  }
}

//----------------------
void task2(void){
//task1

  while(c != 'q'){
    if(kbhit()){
      c=getchar();
    }
    cprintf("task 2\n");
    delnms(500);
    switchtasks();
  }
}

//--------------------------
void menu(void){
//cmds

  initscreen();
  cprintf("cmds:\n");
  cprintf(" 1 task 1\n");
  cprintf(" 2 task 2\n");
  cprintf(" a a/d\n");
  cprintf(" p pwm\n");
//  cprintf(" t timing\n");
  cprintf(" j joystick cal\n");
  cprintf(" m monitor cmds\n");
  cprintf(" r rt loop\n");
}

//--------------------------
void mainswitch(unsigned char c){
//parse char from keyboard

  switch(c){
    case '1': curtask=1; task1(); break;
    case '2': curtask=2; task2(); break;
    case 'a': readadloop(); break;
    case 'm': debugloop();  break;
    case 'p': pwmloop();    break;
//    case 't': timing();     break;
    case 'j': joycal();     break;
    case 'r': rtloop();     break;
    default: menu();
  }
}

//-----------------
void main(void){
//main program
char c;

  init_devices();
  initvars();
  task2sp=(int)&task2; //init task2 sp to point to start of task2
  task1sp=(int)&task1; //init task1 sp to point to start of task1
  _textmode=1;
  initscreen(); //banner
  while(1){     //main loop
    menu();
    crlf();
    putc('>'); //prompt for input
    c=getche();
    crlf();
    mainswitch(c);
  }
}

//---strings embedded in rom--------------
const char copyrightstring[]={"taskswitcher32 computer code\
written by Bob Gardner 407-855-2586 bobgardner at aol.com"};
//--------eof-------------



More information about the Icc-avr mailing list