Browse Source

Remove AP_HAL_AVR

Replace everything under AP_HAL_AVR with a README.md file pointing to
the correct branch for AVR support.
master
Lucas De Marchi 9 years ago committed by Andrew Tridgell
parent
commit
c495bdb299
  1. 20
      libraries/AP_HAL_AVR/AP_HAL_AVR.h
  2. 32
      libraries/AP_HAL_AVR/AP_HAL_AVR_Namespace.h
  3. 17
      libraries/AP_HAL_AVR/AP_HAL_AVR_private.h
  4. 86
      libraries/AP_HAL_AVR/AnalogIn.h
  5. 202
      libraries/AP_HAL_AVR/AnalogIn_ADC.cpp
  6. 125
      libraries/AP_HAL_AVR/AnalogIn_Common.cpp
  7. 222
      libraries/AP_HAL_AVR/GPIO.cpp
  8. 58
      libraries/AP_HAL_AVR/GPIO.h
  9. 105
      libraries/AP_HAL_AVR/HAL_AVR_APM1_Class.cpp
  10. 33
      libraries/AP_HAL_AVR/HAL_AVR_APM1_Class.h
  11. 104
      libraries/AP_HAL_AVR/HAL_AVR_APM2_Class.cpp
  12. 33
      libraries/AP_HAL_AVR/HAL_AVR_APM2_Class.h
  13. 323
      libraries/AP_HAL_AVR/I2CDriver.cpp
  14. 49
      libraries/AP_HAL_AVR/I2CDriver.h
  15. 103
      libraries/AP_HAL_AVR/RCInput.h
  16. 177
      libraries/AP_HAL_AVR/RCInput_APM1.cpp
  17. 177
      libraries/AP_HAL_AVR/RCInput_APM2.cpp
  18. 61
      libraries/AP_HAL_AVR/RCOutput.h
  19. 207
      libraries/AP_HAL_AVR/RCOutput_APM1.cpp
  20. 199
      libraries/AP_HAL_AVR/RCOutput_APM2.cpp
  21. 1
      libraries/AP_HAL_AVR/README.md
  22. 52
      libraries/AP_HAL_AVR/SPIDeviceManager_APM1.cpp
  23. 81
      libraries/AP_HAL_AVR/SPIDeviceManager_APM2.cpp
  24. 160
      libraries/AP_HAL_AVR/SPIDevice_SPI0.cpp
  25. 139
      libraries/AP_HAL_AVR/SPIDevice_SPI2.cpp
  26. 124
      libraries/AP_HAL_AVR/SPIDevice_SPI3.cpp
  27. 124
      libraries/AP_HAL_AVR/SPIDevices.h
  28. 38
      libraries/AP_HAL_AVR/SPIDriver.h
  29. 277
      libraries/AP_HAL_AVR/Scheduler.cpp
  30. 77
      libraries/AP_HAL_AVR/Scheduler.h
  31. 157
      libraries/AP_HAL_AVR/Scheduler_Timer.cpp
  32. 80
      libraries/AP_HAL_AVR/Semaphores.cpp
  33. 23
      libraries/AP_HAL_AVR/Semaphores.h
  34. 31
      libraries/AP_HAL_AVR/Storage.cpp
  35. 17
      libraries/AP_HAL_AVR/Storage.h
  36. 313
      libraries/AP_HAL_AVR/UARTDriver.cpp
  37. 208
      libraries/AP_HAL_AVR/UARTDriver.h
  38. 15
      libraries/AP_HAL_AVR/Util.h
  39. 92
      libraries/AP_HAL_AVR/examples/ArduCopterLibs/ArduCopterLibs.cpp
  40. 2
      libraries/AP_HAL_AVR/examples/ArduCopterLibs/Makefile
  41. 36
      libraries/AP_HAL_AVR/examples/ArduCopterLibs/make.inc
  42. 0
      libraries/AP_HAL_AVR/examples/ArduCopterLibs/nocore.inoflag
  43. 70
      libraries/AP_HAL_AVR/examples/ArduPlaneLibs/ArduPlaneLibs.cpp
  44. 2
      libraries/AP_HAL_AVR/examples/ArduPlaneLibs/Makefile
  45. 32
      libraries/AP_HAL_AVR/examples/ArduPlaneLibs/make.inc
  46. 0
      libraries/AP_HAL_AVR/examples/ArduPlaneLibs/nocore.inoflag
  47. 54
      libraries/AP_HAL_AVR/examples/Blink/Blink.cpp
  48. 1
      libraries/AP_HAL_AVR/examples/Blink/Makefile
  49. 5
      libraries/AP_HAL_AVR/examples/Blink/make.inc
  50. 0
      libraries/AP_HAL_AVR/examples/Blink/nocore.inoflag
  51. 46
      libraries/AP_HAL_AVR/examples/Console/Console.cpp
  52. 2
      libraries/AP_HAL_AVR/examples/Console/Makefile
  53. 5
      libraries/AP_HAL_AVR/examples/Console/make.inc
  54. 0
      libraries/AP_HAL_AVR/examples/Console/nocore.inoflag
  55. 57
      libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/I2CDriver_HMC5883L.cpp
  56. 1
      libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/Makefile
  57. 5
      libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/make.inc
  58. 0
      libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/nocore.inoflag
  59. 84
      libraries/AP_HAL_AVR/examples/LCDTest/LCDTest.cpp
  60. 313
      libraries/AP_HAL_AVR/examples/LCDTest/LCrystal.cpp
  61. 106
      libraries/AP_HAL_AVR/examples/LCDTest/LCrystal.h
  62. 1
      libraries/AP_HAL_AVR/examples/LCDTest/Makefile
  63. 7
      libraries/AP_HAL_AVR/examples/LCDTest/README
  64. 4
      libraries/AP_HAL_AVR/examples/LCDTest/make.inc
  65. 0
      libraries/AP_HAL_AVR/examples/LCDTest/nobuild.txt
  66. 0
      libraries/AP_HAL_AVR/examples/LCDTest/nocore.inoflag
  67. 1
      libraries/AP_HAL_AVR/examples/RCInputTest/Makefile
  68. 69
      libraries/AP_HAL_AVR/examples/RCInputTest/RCInputTest.cpp
  69. 5
      libraries/AP_HAL_AVR/examples/RCInputTest/make.inc
  70. 0
      libraries/AP_HAL_AVR/examples/RCInputTest/nocore.inoflag
  71. 1
      libraries/AP_HAL_AVR/examples/RCJitterTest/Makefile
  72. 121
      libraries/AP_HAL_AVR/examples/RCJitterTest/RCJitterTest.cpp
  73. 5
      libraries/AP_HAL_AVR/examples/RCJitterTest/make.inc
  74. 0
      libraries/AP_HAL_AVR/examples/RCJitterTest/nocore.inoflag
  75. 1
      libraries/AP_HAL_AVR/examples/RCPassthroughTest/Makefile
  76. 101
      libraries/AP_HAL_AVR/examples/RCPassthroughTest/RCPassthroughTest.cpp
  77. 5
      libraries/AP_HAL_AVR/examples/RCPassthroughTest/make.inc
  78. 0
      libraries/AP_HAL_AVR/examples/RCPassthroughTest/nocore.inoflag
  79. 81
      libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/MPU6000.h
  80. 1
      libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/Makefile
  81. 131
      libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/SPIDriver_MPU6000.cpp
  82. 5
      libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/make.inc
  83. 0
      libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/nocore.inoflag
  84. 1
      libraries/AP_HAL_AVR/examples/Scheduler/Makefile
  85. 113
      libraries/AP_HAL_AVR/examples/Scheduler/Scheduler.cpp
  86. 4
      libraries/AP_HAL_AVR/examples/Scheduler/make.inc
  87. 0
      libraries/AP_HAL_AVR/examples/Scheduler/nobuild.txt
  88. 0
      libraries/AP_HAL_AVR/examples/Scheduler/nocore.inoflag
  89. 1
      libraries/AP_HAL_AVR/examples/Semaphore/Makefile
  90. 118
      libraries/AP_HAL_AVR/examples/Semaphore/Semaphore.cpp
  91. 4
      libraries/AP_HAL_AVR/examples/Semaphore/make.inc
  92. 0
      libraries/AP_HAL_AVR/examples/Semaphore/nobuild.txt
  93. 0
      libraries/AP_HAL_AVR/examples/Semaphore/nocore.inoflag
  94. 1
      libraries/AP_HAL_AVR/examples/Storage/Makefile
  95. 51
      libraries/AP_HAL_AVR/examples/Storage/Storage.cpp
  96. 5
      libraries/AP_HAL_AVR/examples/Storage/make.inc
  97. 0
      libraries/AP_HAL_AVR/examples/Storage/nocore.inoflag
  98. 2
      libraries/AP_HAL_AVR/examples/UARTDriver/Makefile
  99. 58
      libraries/AP_HAL_AVR/examples/UARTDriver/UARTDriver.cpp
  100. 5
      libraries/AP_HAL_AVR/examples/UARTDriver/make.inc
  101. Some files were not shown because too many files have changed in this diff Show More

20
libraries/AP_HAL_AVR/AP_HAL_AVR.h

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
#ifndef __AP_HAL_AVR_H__
#define __AP_HAL_AVR_H__
#include <AP_HAL/AP_HAL.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2
/**
* This module exports AP_HAL::HAL instances only.
* All internal drivers must conform to AP_HAL interfaces
* and not expose implementation details.
*/
#include "HAL_AVR_APM1_Class.h"
#include "HAL_AVR_APM2_Class.h"
#endif // CONFIG_HAL_BOARD
#endif // __AP_HAL_AVR_H__

32
libraries/AP_HAL_AVR/AP_HAL_AVR_Namespace.h

@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
#ifndef __AP_HAL_AVR_NAMESPACE_H__
#define __AP_HAL_AVR_NAMESPACE_H__
namespace AP_HAL_AVR {
class HAL_AVR;
class AVRUARTDriver;
class AVRI2CDriver;
class APM1SPIDeviceManager;
class APM2SPIDeviceManager;
class AVRSPI0DeviceDriver;
class AVRSPI2DeviceDriver;
class AVRSPI3DeviceDriver;
class ADCSource;
class AVRAnalogIn;
class AVREEPROMStorage;
class AVRGPIO;
class AVRDigitalSource;
class APM1RCInput;
class APM2RCInput;
class APM1RCOutput;
class APM2RCOutput;
class AVRScheduler;
class AVRTimer;
class AVRSemaphore;
class ISRRegistry;
class AVRUtil;
}
#endif //__AP_HAL_AVR_NAMESPACE_H__

17
libraries/AP_HAL_AVR/AP_HAL_AVR_private.h

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
#ifndef __AP_HAL_AVR_PRIVATE_H__
#define __AP_HAL_AVR_PRIVATE_H__
#include "UARTDriver.h"
#include "I2CDriver.h"
#include "SPIDriver.h"
#include "AnalogIn.h"
#include "Storage.h"
#include "GPIO.h"
#include "RCInput.h"
#include "RCOutput.h"
#include "Scheduler.h"
#include "Util.h"
#include "utility/ISRRegistry.h"
#endif // __AP_HAL_AVR_PRIVATE_H__

86
libraries/AP_HAL_AVR/AnalogIn.h

@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
#ifndef __AP_HAL_AVR_ANALOG_IN_H__
#define __AP_HAL_AVR_ANALOG_IN_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#define AVR_INPUT_MAX_CHANNELS 12
class AP_HAL_AVR::ADCSource : public AP_HAL::AnalogSource {
public:
friend class AP_HAL_AVR::AVRAnalogIn;
/* pin designates the ADC input number, or when == AVR_ANALOG_PIN_VCC,
* board vcc */
ADCSource(uint8_t pin);
/* implement AnalogSource virtual api: */
float read_average();
float read_latest();
void set_pin(uint8_t p);
float voltage_average();
float voltage_latest();
float voltage_average_ratiometric();
void set_stop_pin(uint8_t p);
void set_settle_time(uint16_t settle_time_ms);
/* implementation specific interface: */
/* new_sample(): called with value of ADC measurments, from interrput */
void new_sample(uint16_t);
/* setup_read(): called to setup ADC registers for next measurment,
* from interrupt */
void setup_read();
/* stop_read(): called to stop device measurement */
void stop_read();
/* reading_settled(): called to check if we have read for long enough */
bool reading_settled();
/* read_average: called to calculate and clear the internal average.
* implements read_average(), unscaled. */
float _read_average();
int16_t get_pin() { return _pin; };
private:
/* following three are used from both an interrupt and normal thread */
volatile uint8_t _sum_count;
volatile uint16_t _sum;
volatile uint16_t _latest;
float _last_average;
/* _pin designates the ADC input mux for the sample */
uint8_t _pin;
/* _stop_pin designates a digital pin to use for
enabling/disabling the analog device */
uint8_t _stop_pin;
uint16_t _settle_time_ms;
uint32_t _read_start_time_ms;
};
/* AVRAnalogIn : a concrete class providing the implementations of the
* timer event and the AP_HAL::AnalogIn interface */
class AP_HAL_AVR::AVRAnalogIn : public AP_HAL::AnalogIn {
public:
AVRAnalogIn();
void init(void* ap_hal_scheduler);
AP_HAL::AnalogSource* channel(int16_t n);
float board_voltage(void);
protected:
ADCSource* _create_channel(int16_t num);
void _register_channel(ADCSource*);
void _timer_event(void);
ADCSource* _channels[AVR_INPUT_MAX_CHANNELS];
int16_t _num_channels;
int16_t _active_channel;
uint16_t _channel_repeat_count;
private:
ADCSource _vcc;
};
#endif // __AP_HAL_AVR_ANALOG_IN_H__

202
libraries/AP_HAL_AVR/AnalogIn_ADC.cpp

@ -1,202 +0,0 @@ @@ -1,202 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include "AnalogIn.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
ADCSource::ADCSource(uint8_t pin) :
_sum_count(0),
_sum(0),
_last_average(0),
_pin(ANALOG_INPUT_NONE),
_stop_pin(ANALOG_INPUT_NONE),
_settle_time_ms(0)
{
set_pin(pin);
}
float ADCSource::read_average() {
if (_pin == ANALOG_INPUT_BOARD_VCC) {
uint16_t v = (uint16_t) _read_average();
return 1126400UL / v;
} else {
return _read_average();
}
}
float ADCSource::read_latest() {
uint8_t sreg = SREG;
cli();
uint16_t latest = _latest;
SREG = sreg;
if (_pin == ANALOG_INPUT_BOARD_VCC) {
return 1126400UL / latest;
} else {
return latest;
}
}
/*
return voltage from 0.0 to 5.0V, scaled to Vcc
*/
float ADCSource::voltage_average(void)
{
float vcc_mV = hal.analogin->channel(ANALOG_INPUT_BOARD_VCC)->read_average();
float v = read_average();
// constrain Vcc reading so that a bad Vcc doesn't throw off
// the reading of other sources too badly
if (vcc_mV < 4000) {
vcc_mV = 4000;
} else if (vcc_mV > 6000) {
vcc_mV = 6000;
}
return v * vcc_mV * 9.765625e-7; // 9.765625e-7 = 1.0/(1024*1000)
}
/*
return voltage from 0.0 to 5.0V, scaled to Vcc
*/
float ADCSource::voltage_latest(void)
{
if (_pin == ANALOG_INPUT_BOARD_VCC) {
return read_latest() * 0.001f;
}
float vcc_mV = hal.analogin->channel(ANALOG_INPUT_BOARD_VCC)->read_average();
float v = read_latest();
// constrain Vcc reading so that a bad Vcc doesn't throw off
// the reading of other sources too badly
if (vcc_mV < 4000) {
vcc_mV = 4000;
} else if (vcc_mV > 6000) {
vcc_mV = 6000;
}
return v * vcc_mV * 9.765625e-7; // 9.765625e-7 = 1.0/(1024*1000)
}
/*
return voltage from 0.0 to 5.0V, assuming a ratiometric sensor. This
means the result is really a pseudo-voltage, that assumes the supply
voltage is exactly 5.0V.
*/
float ADCSource::voltage_average_ratiometric(void)
{
float v = read_average();
return v * (5.0f / 1023.0f);
}
void ADCSource::set_pin(uint8_t pin) {
if (pin != _pin) {
// ensure the pin is marked as an INPUT pin
if (pin != ANALOG_INPUT_NONE && pin != ANALOG_INPUT_BOARD_VCC) {
int8_t dpin = hal.gpio->analogPinToDigitalPin(pin);
if (dpin != -1) {
// enable as input without a pull-up. This gives the
// best results for our analog sensors
hal.gpio->pinMode(dpin, HAL_GPIO_INPUT);
hal.gpio->write(dpin, 0);
}
}
uint8_t sreg = SREG;
cli();
_sum = 0;
_sum_count = 0;
_last_average = 0;
_latest = 0;
_pin = pin;
SREG = sreg;
}
}
void ADCSource::set_stop_pin(uint8_t pin) {
_stop_pin = pin;
}
void ADCSource::set_settle_time(uint16_t settle_time_ms)
{
_settle_time_ms = settle_time_ms;
}
/* read_average is called from the normal thread (not an interrupt). */
float ADCSource::_read_average() {
uint16_t sum;
uint8_t sum_count;
if (_sum_count == 0) {
// avoid blocking waiting for new samples
return _last_average;
}
/* Read and clear in a critical section */
uint8_t sreg = SREG;
cli();
sum = _sum;
sum_count = _sum_count;
_sum = 0;
_sum_count = 0;
SREG = sreg;
float avg = sum / (float) sum_count;
_last_average = avg;
return avg;
}
void ADCSource::setup_read() {
if (_stop_pin != ANALOG_INPUT_NONE) {
uint8_t digital_pin = hal.gpio->analogPinToDigitalPin(_stop_pin);
hal.gpio->pinMode(digital_pin, HAL_GPIO_OUTPUT);
hal.gpio->write(digital_pin, 1);
}
if (_settle_time_ms != 0) {
_read_start_time_ms = hal.scheduler->millis();
}
if (_pin == ANALOG_INPUT_BOARD_VCC) {
ADCSRB = (ADCSRB & ~(1 << MUX5));
ADMUX = _BV(REFS0)|_BV(MUX4)|_BV(MUX3)|_BV(MUX2)|_BV(MUX1);
} else if (_pin == ANALOG_INPUT_NONE) {
/* noop */
} else {
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((_pin >> 3) & 0x01) << MUX5);
ADMUX = _BV(REFS0) | (_pin & 0x07);
}
}
void ADCSource::stop_read() {
if (_stop_pin != ANALOG_INPUT_NONE) {
uint8_t digital_pin = hal.gpio->analogPinToDigitalPin(_stop_pin);
hal.gpio->pinMode(digital_pin, HAL_GPIO_OUTPUT);
hal.gpio->write(digital_pin, 0);
}
}
bool ADCSource::reading_settled()
{
if (_settle_time_ms != 0 && (hal.scheduler->millis() - _read_start_time_ms) < _settle_time_ms) {
return false;
}
return true;
}
/* new_sample is called from an interrupt. It always has access to
* _sum and _sum_count. Lock out the interrupts briefly with
* cli/sei to read these variables from outside an interrupt. */
void ADCSource::new_sample(uint16_t sample) {
_sum += sample;
_latest = sample;
if (_sum_count >= 63) {
_sum >>= 1;
_sum_count = 32;
} else {
_sum_count++;
}
}
#endif

125
libraries/AP_HAL_AVR/AnalogIn_Common.cpp

@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AnalogIn.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
/* CHANNEL_READ_REPEAT: how many reads on a channel before using the value.
* This seems to be determined empirically */
#define CHANNEL_READ_REPEAT 2
AVRAnalogIn::AVRAnalogIn() :
_vcc(ADCSource(ANALOG_INPUT_BOARD_VCC))
{}
void AVRAnalogIn::init(void* machtnichts)
{
/* Register AVRAnalogIn::_timer_event with the scheduler. */
hal.scheduler->register_timer_process(FUNCTOR_BIND_MEMBER(&AVRAnalogIn::_timer_event, void));
/* Register each private channel with AVRAnalogIn. */
_register_channel(&_vcc);
}
ADCSource* AVRAnalogIn::_create_channel(int16_t chnum) {
ADCSource *ch = new ADCSource(chnum);
_register_channel(ch);
return ch;
}
void AVRAnalogIn::_register_channel(ADCSource* ch) {
if (_num_channels >= AVR_INPUT_MAX_CHANNELS) {
for(;;) {
hal.console->print_P(PSTR(
"Error: AP_HAL_AVR::AVRAnalogIn out of channels\r\n"));
hal.scheduler->delay(1000);
}
}
_channels[_num_channels] = ch;
/* Need to lock to increment _num_channels as it is used
* by the interrupt to access _channels */
uint8_t sreg = SREG;
cli();
_num_channels++;
SREG = sreg;
if (_num_channels == 1) {
/* After registering the first channel, we can enable the ADC */
PRR0 &= ~_BV(PRADC);
ADCSRA |= _BV(ADEN);
}
}
void AVRAnalogIn::_timer_event(void)
{
if (_channels[_active_channel]->_pin == ANALOG_INPUT_NONE) {
_channels[_active_channel]->new_sample(0);
goto next_channel;
}
if (ADCSRA & _BV(ADSC)) {
/* ADC Conversion is still running - this should not happen, as we
* are called at 1khz. */
return;
}
if (_num_channels == 0) {
/* No channels are registered - nothing to be done. */
return;
}
_channel_repeat_count++;
if (_channel_repeat_count < CHANNEL_READ_REPEAT ||
!_channels[_active_channel]->reading_settled()) {
/* Start a new conversion, throw away the current conversion */
ADCSRA |= _BV(ADSC);
return;
}
_channel_repeat_count = 0;
/* Read the conversion registers. */
{
uint8_t low = ADCL;
uint8_t high = ADCH;
uint16_t sample = low | (((uint16_t)high) << 8);
/* Give the active channel a new sample */
_channels[_active_channel]->new_sample( sample );
}
next_channel:
/* stop the previous channel, if a stop pin is defined */
_channels[_active_channel]->stop_read();
/* Move to the next channel */
_active_channel = (_active_channel + 1) % _num_channels;
/* Setup the next channel's conversion */
_channels[_active_channel]->setup_read();
/* Start conversion */
ADCSRA |= _BV(ADSC);
}
AP_HAL::AnalogSource* AVRAnalogIn::channel(int16_t ch)
{
if (ch == ANALOG_INPUT_BOARD_VCC) {
return &_vcc;
} else {
return _create_channel(ch);
}
}
/*
return board voltage in volts
*/
float AVRAnalogIn::board_voltage(void)
{
return _vcc.voltage_latest();
}
#endif

222
libraries/AP_HAL_AVR/GPIO.cpp

