B.3 PROGRAM .SLAVE

Dependencies:   mbed

problemb1.h

Committer:
manujose
Date:
2010-12-14
Revision:
1:695db1757630
Parent:
0:9092ea8d9a6c

File content as of revision 1:695db1757630:

#ifndef PROBLEMB1_H_
#define PROBLEMB1_H_
#include "mbed.h"
#include "pt.h"
#include "pt-sem.h"
#include "decl.h"
#include "pqueue.h"

pQueue globalQ;
unsigned int gTime =0;
timeval pps; 

union {
    unsigned int t;
    char BYTE[4];
    }t1,t2,t3,t4;
signed int offset;

void initialSetup(void) {
    LPC_SC->PCLKSEL0 |= 0x04;  //set the frequency REF: USER MANULA TAB 40,41,42 ?? check

    LPC_SC-> PCONP |= 1 << 1;    // Power on Timer0

    LPC_TIM0->TCR = 0x2;         // Reset and set to timer mode
    LPC_TIM0->CTCR = 0x0;
    LPC_TIM0->PR = 0;            // No prescale
    //LPC_TIM0->MR0 = 0xF0537000 ;       // Match count for 100mS
     LPC_TIM0->MR0 = RESET_42;
    LPC_TIM0->MCR = 3;           // Interrupt, Stop, and Reset on match


    LPC_TIM0->TCR = 1;           // Enable Timer0
    // Enable the ISR vector
    NVIC_SetVector (TIMER0_IRQn, (uint32_t)&Timer0_IRQHandler);
    NVIC_EnableIRQ(TIMER0_IRQn);

    //  LPC_TIM0->MCR |= 11; //for mr1 and mr0
    //queue set up
    globalQ.numEle = 0;
    globalQ.head = NULL;
}
void Timer0_IRQHandler(void) {
    // LPC_TIM0->IR=0xff;
    //LPC_TIM0->MR0 = 0x5370;
    if (LPC_TIM0->IR&1) {
        gTime++;
       // pc.printf("gtime++ %X",LPC_TIM0->IR);
    } 
    
    if((LPC_TIM0->IR >> 1)&1 ){ //RUN THE RUNAT TIME HIT
        qEle *ele = pop(&globalQ);
     //   pc.putc('1'); 
        ele->foo();
        free(ele);
    }
    //check if more ele for schedule this time ?
    if ((globalQ.numEle >0) && (globalQ.head->sched ==0)&& (globalQ.head->t.tv_sec <((gTime+1)*42))) {
        globalQ.head->sched = 1;
        
       //
       //
       //
       // pc.putc('2'); 
       // LPC_TIM0->MR1 = (globalQ.head->t.tv_sec-gTime*42)*96000000 +globalQ.head->t.tv_usec*96;
        LPC_TIM0->MR1 = (globalQ.head->t.tv_sec-(gTime*42))*CLK_FREQUENCY +globalQ.head->t.tv_usec*CLK_FRQ;
        LPC_TIM0->MCR |= 8;
     //   pc.printf("\n MR1 = %X",LPC_TIM0->MR1); 
    } else if (globalQ.head->sched == 0) //NO events in this gTime update yet .
    { //turn off the match regiester 1 interrupts.
        LPC_TIM0->MCR &= 3;
    }
    
    timeval t;
    getTime(&t);
    LPC_TIM0->IR = 0xff;
  //  pc.printf("INCREMENTING COUNTER or event %d  \n",t.tv_sec);
}


void getTime(timeval *tv) {
    unsigned int nMSec = (LPC_TIM0->TC + offset)/CLK_FRQ; //gives num of micro sec
  //  unsigned int nMSec = (LPC_TIM0->TC + offset)/72; 
    unsigned int nSec = nMSec/1000000;
    tv->tv_sec = gTime*42 + nSec;
    // tv->tv_usec = (LPC_TIM0->TC)*1000 + (float)(LPC_TIM0->PC)/( CLK_FREQUENCY * 1000000);
    tv->tv_usec = nMSec-(nSec*1000000);
}

