Receiver program for assisted power disaggregation project at NESL.

main.cpp

Committer:
the729
Date:
2012-06-14
Revision:
0:3c23ac48cdf3

File content as of revision 0:3c23ac48cdf3:

#include "mbed.h"

InterruptIn rfint(p15);
DigitalIn rfdata(p15);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalOut pi16(p16);
DigitalOut pi17(p17);
DigitalOut pi18(p18);
DigitalOut pi19(p19);
DigitalOut pi20(p20);
Serial pc(USBTX,USBRX);

#define TMR LPC_TIM2
#define CLK_TIMER 12
#define PCTIM2 22        // Power Control Timer2
#define PCLK_DEVIDER 3

uint8_t flag = 0;
int32_t interval;
uint16_t datarecv;
uint32_t o_spl, n_spl;
static enum {
    SYNC0,
    SYNC1
} state = SYNC0;

int32_t lpf1(int32_t x) {
    static int32_t y = 0;
    y = (x>>1) + (x>>2) + (y>>2);
    return y;
}

int32_t lpf2(int32_t x) {
    static int32_t y = 0;
    y = (x>>1) + (x>>2) + (y>>2);
    return y;
}

void rfedge() {
    uint32_t tval = TMR->TC;
    static uint32_t edges[8];
    static uint32_t ospls[8];
    static uint32_t nspls[8];
    static uint8_t  head = 0;
    static uint8_t  tail = 0;
    
    if (state == SYNC0) {
        edges[tail] = tval;
        ospls[tail] = o_spl;
        nspls[tail] = n_spl;
        tail = (tail + 1) & 0x7;
        if (tail == head || tval - edges[head] > 31800) {
            do {
                head = (head+1)&0x7;
            } while (tval - edges[head] > 31800);
        }
        for (uint8_t i = head; i!= tail; i = (i+1)&0x7) {
            if (tval - edges[i] > 29000) {
                if ((o_spl - ospls[i]<<4) < (n_spl - nspls[i])) {
                    o_spl = n_spl = 0;
                    head = tail = 0;
                    TMR->TC = 0;
                    TMR->MR0 = (tval - edges[i]>>3);
                    TMR->MCR = 3;
                    interval = TMR->MR0;
                    state = SYNC1;
                    led4 = 1;
                    pi18 = 1;
                    pi19 = 0;
                    break;
                }
            } else 
                break;
        }
    }
}

void tmr_irq() {
    static uint32_t bitsrecv = 0;
    static uint16_t _datarecv = 0;
    static uint8_t  bitp = 0;
    static uint8_t  bitcnt = 0;
    static uint8_t  parity = 0;
    static uint32_t o_spl_1;
    static uint32_t o_spl_2;
    
    if (TMR->IR & 0x1) {
        pi16 = !pi16;
        
        uint8_t bit = (o_spl > (n_spl>>2)+(n_spl>>3));
        pi17 = bit;
        switch (state) {
            case SYNC0: {
            } break;
            case SYNC1: {
                if (!bitp) {
                    o_spl_1 = o_spl;
                } else {
                    o_spl_2 = o_spl;
                    //if (o_spl_first + o_spl < (n_spl>>1) || o_spl_first + o_spl > n_spl + (n_spl>>1)) {
                    //    state = SYNC0;
                    //    pi19 = 1;
                    //} else 
                    if (o_spl_1 > (o_spl_2<<1)) {
                        bit = 1;
                    } else if (o_spl_2 > (o_spl_1<<1)) {
                        bit = 0;
                    } else {
                        TMR->MCR = 0;
                        bitcnt = 0;
                        bitp = 0;
                        _datarecv = 0;
                        parity = 0;
                        state = SYNC0;
                        led4 = 0;
                        pi18 = 0;
                        pi19 = 1;
                        break;
                    }
                    o_spl_1 = o_spl_2 = 0;
                    if (!bitcnt) {
                        // nothing
                    } else if (bitcnt < 17) {
                        parity ^= bit;
                        _datarecv |= (bit<<(bitcnt-1));
                    } else {
                        parity ^= bit;
                        led2 = !led2;
                        if (!(parity & 0x1)) {
                            led3 = !led3;
                            if (!flag) {
                                flag = 1;
                                datarecv = _datarecv;
                            } else {
                                led1 = 1;
                            }
                        } else {
                            pi19 = 1;
                        }
                        TMR->MCR = 0;
                        bitp = 0;
                        bitcnt = 0;
                        _datarecv = 0;
                        parity = 0;
                        state = SYNC0;
                        led4 = 0;
                        pi18 = 0;
                        break;
                    }
                    bitcnt ++;
                }
                bitp = bitp^1;
            }
        }
        o_spl = n_spl = 0;
    }
    TMR->IR = -1;
}

void init() {
    // select PCLK
    LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(3<<CLK_TIMER)) | (PCLK_DEVIDER<<CLK_TIMER);
    // power on timer
    LPC_SC->PCONP |= (1<<PCTIM2);
    
    // reset timer
    TMR->CTCR = 0;
    TMR->PR = 3;
    TMR->TCR = 2;
    TMR->MCR = 0;

    __enable_irq();
    NVIC_SetVector(TIMER2_IRQn, (uint32_t)&tmr_irq);
    NVIC_EnableIRQ(TIMER2_IRQn);
    
    rfint.rise(&rfedge);
    //rfint.fall(&rfedge);
    rfint.mode(PullNone);
    pc.baud(115200);

    TMR->MR0 = -1;
    //TMR->MCR = 3;  // reset and interrupt on match
    TMR->TCR = 1;
}

void sample_data() {
    o_spl += (rfdata & 1);
    n_spl += 1;
}

int main() {
    uint16_t olddata = 0;
    uint32_t pktrecv = 0;
    uint32_t pktlost = 0;

    init();
    Ticker sampler;
    sampler.attach_us(&sample_data, 20);

    while(1) {
        if (flag) {
            pktrecv ++;
            if (olddata) {
                pktlost += datarecv-olddata-1;
            }
            /*printf("RECV %d (id=%d, gp=%d, seq=%d, idx=%d, atv=%d) (%d) %d/%d\r\n", 
                datarecv, 
                (datarecv&0xFC00)>>10, 
                (datarecv&0x0300)>>8, 
                (datarecv&0xF0)>>4, 
                (datarecv&0xE)>>1, 
                (datarecv&0x1), 
                interval, pktlost, pktlost+pktrecv);*/
            pc.putc(datarecv >> 10);
            pc.putc(((datarecv & 0x3F0)>>4) | 0x40);
            pc.putc((datarecv & 0xF) | 0x80);
            olddata = datarecv;
            flag = 0;
        }
    }
}