@ -1,222 +0,0 @@ @@ -1,222 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/interrupt.h>
#include <avr/io.h>
#include "utility/pins_arduino_mega.h"
#include "GPIO.h"
using namespace AP_HAL_AVR;
AP_HAL::Proc AVRGPIO::_interrupt_6 = NULL;
SIGNAL(INT6_vect) {
if (AVRGPIO::_interrupt_6) {
AVRGPIO::_interrupt_6();
}
}
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
#define analogInPinToBit(P) (P)
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
void AVRGPIO::pinMode(uint8_t pin, uint8_t mode) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
if (mode == HAL_GPIO_INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
int8_t AVRGPIO::analogPinToDigitalPin(uint8_t pin)
{
return analogInputToDigitalPin(pin);
}
uint8_t AVRGPIO::read(uint8_t pin) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return 0;
if (*portInputRegister(port) & bit) return 1;
return 0;
}
void AVRGPIO::write(uint8_t pin, uint8_t value) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (value == 0) {
*out &= ~bit;
} else {
*out |= bit;
}
SREG = oldSREG;
}
void AVRGPIO::toggle(uint8_t pin) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
/* Implement GPIO Interrupt 6, used for MPU6000 data ready on APM2. */
bool AVRGPIO::attach_interrupt(
uint8_t interrupt_num, AP_HAL::Proc proc, uint8_t mode) {
/* Mode is to set the ISCn0 and ISCn1 bits.
* These correspond to the GPIO_INTERRUPT_ defs in AP_HAL.h */
if (!((mode == HAL_GPIO_INTERRUPT_LOW)||
(mode == HAL_GPIO_INTERRUPT_HIGH)||
(mode == HAL_GPIO_INTERRUPT_FALLING)||
(mode == HAL_GPIO_INTERRUPT_RISING))) return false;
if (interrupt_num == 6) {
uint8_t oldSREG = SREG;
cli();
_interrupt_6 = proc;
/* Set the ISC60 and ICS61 bits in EICRB according to the value
* of mode. */
EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
EIMSK |= (1 << INT6);
SREG = oldSREG;
return true;
} else {
return false;
}
}
AP_HAL::DigitalSource* AVRGPIO::channel(uint16_t pin) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return NULL;
return new AVRDigitalSource(bit, port);
}
void AVRDigitalSource::mode(uint8_t output) {
const uint8_t bit = _bit;
const uint8_t port = _port;
volatile uint8_t* reg;
reg = portModeRegister(port);
if (output == HAL_GPIO_INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
uint8_t AVRDigitalSource::read() {
const uint8_t bit = _bit;
const uint8_t port = _port;
if (*portInputRegister(port) & bit) return 1;
return 0;
}
void AVRDigitalSource::write(uint8_t value) {
const uint8_t bit = _bit;
const uint8_t port = _port;
volatile uint8_t* out;
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (value == 0) {
*out &= ~bit;
} else {
*out |= bit;
}
SREG = oldSREG;
}
void AVRDigitalSource::toggle() {
const uint8_t bit = _bit;
const uint8_t port = _port;
volatile uint8_t* out;
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
/*
return true when USB is connected
*/
bool AVRGPIO::usb_connected(void)
{
#if HAL_GPIO_USB_MUX_PIN != -1
pinMode(HAL_GPIO_USB_MUX_PIN, HAL_GPIO_INPUT);
return !read(HAL_GPIO_USB_MUX_PIN);
#else
return false;
#endif
}
#endif

58
libraries/AP_HAL_AVR/GPIO.h

@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
#ifndef __AP_HAL_AVR_GPIO_H__
#define __AP_HAL_AVR_GPIO_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
# define HAL_GPIO_A_LED_PIN 37
# define HAL_GPIO_B_LED_PIN 36
# define HAL_GPIO_C_LED_PIN 35
# define HAL_GPIO_LED_ON HIGH
# define HAL_GPIO_LED_OFF LOW
# define HAL_GPIO_USB_MUX_PIN -1
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM2
# define HAL_GPIO_A_LED_PIN 27
# define HAL_GPIO_B_LED_PIN 26
# define HAL_GPIO_C_LED_PIN 25
# define HAL_GPIO_LED_ON LOW
# define HAL_GPIO_LED_OFF HIGH
# define HAL_GPIO_USB_MUX_PIN 23
#endif
class AP_HAL_AVR::AVRDigitalSource : public AP_HAL::DigitalSource {
public:
AVRDigitalSource(uint8_t bit, uint8_t port) : _bit(bit), _port(port) {}
void mode(uint8_t output);
uint8_t read();
void write(uint8_t value);
void toggle();
private:
const uint8_t _bit;
const uint8_t _port;
};
class AP_HAL_AVR::AVRGPIO : public AP_HAL::GPIO {
public:
AVRGPIO() {}
void init() {}
void pinMode(uint8_t pin, uint8_t output);
int8_t analogPinToDigitalPin(uint8_t pin);
uint8_t read(uint8_t pin);
void write(uint8_t pin, uint8_t value);
void toggle(uint8_t pin);
AP_HAL::DigitalSource* channel(uint16_t);
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc proc,
uint8_t mode);
/* return true if USB cable is connected */
bool usb_connected(void);
/* private-ish: only to be used from the appropriate interrupt */
static AP_HAL::Proc _interrupt_6;
};
#endif // __AP_HAL_AVR_GPIO_H__

105
libraries/AP_HAL_AVR/HAL_AVR_APM1_Class.cpp

@ -1,105 +0,0 @@ @@ -1,105 +0,0 @@
#include <AP_HAL/AP_HAL.h>
/* To save linker space, we need to make sure the HAL_AVR_APM1 class
* is built iff we are building for HAL_BOARD_APM1. These defines must
* wrap the whole HAL_AVR_APM1 class declaration and definition. */
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
#include <assert.h>
#include "AP_HAL_AVR.h"
#include "AP_HAL_AVR_private.h"
#include "HAL_AVR_APM1_Class.h"
using namespace AP_HAL;
using namespace AP_HAL_AVR;
AVRUARTDriverISRs(0);
AVRUARTDriverISRs(1);
AVRUARTDriverISRs(3);
AVRUARTDriverInstance(avrUart0Driver, 0);
AVRUARTDriverInstance(avrUart1Driver, 1);
AVRUARTDriverInstance(avrUart3Driver, 3);
static AVRSemaphore i2cSemaphore;
static AVRI2CDriver avrI2CDriver(&i2cSemaphore);
static APM1SPIDeviceManager apm1SPIDriver;
static AVRAnalogIn avrAnalogIn;
static AVREEPROMStorage avrEEPROMStorage;
static AVRGPIO avrGPIO;
static APM1RCInput apm1RCInput;
static APM1RCOutput apm1RCOutput;
static AVRScheduler avrScheduler;
static AVRUtil avrUtil;
static ISRRegistry isrRegistry;
/* On APM1 the physical UART2 is used for SPI. */
HAL_AVR_APM1::HAL_AVR_APM1() :
AP_HAL::HAL(
&avrUart0Driver, /* phys UART0 -> uartA */
&avrUart1Driver, /* phys UART1 -> uartB */
&avrUart3Driver, /* phys UART3 -> uartC */
NULL, /* no uartD */
NULL, /* no uartE */
&avrI2CDriver,
NULL, /* only 1 i2c */
NULL, /* only 1 i2c */
&apm1SPIDriver,
&avrAnalogIn,
&avrEEPROMStorage,
&avrUart0Driver,
&avrGPIO,
&apm1RCInput,
&apm1RCOutput,
&avrScheduler,
&avrUtil )
{}
void HAL_AVR_APM1::run(int argc, char* const argv[], Callbacks* callbacks) const
{
assert(callbacks);
scheduler->init((void*)&isrRegistry);
/* uartA is the serial port used for the console, so lets make sure
* it is initialized at boot */
uartA->begin(115200);
/* The AVR RCInput drivers take an AP_HAL_AVR::ISRRegistry*
* as the init argument */
rcin->init((void*)&isrRegistry);
rcout->init(NULL);
spi->init(NULL);
i2c->begin();
i2c->setTimeout(100);
analogin->init(NULL);
/* Enable the pullups on the RX pins of the 3 UARTs This is important when
* the RX line is high-Z: capacitive coupling between input and output pins
* can cause bytes written to show up as an input. Occasionally this causes
* us to detect a phantom GPS by seeing our own outgoing config message.
* PE0 : RX0 (uartA)
* PD2 : RX1 (uartB)
* PJ0 : RX3 (uartC)
*/
PORTE |= _BV(0);
PORTD |= _BV(2);
PORTJ |= _BV(0);
callbacks->setup();
scheduler->system_initialized();
for (;;) {
callbacks->loop();
}
}
const AP_HAL::HAL& AP_HAL::get_HAL() {
static const HAL_AVR_APM1 hal;
return hal;
}
#endif // CONFIG_HAL_BOARD == HAL_BOARD_APM1

33
libraries/AP_HAL_AVR/HAL_AVR_APM1_Class.h

@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
#ifndef __AP_HAL_AVR_APM1_HAL_AVR_H__
#define __AP_HAL_AVR_APM1_HAL_AVR_H__
#include <AP_HAL/AP_HAL.h>
/* To save linker space, we need to make sure the HAL_AVR_APM1 class
* is built iff we are building for HAL_BOARD_APM1. These defines must
* wrap the whole HAL_AVR_APM1 class declaration and definition. */
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
#include "AP_HAL_AVR.h"
#include "AP_HAL_AVR_Namespace.h"
/**
* HAL_AVR_APM1 class derives from HAL but provides a constructor to use the
* correct drivers for the APM1, and an init to set them all up properly.
*/
class HAL_AVR_APM1 : public AP_HAL::HAL {
public:
HAL_AVR_APM1();
void run(int argc, char* const argv[], Callbacks* callbacks) const override;
};
/**
* Static instance exported here, defined in the Class.cpp file
*/
extern const HAL_AVR_APM1 AP_HAL_AVR_APM1;
#endif // CONFIG_HAL_BOARD == HAL_BOARD_APM1
#endif // __AP_HAL_AVR_APM1_HAL_AVR_H__

104
libraries/AP_HAL_AVR/HAL_AVR_APM2_Class.cpp

@ -1,104 +0,0 @@ @@ -1,104 +0,0 @@
#include <AP_HAL/AP_HAL.h>
/* To save linker space, we need to make sure the HAL_AVR_APM2 class
* is built iff we are building for HAL_BOARD_APM2. These defines must
* wrap the whole HAL_AVR_APM2 class declaration and definition. */
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
#include <assert.h>
#include "AP_HAL_AVR.h"
#include "AP_HAL_AVR_private.h"
#include "HAL_AVR_APM2_Class.h"
using namespace AP_HAL;
using namespace AP_HAL_AVR;
AVRUARTDriverISRs(0);
AVRUARTDriverISRs(1);
AVRUARTDriverISRs(2);
AVRUARTDriverInstance(avrUart0Driver, 0);
AVRUARTDriverInstance(avrUart1Driver, 1);
AVRUARTDriverInstance(avrUart2Driver, 2);
static AVRSemaphore i2cSemaphore;
static AVRI2CDriver avrI2CDriver(&i2cSemaphore);
static APM2SPIDeviceManager apm2SPIDriver;
static AVRAnalogIn avrAnalogIn;
static AVREEPROMStorage avrEEPROMStorage;
static AVRGPIO avrGPIO;
static APM2RCInput apm2RCInput;
static APM2RCOutput apm2RCOutput;
static AVRScheduler avrScheduler;
static AVRUtil avrUtil;
static ISRRegistry isrRegistry;
HAL_AVR_APM2::HAL_AVR_APM2() :
AP_HAL::HAL(
&avrUart0Driver, /* phys UART0 -> uartA */
&avrUart1Driver, /* phys UART1 -> uartB */
&avrUart2Driver, /* phys UART2 -> uartC */
NULL, /* no uartD */
NULL, /* no uartE */
&avrI2CDriver,
NULL, /* only one i2c */
NULL, /* only one i2c */
&apm2SPIDriver,
&avrAnalogIn,
&avrEEPROMStorage,
&avrUart0Driver,
&avrGPIO,
&apm2RCInput,
&apm2RCOutput,
&avrScheduler,
&avrUtil )
{}
void HAL_AVR_APM2::run(int argc, char* const argv[], Callbacks* callbacks) const
{
assert(callbacks);
scheduler->init((void*)&isrRegistry);
/* uartA is the serial port used for the console, so lets make sure
* it is initialized at boot */
uartA->begin(115200, 128, 128);
/* The AVR RCInput drivers take an AP_HAL_AVR::ISRRegistry*
* as the init argument */
rcin->init((void*)&isrRegistry);
rcout->init(NULL);
spi->init(NULL);
i2c->begin();
i2c->setTimeout(100);
analogin->init(NULL);
/* Enable the pullups on the RX pins of the 3 UARTs This is important when
* the RX line is high-Z: capacitive coupling between input and output pins
* can cause bytes written to show up as an input. Occasionally this causes
* us to detect a phantom GPS by seeing our own outgoing config message.
* PE0 : RX0 (uartA)
* PD2 : RX1 (uartB)
* PH0 : RX2 (uartC)
*/
PORTE |= _BV(0);
PORTD |= _BV(2);
PORTH |= _BV(0);
callbacks->setup();
scheduler->system_initialized();
for (;;) {
callbacks->loop();
}
}
const AP_HAL::HAL& AP_HAL::get_HAL() {
static const HAL_AVR_APM2 hal;
return hal;
}
#endif // CONFIG_HAL_BOARD == HAL_BOARD_APM2

33
libraries/AP_HAL_AVR/HAL_AVR_APM2_Class.h

@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
#ifndef __AP_HAL_AVR_APM2_HAL_AVR_H__
#define __AP_HAL_AVR_APM2_HAL_AVR_H__
#include <AP_HAL/AP_HAL.h>
/* To save linker space, we need to make sure the HAL_AVR_APM2 class
* is built iff we are building for HAL_BOARD_APM2. These defines must
* wrap the whole HAL_AVR_APM2 class declaration and definition. */
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
#include "AP_HAL_AVR.h"
#include "AP_HAL_AVR_Namespace.h"
/**
* HAL_AVR_APM2 class derives from HAL but provides an AVR-specific
* init method.
*/
class HAL_AVR_APM2 : public AP_HAL::HAL {
public:
HAL_AVR_APM2();
void run(int argc, char* const argv[], Callbacks* callbacks) const override;
};
/**
* Static instance exported here, defined in the Class.cpp file
*/
extern const HAL_AVR_APM2 AP_HAL_AVR_APM2;
#endif // CONFIG_HAL_BOARD == HAL_BOARD_APM2
#endif // __AP_HAL_AVR_APM2_HAL_AVR_H__

323
libraries/AP_HAL_AVR/I2CDriver.cpp

@ -1,323 +0,0 @@ @@ -1,323 +0,0 @@
/*
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/>.
*/
/*
* AP_HAL_AVR I2C driver. derived from:
* I2C.cpp - I2C library
* Copyright (c) 2011 Wayne Truchsess. All right reserved.
* Rev 2.0 - September 19th, 2011
* - Added support for timeout function to prevent
* and recover from bus lockup (thanks to PaulS
* and CrossRoads on the Arduino forum)
* - Changed return type for stop() from void to
* uint8_t to handle timeOut function
* Rev 1.0 - August 8th, 2011
*
* This is a modified version of the Arduino Wire/TWI
* library. Functions were rewritten to provide more functionality
* and also the use of Repeated Start. Some I2C devices will not
* function correctly without the use of a Repeated Start. The
* initial version of this library only supports the Master.
*
*/
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "I2CDriver.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
#ifndef F_CPU
#define CPU_FREQ 16000000L
#else
#define CPU_FREQ F_CPU
#endif
#define START 0x08
#define REPEATED_START 0x10
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define MR_SLA_ACK 0x40
#define MR_DATA_ACK 0x50
#define MR_DATA_NACK 0x58
#define TWI_STATUS (TWSR & 0xF8)
#define SLA_W(address) (address << 1)
#define SLA_R(address) ((address << 1) + 0x01)
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
void AVRI2CDriver::begin() {
// activate internal pull-ups for twi
// as per note from atmega128 manual pg204
sbi(PORTD, 0);
sbi(PORTD, 1);
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
// start in high speed. When a driver gets an error it drops it to
// low speed
setHighSpeed(true);
// enable twi module, acks, and twi interrupt
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}
void AVRI2CDriver::end() {
TWCR = 0;
}
void AVRI2CDriver::setHighSpeed(bool active) {
if (active) {
TWBR = ((CPU_FREQ / 400000) - 16) / 2;
} else {
TWBR = ((CPU_FREQ / 100000) - 16) / 2;
}
}
uint8_t AVRI2CDriver::write(uint8_t addr, uint8_t len, uint8_t* data){
uint8_t stat = _start();
if (stat) goto error;
stat = _sendAddress(SLA_W(addr));
if (stat) goto error;
for (uint8_t i = 0; i < len; i++)
{
stat = _sendByte(data[i]);
if (stat) goto error;
}
stat = _stop();
if (stat) goto error;
return stat;
error:
_lockup_count++;
return stat;
}
uint8_t AVRI2CDriver::writeRegisters(uint8_t addr, uint8_t reg,
uint8_t len, uint8_t* data){
uint8_t stat = _start();
if (stat) goto error;
stat = _sendAddress(SLA_W(addr));
if (stat) goto error;
stat = _sendByte(reg);
if (stat) goto error;
for (uint8_t i = 0; i < len; i++)
{
stat = _sendByte(data[i]);
if (stat) goto error;
}
stat = _stop();
if (stat) goto error;
return stat;
error:
if (!_ignore_errors) {
_lockup_count++;
}
return stat;
}
uint8_t AVRI2CDriver::writeRegister(uint8_t addr, uint8_t reg, uint8_t val) {
/* Sometimes avr-gcc fails at dereferencing a uint8_t arg. */
uint8_t data[1];
data[0] = val;
return writeRegisters(addr, reg, 1, data);
}
uint8_t AVRI2CDriver::read(uint8_t addr, uint8_t len, uint8_t* data){
uint8_t stat;
if ( len == 0)
len = 1;
uint8_t nackposition = len - 1;
stat = 0;
stat = _start();
if(stat) goto error;
stat = _sendAddress(SLA_R(addr));
if(stat) goto error;
for(uint8_t i = 0; i < len ; i++) {
if ( i == nackposition ) {
stat = _receiveByte(false);
if (stat != MR_DATA_NACK) goto error;
} else {
stat = _receiveByte(true);
if (stat != MR_DATA_ACK) goto error;
}
data[i] = TWDR;
}
stat = _stop();
if (stat) goto error;
return stat;
error:
_lockup_count++;
return stat;
}
uint8_t AVRI2CDriver::readRegisters(uint8_t addr, uint8_t reg,
uint8_t len, uint8_t* data){
uint8_t stat;
if ( len == 0)
len = 1;
uint8_t nackposition = len - 1;
stat = 0;
stat = _start();
if(stat) goto error;
stat = _sendAddress(SLA_W(addr));
if(stat) goto error;
stat = _sendByte(reg);
if(stat) goto error;
stat = _start();
if(stat) goto error;
stat = _sendAddress(SLA_R(addr));
if(stat) goto error;
for(uint8_t i = 0; i < len ; i++) {
if ( i == nackposition ) {
stat = _receiveByte(false);
if (stat != MR_DATA_NACK) goto error;
} else {
stat = _receiveByte(true);
if (stat != MR_DATA_ACK) goto error;
}
data[i] = TWDR;
}
stat = _stop();
if (stat) goto error;
return stat;
error:
_lockup_count++;
return stat;
}
uint8_t AVRI2CDriver::readRegister(uint8_t addr, uint8_t reg, uint8_t* data) {
return readRegisters(addr, reg, 1, data);
}
uint8_t AVRI2CDriver::_start() {
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
uint8_t stat = _waitInterrupt();
if (stat) return stat;
if ((TWI_STATUS == START) || (TWI_STATUS == REPEATED_START)) {
return 0;
} else {
return TWI_STATUS;
}
}
uint8_t AVRI2CDriver::_stop() {
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
return _waitStop();
}
uint8_t AVRI2CDriver::_sendAddress(uint8_t addr) {
TWDR = addr;
TWCR = _BV(TWINT) | _BV(TWEN);
return _waitInterrupt();
}
uint8_t AVRI2CDriver::_sendByte(uint8_t data) {
TWDR = data;
TWCR = _BV(TWINT) | _BV(TWEN);
uint8_t stat = _waitInterrupt();
if (stat) return stat;
if (TWI_STATUS == MT_DATA_ACK) {
return 0;
} else {
return TWI_STATUS;
}
}
uint8_t AVRI2CDriver::_receiveByte(bool ack) {
if (ack) {
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
} else {
TWCR = _BV(TWINT) | _BV(TWEN);
}
uint8_t stat = _waitInterrupt();
if (stat) return stat;
return TWI_STATUS;
}
void AVRI2CDriver::_handleLockup() {
TWCR = 0; /* Releases SDA and SCL lines to high impedance */
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); /* Reinitialize TWI */
_lockup_count++;
}
uint8_t AVRI2CDriver::_waitInterrupt() {
uint32_t start = hal.scheduler->millis();
if (_timeoutDelay == 0) {
/* Wait indefinitely for interrupt to go off */
while (!(TWCR & _BV(TWINT))) { }
} else {
/* Wait while polling for timeout */
while (!(TWCR & _BV(TWINT))) {
uint32_t current = hal.scheduler->millis();
if ( current - start >= _timeoutDelay ) {
_handleLockup();
return 1;
}
}
}
return 0;
}
uint8_t AVRI2CDriver::_waitStop() {
uint32_t start = hal.scheduler->millis();
if (_timeoutDelay == 0) {
/* Wait indefinitely for stop condition */
while( TWCR & _BV(TWSTO) ) { }
} else {
/* Wait while polling for timeout */
while( TWCR & _BV(TWSTO) ) {
uint32_t current = hal.scheduler->millis();
if (current - start >= _timeoutDelay) {
_handleLockup();
return 1;
}
}
}
return 0;
}
SIGNAL(TWI_vect)
{
switch(TWI_STATUS) {
case 0x20:
case 0x30:
case 0x48:
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO); // send a stop
break;
case 0x38:
case 0x68:
case 0x78:
case 0xB0:
TWCR = 0; //releases SDA and SCL lines to high impedance
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); //reinitialize TWI
break;
}
}
#endif

49
libraries/AP_HAL_AVR/I2CDriver.h

@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
#ifndef __AP_HAL_AVR_I2C_DRIVER_H__
#define __AP_HAL_AVR_I2C_DRIVER_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#define AVRI2CDRIVER_MAX_BUFFER_SIZE 32
class AP_HAL_AVR::AVRI2CDriver : public AP_HAL::I2CDriver {
public:
AVRI2CDriver(AP_HAL::Semaphore *sem) : _sem(sem) {}
void begin();
void end();
void setTimeout(uint16_t ms) { _timeoutDelay = ms; }
void setHighSpeed(bool active);
uint8_t write(uint8_t addr, uint8_t len, uint8_t* data);
uint8_t writeRegister(uint8_t addr, uint8_t reg, uint8_t val);
uint8_t writeRegisters(uint8_t addr, uint8_t reg,
uint8_t len, uint8_t* data);
uint8_t read(uint8_t addr, uint8_t len, uint8_t* data);
uint8_t readRegister(uint8_t addr, uint8_t reg, uint8_t* data);
uint8_t readRegisters(uint8_t addr, uint8_t reg,
uint8_t len, uint8_t* data);
uint8_t lockup_count() { return _lockup_count; }
AP_HAL::Semaphore* get_semaphore() { return _sem; }
private:
uint8_t _start();
uint8_t _stop();
uint8_t _sendAddress(uint8_t addr);
uint8_t _sendByte(uint8_t data);
uint8_t _receiveByte(bool ack);
void _handleLockup();
uint8_t _waitInterrupt();
uint8_t _waitStop();
uint8_t _lockup_count;
uint16_t _timeoutDelay;
AP_HAL::Semaphore *_sem;
};
#endif // __AP_HAL_AVR_I2C_DRIVER_H__

103
libraries/AP_HAL_AVR/RCInput.h

