-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Romi-specific files by copying them from the
Zumo32U4 library and making small modifications.
- Loading branch information
1 parent
1af5769
commit dbbf62c
Showing
5 changed files
with
434 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright Pololu Corporation. For more information, see http://www.pololu.com/ | ||
|
||
/*! \file Romi32U4.h | ||
* | ||
* \brief Main header file for the Romi32U4 library. | ||
* | ||
* This file includes all the other headers files provided by the library. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifndef __AVR_ATmega32U4__ | ||
#error "This library only supports the ATmega32U4. Try selecting A-Star 32U4 in the Boards menu." | ||
#endif | ||
|
||
#include <FastGPIO.h> | ||
#include <LIS3MDL.h> | ||
#include <LSM6.h> | ||
#include <Romi32U4Buttons.h> | ||
#include <Romi32U4Buzzer.h> | ||
#include <Romi32U4Encoders.h> | ||
#include <Romi32U4IRPulses.h> | ||
#include <Romi32U4LCD.h> | ||
#include <Romi32U4Motors.h> | ||
|
||
// TODO: servo support | ||
|
||
/*! \brief Turns the red user LED (RX) on or off. | ||
@param on 1 to turn on the LED, 0 to turn it off. | ||
The red user LED is on pin 17, which is also known as PB0, SS, and RXLED. The | ||
Arduino core code uses this LED to indicate when it receives data over USB, so | ||
it might be hard to control this LED when USB is connected. */ | ||
inline void ledRed(bool on) | ||
{ | ||
FastGPIO::Pin<17>::setOutput(!on); | ||
} | ||
|
||
/*! \brief Turns the yellow user LED on pin 13 on or off. | ||
@param on 1 to turn on the LED, 0 to turn it off. */ | ||
inline void ledYellow(bool on) | ||
{ | ||
FastGPIO::Pin<13>::setOutput(on); | ||
} | ||
|
||
/*! \brief Turns the green user LED (TX) on or off. | ||
@param on 1 to turn on the LED, 0 to turn it off. | ||
The green user LED is pin PD5, which is also known as TXLED. The Arduino core | ||
code uses this LED to indicate when it receives data over USB, so it might be | ||
hard to control this LED when USB is connected. */ | ||
inline void ledGreen(bool on) | ||
{ | ||
FastGPIO::Pin<IO_D5>::setOutput(!on); | ||
} | ||
|
||
/*! \brief Returns true if USB power is detected. | ||
This function returns true if power is detected on the board's USB port and | ||
returns false otherwise. It uses the ATmega32U4's VBUS line, which is directly | ||
connected to the power pin of the USB connector. | ||
\sa A method for detecting whether the board's virtual COM port is open: | ||
http://arduino.cc/en/Serial/IfSerial */ | ||
inline bool usbPowerPresent() | ||
{ | ||
return USBSTA >> VBUS & 1; | ||
} | ||
|
||
/*! \brief Reads the battery voltage and returns it in millivolts. */ | ||
inline uint16_t readBatteryMillivolts() | ||
{ | ||
const uint8_t sampleCount = 8; | ||
uint16_t sum = 0; | ||
for (uint8_t i = 0; i < sampleCount; i++) | ||
{ | ||
sum += analogRead(A1); | ||
} | ||
|
||
// VBAT = 3 * millivolt reading = 3 * raw * 5000/1024 | ||
// = raw * 1875 / 128 | ||
// The correction term below makes it so that we round to the | ||
// nearest whole number instead of always rounding down. | ||
const uint32_t correction = 64 * sampleCount - 1; | ||
return ((uint32_t)sum * 1875 + correction) / (128 * sampleCount); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright Pololu Corporation. For more information, see http://www.pololu.com/ | ||
|
||
/** \file Romi32U4Buttons.h **/ | ||
|
||
#pragma once | ||
|
||
#include <Pushbutton.h> | ||
#include <FastGPIO.h> | ||
#include <USBPause.h> | ||
#include <util/delay.h> | ||
|
||
/*! The pin number for the pin connected to button A on the Romi 32U4. */ | ||
#define ROMI_32U4_BUTTON_A 14 | ||
|
||
/*! The pin number for the pin connected to button B on the Romi 32U4. Note | ||
* that this is not an official Arduino pin number so it cannot be used with | ||
* functions like digitalRead, but it can be used with the FastGPIO library. */ | ||
#define ROMI_32U4_BUTTON_B IO_D5 | ||
|
||
/*! The pin number for the pin conencted to button C on the Romi 32U4. */ | ||
#define ROMI_32U4_BUTTON_C 17 | ||
|
||
/*! \brief Interfaces with button A on the Romi 32U4. */ | ||
class Romi32U4ButtonA : public Pushbutton | ||
{ | ||
public: | ||
Romi32U4ButtonA() : Pushbutton(ROMI_32U4_BUTTON_A) | ||
{ | ||
} | ||
}; | ||
|
||
/*! \brief Interfaces with button B on the Romi 32U4. | ||
* | ||
* The pin used for button B is also used for the TX LED. | ||
* | ||
* This class temporarily disables USB interrupts because the Arduino core code | ||
* has USB interrupts enabled that sometimes write to the pin this button is on. | ||
* | ||
* This class temporarily sets the pin to be an input without a pull-up | ||
* resistor. The pull-up resistor is not needed because of the resistors on the | ||
* board. */ | ||
class Romi32U4ButtonB : public PushbuttonBase | ||
{ | ||
public: | ||
|
||
virtual bool isPressed() | ||
{ | ||
USBPause usbPause; | ||
FastGPIO::PinLoan<ROMI_32U4_BUTTON_B> loan; | ||
FastGPIO::Pin<ROMI_32U4_BUTTON_B>::setInputPulledUp(); | ||
_delay_us(3); | ||
return !FastGPIO::Pin<ROMI_32U4_BUTTON_B>::isInputHigh(); | ||
} | ||
}; | ||
|
||
/*! \brief Interfaces with button C on the Romi 32U4. | ||
* | ||
* The pin used for button C is also used for the RX LED. | ||
* | ||
* This class temporarily disables USB interrupts because the Arduino core code | ||
* has USB interrupts enabled that sometimes write to the pin this button is on. | ||
* | ||
* This class temporarily sets the pin to be an input without a pull-up | ||
* resistor. The pull-up resistor is not needed because of the resistors on the | ||
* board. */ | ||
class Romi32U4ButtonC : public PushbuttonBase | ||
{ | ||
public: | ||
|
||
virtual bool isPressed() | ||
{ | ||
USBPause usbPause; | ||
FastGPIO::PinLoan<ROMI_32U4_BUTTON_C> loan; | ||
FastGPIO::Pin<ROMI_32U4_BUTTON_C>::setInputPulledUp(); | ||
_delay_us(3); | ||
return !FastGPIO::Pin<ROMI_32U4_BUTTON_C>::isInputHigh(); | ||
} | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright Pololu Corporation. For more information, see http://www.pololu.com/ | ||
|
||
/*! \file Romi32U4Buzzer.h */ | ||
|
||
#pragma once | ||
|
||
#include <PololuBuzzer.h> | ||
|
||
/*! \brief Plays beeps and music on the buzzer on the Romi 32U4. | ||
* | ||
* This class uses Timer 4 and pin 6 (PD7/OC4D) to play beeps and melodies on | ||
* the Romi 32U4 buzzer. | ||
* | ||
* Note durations are timed using a timer overflow interrupt | ||
* (`TIMER4_OVF`), which will briefly interrupt execution of your | ||
* main program at the frequency of the sound being played. In most cases, the | ||
* interrupt-handling routine is very short (several microseconds). However, | ||
* when playing a sequence of notes in `PLAY_AUTOMATIC` mode (the default mode) | ||
* with the `play()` command, this interrupt takes much longer than normal | ||
* (perhaps several hundred microseconds) every time it starts a new note. It is | ||
* important to take this into account when writing timing-critical code. | ||
*/ | ||
class Romi32U4Buzzer : public PololuBuzzer | ||
{ | ||
// This is a trivial subclass of PololuBuzzer; it exists because we wanted | ||
// the Romi32U4 class names to be consistent and we didn't just use a typedef | ||
// to define it because that would make the Doxygen documentation harder to | ||
// understand. | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Copyright Pololu Corporation. For more information, see http://www.pololu.com/ | ||
|
||
#include <Romi32U4Encoders.h> | ||
#include <FastGPIO.h> | ||
#include <avr/interrupt.h> | ||
#include <Arduino.h> | ||
|
||
#define LEFT_XOR 8 | ||
#define LEFT_B IO_E2 | ||
#define RIGHT_XOR 7 | ||
#define RIGHT_B 23 | ||
|
||
static volatile bool lastLeftA; | ||
static volatile bool lastLeftB; | ||
static volatile bool lastRightA; | ||
static volatile bool lastRightB; | ||
|
||
static volatile bool errorLeft; | ||
static volatile bool errorRight; | ||
|
||
// These count variables are uint16_t instead of int16_t because | ||
// signed integer overflow is undefined behavior in C++. | ||
static volatile uint16_t countLeft; | ||
static volatile uint16_t countRight; | ||
|
||
ISR(PCINT0_vect) | ||
{ | ||
bool newLeftB = FastGPIO::Pin<LEFT_B>::isInputHigh(); | ||
bool newLeftA = FastGPIO::Pin<LEFT_XOR>::isInputHigh() ^ newLeftB; | ||
|
||
countLeft += (newLeftA ^ lastLeftB) - (lastLeftA ^ newLeftB); | ||
|
||
if((lastLeftA ^ newLeftA) & (lastLeftB ^ newLeftB)) | ||
{ | ||
errorLeft = true; | ||
} | ||
|
||
lastLeftA = newLeftA; | ||
lastLeftB = newLeftB; | ||
} | ||
|
||
static void rightISR() | ||
{ | ||
bool newRightB = FastGPIO::Pin<RIGHT_B>::isInputHigh(); | ||
bool newRightA = FastGPIO::Pin<RIGHT_XOR>::isInputHigh() ^ newRightB; | ||
|
||
countRight += (newRightA ^ lastRightB) - (lastRightA ^ newRightB); | ||
|
||
if((lastRightA ^ newRightA) & (lastRightB ^ newRightB)) | ||
{ | ||
errorLeft = true; | ||
} | ||
|
||
lastRightA = newRightA; | ||
lastRightB = newRightB; | ||
} | ||
|
||
void Romi32U4Encoders::init2() | ||
{ | ||
// Set the pins as pulled-up inputs. | ||
FastGPIO::Pin<LEFT_XOR>::setInputPulledUp(); | ||
FastGPIO::Pin<LEFT_B>::setInputPulledUp(); | ||
FastGPIO::Pin<RIGHT_XOR>::setInputPulledUp(); | ||
FastGPIO::Pin<RIGHT_B>::setInputPulledUp(); | ||
|
||
// Enable pin-change interrupt on PB4 for left encoder, and disable other | ||
// pin-change interrupts. | ||
PCICR = (1 << PCIE0); | ||
PCMSK0 = (1 << PCINT4); | ||
PCIFR = (1 << PCIF0); // Clear its interrupt flag by writing a 1. | ||
|
||
// Enable interrupt on PE6 for the right encoder. We use attachInterrupt | ||
// instead of defining ISR(INT6_vect) ourselves so that this class will be | ||
// compatible with other code that uses attachInterrupt. | ||
attachInterrupt(4, rightISR, CHANGE); | ||
|
||
// Initialize the variables. It's good to do this after enabling the | ||
// interrupts in case the interrupts fired by accident as we were enabling | ||
// them. | ||
lastLeftB = FastGPIO::Pin<LEFT_B>::isInputHigh(); | ||
lastLeftA = FastGPIO::Pin<LEFT_XOR>::isInputHigh() ^ lastLeftB; | ||
countLeft = 0; | ||
errorLeft = 0; | ||
|
||
lastRightB = FastGPIO::Pin<RIGHT_B>::isInputHigh(); | ||
lastRightA = FastGPIO::Pin<RIGHT_XOR>::isInputHigh() ^ lastRightB; | ||
countRight = 0; | ||
errorRight = 0; | ||
} | ||
|
||
int16_t Romi32U4Encoders::getCountsLeft() | ||
{ | ||
init(); | ||
|
||
cli(); | ||
int16_t counts = countLeft; | ||
sei(); | ||
return counts; | ||
} | ||
|
||
int16_t Romi32U4Encoders::getCountsRight() | ||
{ | ||
init(); | ||
|
||
cli(); | ||
int16_t counts = countRight; | ||
sei(); | ||
return counts; | ||
} | ||
|
||
int16_t Romi32U4Encoders::getCountsAndResetLeft() | ||
{ | ||
init(); | ||
|
||
cli(); | ||
int16_t counts = countLeft; | ||
countLeft = 0; | ||
sei(); | ||
return counts; | ||
} | ||
|
||
int16_t Romi32U4Encoders::getCountsAndResetRight() | ||
{ | ||
init(); | ||
|
||
cli(); | ||
int16_t counts = countRight; | ||
countRight = 0; | ||
sei(); | ||
return counts; | ||
} | ||
|
||
bool Romi32U4Encoders::checkErrorLeft() | ||
{ | ||
init(); | ||
|
||
bool error = errorLeft; | ||
errorLeft = 0; | ||
return error; | ||
} | ||
|
||
bool Romi32U4Encoders::checkErrorRight() | ||
{ | ||
init(); | ||
|
||
bool error = errorRight; | ||
errorRight = 0; | ||
return error; | ||
} |
Oops, something went wrong.