Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
olivier gillet committed Apr 20, 2011
0 parents commit acf987e
Show file tree
Hide file tree
Showing 64 changed files with 6,137 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Precompiled python modules
*.pyc

# Eagle backups
*.s#?
*.b#?

# Gerber files
*.GBL
*.GBO
*.GBS
*.GML
*.GTL
*.GTO
*.GTP
*.GTS
*.TXT
*.dri
*.gpi
*.pro

# LaTeX compiled file
*.pdf
*.log
*.aux

# Build directory
build/

# OS X crap
.DS_Stor?
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AVRil, a C++ template library for AVR microcontrollers.
Empty file added __init__.py
Empty file.
3 changes: 3 additions & 0 deletions avrlib/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Hal stands for "Hardware access library". It provides an abstraction layer on top of all the features offered by the ATMega644p, with a focus on efficiency (speed and code size) and non-blocking operation.

Naive examples based on the classes in this directory are given in avrlib/examples
Empty file added avrlib/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions avrlib/adc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2009 Olivier Gillet.
//
// Author: Olivier Gillet ([email protected])
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// -----------------------------------------------------------------------------
//
// Interface to the onboard ADC converter, and analog multiplexer.

#include "avrlib/adc.h"

namespace avrlib {

/* static */
uint8_t Adc::admux_value_ = ADC_DEFAULT << 6;

/* static */
uint8_t AdcInputScanner::current_pin_;

/* static */
uint8_t AdcInputScanner::num_inputs_;

/* static */
int16_t AdcInputScanner::state_[8];

} // namespace avrlib
192 changes: 192 additions & 0 deletions avrlib/adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// Copyright 2009 Olivier Gillet.
//
// Author: Olivier Gillet ([email protected])
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// -----------------------------------------------------------------------------
//
// Interface to the onboard ADC converter, and analog multiplexer.

#ifndef AVRLIB_ADC_H_
#define AVRLIB_ADC_H_

#include <avr/io.h>

#include "avrlib/avrlib.h"

namespace avrlib {

enum AdcReference {
ADC_EXTERNAL = 0,
ADC_DEFAULT = 1,
ADC_INTERNAL = 3
};

enum AdcAlignment {
ADC_RIGHT_ALIGNED = 0,
ADC_LEFT_ALIGNED = 1
};

IORegister(ADCSRA);

typedef BitInRegister<ADCSRARegister, ADSC> AdcConvert;
typedef BitInRegister<ADCSRARegister, ADEN> AdcEnabled;

class Adc {
public:
Adc() { }

static inline void Init() {
set_prescaler(7); // 128 -> 156kHz ADC clock.
Enable();
}
static inline void set_prescaler(uint8_t factor) {
ADCSRA = (ADCSRA & ~0x07) | (factor & 0x07);
}
static inline void set_reference(AdcReference reference) {
admux_value_ = (admux_value_ & 0x3f) | (reference << 6);
}
static inline void set_alignemnt(AdcAlignment alignment) {
admux_value_ &= 0xc0;
if (alignment == ADC_LEFT_ALIGNED) {
admux_value_ |= 0x20;
}
}
static inline void Enable() {
AdcEnabled::set();
}
static inline void Disable() {
AdcEnabled::clear();
}
static inline int16_t Read(uint8_t pin) {
StartConversion(pin);
Wait();
return ReadOut();
}

static inline void StartConversion(uint8_t pin) {
ADMUX = admux_value_ | (pin & 0x07);
AdcConvert::set();
}
static inline void Wait() {
while (AdcConvert::value());
}
static inline int16_t ReadOut() {
uint8_t low = ADCL;
uint8_t high = ADCH;
return (high << 8) | low;
}
// Only works when the ADC is left aligned
static inline uint8_t ReadOut8() {
return ADCH;
}

private:
static uint8_t admux_value_;

DISALLOW_COPY_AND_ASSIGN(Adc);
};

// Class that cycles through all the analog pins and read their value. Compared
// to Adc::Read(), this class is wait-free as it doesn't block on the
// ADSC bit value.
class AdcInputScanner {
public:
enum {
buffer_size = 0,
data_size = 16,
};

AdcInputScanner() { }

static void Init() {
Adc::Init();
current_pin_ = 0;
Adc::StartConversion(0);
}

static inline void set_num_inputs(uint8_t num_inputs) {
num_inputs_ = num_inputs;
}

static inline int16_t Read(uint8_t pin) {
return state_[pin];
}

static uint8_t current_pin() {
return current_pin_;
}

static int16_t Sync(uint8_t pin) {
Adc::Wait();
int16_t value = Adc::Read(pin);
Adc::StartConversion(current_pin_);
return value;
}

static void Scan() {
Adc::Wait();
state_[current_pin_] = Adc::ReadOut();
++current_pin_;
if (current_pin_ >= num_inputs_) {
current_pin_ = 0;
}
Adc::StartConversion(current_pin_);
}

private:
static uint8_t current_pin_;
static uint8_t num_inputs_;
static int16_t state_[8];

DISALLOW_COPY_AND_ASSIGN(AdcInputScanner);
};

template<int pin>
struct AnalogInput {
enum {
buffer_size = 0,
data_size = 16,
};
static void Init() { }
static int16_t Read() {
return Adc::Read(pin);
}
};

template<int id>
class MuxedAnalogInput {
public:
enum {
buffer_size = 0,
data_size = 16,
};
static void Init() { }
static int16_t Read() {
return Adc::Read(current_pin_);
}
static void set_pin(uint8_t current_pin) {
current_pin_ = current_pin;
}

private:
static uint8_t current_pin_;
};

/* static */
template<int id>
uint8_t MuxedAnalogInput<id>::current_pin_ = 0;

} // namespace avrlib