@ -1,103 +0,0 @@ @@ -1,103 +0,0 @@
#ifndef __AP_HAL_AVR_RC_INPUT_H__
#define __AP_HAL_AVR_RC_INPUT_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#define AVR_RC_INPUT_NUM_CHANNELS 11
#define AVR_RC_INPUT_MIN_CHANNELS 5 // for ppm sum we allow less than 8 channels to make up a valid packet
/*
mininum pulse width in microseconds to signal end of a PPM-SUM
frame. This value is chosen to be smaller than the default 3000 sync
pulse width for OpenLRSng. Note that this is the total pulse with
(typically 300us low followed by a long high pulse)
*/
#define AVR_RC_INPUT_MIN_SYNC_PULSE_WIDTH 2700
class AP_HAL_AVR::APM1RCInput : public AP_HAL::RCInput {
public:
/**
* init:
* HAL_AVR::init should pass in a AP_HAL_AVR::ISRRegistry* as a void*
*/
void init(void* isrregistry);
/**
* Return true if there has been new input since the last read()
* call. This call also clears the new_input flag, so once it
* returns true it won't return true again until another frame is
* received.
*/
bool new_input();
/**
* Return the number of input channels in last read()
*/
uint8_t num_channels();
/**
* read(uint8_t):
* Read a single channel at a time
*/
uint16_t read(uint8_t ch);
/**
* read(uint16_t*,uint8_t):
* Read an array of channels, return the valid count
*/
uint8_t read(uint16_t* periods, uint8_t len);
/**
* Overrides: these are really grody and don't belong here but we need
* them at the moment to make the port work.
* case v of:
* v == -1 -> no change to this channel
* v == 0 -> do not override this channel
* v > 0 -> set v as override.
*/
/* set_overrides: array starts at ch 0, for len channels */
bool set_overrides(int16_t *overrides, uint8_t len);
/* set_override: set just a specific channel */
bool set_override(uint8_t channel, int16_t override);
/* clear_overrides: equivelant to setting all overrides to 0 */
void clear_overrides();
private:
/* private callback for input capture ISR */
static void _timer4_capt_cb(void);
/* private variables to communicate with input capture isr */
static volatile uint16_t _pulse_capt[AVR_RC_INPUT_NUM_CHANNELS];
static volatile uint8_t _num_channels;
static volatile bool _new_input;
/* override state */
uint16_t _override[AVR_RC_INPUT_NUM_CHANNELS];
};
class AP_HAL_AVR::APM2RCInput : public AP_HAL::RCInput {
/* Pass in a AP_HAL_AVR::ISRRegistry* as void*. */
void init(void* isrregistry);
bool new_input();
uint8_t num_channels();
uint16_t read(uint8_t ch);
uint8_t read(uint16_t* periods, uint8_t len);
bool set_overrides(int16_t *overrides, uint8_t len);
bool set_override(uint8_t channel, int16_t override);
void clear_overrides();
private:
/* private callback for input capture ISR */
static void _timer5_capt_cb(void);
/* private variables to communicate with input capture isr */
static volatile uint16_t _pulse_capt[AVR_RC_INPUT_NUM_CHANNELS];
static volatile uint8_t _num_channels;
static volatile bool _new_input;
/* override state */
uint16_t _override[AVR_RC_INPUT_NUM_CHANNELS];
};
#endif // __AP_HAL_AVR_RC_INPUT_H__

177
libraries/AP_HAL_AVR/RCInput_APM1.cpp

@ -1,177 +0,0 @@ @@ -1,177 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR.h"
#include "RCInput.h"
#include "utility/ISRRegistry.h"
using namespace AP_HAL;
using namespace AP_HAL_AVR;
extern const HAL& hal;
/* private variables to communicate with input capture isr */
volatile uint16_t APM1RCInput::_pulse_capt[AVR_RC_INPUT_NUM_CHANNELS] = {0};
volatile uint8_t APM1RCInput::_num_channels = 0;
volatile bool APM1RCInput::_new_input = false;
/* private callback for input capture ISR */
void APM1RCInput::_timer4_capt_cb(void) {
static uint16_t icr4_prev;
static uint8_t channel_ctr;
const uint16_t icr4_current = ICR4;
uint16_t pulse_width;
if (icr4_current < icr4_prev) {
/* ICR4 rolls over at TOP=40000 */
pulse_width = icr4_current + 40000 - icr4_prev;
} else {
pulse_width = icr4_current - icr4_prev;
}
if (pulse_width > AVR_RC_INPUT_MIN_SYNC_PULSE_WIDTH*2) {
// sync pulse detected. Pass through values if at least a minimum number of channels received
if( channel_ctr >= AVR_RC_INPUT_MIN_CHANNELS ) {
_num_channels = channel_ctr;
_new_input = true;
}
channel_ctr = 0;
} else {
if (channel_ctr < AVR_RC_INPUT_NUM_CHANNELS) {
_pulse_capt[channel_ctr] = pulse_width;
channel_ctr++;
if (channel_ctr == AVR_RC_INPUT_NUM_CHANNELS) {
_num_channels = AVR_RC_INPUT_NUM_CHANNELS;
_new_input = true;
}
}
}
icr4_prev = icr4_current;
}
void APM1RCInput::init(void* _isrregistry) {
ISRRegistry* isrregistry = (ISRRegistry*) _isrregistry;
isrregistry->register_signal(ISR_REGISTRY_TIMER4_CAPT, _timer4_capt_cb);
/* initialize overrides */
clear_overrides();
/* Arduino pin 49 is ICP4 / PL0, timer 4 input capture */
hal.gpio->pinMode(49, HAL_GPIO_INPUT);
/**
* WGM: 1 1 1 1. Fast WPM, TOP is in OCR4A
* COM all disabled
* CS41: prescale by 8 => 0.5us tick
* ICES4: input capture on rising edge
* OCR4A: 40000, 0.5us tick => 2ms period / 50hz freq for outbound
* fast PWM.
*/
uint8_t oldSREG = SREG;
cli();
/* Timer cleanup before configuring */
TCNT4 = 0;
TIFR4 = 0;
/* Set timer 8x prescaler fast PWM mode toggle compare at OCRA with rising edge input capture */
TCCR4A = _BV(WGM40) | _BV(WGM41);
TCCR4B |= _BV(WGM43) | _BV(WGM42) | _BV(CS41) | _BV(ICES4);
OCR4A = 40000 - 1; // -1 to correct for wrap
/* OCR4B and OCR4C will be used by RCOutput_APM1. Init to 0xFFFF to prevent premature PWM output */
OCR4B = 0xFFFF;
OCR4C = 0xFFFF;
/* Enable input capture interrupt */
TIMSK4 |= _BV(ICIE4);
SREG = oldSREG;
}
bool APM1RCInput::new_input()
{
if (_new_input) {
_new_input = false;
return true;
}
return false;
}
uint8_t APM1RCInput::num_channels() { return _num_channels; }
/* constrain captured pulse to be between min and max pulsewidth. */
static inline uint16_t constrain_pulse(uint16_t p) {
if (p > RC_INPUT_MAX_PULSEWIDTH) return RC_INPUT_MAX_PULSEWIDTH;
if (p < RC_INPUT_MIN_PULSEWIDTH) return RC_INPUT_MIN_PULSEWIDTH;
return p;
}
uint16_t APM1RCInput::read(uint8_t ch) {
/* constrain ch */
if (ch >= AVR_RC_INPUT_NUM_CHANNELS) return 0;
/* grab channel from isr's memory in critical section*/
uint8_t oldSREG = SREG;
cli();
uint16_t capt = _pulse_capt[ch];
SREG = oldSREG;
/* scale _pulse_capt from 0.5us units to 1us units. */
uint16_t pulse = constrain_pulse(capt >> 1);
/* Check for override */
uint16_t over = _override[ch];
return (over == 0) ? pulse : over;
}
uint8_t APM1RCInput::read(uint16_t* periods, uint8_t len) {
/* constrain len */
if (len > AVR_RC_INPUT_NUM_CHANNELS) { len = AVR_RC_INPUT_NUM_CHANNELS; }
/* grab channels from isr's memory in critical section */
uint8_t oldSREG = SREG;
cli();
for (uint8_t i = 0; i < len; i++) {
periods[i] = _pulse_capt[i];
}
SREG = oldSREG;
/* Outside of critical section, do the math (in place) to scale and
* constrain the pulse. */
for (uint8_t i = 0; i < len; i++) {
/* scale _pulse_capt from 0.5us units to 1us units. */
periods[i] = constrain_pulse(periods[i] >> 1);
/* check for override */
if (_override[i] != 0) {
periods[i] = _override[i];
}
}
return _num_channels;
}
bool APM1RCInput::set_overrides(int16_t *overrides, uint8_t len) {
bool res = false;
for (uint8_t i = 0; i < len; i++) {
res |= set_override(i, overrides[i]);
}
return res;
}
bool APM1RCInput::set_override(uint8_t channel, int16_t override) {
if (override < 0) return false; /* -1: no change. */
if (channel < AVR_RC_INPUT_NUM_CHANNELS) {
_override[channel] = override;
if (override != 0) {
_new_input = true;
return true;
}
}
return false;
}
void APM1RCInput::clear_overrides() {
for (uint8_t i = 0; i < AVR_RC_INPUT_NUM_CHANNELS; i++) {
_override[i] = 0;
}
}
#endif

177
libraries/AP_HAL_AVR/RCInput_APM2.cpp

@ -1,177 +0,0 @@ @@ -1,177 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR.h"
#include "RCInput.h"
#include "utility/ISRRegistry.h"
using namespace AP_HAL;
using namespace AP_HAL_AVR;
extern const HAL& hal;
/* private variables to communicate with input capture isr */
volatile uint16_t APM2RCInput::_pulse_capt[AVR_RC_INPUT_NUM_CHANNELS] = {0};
volatile uint8_t APM2RCInput::_num_channels = 0;
volatile bool APM2RCInput::_new_input = false;
/* private callback for input capture ISR */
void APM2RCInput::_timer5_capt_cb(void) {
static uint16_t icr5_prev;
static uint8_t channel_ctr;
const uint16_t icr5_current = ICR5;
uint16_t pulse_width;
if (icr5_current < icr5_prev) {
/* ICR5 rolls over at TOP=40000 */
pulse_width = icr5_current + 40000 - icr5_prev;
} else {
pulse_width = icr5_current - icr5_prev;
}
if (pulse_width > AVR_RC_INPUT_MIN_SYNC_PULSE_WIDTH*2) {
// sync pulse detected. Pass through values if at least a minimum number of channels received
if( channel_ctr >= AVR_RC_INPUT_MIN_CHANNELS ) {
_num_channels = channel_ctr;
_new_input = true;
}
channel_ctr = 0;
} else {
if (channel_ctr < AVR_RC_INPUT_NUM_CHANNELS) {
_pulse_capt[channel_ctr] = pulse_width;
channel_ctr++;
if (channel_ctr == AVR_RC_INPUT_NUM_CHANNELS) {
_num_channels = AVR_RC_INPUT_NUM_CHANNELS;
_new_input = true;
}
}
}
icr5_prev = icr5_current;
}
void APM2RCInput::init(void* _isrregistry) {
ISRRegistry* isrregistry = (ISRRegistry*) _isrregistry;
isrregistry->register_signal(ISR_REGISTRY_TIMER5_CAPT, _timer5_capt_cb);
/* initialize overrides */
clear_overrides();
/* Arduino pin 48 is ICP5 / PL1, timer 5 input capture */
hal.gpio->pinMode(48, HAL_GPIO_INPUT);
/**
* WGM: 1 1 1 1. Fast WPM, TOP is in OCR5A
* COM all disabled
* CS51: prescale by 8 => 0.5us tick
* ICES5: input capture on rising edge
* OCR5A: 40000, 0.5us tick => 2ms period / 50hz freq for outbound
* fast PWM.
*/
uint8_t oldSREG = SREG;
cli();
/* Timer cleanup before configuring */
TCNT5 = 0;
TIFR5 = 0;
/* Set timer 8x prescaler fast PWM mode toggle compare at OCRA with rising edge input capture */
TCCR5A = _BV(WGM50) | _BV(WGM51);
TCCR5B |= _BV(WGM53) | _BV(WGM52) | _BV(CS51) | _BV(ICES5);
OCR5A = 40000 - 1; // -1 to correct for wrap
/* OCR5B and OCR5C will be used by RCOutput_APM2. Init to 0xFFFF to prevent premature PWM output */
OCR5B = 0xFFFF;
OCR5C = 0xFFFF;
/* Enable input capture interrupt */
TIMSK5 |= _BV(ICIE5);
SREG = oldSREG;
}
bool APM2RCInput::new_input()
{
if (_new_input) {
_new_input = false;
return true;
}
return false;
}
uint8_t APM2RCInput::num_channels() { return _num_channels; }
/* constrain captured pulse to be between min and max pulsewidth. */
static inline uint16_t constrain_pulse(uint16_t p) {
if (p > RC_INPUT_MAX_PULSEWIDTH) return RC_INPUT_MAX_PULSEWIDTH;
if (p < RC_INPUT_MIN_PULSEWIDTH) return RC_INPUT_MIN_PULSEWIDTH;
return p;
}
uint16_t APM2RCInput::read(uint8_t ch) {
/* constrain ch */
if (ch >= AVR_RC_INPUT_NUM_CHANNELS) return 0;
/* grab channel from isr's memory in critical section*/
uint8_t oldSREG = SREG;
cli();
uint16_t capt = _pulse_capt[ch];
SREG = oldSREG;
/* scale _pulse_capt from 0.5us units to 1us units. */
uint16_t pulse = constrain_pulse(capt >> 1);
/* Check for override */
uint16_t over = _override[ch];
return (over == 0) ? pulse : over;
}
uint8_t APM2RCInput::read(uint16_t* periods, uint8_t len) {
/* constrain len */
if (len > AVR_RC_INPUT_NUM_CHANNELS) { len = AVR_RC_INPUT_NUM_CHANNELS; }
/* grab channels from isr's memory in critical section */
uint8_t oldSREG = SREG;
cli();
for (int i = 0; i < len; i++) {
periods[i] = _pulse_capt[i];
}
SREG = oldSREG;
/* Outside of critical section, do the math (in place) to scale and
* constrain the pulse. */
for (int i = 0; i < len; i++) {
/* scale _pulse_capt from 0.5us units to 1us units. */
periods[i] = constrain_pulse(periods[i] >> 1);
/* check for override */
if (_override[i] != 0) {
periods[i] = _override[i];
}
}
return _num_channels;
}
bool APM2RCInput::set_overrides(int16_t *overrides, uint8_t len) {
bool res = false;
for (int i = 0; i < len; i++) {
res |= set_override(i, overrides[i]);
}
return res;
}
bool APM2RCInput::set_override(uint8_t channel, int16_t override) {
if (override < 0) return false; /* -1: no change. */
if (channel < AVR_RC_INPUT_NUM_CHANNELS) {
_override[channel] = override;
if (override != 0) {
_new_input = true;
return true;
}
}
return false;
}
void APM2RCInput::clear_overrides() {
for (int i = 0; i < AVR_RC_INPUT_NUM_CHANNELS; i++) {
_override[i] = 0;
}
}
#endif

61
libraries/AP_HAL_AVR/RCOutput.h

@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
#ifndef __AP_HAL_AVR_RC_OUTPUT_H__
#define __AP_HAL_AVR_RC_OUTPUT_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
class AP_HAL_AVR::APM1RCOutput : public AP_HAL::RCOutput {
public:
/* No init argument required */
void init(void* machtnichts);
/* Output freq (1/period) control */
void set_freq(uint32_t chmask, uint16_t freq_hz);
uint16_t get_freq(uint8_t ch);
/* Output active/highZ control, either by single channel at a time
* or a mask of channels */
void enable_ch(uint8_t ch);
void disable_ch(uint8_t ch);
/* Output, either single channel or bulk array of channels */
void write(uint8_t ch, uint16_t period_ms);
/* Read back current output state, as either single channel or
* array of channels. */
uint16_t read(uint8_t ch);
void read(uint16_t* period_ms, uint8_t len);
private:
uint16_t _timer_period(uint16_t speed_hz);
};
class AP_HAL_AVR::APM2RCOutput : public AP_HAL::RCOutput {
public:
/* No init argument required */
void init(void* machtnichts);
/* Output freq (1/period) control */
void set_freq(uint32_t chmask, uint16_t freq_hz);
uint16_t get_freq(uint8_t ch);
/* Output active/highZ control, either by single channel at a time
* or a mask of channels */
void enable_ch(uint8_t ch);
void disable_ch(uint8_t ch);
/* Output, either single channel or bulk array of channels */
void write(uint8_t ch, uint16_t period_us);
/* Read back current output state, as either single channel or
* array of channels starting at 0. */
uint16_t read(uint8_t ch);
void read(uint16_t* period_us, uint8_t len);
private:
uint16_t _timer_period(uint16_t speed_hz);
};
#endif // __AP_HAL_AVR_RC_OUTPUT_H__

207
libraries/AP_HAL_AVR/RCOutput_APM1.cpp

@ -1,207 +0,0 @@ @@ -1,207 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR.h"
#include "RCOutput.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
/* No init argument required */
void APM1RCOutput::init(void* machtnichts) {
// --------------------- TIMER1: CH_3, CH_4, and CH_10 ---------------
hal.gpio->pinMode(11,HAL_GPIO_OUTPUT); // CH_10 (PB5/OC1A)
hal.gpio->pinMode(12,HAL_GPIO_OUTPUT); // CH_3 (PB6/OC1B)
hal.gpio->pinMode(13,HAL_GPIO_OUTPUT); // CH_4 (PB7/OC1C)
// WGM: 1 1 1 0. Clear Timer on Compare, TOP is ICR1.
// CS11: prescale by 8 => 0.5us tick
TCCR1A =((1<<WGM11));
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11);
ICR1 = 40000; // 0.5us tick => 50hz freq
OCR1A = 0xFFFF; // Init OCR registers to nil output signal
OCR1B = 0xFFFF;
OCR1C = 0xFFFF;
//--------------- TIMER3: CH_7, CH_8, and CH_11 ---------------------
hal.gpio->pinMode(5,HAL_GPIO_OUTPUT); // CH_11 (PE3/OC3A)
hal.gpio->pinMode(2,HAL_GPIO_OUTPUT); // CH_8 (PE4/OC3B)
hal.gpio->pinMode(3,HAL_GPIO_OUTPUT); // CH_7 (PE5/OC3C)
// WGM: 1 1 1 0. Clear timer on Compare, TOP is ICR3
// CS31: prescale by 8 => 0.5us tick
TCCR3A =((1<<WGM31));
TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS31);
OCR3A = 0xFFFF; // Init OCR registers to nil output signal
OCR3B = 0xFFFF;
OCR3C = 0xFFFF;
ICR3 = 40000; // 0.5us tick => 50hz freq
//--------------- TIMER4: CH_6 and CH_5 ----------------------------
// NB TIMER4 is shared with PPM input from RCInput_APM1.cpp
// The TIMER4 registers are assumed to be setup already.
hal.gpio->pinMode(7,HAL_GPIO_OUTPUT); // CH_5 (PH4/OC4B)
hal.gpio->pinMode(8,HAL_GPIO_OUTPUT); // CH_6 (PH5/OC4C)
//--------------- TIMER5: CH_1, CH_2 and CH_9 -----------------------
hal.gpio->pinMode(46, HAL_GPIO_OUTPUT); // CH_9 (PL3/OC5A)
hal.gpio->pinMode(45, HAL_GPIO_OUTPUT); // CH_1 (PL4/OC5B)
hal.gpio->pinMode(44, HAL_GPIO_OUTPUT); // CH_2 (PL5/OC5C)
// WGM: 1 1 1 0. Clear timer on Compare, TOP is ICR5
// CS51: prescale by 8 => 0.5us tick
TCCR5A =((1<<WGM51));
TCCR5B = (1<<WGM53)|(1<<WGM52)|(1<<CS51);
OCR5A = 0xFFFF; // Init OCR registers to nil output signal
OCR5B = 0xFFFF;
OCR5C = 0xFFFF;
ICR5 = 40000; // 0.5us tick => 50hz freq
}
/* Output freq (1/period) control */
void APM1RCOutput::set_freq(uint32_t chmask, uint16_t freq_hz) {
uint16_t icr = _timer_period(freq_hz);
if ((chmask & ( _BV(CH_1) | _BV(CH_2) | _BV(CH_9))) != 0) {
ICR5 = icr;
}
if ((chmask & ( _BV(CH_3) | _BV(CH_4) | _BV(CH_10))) != 0) {
ICR1 = icr;
}
if ((chmask & ( _BV(CH_7) | _BV(CH_8) | _BV(CH_11))) != 0) {
ICR3 = icr;
}
/* No change permitted for CH_5 and CH_6 - that ICR register is
* shared with the input capture for RCInput */
}
uint16_t APM1RCOutput::get_freq(uint8_t ch) {
uint16_t icr;
switch (ch) {
case CH_3:
case CH_4:
case CH_10:
icr = ICR1;
break;
/* CH_5 and CH_6 share TIMER4 with input capture.
* The period is specified in OCR4A rather than the ICR. */
case CH_5:
case CH_6:
icr = OCR4A;
break;
case CH_7:
case CH_8:
case CH_11:
icr = ICR3;
break;
case CH_1:
case CH_2:
case CH_9:
icr = ICR5;
break;
default:
return 0;
}
/* transform to period by inverse of _time_period(icr). */
return (2000000UL / icr);
}
/* Output active/highZ control, either by single channel at a time
* or a mask of channels */
void APM1RCOutput::enable_ch(uint8_t ch) {
switch(ch) {
case 0: TCCR5A |= (1<<COM5B1); break; // CH_1 : OC5B
case 1: TCCR5A |= (1<<COM5C1); break; // CH_2 : OC5C
case 2: TCCR1A |= (1<<COM1B1); break; // CH_3 : OC1B
case 3: TCCR1A |= (1<<COM1C1); break; // CH_4 : OC1C
case 4: TCCR4A |= (1<<COM4C1); break; // CH_5 : OC4C
case 5: TCCR4A |= (1<<COM4B1); break; // CH_6 : OC4B
case 6: TCCR3A |= (1<<COM3C1); break; // CH_7 : OC3C
case 7: TCCR3A |= (1<<COM3B1); break; // CH_8 : OC3B
case 8: TCCR5A |= (1<<COM5A1); break; // CH_9 : OC5A
case 9: TCCR1A |= (1<<COM1A1); break; // CH_10: OC1A
case 10: TCCR3A |= (1<<COM3A1); break; // CH_11: OC3A
}
}
void APM1RCOutput::disable_ch(uint8_t ch) {
switch(ch) {
case 0: TCCR5A &= ~(1<<COM5B1); break; // CH_1 : OC5B
case 1: TCCR5A &= ~(1<<COM5C1); break; // CH_2 : OC5C
case 2: TCCR1A &= ~(1<<COM1B1); break; // CH_3 : OC1B
case 3: TCCR1A &= ~(1<<COM1C1); break; // CH_4 : OC1C
case 4: TCCR4A &= ~(1<<COM4C1); break; // CH_5 : OC4C
case 5: TCCR4A &= ~(1<<COM4B1); break; // CH_6 : OC4B
case 6: TCCR3A &= ~(1<<COM3C1); break; // CH_7 : OC3C
case 7: TCCR3A &= ~(1<<COM3B1); break; // CH_8 : OC3B
case 8: TCCR5A &= ~(1<<COM5A1); break; // CH_9 : OC5A
case 9: TCCR1A &= ~(1<<COM1A1); break; // CH_10: OC1A
case 10: TCCR3A &= ~(1<<COM3A1); break; // CH_11: OC3A
}
}
/* constrain pwm to be between min and max pulsewidth. */
static inline uint16_t constrain_period(uint16_t p) {
if (p > RC_OUTPUT_MAX_PULSEWIDTH) return RC_OUTPUT_MAX_PULSEWIDTH;
if (p < RC_OUTPUT_MIN_PULSEWIDTH) return RC_OUTPUT_MIN_PULSEWIDTH;
return p;
}
/* Output, either single channel or bulk array of channels */
void APM1RCOutput::write(uint8_t ch, uint16_t period_us) {
/* constrain, then scale from 1us resolution (input units)
* to 0.5us (timer units) */
uint16_t pwm = constrain_period(period_us) << 1;
switch(ch)
{
case 0: OCR5B=pwm; break; //ch1
case 1: OCR5C=pwm; break; //ch2
case 2: OCR1B=pwm; break; //ch3
case 3: OCR1C=pwm; break; //ch4
case 4: OCR4C=pwm; break; //ch5
case 5: OCR4B=pwm; break; //ch6
case 6: OCR3C=pwm; break; //ch7
case 7: OCR3B=pwm; break; //ch8
case 8: OCR5A=pwm; break; //ch9, PL3
case 9: OCR1A=pwm; break; //ch10, PB5
case 10: OCR3A=pwm; break; //ch11, PE3
}
}
/* Read back current output state, as either single channel or
* array of channels. */
uint16_t APM1RCOutput::read(uint8_t ch) {
uint16_t pwm=0;
switch(ch) {
case 0: pwm=OCR5B; break; //ch1
case 1: pwm=OCR5C; break; //ch2
case 2: pwm=OCR1B; break; //ch3
case 3: pwm=OCR1C; break; //ch4
case 4: pwm=OCR4C; break; //ch5
case 5: pwm=OCR4B; break; //ch6
case 6: pwm=OCR3C; break; //ch7
case 7: pwm=OCR3B; break; //ch8
case 8: pwm=OCR5A; break; //ch9, PL3
case 9: pwm=OCR1A; break; //ch10, PB5
case 10: pwm=OCR3A; break; //ch11, PE3
}
/* scale from 0.5us resolution (timer units) to 1us units */
return pwm>>1;
}
void APM1RCOutput::read(uint16_t* period_us, uint8_t len) {
for (int i = 0; i < len; i++) {
period_us[i] = read(i);
}
}
uint16_t APM1RCOutput::_timer_period(uint16_t speed_hz) {
return 2000000UL / speed_hz;
}
#endif