int curTimeEqualGR(timeval *tv) {
    timeval curT;
    getTime(&curT);
    if (curT.tv_sec == tv->tv_sec) {
        if (curT.tv_usec == tv->tv_usec)
            return 1;
        else
            pc.printf("WROING MICRO CALIBERATION\n");
        return 1;
    } else if (curT.tv_sec > tv->tv_sec) {
        pc.printf("WRONG cur = %d and req = %d \n",curT.tv_sec, tv->tv_sec);
        return 1;
    }
    return 0;
}

int runAtTime(void (*schedFunc)(void), timeval *tv) {
    int ret =0;
    ret = enqueue(&globalQ, *tv, schedFunc);
    if (tv->tv_sec < (gTime+1)*42) {

        if (globalQ.head->sched == 0) {
        
            LPC_TIM0->MR1 = ((globalQ.head->t.tv_sec%42 )*CLK_FREQUENCY+(globalQ.head->t.tv_usec*CLK_FRQ));
            globalQ.head->sched = 1;
            LPC_TIM0->MCR |= 8;
        }
    }
    return ret;
}
void trigEX(timeval *tv) {
    pc.printf(" Triggered at %d\n",tv->tv_sec);
}
void trigger(void) {
    timeval curT;
    getTime(&curT);
    gtrigFunc(&curT);
}
void runAtTrigger(void(*trigFunc)(timeval *tv)) {
    gtrigFunc = trigFunc;
  //  trig.rise(&trigger);
   // pc.printf("Runing runAtTrigger\n");
}


void sync_with_master(void) {
    t1.t = LPC_TIM0->TC ;

    // trigger the master

    sync.putc('x');
    //pc.printf("\n sync_with_master t1=%X\n", t1); 
}

void calculate_offset(void) {

llong  t2minust1, t4minust3; 
    t4.t = LPC_TIM0->TC;

    sync.attach(NULL); 
    
// serially receive data from master

    //t2.t = 0;
    //t3.t = 0;
      
      t2.BYTE[0] = sync.getc();
      t2.BYTE[1] = sync.getc();
      t2.BYTE[2] = sync.getc();
      t2.BYTE[3] = sync.getc();
      
      t3.BYTE[0] = sync.getc();
      t3.BYTE[1] = sync.getc();
      t3.BYTE[2] = sync.getc();
      t3.BYTE[3] = sync.getc();
        
        
    
    //exhaust buffer 
    
    sync.attach(&calculate_offset); 
    
   // pc.printf(" \n t1= %X, t2 = %X, t3 = %X, t4 = %X",t1.t,t2.t,t3.t,t4.t);

// account for the case where the TC has overflowed.

    if ( t1.t > t4.t )
    {
        t4.t = RESET_42 + t4.t;
}
    if (t2.t > t3.t)
 {   
        t3.t = RESET_42 + t3.t;
}

    t2minust1 = (llong)t2.t-t1.t;
    t4minust3 = (llong)t4.t-t3.t;

  //  pc.printf(" \n t2-t1 = %X, t4-t3 = %X",t2minust1, t4minust3);
    
    offset =(int) ((t2minust1-t4minust3)/2);
    
    LPC_TIM0->TC = (LPC_TIM0->TC + offset);
    if(LPC_TIM0->TC >  RESET_42)
        LPC_TIM0->TC = LPC_TIM0->TC - RESET_42;
        
 //   pc.printf(" offset = %d\n",offset);
    offset = 0; 
    while(sync.readable())
    sync.getc(); 
 
     
}


void pinToggle(void)
{
    
    toggle = !toggle; 
    myLED = !myLED;
  // pc.putc('T'); 
//   pc.printf("\nToggle");
    pps.tv_usec+=500000;
    if(pps.tv_usec == 1200000)
    {
       pps.tv_usec = 200000;
       pps.tv_sec++; 
    }
    
    runAtTime(&pinToggle,&pps);
      
}



#endif