PDBLv1 = Public Domain Boot Loader v1 для PIC16F870

8-битные микроконтроллеры PICmicro (ПИКи) от Microchip и совместимые, а также 16-битные PIC24 и 32-битные PIC32

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

PDBLv1 = Public Domain Boot Loader v1 для PIC16F870

Post by Shaos »

Вот собственно этот бутлоадер на 1.4К (в исполнении PICC v9.82 lite), который удалось ужать c 75% до 67% памяти PIC16F870 (т.е. с 3/4 до 2/3 от 2K-слов): http://nedopc.org/nedopc/16/PDBLv1.zip (54K)

Code: Select all

// PDBLv1 - Public Domain Boot Loader version 1 (16 Nov 2011)
// Created by Alexander A. Shabarshin <ashabarshin@gmail.com>
// For PIC16F870 on frequency 20 MHz and speed 9600
// You are free to use this code in any possible way
// Tested in PICC 9.82.9453 lite under MPLABX IDE beta 7.12

// Usage: Press Enter multiple times immediately after reset (~1sec)
// then use commands below to run (all numbers are hexadecimal):
// !AAAA=BBBB - write word BBBB to program memory in address AAAA
// !AAA=BB - write byte BB to data memory in address AAA
// !AA=BB - write byte BB to EEPROM in address AA
// ?AAAA - read one word from program memory with address AAAA
// ?AAA - read one byte from data memory with address AAA
// ?AA - read one byte from EEPROM in address AA
// . - exit from bootloader and jump to address 0x0001

// ToDo (not yet implemented):
// !AAAA=BBBB... - write words to program memory starting with AAAA
// !AAA=BB... - write bytes to data memory starting with AAA
// ?AAAA=BB - read BB words from program memory starting with AAAA
// ?AAA=BB - read BB bytes from data memory starting with AAA
// $A - call subprogram from address A
// ^A - jump to address A

// Errors:
// ERR01 - illegal hexadecimal digit was entered
// ERR02 - character '=' is expected
// ERR03 - enter is expected
// ERR04 - attempt to write in protected region (bootloader code)

#include <pic.h>

__CONFIG(CP_OFF & DEBUG_OFF & WRT_ALL & CPD_OFF & LVP_OFF & PWRTE_OFF & WDTE_OFF & FOSC_HS);

const char sign[] @0x7FA = "PDBLv1";

#define PROTECTION // flag to protect bootloader code

#define ENTER 13 // code of enter key

// all delays for 20 MHz

#define DELAY1US NOP();NOP();NOP();NOP();NOP()
#define DELAY10US delay(1,2)
#define DELAY15US delay(1,4)
#define DELAY20US delay(1,5)
#define DELAY25US delay(1,6)
#define DELAY30US delay(1,8)
#define DELAY40US delay(1,10)
#define DELAY50US delay(1,13)
#define DELAY60US delay(1,15)
#define DELAY75US delay(1,19)
#define DELAY100US delay(1,25)
#define DELAY150US delay(1,38)
#define DELAY200US delay(1,50)
#define DELAY300US delay(1,75)
#define DELAY400US delay(1,100)
#define DELAY500US delay(1,125)
#define DELAY600US delay(1,150)
#define DELAY750US delay(1,188)
#define DELAY900US delay(1,225)
#define DELAY1MS delay(1,250)
#define DELAY(x) delay(x,250)

void delay(unsigned short ms, unsigned char us4)
{
    unsigned short m;
    unsigned char s;
    for(m=0;m<ms;m++)
    {
      for(s=0;s<us4;s++)
      {
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
      }
    }
}

void serial_init()
{
#if 1
    SPBRG = 129; // 9600
#else
    SPBRG = 64; // 19200
#endif
    BRGH = 1;
    SYNC = 0;
    CREN = 0;
    CREN = 1;
    SPEN = 1;
    TXIE = 0;
    RCIE = 0;
    TX9 = 0;
    RX9 = 0;
    TXEN = 0;
    TXEN = 1;
}

void serial_err()
{
    if(OERR){CREN=0;CREN=1;}
    if(FERR){RCREG;}
}