199
libraries/AP_HAL_AVR/RCOutput_APM2.cpp

@ -1,199 +0,0 @@ @@ -1,199 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR.h"
#include "RCOutput.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
/* No init argument required */
void APM2RCOutput::init(void* machtnichts) {
// --------------------- TIMER1: CH_1 and CH_2 -----------------------
hal.gpio->pinMode(12,HAL_GPIO_OUTPUT); // CH_1 (PB6/OC1B)
hal.gpio->pinMode(11,HAL_GPIO_OUTPUT); // CH_2 (PB5/OC1A)
// WGM: 1 1 1 0. Clear Timer on Compare, TOP is ICR1.
// CS11: prescale by 8 => 0.5us tick
TCCR1A =((1<<WGM11));
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11);
ICR1 = 40000; // 0.5us tick => 50hz freq
OCR1A = 0xFFFF; // Init OCR registers to nil output signal
OCR1B = 0xFFFF;
// --------------- TIMER4: CH_3, CH_4, and CH_5 ---------------------
hal.gpio->pinMode(8,HAL_GPIO_OUTPUT); // CH_3 (PH5/OC4C)
hal.gpio->pinMode(7,HAL_GPIO_OUTPUT); // CH_4 (PH4/OC4B)
hal.gpio->pinMode(6,HAL_GPIO_OUTPUT); // CH_5 (PH3/OC4A)
// WGM: 1 1 1 0. Clear Timer on Compare, TOP is ICR4.
// CS41: prescale by 8 => 0.5us tick
TCCR4A =((1<<WGM41));
TCCR4B = (1<<WGM43)|(1<<WGM42)|(1<<CS41);
OCR4A = 0xFFFF; // Init OCR registers to nil output signal
OCR4B = 0xFFFF;
OCR4C = 0xFFFF;
ICR4 = 40000; // 0.5us tick => 50hz freq
//--------------- TIMER3: CH_6, CH_7, and CH_8 ----------------------
hal.gpio->pinMode(3,HAL_GPIO_OUTPUT); // CH_6 (PE5/OC3C)
hal.gpio->pinMode(2,HAL_GPIO_OUTPUT); // CH_7 (PE4/OC3B)
hal.gpio->pinMode(5,HAL_GPIO_OUTPUT); // CH_8 (PE3/OC3A)
// WGM: 1 1 1 0. Clear timer on Compare, TOP is ICR3
// CS31: prescale by 8 => 0.5us tick
TCCR3A =((1<<WGM31));
TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS31);
OCR3A = 0xFFFF; // Init OCR registers to nil output signal
OCR3B = 0xFFFF;
OCR3C = 0xFFFF;
ICR3 = 40000; // 0.5us tick => 50hz freq
//--------------- TIMER5: CH_10, and CH_11 ---------------
// NB TIMER5 is shared with PPM input from RCInput_APM2.cpp
// The TIMER5 registers are assumed to be setup already.
hal.gpio->pinMode(45, HAL_GPIO_OUTPUT); // CH_10 (PL4/OC5B)
hal.gpio->pinMode(44, HAL_GPIO_OUTPUT); // CH_11 (PL5/OC5C)
}
/* Output freq (1/period) control */
void APM2RCOutput::set_freq(uint32_t chmask, uint16_t freq_hz) {
uint16_t icr = _timer_period(freq_hz);
if ((chmask & ( _BV(CH_1) | _BV(CH_2))) != 0) {
ICR1 = icr;
}
if ((chmask & ( _BV(CH_3) | _BV(CH_4) | _BV(CH_5))) != 0) {
ICR4 = icr;
}
if ((chmask & ( _BV(CH_6) | _BV(CH_7) | _BV(CH_8))) != 0) {
ICR3 = icr;
}
}
uint16_t APM2RCOutput::get_freq(uint8_t ch) {
uint16_t icr;
switch (ch) {
case CH_1:
case CH_2:
icr = ICR1;
break;
case CH_3:
case CH_4:
case CH_5:
icr = ICR4;
break;
case CH_6:
case CH_7:
case CH_8:
icr = ICR3;
break;
/* CH_10 and CH_11 share TIMER5 with input capture.
* The period is specified in OCR5A rater than the ICR. */
case CH_10:
case CH_11:
icr = OCR5A;
break;
default:
return 0;
}
/* transform to period by inverse of _time_period(icr). */
return (2000000UL / icr);
}
/* Output active/highZ control, either by single channel at a time
* or a mask of channels */
void APM2RCOutput::enable_ch(uint8_t ch) {
switch(ch) {
case 0: TCCR1A |= (1<<COM1B1); break; // CH_1 : OC1B
case 1: TCCR1A |= (1<<COM1A1); break; // CH_2 : OC1A
case 2: TCCR4A |= (1<<COM4C1); break; // CH_3 : OC4C
case 3: TCCR4A |= (1<<COM4B1); break; // CH_4 : OC4B
case 4: TCCR4A |= (1<<COM4A1); break; // CH_5 : OC4A
case 5: TCCR3A |= (1<<COM3C1); break; // CH_6 : OC3C
case 6: TCCR3A |= (1<<COM3B1); break; // CH_7 : OC3B
case 7: TCCR3A |= (1<<COM3A1); break; // CH_8 : OC3A
case 9: TCCR5A |= (1<<COM5B1); break; // CH_10 : OC5B
case 10: TCCR5A |= (1<<COM5C1); break; // CH_11 : OC5C
}
}
void APM2RCOutput::disable_ch(uint8_t ch) {
switch(ch) {
case 0: TCCR1A &= ~(1<<COM1B1); break; // CH_1 : OC1B
case 1: TCCR1A &= ~(1<<COM1A1); break; // CH_2 : OC1A
case 2: TCCR4A &= ~(1<<COM4C1); break; // CH_3 : OC4C
case 3: TCCR4A &= ~(1<<COM4B1); break; // CH_4 : OC4B
case 4: TCCR4A &= ~(1<<COM4A1); break; // CH_5 : OC4A
case 5: TCCR3A &= ~(1<<COM3C1); break; // CH_6 : OC3C
case 6: TCCR3A &= ~(1<<COM3B1); break; // CH_7 : OC3B
case 7: TCCR3A &= ~(1<<COM3A1); break; // CH_8 : OC3A
case 9: TCCR5A &= ~(1<<COM5B1); break; // CH_10 : OC5B
case 10: TCCR5A &= ~(1<<COM5C1); break; // CH_11 : OC5C
}
}
/* constrain pwm to be between min and max pulsewidth. */
static inline uint16_t constrain_period(uint16_t p) {
if (p > RC_OUTPUT_MAX_PULSEWIDTH) return RC_OUTPUT_MAX_PULSEWIDTH;
if (p < RC_OUTPUT_MIN_PULSEWIDTH) return RC_OUTPUT_MIN_PULSEWIDTH;
return p;
}
/* Output, either single channel or bulk array of channels */
void APM2RCOutput::write(uint8_t ch, uint16_t period_us) {
/* constrain, then scale from 1us resolution (input units)
* to 0.5us (timer units) */
uint16_t pwm = constrain_period(period_us) << 1;
switch(ch)
{
case 0: OCR1B=pwm; break; // out1
case 1: OCR1A=pwm; break; // out2
case 2: OCR4C=pwm; break; // out3
case 3: OCR4B=pwm; break; // out4
case 4: OCR4A=pwm; break; // out5
case 5: OCR3C=pwm; break; // out6
case 6: OCR3B=pwm; break; // out7
case 7: OCR3A=pwm; break; // out8
case 9: OCR5B=pwm; break; // out10
case 10: OCR5C=pwm; break; // out11
}
}
/* Read back current output state, as either single channel or
* array of channels. */
uint16_t APM2RCOutput::read(uint8_t ch) {
uint16_t pwm=0;
switch(ch) {
case 0: pwm=OCR1B; break; // out1
case 1: pwm=OCR1A; break; // out2
case 2: pwm=OCR4C; break; // out3
case 3: pwm=OCR4B; break; // out4
case 4: pwm=OCR4A; break; // out5
case 5: pwm=OCR3C; break; // out6
case 6: pwm=OCR3B; break; // out7
case 7: pwm=OCR3A; break; // out8
case 9: pwm=OCR5B; break; // out10
case 10: pwm=OCR5C; break; // out11
}
/* scale from 0.5us resolution (timer units) to 1us units */
return pwm>>1;
}
void APM2RCOutput::read(uint16_t* period_us, uint8_t len) {
for (int i = 0; i < len; i++) {
period_us[i] = read(i);
}
}
uint16_t APM2RCOutput::_timer_period(uint16_t speed_hz) {
return 2000000UL / speed_hz;
}
#endif

1
libraries/AP_HAL_AVR/README.md

@ -0,0 +1 @@ @@ -0,0 +1 @@
AVR is only supported on its separate [branch](https://github.com/diydrones/ardupilot/tree/master-AVR])

52
libraries/AP_HAL_AVR/SPIDeviceManager_APM1.cpp

@ -1,52 +0,0 @@ @@ -1,52 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
#include <avr/io.h>
#include <AP_HAL/AP_HAL.h>
#include "SPIDriver.h"
#include "SPIDevices.h"
#include "GPIO.h"
#include "utility/pins_arduino_mega.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
void APM1SPIDeviceManager::init(void* machtnichts) {
/* dataflow cs is on arduino pin 53, PORTB0 */
AVRDigitalSource* df_cs = new AVRDigitalSource(_BV(0), PB);
/* dataflash: divide clock by 2 to 8Mhz, set SPI_MODE_3
* spcr gets 0x0C to set SPI_MODE_3
* spsr gets bit SPI2X for clock divider */
_dataflash = new AVRSPI0DeviceDriver(df_cs, 0x0C, 0x0C, _BV(SPI2X));
_dataflash->init();
/* optflow cs is on Arduino pin 34, PORTC3 */
AVRDigitalSource* opt_cs = new AVRDigitalSource(_BV(3), PC);
/* optflow: divide clock by 8 to 2Mhz
* spcr gets bit SPR0, spsr gets bit SPI2X */
_optflow = new AVRSPI0DeviceDriver(opt_cs, _BV(SPR0), _BV(SPR0), 0);
_optflow->init();
/* adc cs is on Arduino pin 33, PORTC4 */
AVRDigitalSource* adc_cs = new AVRDigitalSource(_BV(4), PC);
/* adc: ubbr2 gets value of 2 to run at 2.6Mhz
* (config value cribbed from AP_ADC_ADS7844 driver pre-port) */
_adc = new AVRSPI2DeviceDriver(adc_cs, 0, 2);
_adc->init();
}
AP_HAL::SPIDeviceDriver* APM1SPIDeviceManager::device(enum AP_HAL::SPIDevice d)
{
switch (d) {
case AP_HAL::SPIDevice_Dataflash:
return _dataflash;
case AP_HAL::SPIDevice_ADS7844:
return _adc;
case AP_HAL::SPIDevice_ADNS3080_SPI0:
return _optflow;
default:
return NULL;
};
}
#endif

81
libraries/AP_HAL_AVR/SPIDeviceManager_APM2.cpp

@ -1,81 +0,0 @@ @@ -1,81 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
#include <avr/io.h>
#include <AP_HAL/AP_HAL.h>
#include "SPIDriver.h"
#include "SPIDevices.h"
#include "utility/pins_arduino_mega.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
void APM2SPIDeviceManager::init(void* machtnichts) {
/* Note that the order of the init() of the MS5611 and MPU6k is
* critical for the APM2. If you initialise in the wrong order
* then the MS5611 doesn't initialise itself correctly. This
* indicates an electrical fault in the APM2 which needs to be
* investigated. Meanwhile, initialising the MPU6k CS pin before
* the MS5611 CS pin works around the problem
*/
#define SPI0_SPCR_8MHz 0
#define SPI0_SPSR_8MHz _BV(SPI2X)
#define SPI0_SPCR_500kHz _BV(SPR1)
#define SPI0_SPSR_500kHz _BV(SPI2X)
/* mpu6k cs is on Arduino pin 53, PORTB0 */
AVRDigitalSource* mpu6k_cs = new AVRDigitalSource(_BV(0), PB);
/* mpu6k: run clock at 8MHz in high speed mode and 512kHz for low
* speed */
_mpu6k = new AVRSPI0DeviceDriver(mpu6k_cs, SPI0_SPCR_500kHz, SPI0_SPCR_8MHz, SPI0_SPSR_8MHz);
_mpu6k->init();
/* ms5611 cs is on Arduino pin 40, PORTG1 */
AVRDigitalSource* ms5611_cs = new AVRDigitalSource(_BV(1), PG);
/* ms5611: run clock at 8MHz */
_ms5611 = new AVRSPI0DeviceDriver(ms5611_cs, SPI0_SPCR_500kHz, SPI0_SPCR_8MHz, SPI0_SPSR_8MHz);
_ms5611->init();
/* optflow cs is on Arduino pin A3, PORTF3 */
AVRDigitalSource* optflow_cs = new AVRDigitalSource(_BV(3), PF);
/* optflow: divide clock by 8 to 2Mhz
* spcr gets bit SPR0, spsr gets bit SPI2X */
_optflow_spi0 = new AVRSPI0DeviceDriver(optflow_cs, _BV(SPR0)|_BV(CPOL)|_BV(CPHA), _BV(SPR0)|_BV(CPOL)|_BV(CPHA), _BV(SPI2X));
_optflow_spi0->init();
/* Dataflash CS is on Arduino pin 28, PORTA6 */
AVRDigitalSource* df_cs = new AVRDigitalSource(_BV(6), PA);
/* dataflash uses mode 0 and a clock of 8mhz
* ucsr3c = 0
* ubrr3 = 0 */
_dataflash = new AVRSPI3DeviceDriver(df_cs, 0, 0);
_dataflash->init();
/* optflow uses mode 3 and a clock of 2mhz
* ucsr3c = _BV(UCPHA3N)|_BV(UCPOL3) = 3
* ubrr3 = 3 */
_optflow_spi3 = new AVRSPI3DeviceDriver(optflow_cs, 3, 3);
_optflow_spi3->init();
}
AP_HAL::SPIDeviceDriver* APM2SPIDeviceManager::device(enum AP_HAL::SPIDevice d)
{
switch (d) {
case AP_HAL::SPIDevice_Dataflash:
return _dataflash;
case AP_HAL::SPIDevice_MS5611:
return _ms5611;
case AP_HAL::SPIDevice_MPU6000:
return _mpu6k;
case AP_HAL::SPIDevice_ADNS3080_SPI0:
return _optflow_spi0;
case AP_HAL::SPIDevice_ADNS3080_SPI3:
return _optflow_spi3;
default:
return NULL;
};
}
#endif

160
libraries/AP_HAL_AVR/SPIDevice_SPI0.cpp

@ -1,160 +0,0 @@ @@ -1,160 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <AP_HAL/AP_HAL.h>
#include "SPIDevices.h"
#include "GPIO.h"
#include "Semaphores.h"
#include "utility/pins_arduino_mega.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
#define SPI0_MISO_PIN 50
#define SPI0_MOSI_PIN 51
#define SPI0_SCK_PIN 52
AVRSemaphore AVRSPI0DeviceDriver::_semaphore;
bool AVRSPI0DeviceDriver::_force_low_speed;
static volatile bool spi0_transferflag = false;
void AVRSPI0DeviceDriver::init() {
hal.gpio->pinMode(SPI0_MISO_PIN, HAL_GPIO_INPUT);
hal.gpio->pinMode(SPI0_MOSI_PIN, HAL_GPIO_OUTPUT);
hal.gpio->pinMode(SPI0_SCK_PIN, HAL_GPIO_OUTPUT);
_cs_pin->mode(HAL_GPIO_OUTPUT);
_cs_pin->write(1);
/* Enable the SPI0 peripheral as a master */
SPCR = _BV(SPE) | _BV(MSTR);
}
AP_HAL::Semaphore* AVRSPI0DeviceDriver::get_semaphore() {
return &_semaphore;
}
void AVRSPI0DeviceDriver::_cs_assert()
{
const uint8_t valid_spcr_mask =
(_BV(CPOL) | _BV(CPHA) | _BV(SPR1) | _BV(SPR0));
if (_force_low_speed) {
_spcr = _spcr_lowspeed;
}
uint8_t new_spcr = (SPCR & ~valid_spcr_mask) | (_spcr & valid_spcr_mask);
SPCR = new_spcr;
const uint8_t valid_spsr_mask = _BV(SPI2X);
uint8_t new_spsr = (SPSR & ~valid_spsr_mask) | (_spsr & valid_spsr_mask);
SPSR = new_spsr;
_cs_pin->write(0);
}
void AVRSPI0DeviceDriver::_cs_release()
{
_cs_pin->write(1);
}
uint8_t AVRSPI0DeviceDriver::_transfer(uint8_t data)
{
if (spi0_transferflag) {
hal.scheduler->panic(PSTR("PANIC: SPI0 transfer collision"));
}
spi0_transferflag = true;
SPDR = data;
if (SPSR & _BV(WCOL)) {
hal.scheduler->panic(PSTR("PANIC: SPI0 write collision"));
return 0;
}
while(!(SPSR & _BV(SPIF)));
uint8_t read_spdr = SPDR;
spi0_transferflag = false;
return read_spdr;
}
/**
a specialised transfer function for the MPU6k. This saves 2 usec
per byte
*/
void AVRSPI0DeviceDriver::_transfer16(const uint8_t *tx, uint8_t *rx)
{
spi0_transferflag = true;
#define TRANSFER1(i) do { SPDR = tx[i]; while(!(SPSR & _BV(SPIF))); rx[i] = SPDR; } while(0)
TRANSFER1(0);
TRANSFER1(1);
TRANSFER1(2);
TRANSFER1(3);
TRANSFER1(4);
TRANSFER1(5);
TRANSFER1(6);
TRANSFER1(7);
TRANSFER1(8);
TRANSFER1(9);
TRANSFER1(10);
TRANSFER1(11);
TRANSFER1(12);
TRANSFER1(13);
TRANSFER1(14);
TRANSFER1(15);
spi0_transferflag = false;
}
void AVRSPI0DeviceDriver::transfer(const uint8_t *tx, uint16_t len) {
for (uint16_t i = 0; i < len; i++) {
_transfer(tx[i]);
}
}
bool AVRSPI0DeviceDriver::transaction(const uint8_t *tx, uint8_t *rx,
uint16_t len) {
_cs_assert();
if (rx == NULL) {
for (uint16_t i = 0; i < len; i++) {
_transfer(tx[i]);
}
} else {
while (len >= 16) {
_transfer16(tx, rx);
tx += 16;
rx += 16;
len -= 16;
}
for (uint16_t i = 0; i < len; i++) {
rx[i] = _transfer(tx[i]);
}
}
_cs_release();
return true;
}
void AVRSPI0DeviceDriver::cs_assert() {
_cs_assert();
}
void AVRSPI0DeviceDriver::cs_release() {
_cs_release();
}
uint8_t AVRSPI0DeviceDriver::transfer(uint8_t data) {
return _transfer(data);
}
/**
allow on the fly bus speed changes for MPU6000
*/
void AVRSPI0DeviceDriver::set_bus_speed(AVRSPI0DeviceDriver::bus_speed speed)
{
if (speed == AVRSPI0DeviceDriver::SPI_SPEED_HIGH) {
_spcr = _spcr_highspeed;
_force_low_speed = false;
} else {
_spcr = _spcr_lowspeed;
_force_low_speed = true;
}
}
#endif

139
libraries/AP_HAL_AVR/SPIDevice_SPI2.cpp

@ -1,139 +0,0 @@ @@ -1,139 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <AP_HAL/AP_HAL.h>
#include "SPIDevices.h"
#include "GPIO.h"
#include "Semaphores.h"
#include "utility/pins_arduino_mega.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
AVRSemaphore AVRSPI2DeviceDriver::_semaphore;
void AVRSPI2DeviceDriver::init() {
AVRDigitalSource spi2_miso(_BV(0), PH);
spi2_miso.mode(HAL_GPIO_INPUT);
AVRDigitalSource spi2_mosi(_BV(1), PH);
spi2_mosi.mode(HAL_GPIO_OUTPUT);
AVRDigitalSource spi2_sck(_BV(2), PH);
spi2_sck.mode(HAL_GPIO_OUTPUT);
/* UMSELn1 and UMSELn2: USART in SPI Master mode */
UCSR2C = _BV(UMSEL21) | _BV(UMSEL20);
/* Enable RX and TX. */
UCSR2B = _BV(RXEN2) | _BV(TXEN2);
/* Setup chip select pin */
_cs_pin->mode(HAL_GPIO_OUTPUT);
_cs_pin->write(1);
}
AP_HAL::Semaphore* AVRSPI2DeviceDriver::get_semaphore() {
return &_semaphore;
}
inline void AVRSPI2DeviceDriver::_cs_assert() {
/* set the device UCSRnC configuration bits.
* only sets data order, clock phase, and clock polarity bits (lowest
* three bits) */
const uint8_t new_ucsr2c = (UCSR2C & ~0x07) | (_ucsr2c & (0x07));
UCSR2C = new_ucsr2c;
/* set the device baud rate */
UBRR2 = _ubrr2;
_cs_pin->write(0);
}
inline void AVRSPI2DeviceDriver::_cs_release() {
_cs_pin->write(1);
}
inline uint8_t AVRSPI2DeviceDriver::_transfer(uint8_t data) {
/* Wait for empty transmit buffer */
while ( !( UCSR2A & _BV(UDRE2)) ) ;
/* Put data into buffer, sends the data */
UDR2 = data;
/* Wait for data to be received */
while ( !(UCSR2A & _BV(RXC2)) ) ;
/* Get and return received data from buffer */
return UDR2;
}
/**
a specialist transfer function for the APM1 ADC
*/
void AVRSPI2DeviceDriver::_transfer17(const uint8_t *tx, uint8_t *rx)
{
#define TRANSFER1(i) do { while ( !( UCSR2A & _BV(UDRE2)) ); \
UDR2 = tx[i]; \
while ( !(UCSR2A & _BV(RXC2)) ) ; \
rx[i] = UDR2; } while (0)
TRANSFER1(0);
TRANSFER1(1);
TRANSFER1(2);
TRANSFER1(3);
TRANSFER1(4);
TRANSFER1(5);
TRANSFER1(6);
TRANSFER1(7);
TRANSFER1(8);
TRANSFER1(9);
TRANSFER1(10);
TRANSFER1(11);
TRANSFER1(12);
TRANSFER1(13);
TRANSFER1(14);
TRANSFER1(15);
TRANSFER1(16);
}
bool AVRSPI2DeviceDriver::transaction(const uint8_t *tx, uint8_t *rx,
uint16_t len) {
_cs_assert();
if (rx == NULL) {
for (uint16_t i = 0; i < len; i++) {
_transfer(tx[i]);
}
} else {
while (len >= 17) {
_transfer17(tx, rx);
tx += 17;
rx += 17;
len -= 17;
}
for (uint16_t i = 0; i < len; i++) {
rx[i] = _transfer(tx[i]);
}
}
_cs_release();
return true;
}
void AVRSPI2DeviceDriver::cs_assert() {
_cs_assert();
}
void AVRSPI2DeviceDriver::cs_release() {
_cs_release();
}
uint8_t AVRSPI2DeviceDriver::transfer(uint8_t data) {
return _transfer(data);
}
void AVRSPI2DeviceDriver::transfer(const uint8_t *data, uint16_t len) {
while (len--)
_transfer(*data++);
}
#endif

