Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
mars
committed
Feb 24, 2012
1 parent
da68045
commit 69f01a2
Showing
7 changed files
with
253 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#ifndef _DISCRETE_CONTROLLER_H_ | ||
#define _DISCRETE_CONTROLLER_H_ | ||
|
||
#define ADC_VALUE_RANGE 4096 | ||
|
||
class DiscreteController { | ||
public: | ||
int8_t range; | ||
int8_t value; | ||
virtual void hasChanged(int8_t v){} | ||
void update(uint16_t x){ | ||
uint16_t m = ADC_VALUE_RANGE / range; | ||
if(x > m) | ||
x -= m/4; | ||
else | ||
x = 0; | ||
int8_t v = (int8_t)(x/m); | ||
if(value == v-1 && (x % m) < range/2) | ||
v = value; // suppress change: reading too close to previous value | ||
if(value != v){ | ||
value = v; | ||
hasChanged(value); | ||
} | ||
} | ||
}; | ||
|
||
#endif /* _DISCRETE_CONTROLLER_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,162 @@ | ||
#include <inttypes.h> | ||
#include <avr/io.h> | ||
#include <avr/interrupt.h> | ||
#include "device.h" | ||
#include "bjorklund.h" | ||
#include "adc_freerunner.h" | ||
#include "DiscreteController.h" | ||
|
||
class Sequence { | ||
public: | ||
uint32_t bits; | ||
uint8_t length; | ||
uint8_t pos; | ||
|
||
void calculate(int fills, int steps){ | ||
Sequence() : pos(0), offset(0) {} | ||
void calculate(int fills){ | ||
Bjorklund algo; | ||
bits = algo.compute(steps, fills); | ||
length = steps; | ||
bits = algo.compute(length, fills); | ||
} | ||
|
||
/* Rotate Left */ | ||
void rol(uint8_t steps){ | ||
// steps = std::min(steps, length); | ||
bits = (bits << steps) | (bits >> (length-steps)); | ||
offset += steps; | ||
} | ||
/* Rotate Right */ | ||
void ror(uint8_t steps){ | ||
bits = (bits >> steps) | (bits << (length-steps)); | ||
offset -= steps; | ||
} | ||
bool next(){ | ||
if(pos >= length) | ||
pos = 0; | ||
return bits & pos++; | ||
} | ||
// private: | ||
uint32_t bits; | ||
uint8_t length; | ||
int8_t offset; | ||
volatile uint8_t pos; | ||
}; | ||
|
||
class GateSequencer : public Sequence { | ||
public: | ||
GateSequencer(int8_t p1, int8_t p2, int8_t p3): | ||
output(p1), trigger(p2), alternate(p3){ | ||
SEQUENCER_TRIGGER_SWITCH_DDR &= ~trigger; | ||
SEQUENCER_TRIGGER_SWITCH_PORT |= trigger; | ||
SEQUENCER_ALTERNATE_SWITCH_DDR &= ~alternate; | ||
SEQUENCER_ALTERNATE_SWITCH_PORT |= alternate; | ||
SEQUENCER_OUTPUT_DDR |= output; | ||
off(); | ||
} | ||
void rise(){ | ||
if(Sequence::next()){ | ||
if(isTriggering()) | ||
on(); | ||
else if(isAlternating()) | ||
toggle(); | ||
} | ||
} | ||
void fall(){ | ||
if(isTriggering()) | ||
off(); | ||
} | ||
inline void on(){ | ||
SEQUENCER_OUTPUT_PORT |= output; | ||
} | ||
inline void off(){ | ||
SEQUENCER_OUTPUT_PORT &= ~output; | ||
} | ||
inline void toggle(){ | ||
SEQUENCER_OUTPUT_PORT ^= output; | ||
} | ||
inline bool isTriggering(){ | ||
return SEQUENCER_TRIGGER_SWITCH_PORT & trigger; | ||
} | ||
inline bool isAlternating(){ | ||
return SEQUENCER_ALTERNATE_SWITCH_PORT & alternate; | ||
} | ||
private: | ||
int8_t output; | ||
int8_t trigger; | ||
int8_t alternate; | ||
}; | ||
|
||
GateSequencer seqA(SEQUENCER_OUTPUT_PIN_A, | ||
SEQUENCER_TRIGGER_SWITCH_PIN_A, | ||
SEQUENCER_ALTERNATE_SWITCH_PIN_A); | ||
|
||
GateSequencer seqB(SEQUENCER_OUTPUT_PIN_B, | ||
SEQUENCER_TRIGGER_SWITCH_PIN_B, | ||
SEQUENCER_ALTERNATE_SWITCH_PIN_B); | ||
|
||
SIGNAL(INT0_vect){ | ||
if(SEQUENCER_CLOCK_PORT & SEQUENCER_CLOCK_PIN){ | ||
seqA.fall(); | ||
seqB.fall(); | ||
}else{ | ||
seqA.rise(); | ||
seqB.rise(); | ||
} | ||
} | ||
|
||
void setup(){ | ||
// define interrupt 0 | ||
EICRA = 1 << ISC00; // trigger int0 on any logical change. | ||
// pulses that last longer than one clock period will generate an interrupt. | ||
EIMSK |= (1 << INT0); | ||
// EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); | ||
// EIMSK |= (1 << INT0); | ||
// define interrupt 1 | ||
// EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); | ||
// EIMSK |= (1 << INT1); | ||
SEQUENCER_CLOCK_DDR &= ~SEQUENCER_CLOCK_PIN; | ||
SEQUENCER_CLOCK_PORT |= SEQUENCER_CLOCK_PIN; // enable pull-up resistor | ||
} | ||
|
||
class StepController : public DiscreteController { | ||
public: | ||
Sequence& seq; | ||
DiscreteController& fills; | ||
StepController(Sequence& s, DiscreteController& f) : seq(s), fills(f) {} | ||
virtual void hasChanged(int8_t steps){ | ||
steps += 8; // range is 8-24 | ||
seq.length = steps; | ||
fills.range = steps-1; | ||
fills.value = -1; // force change | ||
} | ||
}; | ||
|
||
class FillController : public DiscreteController { | ||
public: | ||
Sequence& seq; | ||
FillController(Sequence& s) : seq(s) {} | ||
virtual void hasChanged(int8_t val){ | ||
seq.calculate(val+1); | ||
} | ||
}; | ||
|
||
class RotateController : public DiscreteController { | ||
public: | ||
Sequence& seq; | ||
RotateController(Sequence& s) : seq(s) {} | ||
virtual void hasChanged(int8_t val){ | ||
if(val > seq.offset) | ||
seq.rol(val-seq.offset); | ||
else if(val < seq.offset) | ||
seq.ror(seq.offset-val); | ||
} | ||
}; | ||
|
||
FillController fillA(seqA); | ||
FillController fillB(seqB); | ||
StepController stepA(seqA, fillA); | ||
StepController stepB(seqB, fillB); | ||
RotateController rotateA(seqA); | ||
RotateController rotateB(seqB); | ||
|
||
void loop(){ | ||
stepA.update(getAnalogValue(SEQUENCER_STEP_A_CONTROL)); | ||
stepB.update(getAnalogValue(SEQUENCER_STEP_B_CONTROL)); | ||
fillA.update(getAnalogValue(SEQUENCER_FILL_A_CONTROL)); | ||
fillB.update(getAnalogValue(SEQUENCER_FILL_B_CONTROL)); | ||
rotateA.update(getAnalogValue(SEQUENCER_ROTATE_A_CONTROL)); | ||
rotateB.update(getAnalogValue(SEQUENCER_ROTATE_B_CONTROL)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "adc_freerunner.h" | ||
|
||
#include <avr/interrupt.h> | ||
|
||
uint16_t adc_values[ADC_CHANNELS]; | ||
|
||
void setup_adc(){ | ||
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz | ||
|
||
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC | ||
// ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading | ||
|
||
// ADCSRA |= (1 << ADFR); // Set ADC to Free-Running Mode | ||
ADCSRA |= (1 << ADATE); | ||
|
||
ADCSRA |= (1 << ADEN); // Enable ADC | ||
ADCSRA |= (1 << ADSC); // Start A2D Conversions | ||
|
||
// enable ADC interrupt | ||
ADCSRA |= (1 << ADIE); | ||
|
||
// start interrupts | ||
// sei(); | ||
} | ||
|
||
ISR(ADC_vect) | ||
{ | ||
static uint8_t oldchan; | ||
uint8_t curchan = ADMUX & 7; | ||
|
||
adc_values[oldchan] = ADCL; | ||
adc_values[oldchan] |= ADCH << 8; | ||
|
||
oldchan = curchan; | ||
|
||
if(++curchan == ADC_CHANNELS) | ||
curchan = 0; | ||
|
||
ADMUX = (ADMUX & ~7) | curchan; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef _ANALOGREADER_H_ | ||
#define _ANALOGREADER_H_ | ||
|
||
#include <inttypes.h> | ||
|
||
#define ADC_CHANNELS 6 | ||
|
||
extern uint16_t adc_values[ADC_CHANNELS]; | ||
|
||
void setup_adc(); | ||
|
||
#define getAnalogValue(i) adc_values[i] | ||
|
||
#endif /* _ANALOGREADER_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
#define SEQUENCER_STEP_A_CONTROL 0 | ||
#define SEQUENCER_STEP_B_CONTROL 1 | ||
#define SEQUENCER_FILL_A_CONTROL 2 | ||
#define SEQUENCER_FILL_B_CONTROL 3 | ||
#define SEQUENCER_ROTATE_A_CONTROL 4 | ||
#define SEQUENCER_ROTATE_B_CONTROL 5 | ||
|
||
#define SEQUENCER_CLOCK_PORT PORTD | ||
#define SEQUENCER_CLOCK_DDR DDRD | ||
#define SEQUENCER_CLOCK_PIN _BV(PORTD2) | ||
|
||
#define SEQUENCER_OUTPUT_PORT PORTD | ||
#define SEQUENCER_OUTPUT_DDR DDRD | ||
#define SEQUENCER_OUTPUT_PIN_A _BV(PORTD6) | ||
#define SEQUENCER_OUTPUT_PIN_B _BV(PORTD7) | ||
|
||
#define SEQUENCER_TRIGGER_SWITCH_PORT PORTD | ||
#define SEQUENCER_TRIGGER_SWITCH_DDR DDRD | ||
#define SEQUENCER_TRIGGER_SWITCH_PIN_A _BV(PORTD4) | ||
#define SEQUENCER_TRIGGER_SWITCH_PIN_B _BV(PORTD5) | ||
|
||
#define SEQUENCER_ALTERNATE_SWITCH_PORT PORTB | ||
#define SEQUENCER_ALTERNATE_SWITCH_DDR DDRB | ||
#define SEQUENCER_ALTERNATE_SWITCH_PIN_A _BV(PORTB0) | ||
#define SEQUENCER_ALTERNATE_SWITCH_PIN_B _BV(PORTB1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ void setup(); | |
void loop(); | ||
|
||
int main(void){ | ||
init(); | ||
// init(); | ||
setup(); | ||
for (;;) | ||
loop(); | ||
|