syncSlave for problem 2

Committer:
the729
Date:
Fri Dec 03 20:52:44 2010 +0000
Revision:
0:988132ee7271

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
the729 0:988132ee7271 1 #include "mbed.h"
the729 0:988132ee7271 2 #include "timesync.h"
the729 0:988132ee7271 3 #include "timesync_slave.h"
the729 0:988132ee7271 4 #include "hdtimeval_math.h"
the729 0:988132ee7271 5
the729 0:988132ee7271 6 int32_t clock_sec;
the729 0:988132ee7271 7 DigitalOut led(LED1);
the729 0:988132ee7271 8 Serial uart_sync(p28,p27);
the729 0:988132ee7271 9 Timeout tmr_sync;
the729 0:988132ee7271 10 Timeout tmr_callback;
the729 0:988132ee7271 11
the729 0:988132ee7271 12 hdtimeval_t front_lt;
the729 0:988132ee7271 13 hdtimeval_t timeq[QUEUE_SIZE];
the729 0:988132ee7271 14 void (*funcq[QUEUE_SIZE])(void);
the729 0:988132ee7271 15 uint8_t qfront;
the729 0:988132ee7271 16 uint8_t qtail;
the729 0:988132ee7271 17
the729 0:988132ee7271 18 void (*trigf)(struct timeval *);
the729 0:988132ee7271 19 hdtimeval_t trigt;
the729 0:988132ee7271 20 //bool trigactive;
the729 0:988132ee7271 21
the729 0:988132ee7271 22 //syncdata_t syncdata[2];
the729 0:988132ee7271 23 //state_t state;
the729 0:988132ee7271 24 synctype_t syncbusy;
the729 0:988132ee7271 25 synctype_t tmp_synctype;
the729 0:988132ee7271 26 hdtimeval_t txstamp;
the729 0:988132ee7271 27
the729 0:988132ee7271 28 coeff_t coeff;
the729 0:988132ee7271 29
the729 0:988132ee7271 30 void clock_init();
the729 0:988132ee7271 31 void tmr1_irq();
the729 0:988132ee7271 32 void uart_recv();
the729 0:988132ee7271 33 __INLINE void getHDTime(struct hdtimeval * hdtv);
the729 0:988132ee7271 34 void sync_req();
the729 0:988132ee7271 35 void update_data(synctype_t t, void * pkt_p, hdtimeval_t * rxstamp);
the729 0:988132ee7271 36 void getLocalTime(hdtimeval * gt, hdtimeval * lt);
the729 0:988132ee7271 37 void getGlobalTime(hdtimeval * lt, hdtimeval * gt);
the729 0:988132ee7271 38 void runTriggerFunc();
the729 0:988132ee7271 39
the729 0:988132ee7271 40 void timesync_init()
the729 0:988132ee7271 41 {
the729 0:988132ee7271 42 wait_ms(100);
the729 0:988132ee7271 43 coeff.v1div2.tv_sec = 0;
the729 0:988132ee7271 44 coeff.v1div2.ticks = 0;
the729 0:988132ee7271 45 coeff.w1div2.tv_sec = 0;
the729 0:988132ee7271 46 coeff.w1div2.ticks = 0;
the729 0:988132ee7271 47 coeff.beta1.tv_sec = 0;
the729 0:988132ee7271 48 coeff.beta1.ticks = 1;
the729 0:988132ee7271 49 coeff.beta2.tv_sec = 0;
the729 0:988132ee7271 50 coeff.beta2.ticks = 1;
the729 0:988132ee7271 51 coeff.size = 0;
the729 0:988132ee7271 52 coeff.front = 0;
the729 0:988132ee7271 53 trigf = NULL;
the729 0:988132ee7271 54
the729 0:988132ee7271 55 clock_init();
the729 0:988132ee7271 56 uart_sync.baud(115200);
the729 0:988132ee7271 57 uart_sync.attach(&uart_recv, Serial::RxIrq);
the729 0:988132ee7271 58
the729 0:988132ee7271 59 syncbusy = SYNCTYPE_NONE;
the729 0:988132ee7271 60 tmp_synctype = SYNCTYPE_64;
the729 0:988132ee7271 61 tmr_sync.attach(&sync_req, 0.1);
the729 0:988132ee7271 62 }
the729 0:988132ee7271 63 /*
the729 0:988132ee7271 64 void timesync_poll()
the729 0:988132ee7271 65 {
the729 0:988132ee7271 66 //static last_poll;
the729 0:988132ee7271 67 tmp_synctype = SYNCTYPE_24;
the729 0:988132ee7271 68 sync_req();
the729 0:988132ee7271 69 }
the729 0:988132ee7271 70 */
the729 0:988132ee7271 71 void clock_init()
the729 0:988132ee7271 72 {
the729 0:988132ee7271 73 // select PCLK
the729 0:988132ee7271 74 LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(3<<CLK_TIMER)) | (PCLK_DEVIDER<<CLK_TIMER);
the729 0:988132ee7271 75 // power on timer
the729 0:988132ee7271 76 LPC_SC->PCONP |= (1<<PCTIM2);
the729 0:988132ee7271 77
the729 0:988132ee7271 78 // reset timer
the729 0:988132ee7271 79 TMR->TCR = 2;
the729 0:988132ee7271 80 TMR->CTCR = 0;
the729 0:988132ee7271 81 TMR->PR = 0;
the729 0:988132ee7271 82 TMR->TC = 1;
the729 0:988132ee7271 83 TMR->MR0 = SystemCoreClock - 1;
the729 0:988132ee7271 84 TMR->MCR = 3;
the729 0:988132ee7271 85
the729 0:988132ee7271 86 clock_sec = 0;
the729 0:988132ee7271 87
the729 0:988132ee7271 88 // capture on CAP.0
the729 0:988132ee7271 89 TMR->CCR = 0x07;
the729 0:988132ee7271 90 LPC_PINCON->PINSEL0 = LPC_PINCON->PINSEL0 | (3<<8);
the729 0:988132ee7271 91
the729 0:988132ee7271 92 // setup interrupt
the729 0:988132ee7271 93 __enable_irq();
the729 0:988132ee7271 94 NVIC_SetVector(TIMER2_IRQn, (uint32_t)&tmr1_irq);
the729 0:988132ee7271 95 NVIC_EnableIRQ(TIMER2_IRQn);
the729 0:988132ee7271 96
the729 0:988132ee7271 97 NVIC_SetPriority(TIMER2_IRQn, 0);
the729 0:988132ee7271 98 NVIC_SetPriority(UART2_IRQn, 1);
the729 0:988132ee7271 99 NVIC_SetPriority(TIMER3_IRQn, 2);
the729 0:988132ee7271 100 NVIC_SetPriority(UART0_IRQn, 2);
the729 0:988132ee7271 101 NVIC_SetPriority(UART3_IRQn, 1);
the729 0:988132ee7271 102
the729 0:988132ee7271 103 // begin freerun
the729 0:988132ee7271 104 TMR->TCR = 1;
the729 0:988132ee7271 105 }
the729 0:988132ee7271 106
the729 0:988132ee7271 107 void tmr1_irq()
the729 0:988132ee7271 108 {
the729 0:988132ee7271 109 if (TMR->IR & (1<<4)) {
the729 0:988132ee7271 110 if (trigf) {
the729 0:988132ee7271 111 trigt.tv_sec = clock_sec;
the729 0:988132ee7271 112 if ((TMR->IR & 0x01) && TMR->CR0 < 256)
the729 0:988132ee7271 113 trigt.tv_sec = clock_sec+1;
the729 0:988132ee7271 114 trigt.ticks = TMR->CR0;
the729 0:988132ee7271 115 //runTriggerFunc();
the729 0:988132ee7271 116 tmr_callback.attach_us(&runTriggerFunc, 10);
the729 0:988132ee7271 117 }
the729 0:988132ee7271 118 TMR->IR = (1<<4);
the729 0:988132ee7271 119 }
the729 0:988132ee7271 120 if (TMR->IR & 0x1) {
the729 0:988132ee7271 121 // Overflow!
the729 0:988132ee7271 122 clock_sec ++;
the729 0:988132ee7271 123 TMR->IR = 0x1;
the729 0:988132ee7271 124 }
the729 0:988132ee7271 125 if (TMR->IR & 0x2) {
the729 0:988132ee7271 126 if (clock_sec == front_lt.tv_sec) {
the729 0:988132ee7271 127 hdtimeval_t * nowtv = timeq+qfront;
the729 0:988132ee7271 128 funcq[qfront]();
the729 0:988132ee7271 129 qfront = (qfront+1)%QUEUE_SIZE;
the729 0:988132ee7271 130 while(qfront != qtail
the729 0:988132ee7271 131 && nowtv->tv_sec == timeq[qfront].tv_sec
the729 0:988132ee7271 132 && nowtv->ticks == timeq[qfront].ticks) {
the729 0:988132ee7271 133 funcq[qfront]();
the729 0:988132ee7271 134 qfront = (qfront+1)%QUEUE_SIZE;
the729 0:988132ee7271 135 }
the729 0:988132ee7271 136 if (qfront == qtail) {
the729 0:988132ee7271 137 TMR->MCR &= ~(1<<3);
the729 0:988132ee7271 138 } else {
the729 0:988132ee7271 139 getLocalTime(&timeq[qfront], &front_lt);
the729 0:988132ee7271 140 TMR->MR1 = front_lt.ticks;
the729 0:988132ee7271 141 }
the729 0:988132ee7271 142 } else if (clock_sec > front_lt.tv_sec) {
the729 0:988132ee7271 143 // we missed it!
the729 0:988132ee7271 144 qfront = (qfront+1)%QUEUE_SIZE;
the729 0:988132ee7271 145 if (qfront == qtail) {
the729 0:988132ee7271 146 TMR->MCR &= ~(1<<3);
the729 0:988132ee7271 147 } else {
the729 0:988132ee7271 148 getLocalTime(&timeq[qfront], &front_lt);
the729 0:988132ee7271 149 TMR->MR1 = front_lt.ticks;
the729 0:988132ee7271 150 }
the729 0:988132ee7271 151 }
the729 0:988132ee7271 152 TMR->IR = 0x2;
the729 0:988132ee7271 153 }
the729 0:988132ee7271 154 }
the729 0:988132ee7271 155
the729 0:988132ee7271 156 void runTriggerFunc()
the729 0:988132ee7271 157 {
the729 0:988132ee7271 158 timeval_t t;
the729 0:988132ee7271 159 getGlobalTime(&trigt, &trigt);
the729 0:988132ee7271 160 hdtv_totv(&t, &trigt);
the729 0:988132ee7271 161 trigf(&t);
the729 0:988132ee7271 162 }
the729 0:988132ee7271 163
the729 0:988132ee7271 164 void uart_recv()
the729 0:988132ee7271 165 {
the729 0:988132ee7271 166 hdtimeval_t tstamp;
the729 0:988132ee7271 167 getHDTime(&tstamp);
the729 0:988132ee7271 168
the729 0:988132ee7271 169 //if (!(LPC_UART2->IIR & 0x01) && (LPC_UART2->LSR & 0x01)) {
the729 0:988132ee7271 170 if (uart_sync.readable()) {
the729 0:988132ee7271 171 sync_pkt64_t pkt64;
the729 0:988132ee7271 172 sync_pkt32_t pkt32;
the729 0:988132ee7271 173 sync_pkt24_t pkt24;
the729 0:988132ee7271 174 char * data = NULL;
the729 0:988132ee7271 175 void * pkt_p = NULL;
the729 0:988132ee7271 176 uint8_t len = 0;
the729 0:988132ee7271 177
the729 0:988132ee7271 178 if (!syncbusy) {
the729 0:988132ee7271 179 len = uart_sync.getc();
the729 0:988132ee7271 180 return;
the729 0:988132ee7271 181 }
the729 0:988132ee7271 182
the729 0:988132ee7271 183 switch(syncbusy) {
the729 0:988132ee7271 184 case SYNCTYPE_64:
the729 0:988132ee7271 185 data = pkt64.raw;
the729 0:988132ee7271 186 pkt_p = (void *)&pkt64;
the729 0:988132ee7271 187 len = 10;
the729 0:988132ee7271 188 break;
the729 0:988132ee7271 189 case SYNCTYPE_32:
the729 0:988132ee7271 190 data = pkt32.raw;
the729 0:988132ee7271 191 pkt_p = (void *)&pkt32;
the729 0:988132ee7271 192 len = 6;
the729 0:988132ee7271 193 break;
the729 0:988132ee7271 194 case SYNCTYPE_24:
the729 0:988132ee7271 195 pkt24.no_use = 0;
the729 0:988132ee7271 196 pkt_p = (void *)&pkt24;
the729 0:988132ee7271 197 data = pkt24.raw;
the729 0:988132ee7271 198 len = 5;
the729 0:988132ee7271 199 break;
the729 0:988132ee7271 200 }
the729 0:988132ee7271 201 while(len-->0) {
the729 0:988132ee7271 202 //while(!(LPC_UART2->LSR & 0x01));
the729 0:988132ee7271 203 *(data++)= uart_sync.getc(); //LPC_UART2->RBR;
the729 0:988132ee7271 204 }
the729 0:988132ee7271 205
the729 0:988132ee7271 206 update_data(syncbusy, pkt_p, &tstamp);
the729 0:988132ee7271 207 }
the729 0:988132ee7271 208 syncbusy = SYNCTYPE_NONE;
the729 0:988132ee7271 209 }
the729 0:988132ee7271 210
the729 0:988132ee7271 211 void sync_req()
the729 0:988132ee7271 212 {
the729 0:988132ee7271 213 //if (syncbusy) return;
the729 0:988132ee7271 214 __disable_irq();
the729 0:988132ee7271 215 txstamp.tv_sec = clock_sec;
the729 0:988132ee7271 216 txstamp.ticks = TMR->TC;
the729 0:988132ee7271 217 uart_sync.putc(tmp_synctype);
the729 0:988132ee7271 218 //LPC_UART2->THR = tmp_synctype;
the729 0:988132ee7271 219 __enable_irq();
the729 0:988132ee7271 220 syncbusy = tmp_synctype;
the729 0:988132ee7271 221 }
the729 0:988132ee7271 222
the729 0:988132ee7271 223 void update_data(synctype_t t, void * pkt_p, hdtimeval_t * rxstamp)
the729 0:988132ee7271 224 {
the729 0:988132ee7271 225 hdtimeval_t v, w;
the729 0:988132ee7271 226 hdtimeval_t master_rxt, master_txt;
the729 0:988132ee7271 227 int32_t ticks_diff;
the729 0:988132ee7271 228 hdtv_add(&v, &txstamp, rxstamp);
the729 0:988132ee7271 229 switch (t) {
the729 0:988132ee7271 230 case SYNCTYPE_64: {
the729 0:988132ee7271 231 sync_pkt64_t * p = (sync_pkt64_t *)pkt_p;
the729 0:988132ee7271 232 master_rxt = p->rx_time;
the729 0:988132ee7271 233 master_txt.tv_sec = master_rxt.tv_sec;
the729 0:988132ee7271 234 master_txt.ticks = (master_rxt.ticks & 0xFFFF0000) + p->tx_time;
the729 0:988132ee7271 235 } break;
the729 0:988132ee7271 236 case SYNCTYPE_32: {
the729 0:988132ee7271 237 sync_pkt32_t * p = (sync_pkt32_t *)pkt_p;
the729 0:988132ee7271 238 hdtimeval_t tmp;
the729 0:988132ee7271 239 getGlobalTime(&txstamp, &tmp);
the729 0:988132ee7271 240 if (tmp.ticks > MAX_TICK/2) {
the729 0:988132ee7271 241 if (p->rx_time > tmp.ticks-MAX_TICK/2) {
the729 0:988132ee7271 242 master_rxt.tv_sec = tmp.tv_sec;
the729 0:988132ee7271 243 } else {
the729 0:988132ee7271 244 master_rxt.tv_sec = tmp.tv_sec +1;
the729 0:988132ee7271 245 }
the729 0:988132ee7271 246 } else {
the729 0:988132ee7271 247 if (p->rx_time > tmp.ticks+MAX_TICK/2) {
the729 0:988132ee7271 248 master_rxt.tv_sec = tmp.tv_sec-1;
the729 0:988132ee7271 249 } else {
the729 0:988132ee7271 250 master_rxt.tv_sec = tmp.tv_sec;
the729 0:988132ee7271 251 }
the729 0:988132ee7271 252 }
the729 0:988132ee7271 253 master_rxt.ticks = p->rx_time;
the729 0:988132ee7271 254 master_txt.tv_sec = master_rxt.tv_sec;
the729 0:988132ee7271 255 master_txt.ticks = (master_rxt.ticks & 0xFFFF0000) + p->tx_time;
the729 0:988132ee7271 256 } break;
the729 0:988132ee7271 257 case SYNCTYPE_24: {
the729 0:988132ee7271 258 sync_pkt24_t * p = (sync_pkt24_t *)pkt_p;
the729 0:988132ee7271 259 hdtimeval_t tmp;
the729 0:988132ee7271 260 getGlobalTime(&txstamp, &tmp);
the729 0:988132ee7271 261 p->rx_time >>= 8;
the729 0:988132ee7271 262 if (tmp.ticks > (1<<23)) {
the729 0:988132ee7271 263 tmp.ticks = tmp.ticks-(1<<23);
the729 0:988132ee7271 264 master_rxt.ticks = (tmp.ticks & 0xFF000000) + p->rx_time;
the729 0:988132ee7271 265 master_rxt.tv_sec = tmp.tv_sec;
the729 0:988132ee7271 266 } else {
the729 0:988132ee7271 267 tmp.ticks = tmp.ticks+MAX_TICK-(1<<23);
the729 0:988132ee7271 268 master_rxt.ticks = (tmp.ticks & 0xFF000000) + p->rx_time;
the729 0:988132ee7271 269 master_rxt.tv_sec = tmp.tv_sec-1;
the729 0:988132ee7271 270 }
the729 0:988132ee7271 271 if (master_rxt.ticks < tmp.ticks) {
the729 0:988132ee7271 272 master_rxt.ticks += 0x1000000;
the729 0:988132ee7271 273 if (master_rxt.ticks > MAX_TICK) {
the729 0:988132ee7271 274 master_rxt.ticks &= 0xFFFFFF;
the729 0:988132ee7271 275 master_rxt.tv_sec ++;
the729 0:988132ee7271 276 }
the729 0:988132ee7271 277 }
the729 0:988132ee7271 278 master_txt.tv_sec = master_rxt.tv_sec;
the729 0:988132ee7271 279 master_txt.ticks = (master_rxt.ticks & 0xFFFF0000) + p->tx_time;
the729 0:988132ee7271 280 } break;
the729 0:988132ee7271 281 }
the729 0:988132ee7271 282 //printf("t1,t2: %d,%d, %d,%d \r\n",master_rxt.tv_sec, master_rxt.ticks>>24, master_rxt.ticks & 0xFFFFFF, master_txt.ticks);
the729 0:988132ee7271 283 if (master_rxt.ticks > master_txt.ticks) {
the729 0:988132ee7271 284 master_txt.ticks += 0x10000;
the729 0:988132ee7271 285 if (master_txt.ticks >= MAX_TICK) {
the729 0:988132ee7271 286 master_txt.ticks &= 0xFFFF;
the729 0:988132ee7271 287 master_txt.tv_sec ++;
the729 0:988132ee7271 288 }
the729 0:988132ee7271 289 }
the729 0:988132ee7271 290 hdtv_add(&w, &master_rxt, &master_txt);
the729 0:988132ee7271 291
the729 0:988132ee7271 292 hdtv_div2(&v, &v);
the729 0:988132ee7271 293 hdtv_div2(&w, &w);
the729 0:988132ee7271 294 // evaluate performance
the729 0:988132ee7271 295 {
the729 0:988132ee7271 296 hdtimeval_t tmp;
the729 0:988132ee7271 297 getGlobalTime(&v, &tmp);
the729 0:988132ee7271 298 hdtv_sub(&tmp, &tmp, &w);
the729 0:988132ee7271 299 if (tmp.tv_sec > 10)
the729 0:988132ee7271 300 ticks_diff = 0x7FFFFFFF;
the729 0:988132ee7271 301 else {
the729 0:988132ee7271 302 ticks_diff = tmp.tv_sec * MAX_TICK + tmp.ticks;
the729 0:988132ee7271 303 }
the729 0:988132ee7271 304 //printf("perf: %d \r\n", ticks_diff);
the729 0:988132ee7271 305 }
the729 0:988132ee7271 306 if (coeff.size)
the729 0:988132ee7271 307 if (coeff.size<HISTORY_LEN) {
the729 0:988132ee7271 308 hdtv_sub(&coeff.beta1, &w, &(coeff.hisw[0]));
the729 0:988132ee7271 309 hdtv_sub(&coeff.beta2, &v, &(coeff.hisv[0]));
the729 0:988132ee7271 310 } else {
the729 0:988132ee7271 311 hdtv_sub(&coeff.beta1, &w, &(coeff.hisw[coeff.front]));
the729 0:988132ee7271 312 hdtv_sub(&coeff.beta2, &v, &(coeff.hisv[coeff.front]));
the729 0:988132ee7271 313 }
the729 0:988132ee7271 314 /*if(coeff.size>=8) {
the729 0:988132ee7271 315 hdtimeval_t tmp;
the729 0:988132ee7271 316 hdtv_div8(&tmp, &(coeff.hisw[coeff.front]));
the729 0:988132ee7271 317 hdtv_sub(&coeff.w1div2, &coeff.w1div2, &tmp);
the729 0:988132ee7271 318 hdtv_div8(&tmp, &(coeff.hisv[coeff.front]));
the729 0:988132ee7271 319 hdtv_sub(&coeff.v1div2, &coeff.v1div2, &tmp);
the729 0:988132ee7271 320 hdtv_div8(&tmp, &w);
the729 0:988132ee7271 321 hdtv_add(&coeff.w1div2, &coeff.w1div2, &tmp);
the729 0:988132ee7271 322 hdtv_div8(&tmp, &v);
the729 0:988132ee7271 323 hdtv_add(&coeff.v1div2, &coeff.v1div2, &tmp);
the729 0:988132ee7271 324 } else {*/
the729 0:988132ee7271 325 coeff.v1div2 = v;
the729 0:988132ee7271 326 coeff.w1div2 = w;
the729 0:988132ee7271 327 //}
the729 0:988132ee7271 328 coeff.hisw[coeff.front] = w;
the729 0:988132ee7271 329 coeff.hisv[coeff.front] = v;
the729 0:988132ee7271 330 coeff.front = (coeff.front+1) % HISTORY_LEN;
the729 0:988132ee7271 331 if (coeff.size<=HISTORY_LEN) coeff.size++;
the729 0:988132ee7271 332 /*if (coeff.size==8) {
the729 0:988132ee7271 333 hdtimeval_t tmp;
the729 0:988132ee7271 334 coeff.w1div2.tv_sec = 0;
the729 0:988132ee7271 335 coeff.w1div2.ticks = 0;
the729 0:988132ee7271 336 coeff.v1div2.tv_sec = 0;
the729 0:988132ee7271 337 coeff.v1div2.ticks = 0;
the729 0:988132ee7271 338 for (uint8_t i=0; i<8; i++) {
the729 0:988132ee7271 339 hdtv_div8(&tmp, &(coeff.hisw[i]));
the729 0:988132ee7271 340 hdtv_add(&coeff.w1div2, &coeff.w1div2, &tmp);
the729 0:988132ee7271 341 hdtv_div8(&tmp, &(coeff.hisv[i]));
the729 0:988132ee7271 342 hdtv_add(&coeff.v1div2, &coeff.v1div2, &tmp);
the729 0:988132ee7271 343 }
the729 0:988132ee7271 344 printf("updated!\r\n");
the729 0:988132ee7271 345 }*/
the729 0:988132ee7271 346 //printf("w/v: %d, %d \r\n", coeff.w1div2.ticks, coeff.v1div2.ticks);
the729 0:988132ee7271 347 if (qfront != qtail) {
the729 0:988132ee7271 348 getLocalTime(&timeq[qfront], &front_lt);
the729 0:988132ee7271 349 TMR->MR1 = front_lt.ticks;
the729 0:988132ee7271 350 TMR->MCR |= (1<<3);
the729 0:988132ee7271 351 }
the729 0:988132ee7271 352 // schedule next sync
the729 0:988132ee7271 353 ticks_diff = abs(ticks_diff);
the729 0:988132ee7271 354 if (ticks_diff < 200) {
the729 0:988132ee7271 355 tmp_synctype = SYNCTYPE_24;
the729 0:988132ee7271 356 tmr_sync.attach(&sync_req, 60);
the729 0:988132ee7271 357 } else if (ticks_diff < 500) {
the729 0:988132ee7271 358 tmp_synctype = SYNCTYPE_24;
the729 0:988132ee7271 359 tmr_sync.attach(&sync_req, 30);
the729 0:988132ee7271 360 } else if (ticks_diff < 800) {
the729 0:988132ee7271 361 tmp_synctype = SYNCTYPE_24;
the729 0:988132ee7271 362 tmr_sync.attach(&sync_req, 20);
the729 0:988132ee7271 363 } else if (ticks_diff < 5000) {
the729 0:988132ee7271 364 tmp_synctype = SYNCTYPE_32;
the729 0:988132ee7271 365 tmr_sync.attach(&sync_req, 10);
the729 0:988132ee7271 366 } else {
the729 0:988132ee7271 367 tmp_synctype = SYNCTYPE_64;
the729 0:988132ee7271 368 tmr_sync.attach(&sync_req, 5);
the729 0:988132ee7271 369 }
the729 0:988132ee7271 370 led = !led;
the729 0:988132ee7271 371 }
the729 0:988132ee7271 372
the729 0:988132ee7271 373 __INLINE void getHDTime(struct hdtimeval * hdtv)
the729 0:988132ee7271 374 {
the729 0:988132ee7271 375 __disable_irq();
the729 0:988132ee7271 376 hdtv->tv_sec = clock_sec;
the729 0:988132ee7271 377 hdtv->ticks = TMR->TC;
the729 0:988132ee7271 378 __enable_irq();
the729 0:988132ee7271 379 return;
the729 0:988132ee7271 380 }
the729 0:988132ee7271 381
the729 0:988132ee7271 382 void getTime(struct timeval * tv)
the729 0:988132ee7271 383 {
the729 0:988132ee7271 384 hdtimeval_t tstamp, gstamp, tstamp1;
the729 0:988132ee7271 385 static hdtimeval_t comp_delay = {0,0};
the729 0:988132ee7271 386
the729 0:988132ee7271 387 getHDTime(&tstamp);
the729 0:988132ee7271 388
the729 0:988132ee7271 389 hdtv_add(&gstamp, &tstamp, &comp_delay);
the729 0:988132ee7271 390 getGlobalTime(&gstamp, &gstamp);
the729 0:988132ee7271 391
the729 0:988132ee7271 392 getHDTime(&tstamp1);
the729 0:988132ee7271 393 hdtv_sub(&comp_delay, &tstamp1, &tstamp);
the729 0:988132ee7271 394 //printf("delay: %d\r\n", comp_delay.ticks);
the729 0:988132ee7271 395
the729 0:988132ee7271 396 tv->tv_sec = gstamp.tv_sec;
the729 0:988132ee7271 397 tv->tv_usec = ((gstamp.ticks+48) >> 5) / 3;
the729 0:988132ee7271 398 return;
the729 0:988132ee7271 399 }
the729 0:988132ee7271 400
the729 0:988132ee7271 401 void getGlobalTime(hdtimeval * lt, hdtimeval * gt)
the729 0:988132ee7271 402 {
the729 0:988132ee7271 403 hdtimeval_t tmp;
the729 0:988132ee7271 404 hdtv_sub(&tmp, lt, &coeff.v1div2);
the729 0:988132ee7271 405 hdtv_muldiv(&tmp, &tmp, &coeff.beta1, &coeff.beta2);
the729 0:988132ee7271 406 hdtv_add(gt, &tmp, &coeff.w1div2);
the729 0:988132ee7271 407 }
the729 0:988132ee7271 408
the729 0:988132ee7271 409 void getLocalTime(hdtimeval * gt, hdtimeval * lt)
the729 0:988132ee7271 410 {
the729 0:988132ee7271 411 hdtimeval_t tmp;
the729 0:988132ee7271 412 hdtv_sub(&tmp, gt, &coeff.w1div2);
the729 0:988132ee7271 413 hdtv_muldiv(&tmp, &tmp, &coeff.beta2, &coeff.beta1);
the729 0:988132ee7271 414 hdtv_add(lt, &tmp, &coeff.v1div2);
the729 0:988132ee7271 415 }
the729 0:988132ee7271 416
the729 0:988132ee7271 417 int enqueue(void (*schedFunc)(void), hdtimeval_t *tv)
the729 0:988132ee7271 418 {
the729 0:988132ee7271 419 uint8_t p = qtail;
the729 0:988132ee7271 420 if ((qtail+1)%QUEUE_SIZE == qfront) {
the729 0:988132ee7271 421 return 1;
the729 0:988132ee7271 422 }
the729 0:988132ee7271 423 while(p != qfront) {
the729 0:988132ee7271 424 uint8_t prev = (p+QUEUE_SIZE-1)%QUEUE_SIZE;
the729 0:988132ee7271 425 if (tv->tv_sec > timeq[prev].tv_sec
the729 0:988132ee7271 426 || (tv->tv_sec == timeq[prev].tv_sec && tv->ticks >= timeq[prev].ticks)) break;
the729 0:988132ee7271 427 timeq[p] = timeq[prev];
the729 0:988132ee7271 428 funcq[p] = funcq[prev];
the729 0:988132ee7271 429 p = prev;
the729 0:988132ee7271 430 }
the729 0:988132ee7271 431 timeq[p] = *tv;
the729 0:988132ee7271 432 funcq[p] = schedFunc;
the729 0:988132ee7271 433 qtail = (qtail+1)%QUEUE_SIZE;
the729 0:988132ee7271 434 return 0;
the729 0:988132ee7271 435 }
the729 0:988132ee7271 436
the729 0:988132ee7271 437 int runAtTime(void (*schedFunc)(void), struct timeval *tv)
the729 0:988132ee7271 438 {
the729 0:988132ee7271 439 hdtimeval_t hdtv;
the729 0:988132ee7271 440 int ret;
the729 0:988132ee7271 441 hdtv.tv_sec = tv->tv_sec;
the729 0:988132ee7271 442 hdtv.ticks = tv->tv_usec * 96;
the729 0:988132ee7271 443 //getLocalTime(&hdtv, &hdtv);
the729 0:988132ee7271 444 ret = enqueue(schedFunc, &hdtv);
the729 0:988132ee7271 445 if (qfront != qtail) {
the729 0:988132ee7271 446 getLocalTime(&timeq[qfront], &front_lt);
the729 0:988132ee7271 447 TMR->MR1 = front_lt.ticks;
the729 0:988132ee7271 448 TMR->MCR |= (1<<3);
the729 0:988132ee7271 449 }
the729 0:988132ee7271 450 return ret;
the729 0:988132ee7271 451 }
the729 0:988132ee7271 452
the729 0:988132ee7271 453
the729 0:988132ee7271 454 void runAtTrigger(void (*trigFunc)(struct timeval *tv))
the729 0:988132ee7271 455 {
the729 0:988132ee7271 456 trigf = trigFunc;
the729 0:988132ee7271 457 }