124
libraries/AP_HAL_AVR/SPIDevice_SPI3.cpp

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <AP_HAL/AP_HAL.h>
#include "SPIDevices.h"
#include "GPIO.h"
#include "Semaphores.h"
#include "utility/pins_arduino_mega.h"
using namespace AP_HAL_AVR;
#define SPI3_MOSI 14
#define SPI3_MISO 15
extern const AP_HAL::HAL& hal;
AVRSemaphore AVRSPI3DeviceDriver::_semaphore;
void AVRSPI3DeviceDriver::init() {
/* the spi3 (USART3) sck pin PORTJ2 is not enumerated
* by the arduino pin numbers, so we access it directly
* with AVRDigitalSource. */
AVRDigitalSource spi3_sck(_BV(2), PJ);
spi3_sck.mode(HAL_GPIO_OUTPUT);
hal.gpio->pinMode(SPI3_MOSI, HAL_GPIO_OUTPUT);
hal.gpio->pinMode(SPI3_MISO, HAL_GPIO_INPUT);
/* UMSELn1 and UMSELn2: USART in SPI Master mode */
UCSR3C = _BV(UMSEL31) | _BV(UMSEL30);
/* Enable RX and TX. */
UCSR3B = _BV(RXEN3) | _BV(TXEN3);
/* Setup chip select pin */
_cs_pin->mode(HAL_GPIO_OUTPUT);
_cs_pin->write(1);
}
AP_HAL::Semaphore* AVRSPI3DeviceDriver::get_semaphore() {
return &_semaphore;
}
void AVRSPI3DeviceDriver::_cs_assert()
{
/* set the device UCSRnC configuration bits.
* only sets data order, clock phase, and clock polarity bits (lowest
* three bits) */
const uint8_t new_ucsr3c = (UCSR3C & ~0x07) | (_ucsr3c & (0x07));
UCSR3C = new_ucsr3c;
/* set the device baud rate */
UBRR3 = _ubrr3;
_cs_pin->write(0);
}
void AVRSPI3DeviceDriver::_cs_release() {
_cs_pin->write(1);
}
uint8_t AVRSPI3DeviceDriver::_transfer(uint8_t data) {
/* Wait for empty transmit buffer */
while ( !( UCSR3A & _BV(UDRE3)) ) ;
/* Put data into buffer, sends the data */
UDR3 = data;
/* Wait for data to be received */
while ( !(UCSR3A & _BV(RXC3)) ) ;
/* Get and return received data from buffer */
return UDR3;
}
void AVRSPI3DeviceDriver::_transfer(const uint8_t *data, uint16_t len) {
while (len--) {
/* Wait for empty transmit buffer */
while ( !( UCSR3A & _BV(UDRE3)) ) ;
/* Put data into buffer, sends the data */
UDR3 = *data++;
/* Wait for data to be received */
while ( !(UCSR3A & _BV(RXC3)) ) ;
// dummy read of UDR3 to complete
UDR3;
}
}
bool AVRSPI3DeviceDriver::transaction(const uint8_t *tx, uint8_t *rx,
uint16_t len) {
_cs_assert();
if (rx == NULL) {
_transfer(tx, len);
} else {
for (uint16_t i = 0; i < len; i++) {
rx[i] = _transfer(tx[i]);
}
}
_cs_release();
return true;
}
void AVRSPI3DeviceDriver::cs_assert() {
_cs_assert();
}
void AVRSPI3DeviceDriver::cs_release() {
_cs_release();
}
uint8_t AVRSPI3DeviceDriver::transfer(uint8_t data) {
return _transfer(data);
}
void AVRSPI3DeviceDriver::transfer(const uint8_t *data, uint16_t len) {
_transfer(data, len);
}
#endif

124
libraries/AP_HAL_AVR/SPIDevices.h

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
#ifndef __AP_HAL_AVR_SPI_DEVICES_H__
#define __AP_HAL_AVR_SPI_DEVICES_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
class AP_HAL_AVR::AVRSPI0DeviceDriver : public AP_HAL::SPIDeviceDriver {
public:
AVRSPI0DeviceDriver(
AP_HAL_AVR::AVRDigitalSource *cs_pin,
uint8_t spcr_lowspeed,
uint8_t spcr_highspeed,
uint8_t spsr
) :
_cs_pin(cs_pin),
_spcr_lowspeed(spcr_lowspeed),
_spcr_highspeed(spcr_highspeed),
_spcr(spcr_lowspeed),
_spsr(spsr)
{}
void init();
AP_HAL::Semaphore* get_semaphore();
bool transaction(const uint8_t *tx, uint8_t *rx, uint16_t len);
void cs_assert();
void cs_release();
uint8_t transfer(uint8_t data);
void transfer(const uint8_t *data, uint16_t len);
void set_bus_speed(enum bus_speed speed);
private:
void _cs_assert();
void _cs_release();
uint8_t _transfer(uint8_t data);
// used for MPU6k
void _transfer16(const uint8_t *tx, uint8_t *rx);
static AP_HAL_AVR::AVRSemaphore _semaphore;
static bool _force_low_speed;
AP_HAL_AVR::AVRDigitalSource *_cs_pin;
const uint8_t _spcr_lowspeed;
const uint8_t _spcr_highspeed;
uint8_t _spcr;
const uint8_t _spsr;
};
class AP_HAL_AVR::AVRSPI2DeviceDriver : public AP_HAL::SPIDeviceDriver {
public:
AVRSPI2DeviceDriver(
AP_HAL_AVR::AVRDigitalSource *cs_pin,
uint8_t ucsr2c,
uint16_t ubrr2
) :
_cs_pin(cs_pin),
_ucsr2c(ucsr2c),
_ubrr2(ubrr2)
{}
void init();
AP_HAL::Semaphore* get_semaphore();
bool transaction(const uint8_t *tx, uint8_t *rx, uint16_t len);
void cs_assert();
void cs_release();
uint8_t transfer(uint8_t data);
void transfer(const uint8_t *data, uint16_t len);
private:
void _cs_assert();
void _cs_release();
uint8_t _transfer(uint8_t data);
// used for APM1 ADC
void _transfer17(const uint8_t *tx, uint8_t *rx);
static AP_HAL_AVR::AVRSemaphore _semaphore;
AP_HAL_AVR::AVRDigitalSource *_cs_pin;
uint8_t _ucsr2c;
uint16_t _ubrr2;
};
class AP_HAL_AVR::AVRSPI3DeviceDriver : public AP_HAL::SPIDeviceDriver {
public:
AVRSPI3DeviceDriver(
AP_HAL_AVR::AVRDigitalSource *cs_pin,
uint8_t ucsr3c,
uint16_t ubrr3
) :
_cs_pin(cs_pin),
_ucsr3c(ucsr3c),
_ubrr3(ubrr3)
{}
void init();
AP_HAL::Semaphore* get_semaphore();
bool transaction(const uint8_t *tx, uint8_t *rx, uint16_t len);
void cs_assert();
void cs_release();
uint8_t transfer(uint8_t data);
void transfer(const uint8_t *data, uint16_t len);
private:
void _cs_assert();
void _cs_release();
uint8_t _transfer(uint8_t data);
void _transfer(const uint8_t *data, uint16_t size);
static AP_HAL_AVR::AVRSemaphore _semaphore;
AP_HAL_AVR::AVRDigitalSource *_cs_pin;
uint8_t _ucsr3c;
uint16_t _ubrr3;
};
#endif // __AP_HAL_AVR_SPI_DEVICES_H__

38
libraries/AP_HAL_AVR/SPIDriver.h

@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
#ifndef __AP_HAL_AVR_SPI_DRIVER_H__
#define __AP_HAL_AVR_SPI_DRIVER_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#include "GPIO.h"
#include "SPIDevices.h"
#include "Semaphores.h"
class AP_HAL_AVR::APM1SPIDeviceManager : public AP_HAL::SPIDeviceManager {
public:
void init(void* machtnichts);
AP_HAL::SPIDeviceDriver* device(enum AP_HAL::SPIDevice d);
private:
AVRSPI0DeviceDriver* _dataflash;
AVRSPI0DeviceDriver* _optflow;
AVRSPI2DeviceDriver* _adc;
};
class AP_HAL_AVR::APM2SPIDeviceManager : public AP_HAL::SPIDeviceManager {
public:
void init(void* machtnichts);
AP_HAL::SPIDeviceDriver* device(enum AP_HAL::SPIDevice d);
private:
AVRSPI0DeviceDriver* _mpu6k;
AVRSPI0DeviceDriver* _ms5611;
AVRSPI0DeviceDriver* _optflow_spi0;
AVRSPI3DeviceDriver* _dataflash;
AVRSPI3DeviceDriver* _optflow_spi3;
};
#endif // __AP_HAL_AVR_SPI_DRIVER_H__

277
libraries/AP_HAL_AVR/Scheduler.cpp

@ -1,277 +0,0 @@ @@ -1,277 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "Scheduler.h"
#include "utility/ISRRegistry.h"
#include "memcheck.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
/* AVRScheduler timer interrupt period is controlled by TCNT2.
* 256-124 gives a 500Hz period
* 256-62 gives a 1kHz period. */
volatile uint8_t AVRScheduler::_timer2_reset_value = (256 - 62);
/* Static AVRScheduler variables: */
AVRTimer AVRScheduler::_timer;
AP_HAL::Proc AVRScheduler::_failsafe = NULL;
volatile bool AVRScheduler::_timer_suspended = false;
volatile bool AVRScheduler::_timer_event_missed = false;
volatile bool AVRScheduler::_in_timer_proc = false;
AP_HAL::MemberProc AVRScheduler::_timer_proc[AVR_SCHEDULER_MAX_TIMER_PROCS] = {NULL};
uint8_t AVRScheduler::_num_timer_procs = 0;
AVRScheduler::AVRScheduler() :
_delay_cb(NULL),
_min_delay_cb_ms(65535),
_initialized(false)
{}
void AVRScheduler::init(void* _isrregistry) {
ISRRegistry* isrregistry = (ISRRegistry*) _isrregistry;
/* _timer: sets up timer hardware to implement millis & micros. */
_timer.init();
/* TIMER2: Setup the overflow interrupt to occur at 1khz. */
TIMSK2 = 0; /* Disable timer interrupt */
TCCR2A = 0; /* Normal counting mode */
TCCR2B = _BV(CS21) | _BV(CS22); /* Prescaler to clk/256 */
TCNT2 = 0; /* Set count to 0 */
TIFR2 = _BV(TOV2); /* Clear pending interrupts */
TIMSK2 = _BV(TOIE2); /* Enable overflow interrupt*/
/* Register _timer_isr_event to trigger on overflow */
isrregistry->register_signal(ISR_REGISTRY_TIMER2_OVF, _timer_isr_event);
/* Turn on global interrupt flag, AVR interupt system will start from this point */
sei();
memcheck_init();
}
uint32_t AVRScheduler::micros() {
return _timer.micros();
}
uint32_t AVRScheduler::millis() {
return _timer.millis();
}
/*
64 bit version of millis(). This wraps at 32 bits on AVR
*/
uint64_t AVRScheduler::millis64() {
return millis();
}
/*
64 bit version of micros(). This wraps when 32 bit millis() wraps
*/
uint64_t AVRScheduler::micros64() {
// this is slow, but solves the problem with logging uint64_t timestamps
uint64_t ret = millis();
ret *= 1000ULL;
ret += micros() % 1000UL;
return ret;
}
void AVRScheduler::delay_microseconds(uint16_t us) {
_timer.delay_microseconds(us);
}
void AVRScheduler::delay(uint16_t ms)
{
uint32_t start = _timer.micros();
while (ms > 0) {
while ((_timer.micros() - start) >= 1000) {
ms--;
if (ms == 0) break;
start += 1000;
}
if (_min_delay_cb_ms <= ms) {
if (_delay_cb) {
_delay_cb();
}
}
}
}
void AVRScheduler::register_delay_callback(AP_HAL::Proc proc,
uint16_t min_time_ms) {
_delay_cb = proc;
_min_delay_cb_ms = min_time_ms;
}
void AVRScheduler::register_timer_process(AP_HAL::MemberProc proc)
{
for (int i = 0; i < _num_timer_procs; i++) {
if (_timer_proc[i] == proc) {
return;
}
}
if (_num_timer_procs < AVR_SCHEDULER_MAX_TIMER_PROCS) {
/* this write to _timer_proc can be outside the critical section
* because that memory won't be used until _num_timer_procs is
* incremented. */
_timer_proc[_num_timer_procs] = proc;
/* _num_timer_procs is used from interrupt, and multiple bytes long. */
uint8_t sreg = SREG;
cli();
_num_timer_procs++;
SREG = sreg;
}
}
void AVRScheduler::register_io_process(AP_HAL::MemberProc proc)
{
// IO processes not supported on AVR
}
void AVRScheduler::register_timer_failsafe(AP_HAL::Proc failsafe, uint32_t period_us) {
/* XXX Assert period_us == 1000 */
_failsafe = failsafe;
}
void AVRScheduler::suspend_timer_procs() {
_timer_suspended = true;
}
void AVRScheduler::resume_timer_procs() {
_timer_suspended = false;
if (_timer_event_missed == true) {
_run_timer_procs(false);
_timer_event_missed = false;
}
}
bool AVRScheduler::in_timerprocess() {
return _in_timer_proc;
}
void AVRScheduler::_timer_isr_event() {
// we enable the interrupt again immediately and also enable
// interrupts. This allows other time critical interrupts to
// run (such as the serial receive interrupt). We catch the
// timer calls taking too long using _in_timer_call.
// This approach also gives us a nice uniform spacing between
// timer calls
TCNT2 = _timer2_reset_value;
sei();
_run_timer_procs(true);
}
void AVRScheduler::_run_timer_procs(bool called_from_isr) {
if (_in_timer_proc) {
// the timer calls took longer than the period of the
// timer. This is bad, and may indicate a serious
// driver failure. We can't just call the drivers
// again, as we could run out of stack. So we only
// call the _failsafe call. It's job is to detect if
// the drivers or the main loop are indeed dead and to
// activate whatever failsafe it thinks may help if
// need be. We assume the failsafe code can't
// block. If it does then we will recurse and die when
// we run out of stack
if (_failsafe != NULL) {
_failsafe();
}
return;
}
_in_timer_proc = true;
if (!_timer_suspended) {
// now call the timer based drivers
for (int i = 0; i < _num_timer_procs; i++) {
if (_timer_proc[i]) {
_timer_proc[i]();
}
}
} else if (called_from_isr) {
_timer_event_missed = true;
}
// and the failsafe, if one is setup
if (_failsafe != NULL) {
_failsafe();
}
_in_timer_proc = false;
}
bool AVRScheduler::system_initializing() {
return !_initialized;
}
void AVRScheduler::system_initialized() {
if (_initialized) {
panic(PSTR("PANIC: scheduler::system_initialized called"
"more than once"));
}
_initialized = true;
}
void AVRScheduler::panic(const prog_char_t* errormsg, ...) {
/* Suspend timer processes. We still want the timer event to go off
* to run the _failsafe code, however. */
_timer_suspended = true;
/* Print the error message on both ports */
hal.uartA->println_P(errormsg);
hal.uartC->println_P(errormsg);
/* Spin forever. */
for(;;);
}
void AVRScheduler::reboot(bool hold_in_bootloader) {
hal.uartA->println_P(PSTR("GOING DOWN FOR A REBOOT\r\n"));
hal.scheduler->delay(100);
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
/* The APM2 bootloader will reset the watchdog shortly after
* starting, so we can use the watchdog to force a reboot
*/
cli();
wdt_enable(WDTO_15MS);
for(;;);
#else
cli();
/* Making a null pointer call will cause all AVRs to reboot
* but they may not come back alive properly - we need to setup
* the IO the way the bootloader would.
*/
void (*fn)(void) = NULL;
fn();
for(;;);
#endif
}
/**
set timer speed in Hz. Used by ArduCopter on APM2 to reduce the
cost of timer interrupts
*/
void AVRScheduler::set_timer_speed(uint16_t timer_hz)
{
if (timer_hz > 1000) {
timer_hz = 1000;
}
if (timer_hz < 250) {
timer_hz = 250;
}
_timer2_reset_value = 256 - (62 * (1000 / timer_hz));
}
#endif

77
libraries/AP_HAL_AVR/Scheduler.h

@ -1,77 +0,0 @@ @@ -1,77 +0,0 @@
#ifndef __AP_HAL_AVR_SCHEDULER_H__
#define __AP_HAL_AVR_SCHEDULER_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#define AVR_SCHEDULER_MAX_TIMER_PROCS 4
/* Class for managing the AVR Timers: */
class AP_HAL_AVR::AVRTimer {
public:
static void init();
static uint32_t millis();
static uint32_t micros();
static void delay_microseconds(uint16_t us);
};
/* Scheduler implementation: */
class AP_HAL_AVR::AVRScheduler : public AP_HAL::Scheduler {
public:
AVRScheduler();
/* AP_HAL::Scheduler methods */
/* init: implementation-specific void* argument expected to be an
* AP_HAL_AVR::ISRRegistry*. */
void init(void *isrregistry);
void delay(uint16_t ms);
uint32_t millis();
uint32_t micros();
uint64_t millis64();
uint64_t micros64();
void delay_microseconds(uint16_t us);
void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms);
void register_timer_process(AP_HAL::MemberProc);
void register_io_process(AP_HAL::MemberProc);
void suspend_timer_procs();
void resume_timer_procs();
bool in_timerprocess();
void register_timer_failsafe(AP_HAL::Proc, uint32_t period_us);
bool system_initializing();
void system_initialized();
void panic(const prog_char_t *errormsg, ...) FORMAT(2, 3) NORETURN;
void reboot(bool hold_in_bootloader);
void set_timer_speed(uint16_t timer_hz);
private:
static AVRTimer _timer;
static volatile bool _in_timer_proc;
AP_HAL::Proc _delay_cb;
uint16_t _min_delay_cb_ms;
bool _initialized;
/* _timer_isr_event() and _run_timer_procs are static so they can be
* called from an interrupt. */
static void _timer_isr_event();
static void _run_timer_procs(bool called_from_isr);
static AP_HAL::Proc _failsafe;
static volatile bool _timer_suspended;
static volatile bool _timer_event_missed;
static AP_HAL::MemberProc _timer_proc[AVR_SCHEDULER_MAX_TIMER_PROCS];
static uint8_t _num_timer_procs;
static volatile uint8_t _timer2_reset_value;
};
#endif // __AP_HAL_AVR_SCHEDULER_H__

157
libraries/AP_HAL_AVR/Scheduler_Timer.cpp

@ -1,157 +0,0 @@ @@ -1,157 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include "Scheduler.h"
using namespace AP_HAL_AVR;
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 )
#define AVR_TIMER_OVF_VECT TIMER4_OVF_vect
#define AVR_TIMER_TCNT TCNT4
#define AVR_TIMER_TIFR TIFR4
#define AVR_TIMER_TCCRA TCCR4A
#define AVR_TIMER_TCCRB TCCR4B
#define AVR_TIMER_OCRA OCR4A
#define AVR_TIMER_TIMSK TIMSK4
#define AVR_TIMER_TOIE TOIE4
#define AVR_TIMER_WGM0 WGM40
#define AVR_TIMER_WGM1 WGM41
#define AVR_TIMER_WGM2 WGM42
#define AVR_TIMER_WGM3 WGM43
#define AVR_TIMER_CS1 CS41
#elif (CONFIG_HAL_BOARD == HAL_BOARD_APM2 )
#define AVR_TIMER_OVF_VECT TIMER5_OVF_vect
#define AVR_TIMER_TCNT TCNT5
#define AVR_TIMER_TIFR TIFR5
#define AVR_TIMER_TCCRA TCCR5A
#define AVR_TIMER_TCCRB TCCR5B
#define AVR_TIMER_OCRA OCR5A
#define AVR_TIMER_TIMSK TIMSK5
#define AVR_TIMER_TOIE TOIE5
#define AVR_TIMER_WGM0 WGM50
#define AVR_TIMER_WGM1 WGM51
#define AVR_TIMER_WGM2 WGM52
#define AVR_TIMER_WGM3 WGM53
#define AVR_TIMER_CS1 CS51
#endif
static volatile uint32_t timer_micros_counter = 0;
static volatile uint32_t timer_millis_counter = 0;
void AVRTimer::init() {
uint8_t oldSREG = SREG;
cli();
// Timer cleanup before configuring
AVR_TIMER_TCNT = 0;
AVR_TIMER_TIFR = 0;
// Set timer 8x prescaler fast PWM mode toggle compare at OCRA
AVR_TIMER_TCCRA = _BV( AVR_TIMER_WGM0 ) | _BV( AVR_TIMER_WGM1 );
AVR_TIMER_TCCRB |= _BV( AVR_TIMER_WGM3 ) | _BV( AVR_TIMER_WGM2 ) | _BV( AVR_TIMER_CS1 );
AVR_TIMER_OCRA = 40000 - 1; // -1 to correct for wrap
// Enable overflow interrupt
AVR_TIMER_TIMSK |= _BV( AVR_TIMER_TOIE );
// set a2d prescale factor to 128
// 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
// XXX: this will not work properly for other clock speeds, and
// this code should use F_CPU to determine the prescale factor.
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
// enable a2d conversions
sbi(ADCSRA, ADEN);
// the bootloader connects pins 0 and 1 to the USART; disconnect them
// here so they can be used as normal digital i/o; they will be
// reconnected in Serial.begin()
UCSR0B = 0;
SREG = oldSREG;
}
SIGNAL( AVR_TIMER_OVF_VECT)
{
// Hardcoded for AVR@16MHZ and 8x pre-scale 16-bit timer overflow at 40000
timer_micros_counter += 40000 / 2; // 20000us each overflow
timer_millis_counter += 40000 / 2000; // 20ms each overlflow
}
uint32_t AVRTimer::micros() {
uint8_t oldSREG = SREG;
cli();
// Hardcoded for AVR@16MHZ and 8x pre-scale 16-bit timer
//uint32_t time_micros = timer_micros_counter + (AVR_TIMER_TCNT / 2);
//uint32_t time_micros = timer_micros_counter + (AVR_TIMER_TCNT >> 1);
uint32_t time_micros = timer_micros_counter;
uint16_t tcnt = AVR_TIMER_TCNT;
// Check for imminent timer overflow interrupt and pre-increment counter
if ( AVR_TIMER_TIFR & 1 && tcnt < 39999 )
{
time_micros += 40000 / 2;
}
SREG = oldSREG;
return time_micros + (tcnt >> 1);
}
uint32_t AVRTimer::millis() {
uint8_t oldSREG = SREG;
cli();
// Hardcoded for AVR@16MHZ and 8x pre-scale 16-bit timer
//uint32_t time_millis = timer_millis_counter + (AVR_TIMER_TCNT / 2000) ;
//uint32_t time_millis = timer_millis_counter + (AVR_TIMER_TCNT >> 11); // AVR_TIMER_CNT / 2048 is close enough (24us counter delay)
uint32_t time_millis = timer_millis_counter;
uint16_t tcnt = AVR_TIMER_TCNT;
// Check for imminent timer overflow interrupt and pre-increment counter
if ( AVR_TIMER_TIFR & 1 && tcnt < 39999 )
{
time_millis += 40000 / 2000;
}
SREG = oldSREG;
return time_millis + (tcnt >> 11);
}
/* Delay for the given number of microseconds. Assumes a 16 MHz clock. */
void AVRTimer::delay_microseconds(uint16_t us)
{
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call yields a delay of approximately 1 1/8 us.
if (--us == 0)
return;
// the following loop takes a quarter of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2;
// account for the time taken in the preceeding commands.
us -= 2;
// busy wait
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t" // 2 cycles
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
);
}
#endif

