Closed urish closed 3 years ago
I found that the analog pin specified by analogRead() can be found by reading the ADMUX register (0x7c). The following code should find the pin number of the analog pin being read on port C (based on execute.ts from your Simon Says example):
this.cpu.writeHooks[0x7a] = value => {
if (value & (1 << 6)) {
this.cpu.data[0x7a] = value & ~(1 << 6); // clear bit - conversion done
const ADMUXval = this.cpu.data[0x7c]; //Value held in ADMUX selection register
const analogPin = ADMUXval & 15; //Apply mask to clear first 4 bits as only latter half is important for selection
return true; // don't update
}
};
If every pin on port C had an "analogValue" variable, the above code could then check the necessary pin for its analog value and write that to the ADCL and ADCH registers as you have done in the Simon Says example. This could look something like:
this.cpu.writeHooks[0x7a] = value => {
if (value & (1 << 6)) {
this.cpu.data[0x7a] = value & ~(1 << 6); // clear bit - conversion done
const ADMUXval = this.cpu.data[0x7c]; //Value held in ADMUX selection register
const analogPin = ADMUXval & 15; //Apply mask to clear first 4 bits as only latter half is important for selection
const analogValue = eval("runner.portC.analogValue("+analogPin +");");
this.cpu.data[0x78] = analogValue & 0xff;
this.cpu.data[0x79] = (analogValue >> 8) & 0x3;
return true; // don't update
}
};
(Excuse the use of eval(), I'm not sure of a better way of implementing that line right now) The above code is just an idea I haven't had a chance to test yet, but I hope it helps!
My current implementation is as follows:
this.cpu.writeHooks[0x7a] = value => {
if (value & (1 << 6)) {
this.cpu.data[0x7a] = value & ~(1 << 6); // clear bit - conversion done
const ADMUXval = this.cpu.data[0x7c]; //Value held in ADMUX selection register
const analogPin = ADMUXval & 15; //Apply mask to clear first 4 bits as only latter half is important for selection
globalThis.Runner.portC.setAnalogValue(globalThis.analogArray[analogPin]);
return true; // don't update
}
};
In which globalThis.analogArray contains the ADC values for each pin, which are calculated in a circuit simulation running in the same window. Runner.portC.setAnalogValue is defined in gpio.ts as:
setAnalogValue(analogValue: number){
//Write analogValue to ADCH and ADCL
this.cpu.data[0x78] = analogValue & 0xff;
this.cpu.data[0x79] = (analogValue >> 8) & 0x3;
}
This maybe isn't optimal as it uses a lot of global variables, but I'll sort that at some point!
The ADC peripheral as now included in AVR8js 0.18.0
Register description can be found in page 257 / section 24.9 of the datasheet.
Some very quick-and-dirty PoC can be found here (basically, it always returns some random value when reading from the ADC):
AVR8JS Simon Game Demo
(look at the constructor of the
AVRRunner
class, inexecute.ts
).