#endif // AVRLIB_ADC_H_
98 changes: 98 additions & 0 deletions avrlib/audio_output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2009 Olivier Gillet.
//
// Author: Olivier Gillet ([email protected])
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// -----------------------------------------------------------------------------
//
// Audio output. Supports PWM (through a PwmOutput object) and DAC (through a
// Dac object, for example the one defined in mcp492x.h).

#ifndef AVRLIB_AUDIO_OUTPUT_H_
#define AVRLIB_AUDIO_OUTPUT_H_

#include "avrlib/base.h"
#include "avrlib/avrlib.h"
#include "avrlib/ring_buffer.h"

namespace avrlib {

enum UnderrunPolicy {
EMIT_CLICK = 0,
HOLD_SAMPLE = 1
};

template<typename OutputPort,
uint8_t buffer_size_ = 32,
uint8_t block_size = 16,
UnderrunPolicy underrun_policy = HOLD_SAMPLE>
class AudioOutput {
public:
AudioOutput() { }
enum {
buffer_size = buffer_size_,
data_size = OutputPort::data_size,
};
typedef AudioOutput<OutputPort, buffer_size_, block_size, underrun_policy> Me;
typedef typename DataTypeForSize<data_size>::Type Value;
typedef RingBuffer<Me> OutputBuffer;

static inline void Init() {
OutputPort::Init();
}

static inline void Write(Value v) { while (!writable()); Overwrite(v); }
static inline void Overwrite(Value v) { OutputBuffer::Overwrite(v); }

static inline uint8_t writable() { return OutputBuffer::writable(); }
static inline uint8_t writable_block() {
return OutputBuffer::writable() >= block_size;
}
static inline uint8_t NonBlockingWrite(Value v) {
if (!writable()) {
return 0;
}
Overwrite(v);
return 1;
}

// Called from data emission interrupt.
static inline void EmitSample() {
if (OutputBuffer::readable()) {
OutputPort::Write(Value(OutputBuffer::ImmediateRead()));
} else {
++num_glitches_;
if (underrun_policy == EMIT_CLICK) {
// Introduces clicks to allow underruns to be easily detected.
OutputPort::Write(0);
}
}
}
static inline uint8_t num_glitches() { return num_glitches_; }
static inline void ResetGlitchCounter() { num_glitches_ = 0; }

private:
static uint8_t num_glitches_;

DISALLOW_COPY_AND_ASSIGN(AudioOutput);
};

/* static */
template<typename OutputPort, uint8_t buffer_size_, uint8_t block_size,
UnderrunPolicy underrun_policy>
uint8_t AudioOutput<OutputPort, buffer_size_, block_size,
underrun_policy>::num_glitches_ = 0;

} // namespace avrlib

#endif // AVRLIB_AUDIO_OUTPUT_H_
Loading

0 comments on commit acf987e

Please sign in to comment.