80
libraries/AP_HAL_AVR/Semaphores.cpp

@ -1,80 +0,0 @@ @@ -1,80 +0,0 @@
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR.h"
#include "Semaphores.h"
#include "Scheduler.h"
using namespace AP_HAL_AVR;
extern const AP_HAL::HAL& hal;
// Constructor
AVRSemaphore::AVRSemaphore() : _taken(false) {}
bool AVRSemaphore::give() {
if (!_taken) {
return false;
} else {
_taken = false;
return true;
}
}
bool AVRSemaphore::take(uint32_t timeout_ms) {
if (hal.scheduler->in_timerprocess()) {
hal.scheduler->panic(PSTR("PANIC: AVRSemaphore::take used from "
"inside timer process"));
return false; /* Never reached - panic does not return */
}
return _take_from_mainloop(timeout_ms);
}
bool AVRSemaphore::take_nonblocking() {
if (hal.scheduler->in_timerprocess()) {
return _take_nonblocking();
} else {
return _take_from_mainloop(0);
}
}
bool AVRSemaphore::_take_from_mainloop(uint32_t timeout_ms) {
/* Try to take immediately */
if (_take_nonblocking()) {
return true;
} else if (timeout_ms == 0) {
/* Return immediately if timeout is 0 */
return false;
}
uint16_t timeout_ticks = timeout_ms*10;
do {
/* Delay 1ms until we can successfully take, or we timed out */
hal.scheduler->delay_microseconds(100);
timeout_ticks--;
if (_take_nonblocking()) {
return true;
}
} while (timeout_ticks > 0);
return false;
}
bool AVRSemaphore::_take_nonblocking() {
bool result = false;
uint8_t sreg = SREG;
cli();
if (!_taken) {
_taken = true;
result = true;
}
SREG = sreg;
return result;
}
#endif // CONFIG_HAL_BOARD

23
libraries/AP_HAL_AVR/Semaphores.h

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
#ifndef __AP_HAL_AVR_SEMAPHORES_H__
#define __AP_HAL_AVR_SEMAPHORES_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
class AP_HAL_AVR::AVRSemaphore : public AP_HAL::Semaphore {
public:
AVRSemaphore();
bool give();
bool take(uint32_t timeout_ms);
bool take_nonblocking();
protected:
bool _take_from_mainloop(uint32_t timeout_ms);
bool _take_nonblocking();
volatile bool _taken;
};
#endif // __AP_HAL_AVR_SEMAPHORES_H__

31
libraries/AP_HAL_AVR/Storage.cpp

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <avr/io.h>
#include <avr/eeprom.h>
#include "Storage.h"
using namespace AP_HAL_AVR;
void AVREEPROMStorage::read_block(void *dst, uint16_t src, size_t n)
{
eeprom_read_block(dst,(const void*)src,n);
}
void AVREEPROMStorage::write_block(uint16_t dst, const void *src, size_t n)
{
uint8_t *p = (uint8_t *)src;
while (n--) {
/*
it is much faster to read than write, so it is worth
checking if the value is already correct
*/
uint8_t b = eeprom_read_byte((uint8_t*)dst);
if (b != *p) {
eeprom_write_byte((uint8_t*)dst, *p);
}
dst++;
p++;
}
}
#endif

17
libraries/AP_HAL_AVR/Storage.h

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
#ifndef __AP_HAL_AVR_STORAGE_H__
#define __AP_HAL_AVR_STORAGE_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
class AP_HAL_AVR::AVREEPROMStorage : public AP_HAL::Storage {
public:
AVREEPROMStorage() {}
void init(void* machtnichts) {}
void read_block(void *dst, uint16_t src, size_t n);
void write_block(uint16_t dst, const void* src, size_t n);
};
#endif // __AP_HAL_AVR_STORAGE_H__

313
libraries/AP_HAL_AVR/UARTDriver.cpp

@ -1,313 +0,0 @@ @@ -1,313 +0,0 @@
// -*- Mode: C++; c-basic-offset: 8; indent-tabs-mode: nil -*-
/*
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/>.
*/
//
// Copyright (c) 2010 Michael Smith. All rights reserved.
//
#include <AP_HAL/AP_HAL.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <limits.h>
#include <stdlib.h>
#include <stdarg.h>
#include <avr/pgmspace.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_Math/AP_Math.h>
#include "UARTDriver.h"
using namespace AP_HAL_AVR;
#define FS_MAX_PORTS 4
AVRUARTDriver::Buffer __AVRUARTDriver__rxBuffer[FS_MAX_PORTS];
AVRUARTDriver::Buffer __AVRUARTDriver__txBuffer[FS_MAX_PORTS];
AVRUARTDriver::AVRUARTDriver(
const uint8_t portNumber, volatile uint8_t *ubrrh,
volatile uint8_t *ubrrl, volatile uint8_t *ucsra,
volatile uint8_t *ucsrb, const uint8_t u2x,
const uint8_t portEnableBits, const uint8_t portTxBits) :
_ubrrh(ubrrh),
_ubrrl(ubrrl),
_ucsra(ucsra),
_ucsrb(ucsrb),
_u2x(u2x),
_portEnableBits(portEnableBits),
_portTxBits(portTxBits),
_rxBuffer(&__AVRUARTDriver__rxBuffer[portNumber]),
_txBuffer(&__AVRUARTDriver__txBuffer[portNumber])
{
_initialized = true;
begin(57600);
}
/* UARTDriver method implementations */
void AVRUARTDriver::begin(uint32_t baud, uint16_t rxSpace, uint16_t txSpace) {
uint16_t ubrr;
bool use_u2x = true;
bool need_allocate = true;
// if we are currently open...
if (_open) {
// If the caller wants to preserve the buffer sizing, work out what
// it currently is...
if (0 == rxSpace)
rxSpace = _rxBuffer->mask + 1;
if (0 == txSpace)
txSpace = _txBuffer->mask + 1;
if (rxSpace == (_rxBuffer->mask + 1U) &&
txSpace == (_txBuffer->mask + 1U)) {
// avoid re-allocating the buffers if possible
need_allocate = false;
*_ucsrb &= ~(_portEnableBits | _portTxBits);
} else {
// close the port in its current configuration, clears _open
end();
}
}
if (need_allocate) {
// allocate buffers
if (!_allocBuffer(_rxBuffer, rxSpace ? : _default_rx_buffer_size)
|| !_allocBuffer(_txBuffer, txSpace ? : _default_tx_buffer_size)) {
end();
return; // couldn't allocate buffers - fatal
}
}
// reset buffer pointers
_txBuffer->head = _txBuffer->tail = 0;
_rxBuffer->head = _rxBuffer->tail = 0;
// mark the port as open
_open = true;
// If the user has supplied a new baud rate, compute the new UBRR value.
if (baud > 0) {
#if F_CPU == 16000000UL
// hardcoded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560.
if (baud == 57600)
use_u2x = false;
#endif
if (use_u2x) {
*_ucsra = 1 << _u2x;
ubrr = (F_CPU / 4 / baud - 1) / 2;
} else {
*_ucsra = 0;
ubrr = (F_CPU / 8 / baud - 1) / 2;
}
*_ubrrh = ubrr >> 8;
*_ubrrl = ubrr;
}
*_ucsrb |= _portEnableBits;
}
void AVRUARTDriver::end() {
*_ucsrb &= ~(_portEnableBits | _portTxBits);
_freeBuffer(_rxBuffer);
_freeBuffer(_txBuffer);
_open = false;
}
int16_t AVRUARTDriver::available(void) {
if (!_open)
return (-1);
return ((_rxBuffer->head - _rxBuffer->tail) & _rxBuffer->mask);
}
int16_t AVRUARTDriver::txspace(void) {
if (!_open)
return (-1);
return ((_txBuffer->mask+1) - ((_txBuffer->head - _txBuffer->tail) & _txBuffer->mask));
}
int16_t AVRUARTDriver::read(void) {
uint8_t c;
// if the head and tail are equal, the buffer is empty
if (!_open || (_rxBuffer->head == _rxBuffer->tail))
return (-1);
// pull character from tail
c = _rxBuffer->bytes[_rxBuffer->tail];
_rxBuffer->tail = (_rxBuffer->tail + 1) & _rxBuffer->mask;
return (c);
}
void AVRUARTDriver::flush(void) {
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of _rxBuffer->head but before writing
// the value to _rxBuffer->tail; the previous value of head
// may be written to tail, making it appear as if the buffer
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of head but before writing
// the value to tail; the previous value of rx_buffer_head
// may be written to tail, making it appear as if the buffer
// were full, not empty.
_rxBuffer->head = _rxBuffer->tail;
// don't reverse this or there may be problems if the TX interrupt
// occurs after reading the value of _txBuffer->tail but before writing
// the value to _txBuffer->head.
_txBuffer->tail = _txBuffer->head;
}
size_t AVRUARTDriver::write(uint8_t c) {
uint8_t i;
if (!_open) // drop bytes if not open
return 0;
// wait for room in the tx buffer
i = (_txBuffer->head + 1) & _txBuffer->mask;
// if the port is set into non-blocking mode, then drop the byte
// if there isn't enough room for it in the transmit buffer
if (_nonblocking_writes && i == _txBuffer->tail) {
return 0;
}
while (i == _txBuffer->tail)
;
// add byte to the buffer
_txBuffer->bytes[_txBuffer->head] = c;
_txBuffer->head = i;
// enable the data-ready interrupt, as it may be off if the buffer is empty
*_ucsrb |= _portTxBits;
// return number of bytes written (always 1)
return 1;
}
/*
write size bytes to the write buffer
*/
size_t AVRUARTDriver::write(const uint8_t *buffer, size_t size)
{
if (!_open) {
return 0;
}
if (!_nonblocking_writes) {
/*
use the per-byte delay loop in write() above for blocking writes
*/
size_t ret = 0;
while (size--) {
if (write(*buffer++) != 1) break;
ret++;
}
return ret;
}
int16_t space = txspace();
if (space <= 0) {
return 0;
}
if (size > (size_t)space) {
// throw away remainder if too much data
size = space;
}
if (_txBuffer->tail > _txBuffer->head) {
// perform as single memcpy
memcpy(&_txBuffer->bytes[_txBuffer->head], buffer, size);
_txBuffer->head = (_txBuffer->head + size) & _txBuffer->mask;
// enable the data-ready interrupt, as it may be off if the buffer is empty
*_ucsrb |= _portTxBits;
return size;
}
// perform as two memcpy calls
uint16_t n = (_txBuffer->mask+1) - _txBuffer->head;
if (n > size) n = size;
memcpy(&_txBuffer->bytes[_txBuffer->head], buffer, n);
_txBuffer->head = (_txBuffer->head + n) & _txBuffer->mask;
buffer += n;
n = size - n;
if (n > 0) {
memcpy(&_txBuffer->bytes[0], buffer, n);
_txBuffer->head = (_txBuffer->head + n) & _txBuffer->mask;
}
// enable the data-ready interrupt, as it may be off if the buffer is empty
*_ucsrb |= _portTxBits;
return size;
}
// Buffer management ///////////////////////////////////////////////////////////
bool AVRUARTDriver::_allocBuffer(Buffer *buffer, uint16_t size)
{
uint8_t mask;
uint8_t shift;
// init buffer state
buffer->head = buffer->tail = 0;
// Compute the power of 2 greater or equal to the requested buffer size
// and then a mask to simplify wrapping operations. Using __builtin_clz
// would seem to make sense, but it uses a 256(!) byte table.
// Note that we ignore requests for more than BUFFER_MAX space.
for (shift = 1; (1U << shift) < min(_max_buffer_size, size); shift++)
;
mask = (1U << shift) - 1;
// If the descriptor already has a buffer allocated we need to take
// care of it.
if (buffer->bytes) {
// If the allocated buffer is already the correct size then
// we have nothing to do
if (buffer->mask == mask)
return true;
// Dispose of the old buffer.
free(buffer->bytes);
}
buffer->mask = mask;
// allocate memory for the buffer - if this fails, we fail.
buffer->bytes = (uint8_t *) malloc(buffer->mask + (size_t)1);
return (buffer->bytes != NULL);
}
void AVRUARTDriver::_freeBuffer(Buffer *buffer)
{
buffer->head = buffer->tail = 0;
buffer->mask = 0;
if (NULL != buffer->bytes) {
free(buffer->bytes);
buffer->bytes = NULL;
}
}
#endif

208
libraries/AP_HAL_AVR/UARTDriver.h

