5153c8eb4c00d6aa2c2799fc47590c8560d97e0b
4 Autor..........: Thomas Fischl <tfischl@gmx.de>
5 Description....: Provides functions for communication/programming
7 Licence........: GNU GPL v2 (see Readme.txt)
8 Creation Date..: 2005-02-23
9 Last change....: 2007-07-23
16 #define spiHWdisable() SPCR = 0
20 /* enable SPI, master, 375kHz SCK */
21 SPCR
= (1 << SPE
) | (1 << MSTR
) | (1 << SPR1
);
25 void ispSetSCKOption(uchar option
) {
29 /* use software spi */
30 ispTransmit
= ispTransmit_sw
;
35 /* use hardware spi */
36 ispTransmit
= ispTransmit_hw
;
43 uint8_t starttime
= TIMERVALUE
;
44 while ((uint8_t) (TIMERVALUE
- starttime
) < 12) { }
49 /* all ISP pins are inputs before */
50 /* now set output pins */
51 ISP_DDR
|= (1 << ISP_RST
) | (1 << ISP_SCK
) | (1 << ISP_MOSI
);
54 ISP_OUT
&= ~(1 << ISP_RST
); /* RST low */
55 ISP_OUT
&= ~(1 << ISP_SCK
); /* SCK low */
57 /* positive reset pulse > 2 SCK (target) */
59 ISP_OUT
|= (1 << ISP_RST
); /* RST high */
61 ISP_OUT
&= ~(1 << ISP_RST
); /* RST low */
63 if (ispTransmit
== ispTransmit_hw
) {
68 void ispDisconnect() {
70 /* set all ISP pins inputs */
71 ISP_DDR
&= ~((1 << ISP_RST
) | (1 << ISP_SCK
) | (1 << ISP_MOSI
));
72 /* switch pullups off */
73 ISP_OUT
&= ~((1 << ISP_RST
) | (1 << ISP_SCK
) | (1 << ISP_MOSI
));
75 /* disable hardware SPI */
79 uchar
ispTransmit_sw(uchar send_byte
) {
83 for (i
= 0; i
< 8; i
++) {
85 /* set MSB to MOSI-pin */
86 if ((send_byte
& 0x80) != 0) {
87 ISP_OUT
|= (1 << ISP_MOSI
); /* MOSI high */
89 ISP_OUT
&= ~(1 << ISP_MOSI
); /* MOSI low */
91 /* shift to next bit */
92 send_byte
= send_byte
<< 1;
95 rec_byte
= rec_byte
<< 1;
96 if ((ISP_IN
& (1 << ISP_MISO
)) != 0) {
101 ISP_OUT
|= (1 << ISP_SCK
); /* SCK high */
103 ISP_OUT
&= ~(1 << ISP_SCK
); /* SCK low */
110 uchar
ispTransmit_hw(uchar send_byte
) {
113 while (!(SPSR
& (1 << SPIF
)));
117 uchar
ispEnterProgrammingMode() {
124 check
= ispTransmit(0);
134 ISP_OUT
|= (1 << ISP_SCK
); /* SCK high */
136 ISP_OUT
&= ~(1 << ISP_SCK
); /* SCK low */
139 if (ispTransmit
== ispTransmit_hw
) {
145 return 1; /* error: device dosn't answer */
148 uchar
ispReadFlash(unsigned long address
) {
149 ispTransmit(0x20 | ((address
& 1) << 3));
150 ispTransmit(address
>> 9);
151 ispTransmit(address
>> 1);
152 return ispTransmit(0);
156 uchar
ispWriteFlash(unsigned long address
, uchar data
, uchar pollmode
) {
158 /* 0xFF is value after chip erase, so skip programming
164 ispTransmit(0x40 | ((address
& 1) << 3));
165 ispTransmit(address
>> 9);
166 ispTransmit(address
>> 1);
173 clockWait(15); /* wait 4,8 ms */
179 uint8_t starttime
= TIMERVALUE
;
180 while (retries
!= 0) {
181 if (ispReadFlash(address
) != 0x7F) {
185 if ((uint8_t) (TIMERVALUE
- starttime
) > CLOCK_T_320us
) {
186 starttime
= TIMERVALUE
;
191 return 1; /* error */
197 uchar
ispFlushPage(unsigned long address
, uchar pollvalue
) {
199 ispTransmit(address
>> 9);
200 ispTransmit(address
>> 1);
204 if (pollvalue
== 0xFF) {
211 uint8_t starttime
= TIMERVALUE
;
213 while (retries
!= 0) {
214 if (ispReadFlash(address
) != 0xFF) {
218 if ((uint8_t) (TIMERVALUE
- starttime
) > CLOCK_T_320us
) {
219 starttime
= TIMERVALUE
;
225 return 1; /* error */
231 uchar
ispReadEEPROM(unsigned int address
) {
233 ispTransmit(address
>> 8);
234 ispTransmit(address
);
235 return ispTransmit(0);
239 uchar
ispWriteEEPROM(unsigned int address
, uchar data
) {
242 ispTransmit(address
>> 8);
243 ispTransmit(address
);
246 clockWait(30); // wait 9,6 ms
251 clockWait(30); // wait 9,6 ms
256 uchar retries = 30; // about 9,6 ms
257 uint8_t starttime = TIMERVALUE;
259 while (retries != 0) {
260 if (ispReadEEPROM(address) != 0xFF) {
264 if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) {
265 starttime = TIMERVALUE;