; Orange programmer module v4.8 ; (c) 2010-2014 CnCLab ; Atmel AVR AT90CAN128 ;CHIP=AT90CAN32,32K,at90can.hpl ;AREA=FLASH,32K(128),0 ;AREA=EEPROM,1K ;AREA=FUSES,3 ;AREA=LOCK,1 ;IMAGE=atm128 ;CHIP=AT90CAN64,64K,at90can.hpl ;AREA=FLASH,64K(128),0 ;AREA=EEPROM,2K ;AREA=FUSES,3 ;AREA=LOCK,1 ;CHIP=AT90CAN128,128K,at90can.hpl ;AREA=FLASH,128K(128),0 ;AREA=EEPROM,4K ;AREA=FUSES,3 ;AREA=LOCK,1 ;Tested AT90CAN128 ALLPINS=0 ;INFO="AVR Adapter" OPTIONS=mf, ;FLASH: no modify, skip blank CDELAY=4 ; minimum periods for the serial clock (SCK) > 4 XTAL1 clock cycle! PINO=SCK, 0 ;PB1 10 PINO=MOSI, 2 ;PE0 2 PING=MISO, 1 ;PE1 3 PINO=RESET,3 ;20 PINO=GND,255 ;22,53,63 PINO=VCC,254 ;VCC,AVCC 21,52,64 BUSO=CFREQ,128 ;XTAL1 24 R9=Lock,C6,BLB12,BLB11,BLB02,BLB01,LB2,LB1 R10=CKSEL,L,"0000: Ext Clk,0001: IntRC 1MHz,0010: IntRC 2MHz,0011: IntRC 4MHz,0100: IntRC 8MHz,0101: ExtRC 0.9MHz,0110: ExtRC 0.9-3.0M,0111: ExtRC 3.0-8.0M,1000: ExtRC 8.0-12.0M,1001: LowFreq Crystal,1010: Crystal/Ceramic,1011: Crystal/Ceramic,1100: Crystal 0.9-3.0,1101: Crystal 0.9-3.0,1110: Crystal 3.0-8.0,1111: Crystal 3.0-8.0" R11=SUT,C2,1,0 R12=CKOUT,L,"0 - On,1 - Off" R13=CKDIV8,L,"0 - On,1 - Off" R14=BOOTRST,L,"0 - Boot Loader","1 - Application" R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages" R16=EESAVE,L,"0 - Save,1 - Clear" R17=WDTON,L,"0 - On,1 - Off" ;The SPIEN Fuse is not accessible in serial programming mode R18=JTAGEN,L,"0 - On,1 - Off" R19=OCDEN,L,"0 - On,1 - Off" ;TA0SEL Reserved for factory tests R1A=BODLEVEL,L,"000:2.5V,001:2.6V,010:2.7V,011:3.8V,100:3.9V,101:4.0V,110:4.1V,111:BOD DISABLE" [_DOUTIN] R1=0 LOOP=(7,0){MOSI=R0[I],SCK=1,R1[I]=MISO,SCK=0} [_DOUT] ;LOOP=(7,0){MOSI=R0[I],SCK=P} ; fast out MOSI=R0[7],SCK=P MOSI=R0[6],SCK=P MOSI=R0[5],SCK=P MOSI=R0[4],SCK=P MOSI=R0[3],SCK=P MOSI=R0[2],SCK=P MOSI=R0[1],SCK=P MOSI=R0[0],SCK=P [_DIN] R0=0 ;LOOP=(7,0){SCK=1,R0[I]=MISO,SCK=0} ; fast in SCK=1,R0[7]=MISO,SCK=0 SCK=1,R0[6]=MISO,SCK=0 SCK=1,R0[5]=MISO,SCK=0 SCK=1,R0[4]=MISO,SCK=0 SCK=1,R0[3]=MISO,SCK=0 SCK=1,R0[2]=MISO,SCK=0 SCK=1,R0[1]=MISO,SCK=0 SCK=1,R0[0]=MISO,SCK=0 [!#SETUP] $WDELAY=5000 ;tWD_FLASH minimum - 4.5 ms [_RDLOCKO] _DOUT(0x58) ;rd lock bits _DOUT(0x00) _DOUT(0x00) [_RDLOCK] _DOUT(0x58) ;rd lock bits _DOUT(0x00) _DOUT(0x00) _DIN [_WRLOCK] _DOUT(0xAC) ;Write lock bits _DOUT(0xE0) _DOUT(0x00) R0=DATA R0=|0xC0,_DOUT P=10000 [_RDFUSE] R7=ADR R7?0{ _DOUT(0x50) ;Read Fuse LOW _DOUT(0x00) } R7?1{ _DOUT(0x58) ;Read Fuse High _DOUT(0x08) } R7?2{ _DOUT(0x50) ;Read Fuse ext _DOUT(0x08) } _DOUT(0x00) ;_DIN ;read [_WRFUSE] R7=ADR R7?0{ _DOUT(0xAC) ;Fuse LOW _DOUT(0xA0) } R7?1{ _DOUT(0xAC) ;Fuse High _DOUT(0xA8) } R7?2{ _DOUT(0xAC) ;Fuse Ext _DOUT(0xA4) } _DOUT(0x00) R0=DATA _DOUT P=10000 [INIT] SCK=0 MISO=Z CFREQ=2000000 ;2MHz RESET=0,P=20000 ;min 20ms ;R5=0 LOOP=(32){ ; 32 attempts RESET=1,P=500 RESET=0,P=15000 _DOUT(0xAC) ;Programming Enable _DOUT(0x53) _DOUTIN(0x00) R3=R1 _DOUT(0) R3?0x53{BREAK} ;PRINT=("ANSWER: %02lX",R1) ;R5=+1,R5?>16{$CDELAY=+1,PRINT=L(".")} ;if no answer - decrees speed } R3?!0x53{PRINT=("ANSWER ERROR: %02lX",R3),EXIT} P=10 ; check ID code _DOUT(0x30) _DOUT(0x00) _DOUT(0x00) _DIN R0?!0x1E{PRINT=A("MCU return wrong ID code (%02lX)",R0) RA?0{EXIT} } ;PRINT=L("$CDELAY=%u\n",$CDELAY) $AREA?<2{ ;flash and ee can read in secured state RE?<4{ _RDLOCK R0=&3 R0?0{PRINT=S("#MCU memory locked!")} } } [_RDFL] R0=0x20 ;program memory area R1=ADR,R0[3]=R1[0] ;Hi/Lo _DOUT LOOP=(16,9){MOSI=ADR[I],SCK=P} LOOP=(8,1){MOSI=ADR[I],SCK=P} _DIN ;return R0 [READ] $AREA?0{ R0=0x20 ;program memory area R1=ADR,R0[3]=R1[0] ;Hi/Lo _DOUT ;LOOP=(16,9){MOSI=ADR[I],SCK=P} R0=ADR,R0=>>9,_DOUT ;LOOP=(8,1){MOSI=ADR[I],SCK=P} R0=ADR,R0=>>1,_DOUT } $AREA?1{ _DOUT(0xA0) ;eeprom area LOOP=(15,8){MOSI=ADR[I],SCK=P} LOOP=(7,0){MOSI=ADR[I],SCK=P} } $AREA?2{ ;fuse _RDFUSE } $AREA?3{ ;LOCK _RDLOCKO } _DIN ;common DATA=R0 [WRITE] $AREA?0{ PRINT=("Only Page Write Supported!") EXIT } $AREA?1{ _DOUT(0xC0) ;eeprom memory area LOOP=(15,8){MOSI=ADR[I],SCK=P} LOOP=(7,0){MOSI=ADR[I],SCK=P} R0=DATA,_DOUT P=10000 ; tWD_EEPROM minimum 9.0 ms } $AREA?2{ _WRFUSE } $AREA?3{ _WRLOCK } [WRITEBLOCK] ; FLASH area R7=ADR ;check empty (0xFF) block ;LOOP=($BLOCKSIZE){ ;R1=DATA ;R1?!0xFF{BREAK} ;ADR=+1 ;} ;R1?0xFF{RETURN} ;ADR=R7 LOOP=($BLOCKSIZE){ R0=0x40 ;program memory R1=ADR,R0[3]=R1[0],_DOUT ;Hi/Lo R0=0,_DOUT LOOP=(8,1){MOSI=ADR[I],SCK=P} R0=DATA,_DOUT P=10 ADR=+1 } ;Write Program memory Page: ADR=R7 _DOUT(0x4C) LOOP=(16,9){MOSI=ADR[I],SCK=P} LOOP=(8,6){MOSI=ADR[I],SCK=P} LOOP=(5,1){MOSI=0,SCK=P} _DOUT(0) ;dummy data ;Data Polling Flash. will not work for the value 0xFF ;R2=DATA ;R2?0xFF{P=$WDELAY,RETURN} ;tWD_FLASH minimum - 4.5 ms ;LOOP(2000){ ;_RDFL ;R2?R0{BREAK} ;Ok ;P=5 ;} ;R2?!R0{PRINT=S("#Write timeout! [%02X]",R0)} ;AT90CAN specific Poll RDY/BSY LOOP(500){ _DOUT(0xF0) _DOUT(0x00) _DOUT(0x00) _DIN R0=&1 R0?0{BREAK} P=10 } [WRITEEND] P=10000 RESET=1,P=20 ;RESET=0,P=20000 ["!#~Fuse Editor"] $AREA=2 ;FUSE R10=0,R11=0,R12=0,R13=0 R14=0,R15=0,R16=0,R17=0 R18=0,R19=0,R1A=0 ADR=0, R0=DATA ;Low fuse R10=R0,R10=&0xF ;R10=CKSEL,L R11[0]=R0[4] ;R11=SUT,L,1,2,3,4 R11[1]=R0[5] R12[0]=R0[6] ;R12=CKOUT R13[0]=R0[7] ;R13=CKDIV8 ADR=1,R0=DATA R14[0]=R0[0] ;R14=BOOTRST,C1 R15[0]=R0[1] ;R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages" R15[1]=R0[2] R16[0]=R0[3] ;R16=EESAVE R17[0]=R0[4] ;R17=WDTON ;SPIEN not accessible R18[0]=R0[6] ;R18=JTAGEN R19[0]=R0[7] ;R18=OCDEN ADR=2,R0=DATA ;EXT R1A[0]=R0[1] ;BODLEVEL R1A[1]=R0[2] R1A[2]=R0[3] GET=("Fuses",R10,R11,R12,R13,R14,R15,R16,R17,R18,R19,R1A) RA?0{EXIT} ;PRINT=("%lX",R11) R10?0{ ;CKSEL PRINT=A("This fuses value require Ext. Clock, continue?") RA?0{EXIT} } ADR=0 R0=R10,R0=&0xF ;R10=CKSEL,L R0[4]=R11[0] ;R11=SUT,L,1,2,3,4 R0[5]=R11[1] R0[6]=R12[0] ;R12=CKOUT R0[7]=R13[0] ;R13=CKDIV8 DATA=R0 ADR=1 R0=0xFF R0[0]=R14[0] ;R14=BOOTRST,C1 R0[1]=R15[0] ;R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages" R0[2]=R15[1] R0[3]=R16[0] ;R16=EESAVE R0[4]=R17[0] ;R17=WDTON R0[5]=0 ;SPIEN not accessible R0[6]=R18[0] ;R18=JTAGEN R0[7]=R19[0] ;R18=OCDEN DATA=R0 ADR=2 R0=0xFF ;EXT R0[1]=R1A[0] ;BODLEVEL R0[2]=R1A[1] R0[3]=R1A[2] DATA=R0 ["!#~Lock Editor"] $AREA=3 ;Lock R9=DATA GET=("Lock",R9) RA?0{EXIT} R9=|0xC0 DATA=R9 [READID] _DOUT(0x30) _DOUT(0x00) _DOUT(0x00) _DIN R2=R0,R2=<<8 _DOUT(0x30) _DOUT(0x00) _DOUT(0x01) _DIN R2=|R0,R2=<<8 _DOUT(0x30) _DOUT(0x00) _DOUT(0x02) _DIN R0=|R2 ;R2?0x1E9581{PRINT=("ID: %06lX - AT90CAN32",R2),EXIT} PRINT=S("ID: %06lX",R0) ["Read Calibration"] _DOUT(0xF0) _DOUT(0x00) _DOUT(0x00) _DIN PRINT=("Calibration = %02XH",R0) [Erase] _DOUT(0xAC) ;Chip Erase _DOUT(0x80) _DOUT(0x00) _DOUT(0x00) P=50000 ; Check ADR=0 _RDFL ;Read program memory area ;ADR 0 R0?!0xFF{PRINT=E("Erase error")} R0?0xFF{PRINT=S("Erase finished")} RESET=1,P=2000 RESET=0,P=500000 [END] RESET=1 CFREQ=0 ;EO=1,P=10 ;BB off