@ -1,208 +0,0 @@ @@ -1,208 +0,0 @@
#ifndef __AP_HAL_AVR_UART_DRIVER_H__
#define __AP_HAL_AVR_UART_DRIVER_H__
#include <AP_HAL/AP_HAL_Boards.h>
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2)
#include <stdint.h>
#include <stdarg.h>
#include <avr/interrupt.h>
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
/**
* AVRUARTDriver is an implementation of UARTDriver for the AVR.
* It will be a thin wrapper on FastSerial.
*/
class AP_HAL_AVR::AVRUARTDriver : public AP_HAL::UARTDriver {
public:
AVRUARTDriver(
const uint8_t portNumber, volatile uint8_t *ubrrh,
volatile uint8_t *ubrrl, volatile uint8_t *ucsra,
volatile uint8_t *ucsrb, const uint8_t u2x,
const uint8_t portEnableBits, const uint8_t portTxBits);
/* Implementations of UARTDriver virtual methods */
void begin(uint32_t b) { begin(b, 0, 0); }
void begin(uint32_t b, uint16_t rxS, uint16_t txS);
void end();
void flush();
bool is_initialized() { return _initialized; }
void set_blocking_writes(bool blocking) {
_nonblocking_writes = !blocking;
}
bool tx_pending() {
return (_txBuffer->head != _txBuffer->tail);
}
/* Implementations of Stream virtual methods */
int16_t available();
int16_t txspace();
int16_t read();
/* Implementations of Print virtual methods */
size_t write(uint8_t c);
size_t write(const uint8_t *buffer, size_t size);
/// Transmit/receive buffer descriptor.
///
/// Public so the interrupt handlers can see it
struct Buffer {
volatile uint8_t head, tail; ///< head and tail pointers
uint8_t mask; ///< buffer size mask for pointer wrap
uint8_t *bytes; ///< pointer to allocated buffer
};
private:
/* Instance Variables */
bool _initialized;
// register accessors
volatile uint8_t * const _ubrrh;
volatile uint8_t * const _ubrrl;
volatile uint8_t * const _ucsra;
volatile uint8_t * const _ucsrb;
// register magic numbers
const uint8_t _u2x;
const uint8_t _portEnableBits; ///< rx, tx and rx interrupt enables
const uint8_t _portTxBits; ///< tx data and completion interrupt enables
// ring buffers
Buffer * const _rxBuffer;
Buffer * const _txBuffer;
bool _open;
// whether writes to the port should block waiting
// for enough space to appear
bool _nonblocking_writes;
/* Class Variables */
/// Allocates a buffer of the given size
///
/// @param buffer The buffer descriptor for which the buffer will
/// will be allocated.
/// @param size The desired buffer size.
/// @returns True if the buffer was allocated successfully.
///
static bool _allocBuffer(Buffer *buffer, uint16_t size);
/// Frees the allocated buffer in a descriptor
///
/// @param buffer The descriptor whose buffer should be freed.
///
static void _freeBuffer(Buffer *buffer);
/// default receive buffer size
static const uint16_t _default_rx_buffer_size = 4;
/// default transmit buffer size
static const uint16_t _default_tx_buffer_size = 16;
/// maxium tx/rx buffer size
static const uint16_t _max_buffer_size = 256;
};
extern AP_HAL_AVR::AVRUARTDriver::Buffer __AVRUARTDriver__rxBuffer[];
extern AP_HAL_AVR::AVRUARTDriver::Buffer __AVRUARTDriver__txBuffer[];
/// Generic Rx/Tx vectors for a serial port - needs to know magic numbers
///
#define AVRUARTDriverHandler(_PORT, _RXVECTOR, _TXVECTOR, _UDR, _UCSRB, _TXBITS) \
ISR(_RXVECTOR, ISR_BLOCK) \
{ \
uint8_t c; \
uint8_t i; \
\
/* read the byte as quickly as possible */ \
c = _UDR; \
/* work out where the head will go next */ \
i = (__AVRUARTDriver__rxBuffer[_PORT].head + 1) & __AVRUARTDriver__rxBuffer[_PORT].mask; \
/* decide whether we have space for another byte */ \
if (i != __AVRUARTDriver__rxBuffer[_PORT].tail) { \
/* we do, move the head */ \
__AVRUARTDriver__rxBuffer[_PORT].bytes[__AVRUARTDriver__rxBuffer[_PORT].head] = c; \
__AVRUARTDriver__rxBuffer[_PORT].head = i; \
} \
} \
ISR(_TXVECTOR, ISR_BLOCK) \
{ \
/* if there is another character to send */ \
if (__AVRUARTDriver__txBuffer[_PORT].tail != __AVRUARTDriver__txBuffer[_PORT].head) { \
_UDR = __AVRUARTDriver__txBuffer[_PORT].bytes[__AVRUARTDriver__txBuffer[_PORT].tail]; \
/* increment the tail */ \
__AVRUARTDriver__txBuffer[_PORT].tail = \
(__AVRUARTDriver__txBuffer[_PORT].tail + 1) & __AVRUARTDriver__txBuffer[_PORT].mask; \
} else { \
/* there are no more bytes to send, disable the interrupt */ \
if (__AVRUARTDriver__txBuffer[_PORT].head == __AVRUARTDriver__txBuffer[_PORT].tail) \
_UCSRB &= ~_TXBITS; \
} \
} \
struct hack
//
// Portability; convert various older sets of defines for U(S)ART0 up
// to match the definitions for the 1280 and later devices.
//
#if !defined(USART0_RX_vect)
# if defined(USART_RX_vect)
# define USART0_RX_vect USART_RX_vect
# define USART0_UDRE_vect USART_UDRE_vect
# elif defined(UART0_RX_vect)
# define USART0_RX_vect UART0_RX_vect
# define USART0_UDRE_vect UART0_UDRE_vect
# endif
#endif
#if !defined(USART1_RX_vect)
# if defined(UART1_RX_vect)
# define USART1_RX_vect UART1_RX_vect
# define USART1_UDRE_vect UART1_UDRE_vect
# endif
#endif
#if !defined(UDR0)
# if defined(UDR)
# define UDR0 UDR
# define UBRR0H UBRRH
# define UBRR0L UBRRL
# define UCSR0A UCSRA
# define UCSR0B UCSRB
# define U2X0 U2X
# define RXEN0 RXEN
# define TXEN0 TXEN
# define RXCIE0 RXCIE
# define UDRIE0 UDRIE
# endif
#endif
///
/// Macro defining a AVRUARTDriver port instance.
///
#define AVRUARTDriverInstance(_name, _num) \
AVRUARTDriver _name(_num, \
&UBRR##_num##H, \
&UBRR##_num##L, \
&UCSR##_num##A, \
&UCSR##_num##B, \
U2X##_num, \
(_BV(RXEN##_num) | _BV(TXEN##_num) | _BV(RXCIE##_num)), \
(_BV(UDRIE##_num)));
#define AVRUARTDriverISRs(_num) \
AVRUARTDriverHandler(_num, \
USART##_num##_RX_vect, \
USART##_num##_UDRE_vect, \
UDR##_num, \
UCSR##_num##B, \
_BV(UDRIE##_num))
#endif
#endif // __AP_HAL_AVR_UART_DRIVER_H__

15
libraries/AP_HAL_AVR/Util.h

@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
#ifndef __AP_HAL_AVR_UTIL_H__
#define __AP_HAL_AVR_UTIL_H__
#include <AP_HAL/AP_HAL.h>
#include "AP_HAL_AVR_Namespace.h"
#include "memcheck.h"
class AP_HAL_AVR::AVRUtil : public AP_HAL::Util {
public:
bool run_debug_shell(AP_HAL::BetterStream *stream) { return false; }
uint16_t available_memory(void) { return memcheck_available_memory(); }
};
#endif // __AP_HAL_AVR_UTIL_H__

92
libraries/AP_HAL_AVR/examples/ArduCopterLibs/ArduCopterLibs.cpp

@ -1,92 +0,0 @@ @@ -1,92 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#include <AP_Common/AP_Common.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_Menu/AP_Menu.h>
#include <AP_Param/AP_Param.h>
#include <AP_GPS/AP_GPS.h> // ArduPilot GPS library
#include <AP_ADC/AP_ADC.h> // ArduPilot Mega Analog to Digital Converter Library
#include <AP_Baro/AP_Baro.h>
#include <AP_Declination/AP_Declination.h>
#include <AP_Compass/AP_Compass.h> // ArduPilot Mega Magnetometer Library
#include <AP_Math/AP_Math.h> // ArduPilot Mega Vector/Matrix math Library
#include <AP_Curve/AP_Curve.h> // Curve used to linearlise throttle pwm to thrust
#include <AP_InertialSensor/AP_InertialSensor.h> // ArduPilot Mega Inertial Sensor (accel & gyro) Library
// (only included for makefile libpath to work)
#include <AP_AHRS/AP_AHRS.h>
#include <AC_PID/AC_PID.h> // PID library
#include <AC_PID/AC_P.h> // P library
#include <RC_Channel/RC_Channel.h> // RC Channel Library
#include <AP_Motors/AP_Motors.h> // AP Motors library
#include <AP_ADC_AnalogSource/AP_ADC_AnalogSource.h>
#include <AP_RangeFinder/AP_RangeFinder.h> // Range finder library
#include <AP_OpticalFlow/AP_OpticalFlow.h> // Optical Flow library
#include <Filter/Filter.h> // Filter library
#include <AP_Buffer/AP_Buffer.h> // APM FIFO Buffer
#include <AP_Relay/AP_Relay.h> // APM relay
#include <AP_Camera/AP_Camera.h> // Photo or video camera
#include <AP_Mount/AP_Mount.h> // Camera/Antenna mount
#include <AP_Airspeed/AP_Airspeed.h> // needed for AHRS build
#include <AP_Vehicle/AP_Vehicle.h> // needed for AHRS build
#include <AP_Notify/AP_Notify.h>
#include <DataFlash/DataFlash.h>
#include <AP_InertialNav/AP_InertialNav.h> // ArduPilot Mega inertial navigation library
#include <GCS_MAVLink/GCS_MAVLink.h>
#include <AP_Mission/AP_Mission.h>
#include <StorageManager/StorageManager.h>
#include <AP_Terrain/AP_Terrain.h>
#include <AP_HAL_AVR/memcheck.h>
#include <AP_NavEKF/AP_NavEKF.h>
#include <AP_NavEKF/AP_Nav_Common.h>
#include <AP_BattMonitor/AP_BattMonitor.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void stream_loopback(AP_HAL::Stream* s, uint32_t time) {
uint32_t end = hal.scheduler->millis() + time;
for(;;) {
if (hal.scheduler->millis() >= end && time != 0) {
return;
}
if (s->available() > 0) {
int c;
c = s->read();
if (-1 != c) {
s->write((uint8_t)c);
}
}
}
}
void setup(void)
{
//
// Test printing things
//
hal.console->print("test");
hal.console->println(" begin");
hal.console->println(1000);
hal.console->println(1000, 8);
hal.console->println(1000, 10);
hal.console->println(1000, 16);
hal.console->println_P(PSTR("progmem"));
hal.console->printf("printf %d %u %#x %p %f %S\n", -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
hal.console->printf_P(PSTR("printf_P %d %u %#x %p %f %S\n"), -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
hal.console->println("done.");
for(;;);
}
void loop(void){}
AP_HAL_MAIN();

2
libraries/AP_HAL_AVR/examples/ArduCopterLibs/Makefile

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
BOARD = mega
include ../../../../mk/apm.mk

36
libraries/AP_HAL_AVR/examples/ArduCopterLibs/make.inc

@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
LIBRARIES += AC_PID
LIBRARIES += AP_ADC
LIBRARIES += AP_ADC_AnalogSource
LIBRARIES += AP_AHRS
LIBRARIES += AP_Airspeed
LIBRARIES += AP_Baro
LIBRARIES += AP_BattMonitor
LIBRARIES += AP_Buffer
LIBRARIES += AP_Camera
LIBRARIES += AP_Common
LIBRARIES += AP_Compass
LIBRARIES += AP_Curve
LIBRARIES += AP_Declination
LIBRARIES += AP_GPS
LIBRARIES += AP_InertialNav
LIBRARIES += AP_InertialSensor
LIBRARIES += AP_Math
LIBRARIES += AP_Menu
LIBRARIES += AP_Mission
LIBRARIES += AP_Motors
LIBRARIES += AP_Mount
LIBRARIES += AP_NavEKF
LIBRARIES += AP_Notify
LIBRARIES += AP_OpticalFlow
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += AP_RangeFinder
LIBRARIES += AP_Relay
LIBRARIES += AP_Terrain
LIBRARIES += AP_Vehicle
LIBRARIES += DataFlash
LIBRARIES += Filter
LIBRARIES += GCS_MAVLink
LIBRARIES += memcheck
LIBRARIES += RC_Channel
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/ArduCopterLibs/nocore.inoflag

70
libraries/AP_HAL_AVR/examples/ArduPlaneLibs/ArduPlaneLibs.cpp

@ -1,70 +0,0 @@ @@ -1,70 +0,0 @@
// Libraries
#include <AP_Common/AP_Common.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_Menu/AP_Menu.h>
#include <AP_Param/AP_Param.h>
#include <AP_GPS/AP_GPS.h> // ArduPilot GPS library
#include <AP_Baro/AP_Baro.h> // ArduPilot barometer library
#include <AP_Compass/AP_Compass.h> // ArduPilot Mega Magnetometer Library
#include <AP_Math/AP_Math.h> // ArduPilot Mega Vector/Matrix math Library
#include <AP_ADC/AP_ADC.h> // ArduPilot Mega Analog to Digital Converter Library
#include <AP_InertialSensor/AP_InertialSensor.h> // Inertial Sensor Library
#include <AP_AHRS/AP_AHRS.h> // ArduPilot Mega DCM Library
#include <PID/PID.h> // PID library
#include <RC_Channel/RC_Channel.h> // RC Channel Library
#include <AP_ADC_AnalogSource/AP_ADC_AnalogSource.h>
#include <AP_RangeFinder/AP_RangeFinder.h> // Range finder library
#include <Filter/Filter.h> // Filter library
#include <AP_Buffer/AP_Buffer.h> // APM FIFO Buffer
#include <AP_Relay/AP_Relay.h> // APM relay
#include <AP_Camera/AP_Camera.h> // Photo or video camera
#include <AP_Airspeed/AP_Airspeed.h>
#include <AP_Notify/AP_Notify.h>
#include <AP_HAL_AVR/memcheck.h>
#include <DataFlash/DataFlash.h>
#include <APM_Control/APM_Control.h>
#include <AP_Vehicle/AP_Vehicle.h>
#include <GCS_MAVLink/GCS_MAVLink.h> // MAVLink GCS definitions
#include <AP_Mission/AP_Mission.h>
#include <StorageManager/StorageManager.h>
#include <AP_Terrain/AP_Terrain.h>
#include <AP_Mount/AP_Mount.h> // Camera/Antenna mount
#include <AP_Declination/AP_Declination.h> // ArduPilot Mega Declination Helper Library
#include <AP_BattMonitor/AP_BattMonitor.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void setup(void)
{
//
// Test printing things
//
hal.console->print("test");
hal.console->println(" begin");
hal.console->println(1000);
hal.console->println(1000, 8);
hal.console->println(1000, 10);
hal.console->println(1000, 16);
hal.console->println_P(PSTR("progmem"));
hal.console->printf("printf %d %u %#x %p %f %S\n", -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
hal.console->printf_P(PSTR("printf_P %d %u %#x %p %f %S\n"), -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
for(;;);
}
void loop(void){}
AP_HAL_MAIN();

2
libraries/AP_HAL_AVR/examples/ArduPlaneLibs/Makefile

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
BOARD = mega
include ../../../../mk/apm.mk

32
libraries/AP_HAL_AVR/examples/ArduPlaneLibs/make.inc

@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
LIBRARIES += AP_ADC
LIBRARIES += AP_ADC_AnalogSource
LIBRARIES += AP_AHRS
LIBRARIES += AP_Airspeed
LIBRARIES += AP_Baro
LIBRARIES += AP_BattMonitor
LIBRARIES += AP_Buffer
LIBRARIES += AP_Camera
LIBRARIES += AP_Common
LIBRARIES += AP_Compass
LIBRARIES += AP_Declination
LIBRARIES += AP_GPS
LIBRARIES += AP_InertialSensor
LIBRARIES += AP_Math
LIBRARIES += APM_Control
LIBRARIES += AP_Menu
LIBRARIES += AP_Mission
LIBRARIES += AP_Mount
LIBRARIES += AP_Notify
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += AP_RangeFinder
LIBRARIES += AP_Relay
LIBRARIES += AP_Terrain
LIBRARIES += AP_Vehicle
LIBRARIES += DataFlash
LIBRARIES += Filter
LIBRARIES += GCS_MAVLink
LIBRARIES += memcheck
LIBRARIES += PID
LIBRARIES += RC_Channel
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/ArduPlaneLibs/nocore.inoflag

54
libraries/AP_HAL_AVR/examples/Blink/Blink.cpp

@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#endif
AP_HAL::DigitalSource *a_led;
AP_HAL::DigitalSource *b_led;
AP_HAL::DigitalSource *c_led;
void loop (void) {
hal.scheduler->delay(1000);
hal.gpio->write(13, 1);
a_led->write(1);
b_led->write(0);
c_led->write(1);
hal.scheduler->delay(1000);
hal.gpio->write(13, 0);
a_led->write(0);
b_led->write(1);
c_led->write(0);
}
void setup (void) {
hal.gpio->pinMode(13, HAL_GPIO_OUTPUT);
hal.gpio->write(13, 0);
a_led = hal.gpio->channel(27);
b_led = hal.gpio->channel(26);
c_led = hal.gpio->channel(25);
a_led->mode(HAL_GPIO_OUTPUT);
b_led->mode(HAL_GPIO_OUTPUT);
c_led->mode(HAL_GPIO_OUTPUT);
a_led->write(0);
b_led->write(0);
c_led->write(0);
}
AP_HAL_MAIN();

1
libraries/AP_HAL_AVR/examples/Blink/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

5
libraries/AP_HAL_AVR/examples/Blink/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/Blink/nocore.inoflag

46
libraries/AP_HAL_AVR/examples/Console/Console.cpp

@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
// -*- Mode: C++; c-basic-offset: 8; indent-tabs-mode: nil -*-
//
// Example code for the AP_HAL AVRUARTDriver, based on FastSerial
//
// This code is placed into the public domain.
//
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void setup(void)
{
//
// Test printing things
//
hal.console->print("test");
hal.console->println(" begin");
hal.console->println(1000);
hal.console->println(1000, 8);
hal.console->println(1000, 10);
hal.console->println(1000, 16);
hal.console->println_P(PSTR("progmem"));
hal.console->printf("printf %d %u %#x %p %f %S\n", -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
hal.console->printf_P(PSTR("printf_P %d %u %#x %p %f %S\n"), -1000, 1000, 1000, 1000, 1.2345, PSTR("progmem"));
for(;;);
}
void loop(void){}
AP_HAL_MAIN();

2
libraries/AP_HAL_AVR/examples/Console/Makefile

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
BOARD = mega
include ../../../../mk/apm.mk

5
libraries/AP_HAL_AVR/examples/Console/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/Console/nocore.inoflag

57
libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/I2CDriver_HMC5883L.cpp

@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
/*******************************************
* Sample sketch that configures an HMC5883L 3 axis
* magnetometer to continuous mode and reads back
* the three axis of data.
*******************************************/
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
#define HMC5883L 0x1E
void setup() {
hal.console->printf_P(PSTR("Initializing HMC5883L at address %x\r\n"),
HMC5883L);
uint8_t stat = hal.i2c->writeRegister(HMC5883L,0x02,0x00);
if (stat == 0) {
hal.console->printf_P(PSTR("successful init\r\n"));
} else {
hal.console->printf_P(PSTR("failed init: return status %d\r\n"),
(int)stat);
for(;;);
}
}
void loop() {
uint8_t data[6];
//read 6 bytes (x,y,z) from the device
uint8_t stat = hal.i2c->readRegisters(HMC5883L,0x03,6, data);
if (stat == 0){
int x, y, z;
x = data[0] << 8;
x |= data[1];
y = data[2] << 8;
y |= data[3];
z = data[4] << 8;
z |= data[5];
hal.console->printf_P(PSTR("x: %d y: %d z: %d \r\n"), x, y, z);
} else {
hal.console->printf_P(PSTR("i2c error: status %d\r\n"), (int)stat);
}
}
AP_HAL_MAIN();

1
libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

5
libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/I2CDriver_HMC5883L/nocore.inoflag

84
libraries/AP_HAL_AVR/examples/LCDTest/LCDTest.cpp

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
/*
LiquidCrystal Library - Hello World
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
library works with all LCD displays that are compatible with the
Hitachi HD44780 driver. There are many of them out there, and you
can usually tell them by the 16-pin interface.
This sketch prints "Hello World!" to the LCD
and shows the time.
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/
// include the library code:
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#include "LCrystal.h"
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
/* pin 54 is A0 on the mega */
hal.gpio->pinMode(54, HAL_GPIO_INPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(hal.scheduler->millis()/1000);
lcd.setCursor(8, 1); /* Halfway over second row */
if (hal.gpio->read(54)) {
lcd.print("high");
} else {
lcd.print("low ");
}
}
AP_HAL_MAIN();

313
libraries/AP_HAL_AVR/examples/LCDTest/LCrystal.cpp

@ -1,313 +0,0 @@ @@ -1,313 +0,0 @@
#include "LCrystal.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <AP_HAL/AP_HAL.h>
extern const AP_HAL::HAL& hal;
// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set:
// DL = 1; 8-bit interface data
// N = 0; 1-line display
// F = 0; 5x8 dot character font
// 3. Display on/off control:
// D = 0; Display off
// C = 0; Cursor off
// B = 0; Blinking off
// 4. Entry mode set:
// I/D = 1; Increment by 1
// S = 0; No shift
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
_rs_pin = rs;
_rw_pin = rw;
_enable_pin = enable;
_data_pins[0] = d0;
_data_pins[1] = d1;
_data_pins[2] = d2;
_data_pins[3] = d3;
_data_pins[4] = d4;
_data_pins[5] = d5;
_data_pins[6] = d6;
_data_pins[7] = d7;
hal.gpio->pinMode(_rs_pin, HAL_GPIO_OUTPUT);
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
if (_rw_pin != 255) {
hal.gpio->pinMode(_rw_pin, HAL_GPIO_OUTPUT);
}
hal.gpio->pinMode(_enable_pin, HAL_GPIO_OUTPUT);
if (fourbitmode)
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
else
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
begin(16, 1);
}
void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
_numlines = lines;
_currline = 0;
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != 0) && (lines == 1)) {
_displayfunction |= LCD_5x10DOTS;
}
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
// according to datasheet, we need at least 40ms after power rises above 2.7V
// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
hal.scheduler->delay_microseconds(50000);
// Now we pull both RS and R/W low to begin commands
hal.gpio->write(_rs_pin, 0);
hal.gpio->write(_enable_pin, 0);
if (_rw_pin != 255) {
hal.gpio->write(_rw_pin, 0);
}
//put the LCD into 4 bit or 8 bit mode
if (! (_displayfunction & LCD_8BITMODE)) {
// this is according to the hitachi HD44780 datasheet
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
write4bits(0x03);
hal.scheduler->delay_microseconds(4500); // wait min 4.1ms
// second try
write4bits(0x03);
hal.scheduler->delay_microseconds(4500); // wait min 4.1ms
// third go!
write4bits(0x03);
hal.scheduler->delay_microseconds(150);
// finally, set to 4-bit interface
write4bits(0x02);
} else {
// this is according to the hitachi HD44780 datasheet
// page 45 figure 23
// Send function set command sequence
command(LCD_FUNCTIONSET | _displayfunction);
hal.scheduler->delay_microseconds(4500); // wait more than 4.1ms
// second try
command(LCD_FUNCTIONSET | _displayfunction);
hal.scheduler->delay_microseconds(150);
// third go
command(LCD_FUNCTIONSET | _displayfunction);
}
// finally, set # lines, font size, etc.
command(LCD_FUNCTIONSET | _displayfunction);
// turn the display on with no cursor or blinking default
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
display();
// clear it off
clear();
// Initialize to default text direction (for romance languages)
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
// set the entry mode
command(LCD_ENTRYMODESET | _displaymode);
}
/********** high level commands, for the user! */
void LiquidCrystal::clear()
{
command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
hal.scheduler->delay_microseconds(2000); // this command takes a long time!
}
void LiquidCrystal::home()
{
command(LCD_RETURNHOME); // set cursor position to zero
hal.scheduler->delay_microseconds(2000); // this command takes a long time!
}
void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
if ( row >= _numlines ) {
row = _numlines-1; // we count rows starting w/0
}
command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
// Turn the display on/off (quickly)
void LiquidCrystal::noDisplay() {
_displaycontrol &= ~LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::display() {
_displaycontrol |= LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turns the underline cursor on/off
void LiquidCrystal::noCursor() {
_displaycontrol &= ~LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::cursor() {
_displaycontrol |= LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turn on and off the blinking cursor
void LiquidCrystal::noBlink() {
_displaycontrol &= ~LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal::blink() {
_displaycontrol |= LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// These commands scroll the display without changing the RAM
void LiquidCrystal::scrollDisplayLeft(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void LiquidCrystal::scrollDisplayRight(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}
// This is for text that flows Left to Right
void LiquidCrystal::leftToRight(void) {
_displaymode |= LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This is for text that flows Right to Left
void LiquidCrystal::rightToLeft(void) {
_displaymode &= ~LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'right justify' text from the cursor
void LiquidCrystal::autoscroll(void) {
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'left justify' text from the cursor
void LiquidCrystal::noAutoscroll(void) {
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++) {
write(charmap[i]);
}
}
/*********** mid level commands, for sending data/cmds */
inline void LiquidCrystal::command(uint8_t value) {
send(value, 0);
}
inline size_t LiquidCrystal::write(uint8_t value) {
send(value, 1);
return 1; // assume sucess
}
/************ low level data pushing commands **********/
// write either command or data, with automatic 4/8-bit selection
void LiquidCrystal::send(uint8_t value, uint8_t mode) {
hal.gpio->write(_rs_pin, mode);
// if there is a RW pin indicated, set it low to Write
if (_rw_pin != 255) {
hal.gpio->write(_rw_pin, 0);
}
if (_displayfunction & LCD_8BITMODE) {
write8bits(value);
} else {
write4bits(value>>4);
write4bits(value);
}
}
void LiquidCrystal::pulseEnable(void) {
hal.gpio->write(_enable_pin, 0);
hal.scheduler->delay_microseconds(1);
hal.gpio->write(_enable_pin, 1);
hal.scheduler->delay_microseconds(1); // enable pulse must be >450ns
hal.gpio->write(_enable_pin, 0);
hal.scheduler->delay_microseconds(100); // commands need > 37us to settle
}
void LiquidCrystal::write4bits(uint8_t value) {
for (int i = 0; i < 4; i++) {
hal.gpio->pinMode(_data_pins[i], HAL_GPIO_OUTPUT);
hal.gpio->write(_data_pins[i], (value >> i) & 0x01);
}
pulseEnable();
}
void LiquidCrystal::write8bits(uint8_t value) {
for (int i = 0; i < 8; i++) {
hal.gpio->pinMode(_data_pins[i], HAL_GPIO_OUTPUT);
hal.gpio->write(_data_pins[i], (value >> i) & 0x01);
}
pulseEnable();
}

106
libraries/AP_HAL_AVR/examples/LCDTest/LCrystal.h

@ -1,106 +0,0 @@ @@ -1,106 +0,0 @@
#ifndef LiquidCrystal_h
#define LiquidCrystal_h
#include <inttypes.h>
#include <AP_HAL/utility/Print.h>
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
class LiquidCrystal : public AP_HAL::Print {
public:
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
void clear();
void home();
void noDisplay();
void display();
void noBlink();
void blink();
void noCursor();
void cursor();
void scrollDisplayLeft();
void scrollDisplayRight();
void leftToRight();
void rightToLeft();
void autoscroll();
void noAutoscroll();
void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t, uint8_t);
virtual size_t write(uint8_t);
void command(uint8_t);
using Print::write;
private:
void send(uint8_t, uint8_t);
void write4bits(uint8_t);
void write8bits(uint8_t);
void pulseEnable();
uint8_t _rs_pin; // LOW: command. HIGH: character.
uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
uint8_t _enable_pin; // activated by a HIGH pulse.
uint8_t _data_pins[8];
uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _initialized;
uint8_t _numlines,_currline;
};
#endif

1
libraries/AP_HAL_AVR/examples/LCDTest/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

7
libraries/AP_HAL_AVR/examples/LCDTest/README

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
This is a quick test app based on the Arduino LiquidCrystal library,
modified to use an AP_HAL instead of the Arduino core.
I tested it with a Freetronics 16x2 LCD shield v2 on an Arduino Mega 2560.
Pat Hickey, 23 Aug 2012

4
libraries/AP_HAL_AVR/examples/LCDTest/make.inc

@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem

0
libraries/AP_HAL_AVR/examples/LCDTest/nobuild.txt

0
libraries/AP_HAL_AVR/examples/LCDTest/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/RCInputTest/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

69
libraries/AP_HAL_AVR/examples/RCInputTest/RCInputTest.cpp

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void multiread(AP_HAL::RCInput* in) {
/* Multi-channel read method: */
uint16_t channels[8];
uint8_t valid;
valid = in->read(channels, 8);
hal.console->printf_P(
PSTR("multi read %d: %d %d %d %d %d %d %d %d\r\n"),
(int) valid,
channels[0], channels[1], channels[2], channels[3],
channels[4], channels[5], channels[6], channels[7]);
}
void individualread(AP_HAL::RCInput* in) {
/* individual channel read method: */
bool valid;
uint16_t channels[8];
valid = in->new_input();
for (int i = 0; i < 8; i++) {
channels[i] = in->read(i);
}
hal.console->printf_P(
PSTR("individual read %d: %d %d %d %d %d %d %d %d\r\n"),
(int) valid,
channels[0], channels[1], channels[2], channels[3],
channels[4], channels[5], channels[6], channels[7]);
}
void loop (void) {
static int ctr = 0;
hal.gpio->write(27, 1);
/* Cycle between using the individual read method
* and the multi read method*/
if (ctr < 500) {
multiread(hal.rcin);
} else {
individualread(hal.rcin);
if (ctr > 1000) ctr = 0;
}
ctr++;
hal.gpio->write(27, 0);
hal.scheduler->delay(2);
}
void setup (void) {
hal.console->printf_P(PSTR("reading rc in:"));
hal.gpio->pinMode(27, HAL_GPIO_OUTPUT);
hal.gpio->write(27, 0);
}
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/RCInputTest/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/RCInputTest/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/RCJitterTest/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

121
libraries/AP_HAL_AVR/examples/RCJitterTest/RCJitterTest.cpp

@ -1,121 +0,0 @@ @@ -1,121 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
uint16_t ppm_center[ 8 ];
uint16_t ppm_min[ 8 ];
uint16_t ppm_max[ 8 ];
uint16_t ppm_delta[ 8 ];
uint16_t ppm_mark[ 8 ];
void setup (void) {
hal.console->printf_P(PSTR("RC input jitter test - Do not move sticks:\n"));
hal.scheduler->delay(2000);
for( uint8_t rep = 0; rep < 10; rep++ )
{
for( uint8_t i = 0; i < 8; i++ )
{
uint16_t ppm_tmp = hal.rcin->read( i );
ppm_center[ i ] += ppm_tmp;
}
hal.scheduler->delay( 100 );
}
for( uint8_t i = 0; i < 8; i++ )
{
uint16_t ppm_tmp = ppm_center[ i ] / 10;
ppm_center[ i ] = ppm_tmp;
ppm_min[ i ] = ppm_tmp;
ppm_max[ i ] = ppm_tmp;
ppm_delta[ i ] = 0;
}
}
void loop (void) {
static bool update = true;
static uint32_t time_trigger;
for( uint8_t i = 0; i < 8; i++ )
{
uint16_t ppm_tmp = hal.rcin->read( i );
// min?
if( ppm_tmp < ppm_min[ i ] )
{
uint16_t delta_tmp = ppm_center[ i ] - ppm_tmp;
if( delta_tmp > ppm_delta[ i ] ) ppm_delta[ i ] = delta_tmp;
ppm_min[ i ] = ppm_tmp;
ppm_mark[ i ] = ppm_tmp;
update = true;
}
// max?
if( ppm_tmp > ppm_max[ i ] )
{
uint16_t delta_tmp = ppm_tmp - ppm_center[ i ];
if( delta_tmp > ppm_delta[ i ] ) ppm_delta[ i ] = delta_tmp;
ppm_max[ i ] = ppm_tmp;
ppm_mark[ i ] = ppm_tmp;
update = true;
}
}
if( update && hal.scheduler->millis() > time_trigger )
{
update = false;
time_trigger = hal.scheduler->millis() + 5000;
uint32_t time = hal.scheduler->millis() / 1000;
uint16_t hour = time / 3600;
time -= hour * 3600;
uint16_t minutte = time / 60;
time -= minutte * 60;
uint16_t second = time;
//hal.console->printf_P( PSTR("%c%c%c\r\n"), 0x1B, 0x5B, 0x48 ); // Terminal home position
hal.console->printf_P( PSTR("\n< %.2u:%.2u:%.2u >------------------------------------- \n"), hour, minutte, second );
for( uint8_t i = 0; i < 8; i++ )
{
hal.console->printf_P( PSTR("ch%d: center:%d min:%d max:%d delta:%d"),
i + 1, ppm_center[ i ], ppm_min[ i ],ppm_max[ i ], ppm_delta[ i ] );
if( ppm_mark[ i ] > 0 )
{
hal.console->printf_P( PSTR(" [%d]"), ppm_mark[ i ] );
ppm_mark[ i ] = 0;
}
hal.console->printf_P( PSTR("\n") );
}
}
hal.scheduler->delay( 10 );
}
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/RCJitterTest/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/RCJitterTest/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/RCPassthroughTest/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

101
libraries/AP_HAL_AVR/examples/RCPassthroughTest/RCPassthroughTest.cpp

@ -1,101 +0,0 @@ @@ -1,101 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void multiread(AP_HAL::RCInput* in, uint16_t* channels) {
/* Multi-channel read method: */
uint8_t valid;
valid = in->read(channels, 8);
hal.console->printf_P(
PSTR("multi read %d: %d %d %d %d %d %d %d %d\r\n"),
(int) valid,
channels[0], channels[1], channels[2], channels[3],
channels[4], channels[5], channels[6], channels[7]);
}
void individualread(AP_HAL::RCInput* in, uint16_t* channels) {
/* individual channel read method: */
bool valid;
valid = in->new_input();
for (int i = 0; i < 8; i++) {
channels[i] = in->read(i);
}
hal.console->printf_P(
PSTR("individual read %d: %d %d %d %d %d %d %d %d\r\n"),
(int) valid,
channels[0], channels[1], channels[2], channels[3],
channels[4], channels[5], channels[6], channels[7]);
}
void multiwrite(AP_HAL::RCOutput* out, uint16_t* channels) {
out->write(0, channels, 8);
/* Upper channels duplicate lower channels*/
out->write(8, channels, 8);
}
void individualwrite(AP_HAL::RCOutput* out, uint16_t* channels) {
for (int ch = 0; ch < 8; ch++) {
out->write(ch, channels[ch]);
/* Upper channels duplicate lower channels*/
out->write(ch+8, channels[ch]);
}
}
void loop (void) {
static int ctr = 0;
uint16_t channels[8];
hal.gpio->write(27, 1);
/* Cycle between using the individual read method
* and the multi read method*/
if (ctr < 500) {
multiread(hal.rcin, channels);
} else {
individualread(hal.rcin, channels);
if (ctr > 1000) ctr = 0;
}
/* Cycle between individual output and multichannel output */
if (ctr % 500 < 250) {
multiwrite(hal.rcout, channels);
} else {
individualwrite(hal.rcout, channels);
}
hal.gpio->write(27, 0);
hal.scheduler->delay(4);
ctr++;
}
void setup (void) {
hal.gpio->pinMode(27, HAL_GPIO_OUTPUT);
hal.gpio->write(27, 0);
for (uint8_t i=0; i<16; i++) {
hal.rcout->enable_ch(i);
}
/* Bottom 4 channels at 400hz (like on a quad) */
hal.rcout->set_freq(0x0000000F, 400);
for(int i = 0; i < 12; i++) {
hal.console->printf_P(PSTR("rcout ch %d has frequency %d\r\n"),
i, hal.rcout->get_freq(i));
}
/* Delay to let the user see the above printouts on the terminal */
hal.scheduler->delay(1000);
}
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/RCPassthroughTest/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/RCPassthroughTest/nocore.inoflag

81
libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/MPU6000.h

@ -1,81 +0,0 @@ @@ -1,81 +0,0 @@
#ifndef __MPU6000_H__
#define __MPU6000_H__
// MPU 6000 registers
#define MPUREG_WHOAMI 0x75 //
#define MPUREG_SMPLRT_DIV 0x19 //
#define MPUREG_CONFIG 0x1A //
#define MPUREG_GYRO_CONFIG 0x1B
#define MPUREG_ACCEL_CONFIG 0x1C
#define MPUREG_FIFO_EN 0x23
#define MPUREG_INT_PIN_CFG 0x37
#define MPUREG_INT_ENABLE 0x38
#define MPUREG_INT_STATUS 0x3A
#define MPUREG_ACCEL_XOUT_H 0x3B //
#define MPUREG_ACCEL_XOUT_L 0x3C //
#define MPUREG_ACCEL_YOUT_H 0x3D //
#define MPUREG_ACCEL_YOUT_L 0x3E //
#define MPUREG_ACCEL_ZOUT_H 0x3F //
#define MPUREG_ACCEL_ZOUT_L 0x40 //
#define MPUREG_TEMP_OUT_H 0x41//
#define MPUREG_TEMP_OUT_L 0x42//
#define MPUREG_GYRO_XOUT_H 0x43 //
#define MPUREG_GYRO_XOUT_L 0x44 //
#define MPUREG_GYRO_YOUT_H 0x45 //
#define MPUREG_GYRO_YOUT_L 0x46 //
#define MPUREG_GYRO_ZOUT_H 0x47 //
#define MPUREG_GYRO_ZOUT_L 0x48 //
#define MPUREG_USER_CTRL 0x6A //
#define MPUREG_PWR_MGMT_1 0x6B //
#define MPUREG_PWR_MGMT_2 0x6C //
#define MPUREG_FIFO_COUNTH 0x72
#define MPUREG_FIFO_COUNTL 0x73
#define MPUREG_FIFO_R_W 0x74
#define MPUREG_PRODUCT_ID 0x0C // Product ID Register
// Configuration bits MPU 3000 and MPU 6000 (not revised)?
#define BIT_SLEEP 0x40
#define BIT_H_RESET 0x80
#define BITS_CLKSEL 0x07
#define MPU_CLK_SEL_PLLGYROX 0x01
#define MPU_CLK_SEL_PLLGYROZ 0x03
#define MPU_EXT_SYNC_GYROX 0x02
#define BITS_FS_250DPS 0x00
#define BITS_FS_500DPS 0x08
#define BITS_FS_1000DPS 0x10
#define BITS_FS_2000DPS 0x18
#define BITS_FS_MASK 0x18
#define BITS_DLPF_CFG_256HZ_NOLPF2 0x00
#define BITS_DLPF_CFG_188HZ 0x01
#define BITS_DLPF_CFG_98HZ 0x02
#define BITS_DLPF_CFG_42HZ 0x03
#define BITS_DLPF_CFG_20HZ 0x04
#define BITS_DLPF_CFG_10HZ 0x05
#define BITS_DLPF_CFG_5HZ 0x06
#define BITS_DLPF_CFG_2100HZ_NOLPF 0x07
#define BITS_DLPF_CFG_MASK 0x07
#define BIT_INT_ANYRD_2CLEAR 0x10
#define BIT_RAW_RDY_EN 0x01
#define BIT_I2C_IF_DIS 0x10
#define BIT_INT_STATUS_DATA 0x01
// Product ID Description for MPU6000
// high 4 bits low 4 bits
// Product Name Product Revision
#define MPU6000ES_REV_C4 0x14 // 0001 0100
#define MPU6000ES_REV_C5 0x15 // 0001 0101
#define MPU6000ES_REV_D6 0x16 // 0001 0110
#define MPU6000ES_REV_D7 0x17 // 0001 0111
#define MPU6000ES_REV_D8 0x18 // 0001 1000
#define MPU6000_REV_C4 0x54 // 0101 0100
#define MPU6000_REV_C5 0x55 // 0101 0101
#define MPU6000_REV_D6 0x56 // 0101 0110
#define MPU6000_REV_D7 0x57 // 0101 0111
#define MPU6000_REV_D8 0x58 // 0101 1000
#define MPU6000_REV_D9 0x59 // 0101 1001
#endif // __MPU6000_H__

1
libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

131
libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/SPIDriver_MPU6000.cpp

@ -1,131 +0,0 @@ @@ -1,131 +0,0 @@
/*******************************************
* Sample sketch that configures an MPU6000
* and reads back the three axis of accel,
* temperature, three axis of gyro data
*******************************************/
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
/* register #defines */
#include "MPU6000.h"
// debug only:
#include <avr/io.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
AP_HAL::SPIDeviceDriver* spidev;
static void register_write(uint8_t reg, uint8_t val) {
hal.console->printf_P(PSTR("write reg %d val %d\r\n"),
(int) reg, (int) val);
spidev->cs_assert();
spidev->transfer(reg);
spidev->transfer(val);
spidev->cs_release();
}
static uint8_t register_read(uint8_t reg) {
/* set most significant bit to read register */
uint8_t regaddr = reg | 0x80;
spidev->cs_assert();
spidev->transfer(regaddr);
uint8_t val = spidev->transfer(0);
spidev->cs_release();
return val;
}
static uint16_t spi_read_16(void) {
uint8_t byte_h, byte_l;
byte_h = spidev->transfer(0);
byte_l = spidev->transfer(0);
return (((int16_t) byte_h)<< 8) | byte_l;
}
static void mpu6k_init(void) {
// chip reset
register_write(MPUREG_PWR_MGMT_1, BIT_H_RESET);
hal.scheduler->delay(100);
// Wake up device and select GyroZ clock (better performance)
register_write(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
hal.scheduler->delay(1);
register_write(MPUREG_PWR_MGMT_2, 0);
hal.scheduler->delay(1);
// Disable I2C bus (recommended on datasheet)
register_write(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
hal.scheduler->delay(1);
// SAMPLE RATE
//// Sample rate = 200Hz Fsample= 1Khz/(4+1) = 200Hz
register_write(MPUREG_SMPLRT_DIV,0x04);
hal.scheduler->delay(1);
// FS & DLPF FS=2000º/s, DLPF = 98Hz (low pass filter)
register_write(MPUREG_CONFIG, BITS_DLPF_CFG_98HZ);
hal.scheduler->delay(1);
register_write(MPUREG_GYRO_CONFIG,BITS_FS_2000DPS); // Gyro scale 2000º/s
hal.scheduler->delay(1);
// read the product ID rev c has 1/2 the sensitivity of rev d
uint8_t _product_id = register_read(MPUREG_PRODUCT_ID);
//Serial.printf("Product_ID= 0x%x\n", (unsigned) _product_id);
if ((_product_id == MPU6000ES_REV_C4) || (_product_id == MPU6000ES_REV_C5)
||(_product_id == MPU6000_REV_C4) || (_product_id == MPU6000_REV_C5)){
// Accel scale 8g (4096 LSB/g)
// Rev C has different scaling than rev D
register_write(MPUREG_ACCEL_CONFIG,1<<3);
} else {
// Accel scale 8g (4096 LSB/g)
register_write(MPUREG_ACCEL_CONFIG,2<<3);
}
hal.scheduler->delay(1);
// INT CFG => Interrupt on Data Ready
//// INT: Raw data ready
register_write(MPUREG_INT_ENABLE,BIT_RAW_RDY_EN);
hal.scheduler->delay(1);
// INT: Clear on any read
register_write(MPUREG_INT_PIN_CFG,BIT_INT_ANYRD_2CLEAR);
hal.scheduler->delay(1);
}
static void mpu6k_read(int16_t* data) {
spidev->cs_assert();
spidev->transfer( MPUREG_ACCEL_XOUT_H | 0x80 );
for (int i = 0; i < 7; i++) {
data[i] = spi_read_16();
}
spidev->cs_release();
}
static void setup() {
hal.console->printf_P(PSTR("Initializing MPU6000\r\n"));
spidev = hal.spi->device(AP_HAL::SPIDevice_MPU6000);
mpu6k_init();
}
static void loop() {
int16_t sensors[7];
mpu6k_read(sensors);
hal.console->printf_P(PSTR("mpu6k: %d %d %d %d %d %d %d\r\n"),
sensors[0], sensors[1], sensors[2],
sensors[3], sensors[4], sensors[5], sensors[6]);
hal.scheduler->delay(10);
}
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/SPIDriver_MPU6000/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/Scheduler/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

113
libraries/AP_HAL_AVR/examples/Scheduler/Scheduler.cpp

@ -1,113 +0,0 @@ @@ -1,113 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
/**
* You'll want to use a logic analyzer to watch the effects of this test.
* On the APM2 its pretty easy to hook up an analyzer to pins A0 through A3.
*/
#define DELAY_TOGGLE_PIN 54 /* A0 */
#define FAILSAFE_TOGGLE_PIN 55 /* A1 */
#define SCHEDULED_TOGGLE_PIN_1 56 /* A2 */
#define SCHEDULED_TOGGLE_PIN_2 57 /* A3 */
void delay_toggle() {
volatile int i;
hal.gpio->write(DELAY_TOGGLE_PIN, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(DELAY_TOGGLE_PIN, 0);
}
void failsafe_toggle(void *) {
volatile int i;
hal.gpio->write(FAILSAFE_TOGGLE_PIN, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(FAILSAFE_TOGGLE_PIN, 0);
}
void schedule_toggle_1(void *) {
volatile int i;
hal.gpio->write(SCHEDULED_TOGGLE_PIN_1, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(SCHEDULED_TOGGLE_PIN_1, 0);
}
void schedule_toggle_2(void *) {
volatile int i;
hal.gpio->write(SCHEDULED_TOGGLE_PIN_2, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(SCHEDULED_TOGGLE_PIN_2, 0);
}
void schedule_toggle_hang(void *) {
hal.gpio->write(SCHEDULED_TOGGLE_PIN_2, 1);
for(;;);
}
void setup_pin(int pin_num) {
hal.console->printf_P(PSTR("Setup pin %d\r\n"), pin_num);
hal.gpio->pinMode(pin_num,HAL_GPIO_OUTPUT);
/* Blink so we can see setup on the logic analyzer.*/
hal.gpio->write(pin_num,1);
hal.gpio->write(pin_num,0);
}
void setup (void) {
hal.console->printf_P(PSTR("Starting AP_HAL_AVR::Scheduler test\r\n"));
setup_pin(DELAY_TOGGLE_PIN);
setup_pin(FAILSAFE_TOGGLE_PIN);
setup_pin(SCHEDULED_TOGGLE_PIN_1);
setup_pin(SCHEDULED_TOGGLE_PIN_2);
hal.console->printf_P(PSTR("Testing delay callback. "
"Pin %d should toggle at 1khz:\r\n"),
(int) DELAY_TOGGLE_PIN);
hal.scheduler->register_delay_callback(delay_toggle,0);
hal.scheduler->delay(100);
hal.console->printf_P(PSTR("Testing failsafe callback. "
"Pin %d should toggle at 1khz:\r\n"),
(int) FAILSAFE_TOGGLE_PIN);
hal.scheduler->register_timer_failsafe(failsafe_toggle, 1000);
hal.scheduler->delay(100);
hal.console->printf_P(PSTR("Testing running timer processes.\r\n"));
hal.console->printf_P(PSTR("Pin %d should toggle at 1khz.\r\n"),
(int) SCHEDULED_TOGGLE_PIN_1);
hal.console->printf_P(PSTR("Pin %d should toggle at 1khz.\r\n"),
(int) SCHEDULED_TOGGLE_PIN_2);
hal.scheduler->register_timer_process(schedule_toggle_1, NULL);
hal.scheduler->register_timer_process(schedule_toggle_2, NULL);
hal.scheduler->delay(100);
hal.console->printf_P(PSTR("Test running a pathological timer process.\r\n"
"Failsafe should continue even as pathological process "
"dominates the processor."));
hal.console->printf_P(PSTR("Pin %d should toggle then go high forever.\r\n"),
(int) SCHEDULED_TOGGLE_PIN_2);
hal.scheduler->register_timer_process(schedule_toggle_hang, NULL);
}
void loop (void) { }
AP_HAL_MAIN();

4
libraries/AP_HAL_AVR/examples/Scheduler/make.inc

@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem

0
libraries/AP_HAL_AVR/examples/Scheduler/nobuild.txt

0
libraries/AP_HAL_AVR/examples/Scheduler/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/Semaphore/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

118
libraries/AP_HAL_AVR/examples/Semaphore/Semaphore.cpp

@ -1,118 +0,0 @@ @@ -1,118 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
/**
* You'll want to use a logic analyzer to watch the effects of this test.
* On the APM2 its pretty easy to hook up an analyzer to pins A0 through A3.
*/
#define PIN_A0 54 /* A0 */
#define PIN_A1 55 /* A1 */
#define PIN_A2 56 /* A2 */
#define PIN_A3 57 /* A3 */
/**
* Create an AVRSemaphore for this test.
*/
AP_HAL::Semaphore *sem;
void blink_a0() {
volatile int i;
hal.gpio->write(PIN_A0, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(PIN_A0, 0);
}
void blink_a1() {
volatile int i;
hal.gpio->write(PIN_A1, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(PIN_A1, 0);
}
void blink_a2() {
volatile int i;
hal.gpio->write(PIN_A2, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(PIN_A2, 0);
}
void blink_a3() {
volatile int i;
hal.gpio->write(PIN_A3, 1);
for (i = 0; i < 10; i++);
hal.gpio->write(PIN_A3, 0);
}
void setup_pin(int pin_num) {
hal.console->printf_P(PSTR("Setup pin %d\r\n"), pin_num);
hal.gpio->pinMode(pin_num,HAL_GPIO_OUTPUT);
/* Blink so we can see setup on the logic analyzer.*/
hal.gpio->write(pin_num,1);
hal.gpio->write(pin_num,0);
}
void setup (void) {
hal.console->printf_P(PSTR("Starting Semaphore test\r\n"));
setup_pin(PIN_A0);
setup_pin(PIN_A1);
setup_pin(PIN_A2);
setup_pin(PIN_A3);
hal.console->printf_P(PSTR("Using Dataflash's Semaphore\r\n"));
AP_HAL::SPIDeviceDriver *dataflash = hal.spi->device(
AP_HAL::SPIDevice_Dataflash);
if (dataflash == NULL) {
hal.scheduler->panic(PSTR("Error: No SPIDevice_Dataflash driver!"));
}
sem = dataflash->get_semaphore();
if (sem == NULL) {
hal.scheduler->panic(PSTR("Error: No SPIDeviceDriver semaphore!"));
}
hal.scheduler->register_timer_process(async_blinker, NULL);
}
static uint32_t async_last_run;
void async_blinker(void *)
{
uint32_t now = hal.scheduler->millis();
if ((now - async_last_run) < 5) {
return;
}
async_last_run = now;
if (sem->take_nonblocking()) {
blink_a0();
sem->give();
} else {
blink_a1();
}
}
void loop (void) {
if (sem->take(1)) {
blink_a2();
sem->give();
} else {
/* This should never happen: */
blink_a3();
}
}
AP_HAL_MAIN();

4
libraries/AP_HAL_AVR/examples/Semaphore/make.inc

@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem

0
libraries/AP_HAL_AVR/examples/Semaphore/nobuild.txt

0
libraries/AP_HAL_AVR/examples/Semaphore/nocore.inoflag

1
libraries/AP_HAL_AVR/examples/Storage/Makefile

@ -1 +0,0 @@ @@ -1 +0,0 @@
include ../../../../mk/apm.mk

51
libraries/AP_HAL_AVR/examples/Storage/Storage.cpp

@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
uint8_t fibs[12] = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 };
void test_write() {
hal.console->printf_P(PSTR("writing... "));
hal.storage->write_block(0, fibs, 12);
hal.console->printf_P(PSTR(" done.\r\n"));
}
void test_readback() {
hal.console->printf_P(PSTR("reading back...\r\n"));
uint8_t readback[12];
bool success = true;
hal.storage->read_block(readback, 0, 12);
for (int i = 0; i < 12; i++) {
if (readback[i] != fibs[i]) {
success = false;
hal.console->printf_P(PSTR("At index %d expected %d got %d\r\n"),
i, (int) fibs[i], (int) readback[i]);
}
}
if (success) {
hal.console->printf_P(PSTR("all bytes read successfully\r\n"));
}
hal.console->printf_P(PSTR("done reading back.\r\n"));
}
void setup (void) {
hal.console->printf_P(PSTR("Starting AP_HAL_AVR::Storage test\r\n"));
test_write();
test_readback();
}
void loop (void) { }
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/Storage/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

0
libraries/AP_HAL_AVR/examples/Storage/nocore.inoflag

2
libraries/AP_HAL_AVR/examples/UARTDriver/Makefile

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
BOARD = mega
include ../../../../mk/apm.mk

58
libraries/AP_HAL_AVR/examples/UARTDriver/UARTDriver.cpp

@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
// -*- Mode: C++; c-basic-offset: 8; indent-tabs-mode: nil -*-
//
// Example code for the AP_HAL AVRUARTDriver, based on FastSerial
//
// This code is placed into the public domain.
//
#include <AP_Common/AP_Common.h>
#include <AP_Math/AP_Math.h>
#include <AP_Param/AP_Param.h>
#include <StorageManager/StorageManager.h>
#include <AP_Progmem/AP_Progmem.h>
#include <AP_HAL/AP_HAL.h>
#include <AP_HAL_AVR/AP_HAL_AVR.h>
#if CONFIG_HAL_BOARD == HAL_BOARD_APM2
const AP_HAL::HAL& hal = AP_HAL_AVR_APM2;
#elif CONFIG_HAL_BOARD == HAL_BOARD_APM1
const AP_HAL::HAL& hal = AP_HAL_AVR_APM1;
#endif
void setup(void)
{
//
// HAL will start serial port at 115200.
//
//
// Test printing things
//
hal.console->print("test");
hal.console->println(" begin");
hal.console->println(1000);
hal.console->println(1000, 8);
hal.console->println(1000, 10);
hal.console->println(1000, 16);
hal.console->println_P(PSTR("progmem"));
int x = 3;
int *ptr = &x;
hal.console->printf("printf %d %u %#x %p %f %S\n", -1000, 1000, 1000, ptr, 1.2345, PSTR("progmem"));
hal.console->printf_P(PSTR("printf_P %d %u %#x %p %f %S\n"), -1000, 1000, 1000, ptr, 1.2345, PSTR("progmem"));
hal.console->println("done");
}
void loop(void)
{
int c;
//
// Perform a simple loopback operation.
//
c = hal.console->read();
if (-1 != c)
hal.console->write(c);
}
AP_HAL_MAIN();

5
libraries/AP_HAL_AVR/examples/UARTDriver/make.inc

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
LIBRARIES += AP_Common
LIBRARIES += AP_Math
LIBRARIES += AP_Param
LIBRARIES += AP_Progmem
LIBRARIES += StorageManager

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save