void serial_send(unsigned char s)
{
    while(!TXIF) serial_err();
    TXREG = s;
    DELAY50US;
}

unsigned char serial_recv()
{
    while(!RCIF) serial_err();
    return RCREG;
}

unsigned char serial_read()
{
    unsigned char b = serial_recv();
    if(b>=0x20 && b<0x7F) serial_send(b);
    return b;
}

unsigned char serial_check(unsigned short ms)
{
    unsigned short i;
    unsigned char r = 0;
    for(i=0;i<ms;i++)
    {
        if(RCIF){r=RCREG;break;}
        serial_err();
        DELAY1MS;
    }
    return r;
}

void serial_print_nl()
{
    serial_send('\r');
    serial_send('\n');
}

void serial_print_hex(char h)
{
    if(h>=0 && h<10) serial_send('0'+h);
    else if(h>=10 && h<16) serial_send('A'+h-10);
}

void serial_print_byte(unsigned char b)
{
    serial_print_hex(b>>4);
    serial_print_hex(b&15);
}

void serial_print_word(unsigned short s)
{
    serial_print_byte(s>>8);
    serial_print_byte(s&255);
}

void serial_print_err(unsigned char n)
{
    serial_print_nl();
    serial_send('E');
    serial_send('R');
    serial_send('R');
    serial_print_byte(n);
}

void serial_print_ok()
{
    serial_print_nl();
    serial_send('O');
    serial_send('K');
}

signed char hex1(char h)
{
    char i = -1;
    if(h >= '0' && h <= '9') i = h-'0';
    else if(h >= 'a' && h <= 'f') i = 10+h-'a';
    else if(h >= 'A' && h <= 'F') i = 10+h-'A';
    return i;
}

void data_write(unsigned short a, unsigned char b)
{
    unsigned char* p = a;
    *p = b;
}

unsigned char data_read(unsigned short a)
{
    unsigned char* p = a;
    return *p;
}

void prog_write(unsigned short a, unsigned short b)
{
    FLASH_WRITE(a,b);
}

unsigned short prog_read(unsigned short a)
{
    return FLASH_READ(a);
}

unsigned short compact_nibbles(unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
    return (a<<12)|(b<<8)|(c<<4)|d;
}

