Old computer enthusiasm and chemistry wizardry have come up with a recipe for undoing the supposedly permanent effects of UV and fire retardants!
I'm definitely going to try this out, as soon as I can get hold of the requisite chemicals...
Sorted by Squirrels.
10@=0
20!#208=!#208+3
30V=#B800
40W=#FFF4
50T=#80
60DIM LL(13),C(6)
70F.N=0TO13;LL(N)=#FFFF;N.N
80F.N=1TO2; DIM P(-1)
90P."PASS "N',$21
100[
110\ main
120:LL0 LDA @#0
130STA C+1; STA C+2; STA C+3; STA C+4
140LDA @#95; STA C+0
150JSR LL3
160LDA @#40+#0; JSR LL7
170LDA @CH"1"; SBC @0; JMP W
180\ select card
190:LL1 LDA @0; STA V; RTS
200\ deselect card
210:LL2 LDA @#20; STA V; RTS
220\ init hw and go spi
230:LL3 LDA @0; STA V+#C
240LDA @#FE; STA V+2
250LDA @#20; STA V
260LDY @10
270:LL4 LDA @#FF; JSR LL5; DEY; BNE LL4
280RTS
290\ xferbyte
300:LL5 STX T+0; STY T+1; LDY @8
310:LL6 PHA; AND @#80; STA V
320ORA @#40; STA V
330LDX V; AND @#BF; STA V
340TXA; ROR A
350PLA; ROL A
360DEY; BNE LL6
370PHA; JSR #F7FA; PLA
380LDY T+1; LDX T+0;
390RTS
400\ command
410:LL7 STA C+5; LDY @5
420:LL8 LDA C,Y; JSR LL5; DEY; BPL LL8
430:LL9 LDA @#FF; JSR LL5; AND @#FF; CLC; BPL LL10
440DEY; BNE LL9;
450SEC
460:LL10 RTS
470]
480P.$6
490NE.N
500END
/*
/ Microfat.
/
/ Developed by Charlie Robson in 2008.
/
/ This is the bare minimum* functionality required to read and write data
/ to a FAT formatted device. In this case, an MMC card.
/
/ Rather than build a fully-featured FAT implimentation this will allow
/ the user to locate sectors associated with a file on the device, and
/ read and write to them in a brute force manner. No error checking, no
/ long filenames, not even any support for fragmented files :) This is
/ raw access, we only deal with existing files.
/
/ What you do get is a very lightweight module for extremely limited
/ environments. Arduino has 2k of SRAM. Holding the sector of FAT data
/ needed to traverse a fragged file would instantly gobble up 1/4
/ of that. Enough said. Another benefit to not using the FAT is that
/ there's no need to worry about whether a device is FAT12 or 16.
/
/ To use:
/ Format a card.
/ Make a file big enough to hold all the data you expect to write.
/ Copy to the card.
/
/ With the MMC module started up, call initialise. This will cache some
/ relevant information about the card such as the sector location of the
/ root directory and data area.
/
/ Call locateFileStart, passing the name of the file which is providing
/ the backing store for your transfers, and assuming the file is found
/ in the directory you'll receive its start sector and file size.
/
/ Now feel free to read and write data to and from the sectors allocated
/ to the file. Code carefully though - stray writes can twat your card!
/
/ Enjoy :)
/
/ *Massive understatement!
*/
#ifndef __MICROFAT_H__
#define __MICROFAT_H__
// some data structures we'll be encountering on our travels.
typedef struct
{
byte bootable;
byte chsAddrOfFirstSector[3];
byte partitionType;
byte chsAddrOfLastSector[3];
uint32_t lbaAddrOfFirstSector;
uint32_t partitionLengthSectors;
}
partition_record;
typedef struct
{
byte jump[3];
char oemName[8];
uint16_t bytesPerSector;
byte sectorsPerCluster;
uint16_t reservedSectors;
byte fatCopies;
uint16_t rootDirectoryEntries;
uint16_t totalFilesystemSectors;
byte mediaDescriptor;
uint16_t sectorsPerFAT;
uint16_t sectorsPerTrack;
uint16_t headCount;
uint32_t hiddenSectors;
uint32_t totalFilesystemSectors2;
byte logicalDriveNum;
byte reserved;
byte extendedSignature;
uint32_t partitionSerialNum;
char volumeLabel[11];
char fsType[8];
byte bootstrapCode[447];
byte signature[2];
}
boot_sector;
typedef struct
{
char filespec[11];
byte attributes;
byte reserved[10];
uint16_t time;
uint16_t date;
uint16_t startCluster;
uint32_t fileSize;
}
directory_entry;
namespace microfat
{
// Cache some relevant info about the card.
//
bool initialise(byte* buffer);
// Get start sector, file size for given filename. Returns false if the file
// is not found in the directory.
//
bool locateFileStart(const char* filename, unsigned long& sector, unsigned long& size);
};
#endif // __MICROFAT_H__
#include <wprogram.h>
#include "microfat.h"
#include "mmc.h"
// Data which remains constant over one session. Re-initialise if
// the card is changed.
//
static struct
{
uint16_t sectorsPerCluster;
uint32_t rootDirSect, cluster2;
byte* buffer;
}
vars;
bool microfat::initialise(byte* buffer)
{
vars.buffer = buffer;
if (RES_OK != mmc::readSectors(vars.buffer, 0, 1))
{
return false;
}
partition_record* p = (partition_record*)&vars.buffer[0x1be];
long bootSector = p->lbaAddrOfFirstSector;
if (RES_OK != mmc::readSectors(vars.buffer, bootSector, 1))
{
return false;
}
boot_sector* b = (boot_sector*)vars.buffer;
if (BYTESPERSECTOR != b->bytesPerSector)
{
return false;
}
vars.sectorsPerCluster = b->sectorsPerCluster;
vars.rootDirSect = bootSector + b->reservedSectors + (b->fatCopies * b->sectorsPerFAT);
long dirBytes = b->rootDirectoryEntries * 32;
long dirSects = dirBytes / BYTESPERSECTOR;
if (dirBytes % BYTESPERSECTOR != 0)
{
++dirSects;
}
vars.cluster2 = vars.rootDirSect + dirSects;
return true;
}
// Get start sector for given filename.
//
// Returns false if the specified file wasn't found in the directory.
// Short filenames only. Be aware that the directory fills up with 'deleted'
// filenames. Rather than deleting too many files try a quick reformat.
//
bool microfat::locateFileStart(const char* filename, uint32_t& sector, uint32_t& size)
{
if (RES_OK == mmc::readSectors(vars.buffer, vars.rootDirSect, 1))
{
// The filenames are stored in [8][3] format. No dot, all upper case.
// Names shorter than 8 chars are padded with spaces.
//
// Cook the supplied name. fred.txt -> FRED----TXT
//
char cookedName[11];
for(int i = 0; i < 12; ++i)
{
cookedName[i] = 0x20;
}
for (int i = 0, j = 0; i < 12 && filename[i]; ++i)
{
if (filename[i] != '.')
{
// Force char to uppercase. Cheesy I know :)
//
cookedName[j] = filename[i] >= 96 ? filename[i] - 32 : filename[i];
++j;
}
else
{
// Continue cooking chars at the extension position
//
j = 8;
}
}
for (int i = 0; i < BYTESPERSECTOR; i += 32)
{
directory_entry* de = (directory_entry*)&vars.buffer[i];
// Don't match with deleted or system/volname/subdir/hidden files
//
if (de->filespec[0] != 0xe5 && (de->attributes & 0x1e) == 0 && memcmp(cookedName, de->filespec, 11) == 0)
{
sector = vars.cluster2 + ((de->startCluster-2) * vars.sectorsPerCluster);
size = de->fileSize;
return true;
}
}
}
return false;
}
/*
* Support code for ACE - the arduino cassette engine
*
* Example code to write a wav file which can be played to
* a microcontroller running the ACE software.
*
* Should be fairly portable unlike the original example.
*
* Enjoy.
*
*/
#include <iostream>
#include <fstream>
typedef unsigned char uint8_t;
// adjust these to control endiannesses.
//
static const int ENDIAN0 = 0;
static const int ENDIAN1 = 1;
static const int ENDIAN2 = 2;
static const int ENDIAN3 = 3;
static const int ENDIAN0_S = 0;
static const int ENDIAN1_S = 1;
// desired wave structure - AHEM THESE ARE READ-ONLY
// - THEY CAN'T BE CHANGED WITHOUT FUTZING THE CODE. SORRY.
//
static const int CHANNELS = 2;
static const int SAMPLERATE = 44100;
static const int BITSPERSAMPLE = 16;
// this is as loud as we can get. not quite 11,
// but approaching it.
//
static const double maxLevel = (double)SHRT_MAX * 1.0;
static const short maxLevelS = (short)maxLevel;
static const double minLevel = (double)SHRT_MIN * 1.0;
static const short minLevelS = (short)minLevel;
// number of samples per cycle. 60 samples = 1 low or 2 high cycles.
//
static const int f1 = 60;
static const int f1cyc = 1;
static const int f2 = f1 / 2;
static const int f2cyc = f1cyc * 2;
// useful values, maybe
//
static const int usPerCycle = (int)(((double)f1 / 44100) * 1000000.0);
static const int usPerHalfCycle = (int)(((double)f1 / 44100) * 500000.0);
static const int usPerQuarterCycle = (int)(((double)f1 / 44100) * 250000.0);
static const int usPerEighthCycle = (int)(((double)f1 / 44100) * 125000.0);
static const int baudrate = (1000000 / usPerCycle);
// 8 + stop + start;
//
static const int bitsPerFrame = 10;
static const int samplesPerBit = f1 * f1cyc;
static const int samplesPerFrame = bitsPerFrame * samplesPerBit;
static const int LOW_BIT = 0;
static const int HIGH_BIT = !LOW_BIT;
static const int LEADIN_BIT = LOW_BIT;
static const int START_BIT = !LEADIN_BIT;
static const int STOP_BIT = !START_BIT;
// NASTY HACK FOR WRITING WAVS. PLEASE LOOK AWAY NOW.
void CreateWaveFile(std::ostream& output)
{
char chars[4];
output << "RIFF";
*(int*)chars = 16;
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
output << "WAVE";
output << "fmt ";
*(int*)chars = 16;
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
*(short*)chars = 1;
output << chars[ENDIAN0_S] << chars[ENDIAN1_S];
*(short*)chars = CHANNELS;
output << chars[ENDIAN0_S] << chars[ENDIAN1_S];
*(int*)chars = SAMPLERATE;
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
*(int*)chars = (int)(SAMPLERATE*(BITSPERSAMPLE/8*CHANNELS));
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
*(short*)chars = (short)(BITSPERSAMPLE/8*CHANNELS);
output << chars[ENDIAN0_S] << chars[ENDIAN1_S];
*(short*)chars = (short)BITSPERSAMPLE;
output << chars[ENDIAN0_S] << chars[ENDIAN1_S];
output << "data";
*(int*)chars = 0;
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
}
void FinaliseWaveFile(std::ostream& output, size_t bytesWrit)
{
char chars[4];
output.seekp(40);
*(int*)chars = (int)bytesWrit;
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
output.seekp(4);
*(int*)chars = (int)(bytesWrit + 36);
output << chars[ENDIAN0] << chars[ENDIAN1] << chars[ENDIAN2] << chars[ENDIAN3];
}
// OK IT'S SAFE TO LOOK AGAIN
// here we represent:
//
// 0 bit as 1 cycle of low frequency,
// 1 bit as 2 cycles of high frequency
//
// where the high frequency is double that of the low.
//
void OutputBit(std::ostream& output, int bit, size_t& written,
short maxval = maxLevelS, short minval = minLevelS)
{
// default to low
//
int cycles = f1cyc;
int samplesPerCycle = f1;
if (bit != 0)
{
cycles = f2cyc;
samplesPerCycle = f2;
}
// generate square pulse, start with rising edge
//
for (int i = 0; i < cycles; ++i)
{
for (int j = 0; j < samplesPerCycle / 2; ++j)
{
// high [1] period
//
output << uint8_t(maxval & 0xff);
output << uint8_t(maxval >> 8);
output << uint8_t(maxval & 0xff);
output << uint8_t(maxval >> 8);
written += 4;
}
for (int j = 0; j < samplesPerCycle / 2; ++j)
{
// low [0] period
//
output << uint8_t(minval & 0xff);
output << uint8_t(minval >> 8);
output << uint8_t(minval & 0xff);
output << uint8_t(minval >> 8);
written += 4;
}
}
}
// outputs a start bit, 8 data bits and a stop bit
//
void OutputByte(std::ostream& output, uint8_t value, size_t& written)
{
OutputBit(output, START_BIT, written);
for (int i = 0; i < 8; ++i)
{
OutputBit(output, (value & 0x80) ? HIGH_BIT : LOW_BIT, written);
value <<= 1;
}
OutputBit(output, STOP_BIT, written);
}
// outputs a lead train of bits, terminated with a start bit.
//
void OutputLeader(std::ostream& output, int milliseconds, size_t& written)
{
int microseconds = (milliseconds * 1000) - usPerCycle;;
// this is a bit of a decoration -
// ramp up the volume during the 1st half of the leader. this might
// prevent some unexpected eardrum-rupture events.. and yes, i know
// that volume should be ramped non-linearly :) this will do for
// the time being.
//
double vol = 0, ramp = 1.0 / (microseconds/(usPerCycle*2));
while (microseconds >= 0)
{
OutputBit(output, LEADIN_BIT, written, (short)(vol * maxLevel), (short)(vol * minLevel));
vol += ramp;
vol = __min(vol, 1.0);
microseconds -= usPerCycle;
}
OutputBit(output, START_BIT, written);
}
void main (int argc, char **argv)
{
if (argc < 3)
{
std::cout << "Usage: makewav [input file] [output file]" << std::endl;
exit(1);
}
std::ifstream inner(argv[1], std::ios_base::binary);
if (!inner.is_open())
{
std::cout << "Could not open input file." << std::endl;
exit(1);
}
std::ofstream outer(argv[2], std::ios_base::binary);
if (!outer.is_open())
{
std::cout << "Could not open output file." << std::endl;
exit(1);
}
// write wav header
//
CreateWaveFile(outer);
// determine input file size
//
inner.seekg(0, std::ios_base::end);
size_t size = (size_t)inner.tellg();
inner.seekg(0);
size_t pc = 0;
size_t written = 0;
// file is structured:
// some seconds of leader
// size msb
// size lsb
// {
// data[512]
// some milliseconds of leader
// }
OutputLeader(outer, 2000, written);
OutputByte(outer, uint8_t(size >> 8), written);
OutputByte(outer, uint8_t(size & 0xff), written);
while (pc != size)
{
// dummy data - replace this with either read from buffer indexed by [pc]
// or a byte get from the file to be encoded
//
OutputByte(outer, inner.get(), written);
++pc;
if (pc % 512 == 0 && pc != size)
{
OutputLeader(outer, 50, written);
}
}
FinaliseWaveFile(outer, written);
outer.close();
}
/*
/ 'Arduino Cassette Engine'.
/
/ Developed by Charlie Robson in 2008.
/
/ This is half of a solution for getting data into an arduino. The other
/ half being code to generate frequency shift keyed (FSK) data in the form
/ of WAV files which should be widely playable. These can be recorded or
/ otherwise electronically distributed. Why do it this way? 1. Because it's
/ funny. 2. Having given an updatable arduino-powered 'toy' to someone, I
/ can't expect them to re-program the device by traditional means in order
/ to update it. Everyone has a means of playing a sound!
/
/ On with the show.
/
/ The data is encoded like so:
/
/ Lead-in
/ High byte of data length
/ Low byte of data length
/ {
/ Data[0 < size <= 512]
/ (Lead-in)
/ }
/
/ Lead-in is a train of bits terminated with a start bit. This means the lead-in
/ bit needs to be the logical complement of the start bit.
/
/ Every byte is represented by 10 bits - a start bit, 8 data bits, and a stop
/ bit. The start and stop bits are complementary.
/
/ Data arrives in 512 byte blocks. Each block except the last is followed by a
/ short period, about 25 milliseconds, of lead-in. This is to allow processing time
/ on each block as it arrives.
/
/ Decoding a data bit is done something like so:
/
/ Await a rising edge then take 2 samples at a period which will allow us
/ to distinguish a 0 or 1 bit. Sampling 2 identical values yields a 0 bit.
/ Delay so the next bit read will occur when the signal is in a low period.
/
/ Following is a picture of a '0' bit, or low frequency cycle, followed by
/ a '1' bit or high frequency cycle, with some important times noted.
/
/ The X shows a rough expected time at which we start the bit reading.
/ The 0 shows relative time zero, when we detect the rising edge.
/ The + signs show the times at which we sample.
/ The * shows the earliest time at which we can await a new bit. IOW, X.
/
/ __`_____`__ __
/ | ` ` | |
/ | ` ` | |
/ | ` ` | ` |
/ ` | ` ` | ` |
/ __`_| ` ` | ____`_____|
/ ` ` ` ` `
/ X 0 + + *
/ ` `__`__ ` _____`
/ ` | ` | ` | |
/ ` | ` | ` | |
/ | | | |
/ | | | | |
/ ____| |_____| |_____|
/ `
/ `
/ |-----------------------| = usPerCycle = 1360uS
/ |-----------| = usPerHalfCycle = 680uS
/ |-----| = usPerQuarterCycle = 340uS
/ |--| = usPerEighthCycle = 170uS
/
/
/ It's assumed that the audio signal is connected to PORTB-0 which is
/ digital pin 8. If you'd like to change that, then replace occurrences
/ of...
/
/ PINB & 1
/
/ ... with the direct bit-access for your implementation. I do it this
/ way because it's slightly faster than digitalRead()ing. If you do change
/ the port you'll also need to change the logic in readBit as this relies
/ on the fact that we work with bit 0.
/
*/
// XA1 XA0 Action when XTAL1 is Pulsed
// --- --- ---------------------------
// 0 0 Load Flash or EEPROM Address (High or low address byte determined by BS1)
// 0 1 Load Data (High or Low data byte for Flash determined by BS1)
// 1 0 Load Command
// 1 1 No Action, Idle
//
const byte XA_LOAD_ADDR = B00;
const byte XA_LOAD_DATA = B01;
const byte XA_LOAD_CMND = B10;
const byte XA_NOP = B11;
const byte CMD_ERASE = B10000000;
const byte CMD_WRITE_FUSE = B01000000;
const byte CMD_READ_SIG = B00001000;
const byte CMD_READ_FUSE = B00000100;
#define DLY delayMicroseconds(100)
inline void SETB(byte x)
{
PORTB |= _BV(x);
DLY;
}
inline void SETD(byte x)
{
PORTD |= _BV(x);
DLY;
}
inline void CLRB(byte x)
{
PORTB &= ~_BV(x);
DLY;
}
inline void CLRD(byte x)
{
PORTD &= ~_BV(x);
DLY;
}
// PORTB
#define PIN_BS1 0
#define PIN_XA0 1
#define PIN_XA1 2
#define PIN_BS2 3
#define PIN_PAGEL 4
#define PIN_POWERTOCHIP 5
#define SET_BS1 SETB(PIN_BS1)
#define CLR_BS1 CLRB(PIN_BS1)
void SET_XA(byte xtal_action)
{
PORTB &= ~(_BV(PIN_XA1)|_BV(PIN_XA0));
PORTB |= xtal_action << PIN_XA0;
DLY;
}
void CLR_XA()
{
PORTB &= ~(_BV(PIN_XA1)|_BV(PIN_XA0));
DLY;
}
#define SET_BS2 SETB(PIN_BS2)
#define CLR_BS2 CLRB(PIN_BS2)
#define SET_PAGEL SETB(PIN_PAGEL)
#define CLR_PAGEL CLRB(PIN_PAGEL)
#define SET_POWERTOCHIP SETB(PIN_POWERTOCHIP)
#define CLR_POWERTOCHIP CLRB(PIN_POWERTOCHIP)
// PORTD
#define PIN_XTAL1 2
#define PIN_RDYNOTBSY 3
#define PIN_OE 4
#define PIN_WR 5
// <- PORTD3 rdy/bsy
//
void AWAIT_READY()
{
while ((PIND & _BV(PIN_RDYNOTBSY)) == 1);
long time = millis();
while ((PIND & _BV(PIN_RDYNOTBSY)) == 0);
Serial.println(millis()-time,DEC);
}
#define SET_OE SETD(PIN_OE)
#define CLR_OE CLRD(PIN_OE)
#define SET_WR SETD(PIN_WR)
#define CLR_WR CLRD(PIN_WR)
void PULSE_WR(bool wait = true);
void PULSE_WR(bool wait)
{
PORTD &= ~_BV(PIN_WR);
delayMicroseconds(100);
PORTD |= _BV(PIN_WR);
if (wait)
{
AWAIT_READY();
}
}
#define SET_XTAL1 SETD(PIN_XTAL1)
#define CLR_XTAL1 CLRD(PIN_XTAL1)
void PULSE_XTAL(bool wait = true);
void PULSE_XTAL(bool wait)
{
PORTD |= _BV(PIN_XTAL1);
delayMicroseconds(100);
PORTD &= ~_BV(PIN_XTAL1);
if (wait)
{
AWAIT_READY();
}
}
// <-> PORTD6...7 will be used as DATA6...7
// <-> PORTC0...5 will be used as DATA0...5
//
void SET_DATA_IN(void)
{
DDRC &= B11000000;
DDRD &= B00111111;
}
byte GET_DATA()
{
return (PORTC & B00111111) | (PORTD & B11000000);
}
void SET_DATA(byte data)
{
DDRC |= B00111111;
PORTC = (PORTC & B11000000) | (data & B00111111);
DDRD |= B11000000;
PORTD = (PORTD & B00111111) | (data & B11000000);
DLY;
}
//
//
//
void LOAD_COMMAND(byte command)
{
SET_XA(XA_LOAD_CMND);
SET_DATA(command);
PULSE_XTAL();
CLR_XA();
}
void LOAD_ADDRESS(byte address)
{
SET_XA(XA_LOAD_ADDR);
SET_DATA(address);
PULSE_XTAL();
CLR_XA();
}
void LOAD_DATA(byte data, bool low)
{
SET_XA(XA_LOAD_DATA);
if (!low)
{
SET_BS1;
}
SET_DATA(data);
PULSE_XTAL();
CLR_XA();
CLR_BS1;
}
byte GET_SIG(byte offset)
{
LOAD_COMMAND(CMD_READ_SIG);
LOAD_ADDRESS(offset);
SET_DATA_IN();
CLR_OE;
byte x = GET_DATA();
SET_OE;
}
inline void PROG_ENABLE(void)
{
SET_POWERTOCHIP;
delayMicroseconds(100);
}
inline void PROG_DISABLE(void)
{
CLR_POWERTOCHIP;
}
inline void PROG_ENABLE_PROPER(void)
{
SET_XTAL1;
CLR_XTAL1;
SET_XTAL1;
CLR_XTAL1;
SET_XTAL1;
CLR_XTAL1;
SET_POWERTOCHIP;
}
//
//
//
void setup(void)
{
Serial.begin(115200);
// PORTB 5...0 all outputs. Zero the ports before setting them as outputs
// to prevent spikes.
//
PORTB = 0;
DDRB |= B00111111;
// Not interested in DATA pins, they'll get set later as required
//
// PORTD0/1 are rx/tx: leave alone
// PORTD3 is input
// D6/7 are set on demand
// the rest are output
//
PORTD = 0;
DDRD = (DDRD & B11110111) | B00110100;
// bring the active low pins to their inactive state.
//
SET_OE;
SET_WR;
}
void loop(void)
{
Serial.println("Fuser 1.0 Ready.");
while(!Serial.available());
if (Serial.read() == 'p')
{
Serial.println("Sig: ");
PROG_ENABLE_PROPER();
Serial.println(GET_SIG(0),HEX);
Serial.println(GET_SIG(1),HEX);
Serial.println(GET_SIG(2),HEX);
}
else
{
Serial.println("Burn: ");
PROG_ENABLE();
delay(2);
Serial.println("Erase: ");
LOAD_COMMAND(CMD_ERASE);
PULSE_WR();
Serial.println("Lo fuse: ");
LOAD_COMMAND(CMD_WRITE_FUSE);
LOAD_DATA(0xE1, true);
PULSE_WR();
Serial.println("Hi fuse: ");
LOAD_COMMAND(CMD_WRITE_FUSE);
LOAD_DATA(0x99, false);
PULSE_WR();
}
PROG_DISABLE();
}
Target - atmega32
____ ____
| pb0 =| U |= pa0 | bs2
| 1 =| |=
/ | 2 =| |=
DATA | 3 =| |=
\ | 4 =| |=
| 5 =| |=
| 6 =| |=
| 7 =| |=
reset =| |= aref
vcc =| |= gnd
gnd =| |= avcc
=| |=
xtal1 | xtal1 =| |=
pd0 =| |=
rdy/~bsy | 1 =| |=
~oe | 2 =| |=
~wr | 3 =| |=
bs1 | 4 =| |=
xa0 | 5 =| |=
xa1 | 6 =|_________|= pd7 | pagel
Diecimila - pin assignment
ANA-IN5 |o| DATA5
4 |o| 4
3 |o| 3
2 |o| 2
1 |o| 1
0 |o| 0
D0 [rx] |o| -
1 [tx] |o| -
2 |o| xtal1
3 |o| rdy/~bsy
4 |o| ~oe
5 |o| ~wr
6 |o| DATA6
7 |o| DATA7
D8 |o| bs1
9 |o| xa0
10 |o| xa1
11 |o| bs2
12 |o| pagel
13 |o| juice
gnd |o| -
aref |o| -
/* CUT DUE TO ITS TEMPORARY NATURE - PLEASE SEE LATER POST */