Receiver program for assisted power disaggregation project at NESL.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 InterruptIn rfint(p15);
00004 DigitalIn rfdata(p15);
00005 DigitalOut led1(LED1);
00006 DigitalOut led2(LED2);
00007 DigitalOut led3(LED3);
00008 DigitalOut led4(LED4);
00009 DigitalOut pi16(p16);
00010 DigitalOut pi17(p17);
00011 DigitalOut pi18(p18);
00012 DigitalOut pi19(p19);
00013 DigitalOut pi20(p20);
00014 Serial pc(USBTX,USBRX);
00015 
00016 #define TMR LPC_TIM2
00017 #define CLK_TIMER 12
00018 #define PCTIM2 22        // Power Control Timer2
00019 #define PCLK_DEVIDER 3
00020 
00021 uint8_t flag = 0;
00022 int32_t interval;
00023 uint16_t datarecv;
00024 uint32_t o_spl, n_spl;
00025 static enum {
00026     SYNC0,
00027     SYNC1
00028 } state = SYNC0;
00029 
00030 int32_t lpf1(int32_t x) {
00031     static int32_t y = 0;
00032     y = (x>>1) + (x>>2) + (y>>2);
00033     return y;
00034 }
00035 
00036 int32_t lpf2(int32_t x) {
00037     static int32_t y = 0;
00038     y = (x>>1) + (x>>2) + (y>>2);
00039     return y;
00040 }
00041 
00042 void rfedge() {
00043     uint32_t tval = TMR->TC;
00044     static uint32_t edges[8];
00045     static uint32_t ospls[8];
00046     static uint32_t nspls[8];
00047     static uint8_t  head = 0;
00048     static uint8_t  tail = 0;
00049     
00050     if (state == SYNC0) {
00051         edges[tail] = tval;
00052         ospls[tail] = o_spl;
00053         nspls[tail] = n_spl;
00054         tail = (tail + 1) & 0x7;
00055         if (tail == head || tval - edges[head] > 31800) {
00056             do {
00057                 head = (head+1)&0x7;
00058             } while (tval - edges[head] > 31800);
00059         }
00060         for (uint8_t i = head; i!= tail; i = (i+1)&0x7) {
00061             if (tval - edges[i] > 29000) {
00062                 if ((o_spl - ospls[i]<<4) < (n_spl - nspls[i])) {
00063                     o_spl = n_spl = 0;
00064                     head = tail = 0;
00065                     TMR->TC = 0;
00066                     TMR->MR0 = (tval - edges[i]>>3);
00067                     TMR->MCR = 3;
00068                     interval = TMR->MR0;
00069                     state = SYNC1;
00070                     led4 = 1;
00071                     pi18 = 1;
00072                     pi19 = 0;
00073                     break;
00074                 }
00075             } else 
00076                 break;
00077         }
00078     }
00079 }
00080 
00081 void tmr_irq() {
00082     static uint32_t bitsrecv = 0;
00083     static uint16_t _datarecv = 0;
00084     static uint8_t  bitp = 0;
00085     static uint8_t  bitcnt = 0;
00086     static uint8_t  parity = 0;
00087     static uint32_t o_spl_1;
00088     static uint32_t o_spl_2;
00089     
00090     if (TMR->IR & 0x1) {
00091         pi16 = !pi16;
00092         
00093         uint8_t bit = (o_spl > (n_spl>>2)+(n_spl>>3));
00094         pi17 = bit;
00095         switch (state) {
00096             case SYNC0: {
00097             } break;
00098             case SYNC1: {
00099                 if (!bitp) {
00100                     o_spl_1 = o_spl;
00101                 } else {
00102                     o_spl_2 = o_spl;
00103                     //if (o_spl_first + o_spl < (n_spl>>1) || o_spl_first + o_spl > n_spl + (n_spl>>1)) {
00104                     //    state = SYNC0;
00105                     //    pi19 = 1;
00106                     //} else 
00107                     if (o_spl_1 > (o_spl_2<<1)) {
00108                         bit = 1;
00109                     } else if (o_spl_2 > (o_spl_1<<1)) {
00110                         bit = 0;
00111                     } else {
00112                         TMR->MCR = 0;
00113                         bitcnt = 0;
00114                         bitp = 0;
00115                         _datarecv = 0;
00116                         parity = 0;
00117                         state = SYNC0;
00118                         led4 = 0;
00119                         pi18 = 0;
00120                         pi19 = 1;
00121                         break;
00122                     }
00123                     o_spl_1 = o_spl_2 = 0;
00124                     if (!bitcnt) {
00125                         // nothing
00126                     } else if (bitcnt < 17) {
00127                         parity ^= bit;
00128                         _datarecv |= (bit<<(bitcnt-1));
00129                     } else {
00130                         parity ^= bit;
00131                         led2 = !led2;
00132                         if (!(parity & 0x1)) {
00133                             led3 = !led3;
00134                             if (!flag) {
00135                                 flag = 1;
00136                                 datarecv = _datarecv;
00137                             } else {
00138                                 led1 = 1;
00139                             }
00140                         } else {
00141                             pi19 = 1;
00142                         }
00143                         TMR->MCR = 0;
00144                         bitp = 0;
00145                         bitcnt = 0;
00146                         _datarecv = 0;
00147                         parity = 0;
00148                         state = SYNC0;
00149                         led4 = 0;
00150                         pi18 = 0;
00151                         break;
00152                     }
00153                     bitcnt ++;
00154                 }
00155                 bitp = bitp^1;
00156             }
00157         }
00158         o_spl = n_spl = 0;
00159     }
00160     TMR->IR = -1;
00161 }
00162 
00163 void init() {
00164     // select PCLK
00165     LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(3<<CLK_TIMER)) | (PCLK_DEVIDER<<CLK_TIMER);
00166     // power on timer
00167     LPC_SC->PCONP |= (1<<PCTIM2);
00168     
00169     // reset timer
00170     TMR->CTCR = 0;
00171     TMR->PR = 3;
00172     TMR->TCR = 2;
00173     TMR->MCR = 0;
00174 
00175     __enable_irq();
00176     NVIC_SetVector(TIMER2_IRQn, (uint32_t)&tmr_irq);
00177     NVIC_EnableIRQ(TIMER2_IRQn);
00178     
00179     rfint.rise(&rfedge);
00180     //rfint.fall(&rfedge);
00181     rfint.mode(PullNone);
00182     pc.baud(115200);
00183 
00184     TMR->MR0 = -1;
00185     //TMR->MCR = 3;  // reset and interrupt on match
00186     TMR->TCR = 1;
00187 }
00188 
00189 void sample_data() {
00190     o_spl += (rfdata & 1);
00191     n_spl += 1;
00192 }
00193 
00194 int main() {
00195     uint16_t olddata = 0;
00196     uint32_t pktrecv = 0;
00197     uint32_t pktlost = 0;
00198 
00199     init();
00200     Ticker sampler;
00201     sampler.attach_us(&sample_data, 20);
00202 
00203     while(1) {
00204         if (flag) {
00205             pktrecv ++;
00206             if (olddata) {
00207                 pktlost += datarecv-olddata-1;
00208             }
00209             /*printf("RECV %d (id=%d, gp=%d, seq=%d, idx=%d, atv=%d) (%d) %d/%d\r\n", 
00210                 datarecv, 
00211                 (datarecv&0xFC00)>>10, 
00212                 (datarecv&0x0300)>>8, 
00213                 (datarecv&0xF0)>>4, 
00214                 (datarecv&0xE)>>1, 
00215                 (datarecv&0x1), 
00216                 interval, pktlost, pktlost+pktrecv);*/
00217             pc.putc(datarecv >> 10);
00218             pc.putc(((datarecv & 0x3F0)>>4) | 0x40);
00219             pc.putc((datarecv & 0xF) | 0x80);
00220             olddata = datarecv;
00221             flag = 0;
00222         }
00223     }
00224 }