void do_write()
{
    signed char a,b,c,d,e;
    unsigned short adr = 0;
    unsigned short val = 0;
    a = hex1(serial_read());
    if(a < 0) serial_print_err(1);
    else
    {
        b = hex1(serial_read());
        if(b < 0) serial_print_err(1);
        else
        {
            c = serial_read();
            if(c=='=')
            {   // EEPROM
                adr = compact_nibbles(0,0,a,b);
                a = hex1(serial_read());
                if(a < 0) serial_print_err(1);
                else
                {
                    b = hex1(serial_read());
                    if(b < 0) serial_print_err(1);
                    else
                    {
                        val = compact_nibbles(0,0,a,b);
                        if(serial_recv()!=ENTER) serial_print_err(3);
                        else
                        {
                            eeprom_write(adr,val);
                            serial_print_ok();
                        }
                    }
                }
            }
            else
            {
                c = hex1(c);
                if(c < 0) serial_print_err(1);
                else
                {
                    d = serial_read();
                    if(d=='=')
                    {   // DATA
                        adr = compact_nibbles(0,a,b,c);
                        a = hex1(serial_read());
                        if(a < 0) serial_print_err(1);
                        else
                        {
                            b = hex1(serial_read());
                            if(b < 0) serial_print_err(1);
                            else
                            {
                                val = compact_nibbles(0,0,a,b);
                                if(serial_recv()!=ENTER) serial_print_err(3);
                                else
                                {
                                    data_write(adr,val);
                                    serial_print_ok();
                                }
                            }
                        }
                    }
                    else
                    {
                        d = hex1(d);
                        if(d < 0) serial_print_err(1);
                        else
                        {
                            e = serial_read();
                            if(e!='=') serial_print_err(2);
                            else
                            {   // FLASH
                                adr = compact_nibbles(a,b,c,d);
                                a = hex1(serial_read());
                                if(a < 0) serial_print_err(1);
                                else
                                {
                                    b = hex1(serial_read());
                                    if(b < 0) serial_print_err(1);
                                    else
                                    {
                                        c = hex1(serial_read());
                                        if(c < 0) serial_print_err(1);
                                        else
                                        {
                                            d = hex1(serial_read());
                                            if(d < 0) serial_print_err(1);
                                            else
                                            {
                                                val = compact_nibbles(a,b,c,d);
                                                if(serial_recv()!=ENTER) serial_print_err(3);
                                                else
                                                {
#ifdef PROTECTION
                                                    static unsigned short bootadr = 0;
                                                    if(bootadr==0)
                                                    {
                                                        bootadr = prog_read(0);
                                                        bootadr &= 0x07FF;
                                                    }
                                                    if(adr >= bootadr)
                                                    {
                                                        serial_print_err(4);
                                                        return;
                                                    }
                                                    if(adr==0) adr=1;
#endif
                                                    prog_write(adr,val);
                                                    serial_print_ok();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void do_read()
{
    signed char a,b,c,d,e;
    unsigned short adr = 0;
    unsigned short val = 0;
    unsigned char byte = 0;
    a = hex1(serial_read());
    if(a < 0) serial_print_err(0);
    else
    {
        b = hex1(serial_read());
        if(b < 0) serial_print_err(0);
        else
        {
            c = serial_read();
            if(c==ENTER)
            {   // EEPROM
                adr = compact_nibbles(0,0,a,b);
                byte = eeprom_read(adr);
                serial_print_nl();
                serial_print_byte(byte);
            }
            else
            {
                c = hex1(c);
                if(c < 0) serial_print_err(0);
                else
                {
                    d = serial_read();
                    if(d==ENTER)
                    {   // DATA
                        adr = compact_nibbles(0,a,b,c);
                        byte = data_read(adr);
                        serial_print_nl();
                        serial_print_byte(byte);
                    }
                    else
                    {
                        d = hex1(d);
                        if(d < 0) serial_print_err(0);
                        else
                        {
                            if(serial_recv()!=ENTER) serial_print_err(3);
                            else
                            {   // FLASH
                                adr = compact_nibbles(a,b,c,d);
                                val = prog_read(adr);
                                serial_print_nl();
                                serial_print_word(val);
                            }
                        }
                    }
                }
            }
        }
    }
}

main()
{
    ADCON1 = 0x06;
    INTCON = 0x00;
    TRISC = 0xFF; // RC6 and RC7 must be inputs
    serial_init();
    unsigned char b = serial_check(1000);
    if(b==ENTER)
    {
        serial_print_nl();
        serial_send('P');
        serial_send('D');
        serial_send('B');
        serial_send('L');
        serial_send('v');
        serial_send('1');
        serial_print_nl();
        serial_send('>');
        b = 0;
        do
        {
            if(b!=ENTER)
            {
                b = serial_read();
            }
            if(b==ENTER)
            {
                serial_print_nl();
                serial_send('>');
                b = 0;
            }
            if(b=='?'){do_read();b=ENTER;}
            if(b=='!'){do_write();b=ENTER;}
        }
        while(b!='.');
    }
/*
    // TEST: print next character from the range [0x20..0x7E] every second
    char a = 0x20;
    while(1)
    {
      serial_send(a);
      if(++a==127) a=0x20;
      DELAY(1000);
    }
 */
    asm("goto 1"); // jump to the loaded code
}
На подгружаемые программы остаётся 671 байт...

P.S. Эту версию (точнее конкретную бинарную сборку этой версии) можно обозвать PDBL v1.2A2 т.к. GOTO 0x2A2 (слово 0x2AA2) стоит по нулевому адресу (это переход на бутлоадер)
Last edited by Shaos on 07 Dec 2014 06:10, edited 8 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

вот так выглядел процесс отладки:

Image

тут PICKit3 сам питает плату и адаптер RS-232
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Написал сишную программку под линух (должно работать на любой POSIX системе), которая зашивает HEX в бутлоадер PDBLv1:

http://nedopc.cvs.sourceforge.net/viewv ... c?view=log

Если ребутнуть девайс и запустить эту программку с аргументом, то она напишет:

Code: Select all

> pdbl1hex testprog.hex

pdbl1hex sends HEX-file to the PDBLv1 device

HEX 'testprog.hex'...
HEX Ok
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Program OK
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:Написал сишную программку под линух (должно работать на любой POSIX системе), которая зашивает HEX в бутлоадер PDBLv1:

http://nedopc.cvs.sourceforge.net/viewv ... c?view=log

Если ребутнуть девайс и запустить эту программку с аргументом, то она напишет:

Code: Select all

> pdbl1hex testprog.hex

pdbl1hex sends HEX-file to the PDBLv1 device

HEX 'testprog.hex'...
HEX Ok
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Program OK
Процесс создания программулек и их отладки пошёл значительно веселее :)

Image

Теперь не нужно ни программатора El Cheapo, ни программатора-отладчика PICKit3 ;)
Разве что для первоначальной прошивки бутлоадером...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Инклудник для работы с подпрограммами бутлоадера PDBLv1:

Code: Select all

; Constants for PDBLv1.2A2 (16 Nov 2011 - 26 Nov 2011)
; Created by Alexander A. Shabarshin <ashabarshin@gmail.com>

; COMMON #70..#7D(14) free #7E,#7F
; BANK0 #20..#3B(27) free #3C..#6F
; BANK1 (0) free #A0..#BF

bootloader equ 0x02A2

pdbl_entry equ 0x04DC

_PDBL MACRO
	goto	pdbl_entry
	ENDM

; compact_nibbles - compact 4 nibbles to 1 word
; ARG:W,#70,#71,#72 RET:#70,#71 USE:#20..#2B,#70..#73
compact_nibbles		equ	0x0450
compact_nibbles_1	equ	0x70
compact_nibbles_2	equ	0x71
compact_nibbles_3	equ	0x72

_compact_nibbles MACRO A,B,C,D,W0,W1
	movf	B,w
	movwf	compact_nibbles_1
	movf	C,w
	movwf	compact_nibbles_2
	movf	D,w
	movwf	compact_nibbles_3
	movf	A,w
	call	compact_nibbles
	movf	compact_nibbles_1,w
	movwf	W0
	movf	compact_nibbles_2,w
	movwf	W1
	ENDM

data_read		equ	0x02CE
; ARG:a0,a1 RET:W USE:#70..#73
data_read_a0		equ	0x70
data_read_a1		equ	0x71

data_write		equ	0x2FA
; ARG:a0,a1,b RET:no USE:#70..#75
data_write_a0		equ	0x70
data_write_a1		equ	0x71
data_write_b		equ	0x72

; delay - universal delay in ms or us (for 20MHz)
delay			equ	0x03C4
; ARG:#70,#71,#72 RET:no USE:#70..#76
delay_ms0		equ	0x70
delay_ms1		equ	0x71
delay_us4		equ	0x72

_delay_ MACRO H,L,U
	movlw	L
	movwf	delay_ms0
	movlw	H
	movwf	delay_ms1
	movlw	U
	movwf	delay_us4
	call	delay
	ENDM

_delay_ms MACRO H,L
	_delay_ H,L,250
	ENDM

_delay_us MACRO U
	_delay_ 0,1,U/4
	ENDM

do_read 		equ	0x052F
; ARG:no RET:no USE:#2C..#37

do_write		equ	0x0614
; ARG:no RET:no USE:#2C..#37,#3A,#3B
do_write_bootadr0	equ	0x3A
do_write_bootadr1	equ	0x3B

eeprom_read		equ	0x0385
; ARG:W RET:W USE:#70,#71

_eeprom_read MACRO A,B
	movf	A,w
	call	eeprom_read
	bcf STATUS,RP0
	bcf STATUS,RP1
	movwf	B
	ENDM

_eeprom_read_ MACRO A,B
	movlw	A
	call	eeprom_read
	bcf STATUS,RP0
	bcf STATUS,RP1
	movwf	B
	ENDM

eeprom_write		equ	0x041F
; ARG:W,value RET:W USE:#70-#72
eeprom_write_value	equ	0x70

_eeprom_write MACRO A,B
	movf	B,w
	movwf	eeprom_write_value
	movf	A,w
	call eeprom_write
	ENDM

_eeprom_write_ MACRO A,B
	movf	B,w
	movwf	eeprom_write_value
	movlw	A
	call eeprom_write
	ENDM

_eeprom_write_a MACRO A,B
	movlw	B
	movwf	eeprom_write_value
	movf	A,w
	call eeprom_write
	ENDM

_eeprom_write__ MACRO A,B
	movlw	B
	movwf	eeprom_write_value
	movlw	A
	call eeprom_write
	ENDM

hex1			equ	0x0484
; ARG:W RET:W USE:#70..#72

prog_read		equ	0x03A4
; ARG:a0,a1 RET:a0,a1 USE:#70..#74
prog_read_a0		equ	0x70
prog_read_a1		equ	0x71

_prog_read MACRO A0,A1,W0,W1
	movf	A0,w
	movwf	prog_read_a0
	movf	A1,w
	movwf	prog_read_a1
	call	prog_read
	movf	prog_read_a0,w
	movwf	W0
	movf	prog_read_a1,w
	movwf	W1
	ENDM

prog_write		equ	0x034F
; ARG:a0,a1,b0,b1 RET:no USE:#70..#73
prog_write_a0		equ	0x70
prog_write_a1		equ	0x71
prog_write_b0		equ	0x72
prog_write_b1		equ	0x73

_prog_write MACRO A0,A1,W0,W1
	movf	A0,w
	movwf	prog_write_a0
	movf	A1,w
	movwf	prog_write_a1
	movf	W0,w
	movwf	prog_write_b0
	movf	W1,w
	movwf	prog_write_b1
	call	prog_write
	ENDM

serial_check		equ	0x03F1
; ARG:ms0,ms1 RET:no USE:#77..#7C
serial_check_ms0	equ	0x77
serial_check_ms1	equ	0x78

serial_err		equ	0x02DC
; ARG:no RET:no USE:?

serial_init		equ	0x0337
; ARG:no RET:no USE:?

serial_print_byte	equ	0x02EB
; ARG:W RET:no USE:#7A,#7B

_serial_print_byte MACRO B
	movf	B,w
	call	serial_print_byte
	ENDM

_serial_print_byte_ MACRO B
	movlw	B
	call	serial_print_byte
	ENDM

serial_print_err	equ	0x02B6
; ARG:W RET:no USE:#7C

_serial_print_err MACRO B
	movf	B,w
	call	serial_print_err
	ENDM

_serial_print_err_ MACRO B
	movlw	B
	call	serial_print_err
	ENDM

serial_print_hex	equ	0x0368
; ARG:W RET:no USE:#79

serial_print_nl		equ	0x02A6
; ARG:no RET:no USE:?

_serial_print_nl MACRO
	call	serial_print_nl
	ENDM

serial_print_ok		equ	0x02B0
; ARG:no RET:no USE:?

_serial_print_ok MACRO
	call	serial_print_ok
	ENDM

serial_print_word	equ	0x02AB
; ARG:0,1 RET:no USE:#7C,#7D
serial_print_word_0	equ	0x7C
serial_print_word_1	equ	0x7D

_serial_print_word MACRO B0,B1
	movf	B0,w
	movwf	serial_print_word_0
	movf	B1,w
	movwf	serial_print_word_1
	call	serial_print_word
	ENDM

serial_read		equ	0x030A
; ARG:no RET:W USE:#79,#7A

_serial_read MACRO B
	call	serial_read
	movwf	B
	ENDM

serial_recv		equ	0x02C1
; ARG:no RET:W USE:?

_serial_recv MACRO B
	call	serial_recv
	movwf	B
	ENDM
	
serial_send		equ	0x0320
; ARG:W RET:no USE:#77,#78

_serial_send MACRO B
	movf	B,w
	call	serial_send
	ENDM

_serial_send_ MACRO B
	movlw	B
	call	serial_send
	ENDM
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Вот как выглядит процесс заливки программы, занимающей всю свободную память под завязку:
> pdbl1hex t1_test3.hex

pdbl1hex v1.1 sends HEX-file to the PDBLv1 device

HEX 't1_test3.hex'...
HEX Ok
Opening /dev/ttyS0
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooo
Program OK (669 words)
Вся процедура занимает порядка 1 минуты 25 секунд
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Надо незабыть переписать бутлоадер на ассемблер - а то уже 3 года прошло с момента его создания, а он всё ещё на сях...

P.S. и портировать его на бо'льшие пики типа PIC16F873-PIC16F877 тоже не помешает...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: PDBLv1 = Public Domain Boot Loader v1 для PIC16F870

Post by Shaos »

Подумалось тут - раз уж мой бутлоадэр умеет писать и читать данные пика, а не только код, то ведь можно пустой пик с этим бутлоадером на борту использовать как пачку двоичных сигналов ввода-вывода (а то и троичных ; - )
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: PDBLv1 = Public Domain Boot Loader v1 для PIC16F870

Post by Shaos »

Shaos wrote:Подумалось тут - раз уж мой бутлоадэр умеет писать и читать данные пика, а не только код, то ведь можно пустой пик с этим бутлоадером на борту использовать как пачку двоичных сигналов ввода-вывода (а то и троичных ; - )
Например вот так выглядит запуск АЦП на нулевом канале:

Code: Select all

>!01F=85
OK
>?01E
80

>!01F=85
OK
>?01E
FF
Сначала мы померяли +2.5В (0x80), а потом +5В (0xFF)

А теперь подключим ногу B0 к ноге A0 и туда же два резистора по 1К от земли и питания, чтобы сымитировать троичный сигнал :)

Code: Select all

>!086=00
OK

>!006=00
OK
>!01F=85
OK
>?01E
07

>!006=FF
OK
>!01F=85
OK
>?01E
E8

>!086=FF
OK
>!01F=85
OK
>?01E
80
Первый раз подали ноль, второй - единицу, а третий - перевели в Z состояние :dj:

Таким образом мы выдали наружу и затем прочитали троичный сигнал с помощью двоичного микроконтроллера управляемого по COM-порту ;)

P.S. Единственное неудобство - АЦП медленный - по моим подсчётам скорость оцифровки не может превышать 40 кГц, а если управлять им по COM-порту на скорости 9600 бод, то и подавно...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23992
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re:

Post by Shaos »

Shaos wrote:Написал сишную программку под линух (должно работать на любой POSIX системе), которая зашивает HEX в бутлоадер PDBLv1:

http://nedopc.cvs.sourceforge.net/viewv ... c?view=log

Если ребутнуть девайс и запустить эту программку с аргументом, то она напишет:

Code: Select all

> pdbl1hex testprog.hex

pdbl1hex sends HEX-file to the PDBLv1 device

HEX 'testprog.hex'...
HEX Ok
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Program OK
Не прошло и 5 лет, как я добавил в эту программку поддержку Windows - теперь указав этой программке макрос WINDA можно собрать её под винды, с использованием виндового Serial API - т.е. теперь эта программка работает не только в Linux и Mac OS X, но и Windows ;)

P.S. Попутно оказалось, что после прошивки верификации как-таковой и не происходило - поправил...

P.P.S. Вот так выглядит процесс прошивки под виндами (выбран порт COM10, которым система WinXP обозвала мой шнур RS-232-to-USB "Keyspan"):

Code: Select all

C:\> pdbl1hex.exe T1_TEST1.HEX 10 

pdbl1hex v1.2 sends HEX-file to the PDBLv1 device

HEX 'T1_TEST1.HEX'...
HEX Ok
Opening \\.\COM10
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Program OK (66 words)
P.P.P.S. Интересно, что тот же самый код, собранный в CYGWIN (эмулятор Linux окружения под виндой), также работает :)

Code: Select all

$ ./pdbl1hex-c T1.HEX 9

pdbl1hex v1.2 sends HEX-file to the PDBLv1 device

HEX 'T1.HEX'...
HEX Ok
Opening /dev/ttyS9
PDBLv1 device detected
Programming...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Verification...
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Program OK (66 words)
Я тут за главного - если что шлите мыло на me собака shaos точка net