Ejemplo n.º 1
0
int main(void)
 {
    char c;
    unsigned char idx[4] = {0, 0, 0, 0};
    unsigned char port, total_ports = 2, valid_ports = 0x3;
    volatile unsigned long i, j;
    int ret = 0;
    u32union delay;

    RCONbits.SWDTEN = 0;

    /* 70 MIPS; 140MHz */
    CLKDIVbits.PLLPRE = 0;
    PLLFBDbits.PLLDIV = 74;
    CLKDIVbits.PLLPOST = 0;

    /* switch clock to FRC oscillator with PLL */
    __builtin_write_OSCCONH(1);
    __builtin_write_OSCCONL(OSCCON | 1);

    /* wait for clock switch to complete */
    while (OSCCONbits.OSWEN == 1);
    /* wait for PLL lock */
    while (OSCCONbits.LOCK != 1);

    ANSELA = 0;
    ANSELB = 0;
    ANSELC = 0;

    TRIS_LED = 0;
    LED = 0;

    /* detect hw revision */
    /* set RB1 internal pull down */
    _TRISB1 = 1;
    _CNPDB1 = 1;
    
    /* hw 0v5 has RB1 connected to RB4 */
    _TRISB4 = 0;
    _LATB4 = 0;
    for (i = 0; i < 100000; i++);
    j = (_RB1 & 1);
    _LATB4 = 1;
    for (i = 0; i < 100000; i++);
    j |= ((_RB1 & 1) << 1);
    
    if (j == 0b10) {
        hw_rev = 0x05;
    } else {
        /* set RB9 internal pull down */
        _TRISB9 = 1;
        _CNPDB9 = 1;

        /* set RA9 internal pull down */
        _TRISA9 = 1;
        _CNPDA9 = 1;

        ANSELBbits.ANSB1 = 1;
        AD1CON3bits.ADCS = 16;
        AD1CON2bits.CHPS = 2;
        AD1CON1bits.ADON = 1;
        AD1CHS0bits.CH0SA = 3;
        AD1CON1bits.SAMP = 1;
        for (i = 0; i < 1000; i++);
        AD1CON1bits.SAMP = 0;
        for (i = 0; i < 10000; i++);

        if (ADC1BUF0 > 400)
            /* hw 0v4 has 1.25V vref on AN3 */
            hw_rev = 0x04;
        else if (_RB9 == 1)
            /* hw 0v3 has external pull-up on RB9 */
            hw_rev = 0x03;
        else if (_RA9 == 1)
            /* hw 0v2 has RB9 floating and RA9 pull-up */
            hw_rev = 0x02;
        else
            /* hw 0v1 has RA9 and RB9 floating */
            hw_rev = 0x01;
        _CNPDB9 = 0;
        _CNPDA9 = 0;
        AD1CON1bits.ADON = 0;
    }
    _CNPDB1 = 0;
    _TRISB4 = 1;
    
    /* weak pull up on serial port rx pins */
    if (hw_rev >= 0x05) {
        _CNPUB12 = 1;
        _CNPUB15 = 1;
        _CNPUC7 = 1;
        _CNPUB7 = 1;
    } else if (hw_rev >= 0x03) {
        _CNPUB11 = 1;
        _CNPUB6 = 1;
        _CNPUB2 = 1;
        _CNPUB13 = 1;
    } else {
        _CNPUB6 = 1;
        _CNPUA4 = 1;
    }

    if (hw_rev >= 0x03) {
        total_ports = 4;
        valid_ports = 0xf;
    }
    
    /* get devid */
    read_flash(0xff0000, &devid);
    
    delay.l = BOOT_DELAY;

    if (delay.b[0] == 0)
        goto_usercode();

    /* Timer setup */
    /* increments every instruction cycle */
    T2CONbits.T32 = 1;
    /* clear timer3 IF */
    IFS0bits.T3IF = 0;
    /* disable timer3 isr */
    IEC0bits.T3IE = 0; 
    /* Convert seconds into timer count value */
    delay.l = ((unsigned long) (FCY)) * ((unsigned long) (delay.b[0]));
    PR3 = delay.w[1];
    PR2 = delay.w[0];
    TMR3HLD = 0x0000;
    TMR2 = 0x0000;
    T2CONbits.TON = 1;

    uart_init();

    while (1) {
        for (port = 0; port < total_ports; port++) {
            if (valid_ports & (1 << port)) {
                used_port = port;
                if (get_char(&c)) {
                    if (c != magic_word_bin[idx[port]])
                        valid_ports &= ~(1 << port);
                    else
                        idx[port]++;

                    if (idx[port] == (sizeof(magic_word_bin)-1)) {
                        ret = 1;
                        break;
                    }
                }
            }
        }

        if (valid_ports == 0)
            ret = 0xff;
        if (_T3IF == 1) {
            ret = 0xff;
        }
        if (ret)
            break;
    }
    T2CONbits.TON = 0;

    LED = 1;
    
    if (ret == 0xff) {
        put_char('*');
        goto_usercode();
    }
    
    put_str((char*) msg);
    put_str((char*) msg_bin);
    load_bin();
    return 0;
}
Ejemplo n.º 2
0
void load_bin(void)
{
    unsigned char c;
    int ret;
    u32union page_addr;
    unsigned int crc, rcrc, i;

    for (i = 0; i < PAGE_SIZE; i++)
        page[i].b[3] = 0xff;


    while (1) {

        /* request page */

        /* 3 bytes - msb first */
        page_addr.b[3] = 0;
        ret = get_char((char*) &page_addr.b[2]);
        ret |= get_char((char*) &page_addr.b[1]);
        ret |= get_char((char*) &page_addr.b[0]);

        if (page_addr.l == 0x00ffffff) {
            put_char('e');
            break;
        } else {
            put_char('p');
        }

        page_addr.l &= ~((PAGE_SIZE << 1)-1);

        if ( ((page_addr.l >= BOOT_FLASH_START_ADDR) && (page_addr.l < BOOT_FLASH_END_ADDR)) 
           || (page_addr.l == DEV_CONFIG_PAGE_ADDRESS) ) {
            put_char('s');
            continue;
        } else {
            put_char('d');
        }

        /* load page to sram */
        ret = 0;
        crc = 0;
        for (i = 0; i < PAGE_SIZE; i++) {
            ret |= get_char((char*) &c);
            crc += c;
            page[i].b[2] = c;
                    
            ret |= get_char((char*) &c);
            crc += c;
            page[i].b[1] = c;

            ret |= get_char((char*) &c);
            crc += c;
            page[i].b[0] = c;
        }

        /* get crc */
        put_char('c');
        rcrc = 0;
        ret |= get_char((char*) &c);
        rcrc = c << 8;
        ret |= get_char((char*) &c);
        rcrc |= c;

        if (rcrc != crc) {
            ret = 100;
            put_char('x');
        }

        if (ret)
            break;

        erase_page(page_addr.l);
        put_char('e');

        /* protect bootloader start addr */
        if (page_addr.l == 0) {
            page[0].l = 0x040800;
            page[1].l = 0x000000;
        }

        for (i = 0; i < PAGE_SIZE/2; i++) {
            write_dword(page_addr.l + i*4, page[i*2].l, page[i*2 + 1].l);
        }

        put_char('w');

    }

    if (ret) {
        put_char('X');
        while (1);
    } else {
        put_char('K');
        goto_usercode();
    }
}