B.3 PROGRAM .SLAVE

Dependencies:   mbed

Revision:
0:9092ea8d9a6c
Child:
1:695db1757630
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/problemb1.h	Sat Dec 04 05:09:46 2010 +0000
@@ -0,0 +1,215 @@
+#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;
+        
+    offset = 0; 
+    while(sync.readable())
+    sync.getc(); 
+ 
+    //pc.printf(" offset = %d\n",offset); 
+}
+
+
+void pinToggle(void)
+{
+    toggle = !toggle; 
+    myLED = !myLED; 
+   // pc.printf("\nToggle");
+    pps.tv_sec++; 
+    runAtTime(&pinToggle,&pps);
+      
+}
+
+
+
+#endif
\ No newline at end of file