-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from bxparks/develop
0.1 - initial release after renaming and splitting from AUnit/unitduino
- Loading branch information
Showing
23 changed files
with
3,353 additions
and
1 deletion.
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,137 @@ | ||
/* | ||
* Copyright (c) 2019 Brian T. Park | ||
* | ||
* Parts derived from the Arduino SDK | ||
* Copyright (c) 2005-2013 Arduino Team | ||
* | ||
* Parts inspired by [Entering raw | ||
* mode](https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html). | ||
* | ||
* Parts inspired by [ESP8266 Host | ||
* Emulation](https://github.com/esp8266/Arduino/tree/master/tests/host). | ||
* | ||
* The 'Serial' object sends output to STDOUT, and receives input from STDIN in | ||
* 'raw' mode. The main() loop checks the STDIN and if it finds a character, | ||
* inserts it into the Serial buffer. | ||
*/ | ||
|
||
#include <inttypes.h> | ||
#include <unistd.h> // usleep() | ||
#include <signal.h> // SIGINT | ||
#include <termios.h> | ||
#include <time.h> // clock_gettime() | ||
#include <stdlib.h> // exit() | ||
#include <stdio.h> // perror() | ||
#include "Arduino.h" | ||
|
||
// ----------------------------------------------------------------------- | ||
// Arduino methods emulated in Unix | ||
// ----------------------------------------------------------------------- | ||
|
||
void delay(unsigned long ms) { | ||
usleep(ms * 1000); | ||
} | ||
|
||
void yield() { | ||
usleep(1000); // prevents program from consuming 100% CPU | ||
} | ||
|
||
unsigned long millis() { | ||
struct timespec spec; | ||
clock_gettime(CLOCK_MONOTONIC, &spec); | ||
unsigned long ms = spec.tv_sec * 1000U + spec.tv_nsec / 1000000UL; | ||
return ms; | ||
} | ||
|
||
unsigned long micros() { | ||
struct timespec spec; | ||
clock_gettime(CLOCK_MONOTONIC, &spec); | ||
unsigned long us = spec.tv_sec * 1000000UL + spec.tv_nsec / 1000U; | ||
return us; | ||
} | ||
|
||
void digitalWrite(uint8_t pin, uint8_t val) {} | ||
|
||
int digitalRead(uint8_t pin) { return 0; } | ||
|
||
void pinMode(uint8_t pin, uint8_t mode) {} | ||
|
||
// ----------------------------------------------------------------------- | ||
// Unix compatibility. Put STDIN into raw mode and hook it into the 'Serial' | ||
// object. Trap Ctrl-C and perform appropriate clean up. | ||
// ----------------------------------------------------------------------- | ||
|
||
static struct termios orig_termios; | ||
static bool inRawMode = false; | ||
|
||
static void die(const char* s) { | ||
perror(s); | ||
exit(1); | ||
} | ||
|
||
static void disableRawMode() { | ||
if (!inRawMode) return; | ||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) { | ||
inRawMode = false; // prevent exit(1) from being called twice | ||
die("disableRawMode(): tcsetattr() failure"); | ||
} | ||
} | ||
|
||
static void enableRawMode() { | ||
if (!isatty(STDIN_FILENO)) { | ||
die("enableRawMode(): redirection on STDIN not supported"); | ||
} | ||
if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) { | ||
die("enableRawMode(): tcgetattr() failure"); | ||
} | ||
|
||
struct termios raw = orig_termios; | ||
// The 'Enter' key in raw mode is ^M (\r, CR). But internally, we want this | ||
// to be ^J (\n, NL), so ICRNL and INLCR causes the ^M to become a \n. | ||
raw.c_iflag &= ~(/*ICRNL | INLCR |*/ INPCK | ISTRIP | IXON); | ||
// Set the output into cooked mode, to handle NL and CR properly. | ||
// Print.println() sends CR-NL (\r\n). But some code will send just \n. The | ||
// ONLCR translates \n into \r\n. So '\r\n' will become \r\r\n, which is just | ||
// fine. | ||
raw.c_oflag |= (OPOST | ONLCR); | ||
raw.c_cflag |= (CS8); | ||
// Enable ISIG to allow Ctrl-C to kill the program. | ||
raw.c_lflag &= ~(/*ECHO | ISIG |*/ ICANON | IEXTEN); | ||
raw.c_cc[VMIN] = 0; | ||
raw.c_cc[VTIME] = 0; | ||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) { | ||
die("enableRawMode(): tcsetattr() failure"); | ||
} | ||
inRawMode = true; | ||
} | ||
|
||
static void handleControlC(int /*sig*/) { | ||
if (inRawMode) { | ||
// If this returns an error, don't call die() because it will call exit(), | ||
// which may call this again, causing an infinite recursion. | ||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) { | ||
perror("handleControlC(): tcsetattr() failure"); | ||
} | ||
inRawMode = false; | ||
} | ||
exit(1); | ||
} | ||
|
||
// ----------------------------------------------------------------------- | ||
// Main loop. User code will provide setup() and loop(). | ||
// ----------------------------------------------------------------------- | ||
|
||
int main(int argc, char** argv) { | ||
signal(SIGINT, handleControlC); | ||
atexit(disableRawMode); | ||
enableRawMode(); | ||
|
||
setup(); | ||
while (true) { | ||
char c = '\0'; | ||
read(STDIN_FILENO, &c, 1); | ||
if (c) Serial.insertChar(c); | ||
loop(); | ||
yield(); | ||
} | ||
} |
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,69 @@ | ||
/* | ||
* Copyright (c) 2019 Brian T. Park | ||
* MIT License | ||
* | ||
* Parts derived from the Arduino SDK | ||
* Copyright (c) 2005-2013 Arduino Team | ||
*/ | ||
|
||
#ifndef UNIX_HOST_DUINO_ARDUINO_H | ||
#define UNIX_HOST_DUINO_ARDUINO_H | ||
|
||
#include "Print.h" | ||
#include "StdioSerial.h" | ||
|
||
// Macros defined when running under UnixHostDuino | ||
#define UNIX_HOST_DUINO 1 | ||
// xx.yy.zz => xxyyzz (without leading 0) | ||
#define UNIX_HOST_DUINO_VERSION 100 | ||
#define UNIX_HOST_DUINO_VERSION_STRING "0.1" | ||
|
||
// Used by digitalRead() and digitalWrite() | ||
#define HIGH 0x1 | ||
#define LOW 0x0 | ||
|
||
// Used by pinMode() | ||
#define INPUT 0x0 | ||
#define OUTPUT 0x1 | ||
#define INPUT_PULLUP 0x2 | ||
|
||
// Various math constants. | ||
#define PI 3.1415926535897932384626433832795 | ||
#define HALF_PI 1.5707963267948966192313216916398 | ||
#define TWO_PI 6.283185307179586476925286766559 | ||
#define DEG_TO_RAD 0.017453292519943295769236907684886 | ||
#define RAD_TO_DEG 57.295779513082320876798154814105 | ||
#define EULER 2.718281828459045235360287471352 | ||
|
||
#define SERIAL 0x0 | ||
#define DISPLAY 0x1 | ||
|
||
#define LSBFIRST 0 | ||
#define MSBFIRST 1 | ||
|
||
#define CHANGE 1 | ||
#define FALLING 2 | ||
#define RISING 3 | ||
|
||
// Arbitrarily define the pin for the LED_BUILTIN | ||
#define LED_BUILTIN 1 | ||
|
||
extern "C" { | ||
|
||
void delay(unsigned long ms); | ||
void yield(); | ||
unsigned long millis(); | ||
unsigned long micros(); | ||
void digitalWrite(uint8_t pin, uint8_t val); | ||
int digitalRead(uint8_t pin); | ||
void pinMode(uint8_t pin, uint8_t mode); | ||
|
||
/** Provided in the client code's *.ino file. */ | ||
void setup(); | ||
|
||
/** Provided in the client code's *.ino file. */ | ||
void loop(); | ||
|
||
} | ||
|
||
#endif |
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,8 @@ | ||
# Changelog | ||
|
||
* Unreleased | ||
* 0.1 (2019-07-31) | ||
* Split from `AUnit` and renamed from `unitduino` to `UnixHostDuino`. | ||
* Add `UNIT_HOST_DUINO` macro. | ||
* Add `FPSTR()` macro for compatibilty with ESP8266 and ESP32. | ||
* Add `LED_BUILTIN` macro. |
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 @@ | ||
/* | ||
EEPROM.h - EEPROM library | ||
Original Copyright (c) 2006 David A. Mellis. All right reserved. | ||
New version by Christopher Andrews 2015. | ||
Modified by Brian T. Park 2019. | ||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
This library 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 | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#ifndef UNIX_HOST_DUINO_EEPROM_H | ||
#define UNIX_HOST_DUINO_EEPROM_H | ||
|
||
#include <inttypes.h> | ||
/* | ||
#include <avr/eeprom.h> | ||
#include <avr/io.h> | ||
*/ | ||
|
||
/*** | ||
EERef class. | ||
This object references an EEPROM cell. | ||
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. | ||
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. | ||
***/ | ||
|
||
struct EERef{ | ||
|
||
EERef( const int index ) | ||
: index( index ) {} | ||
|
||
//Access/read members. | ||
uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); } | ||
operator uint8_t() const { return **this; } | ||
|
||
//Assignment/write members. | ||
EERef &operator=( const EERef &ref ) { return *this = *ref; } | ||
EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; } | ||
EERef &operator +=( uint8_t in ) { return *this = **this + in; } | ||
EERef &operator -=( uint8_t in ) { return *this = **this - in; } | ||
EERef &operator *=( uint8_t in ) { return *this = **this * in; } | ||
EERef &operator /=( uint8_t in ) { return *this = **this / in; } | ||
EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } | ||
EERef &operator %=( uint8_t in ) { return *this = **this % in; } | ||
EERef &operator &=( uint8_t in ) { return *this = **this & in; } | ||
EERef &operator |=( uint8_t in ) { return *this = **this | in; } | ||
EERef &operator <<=( uint8_t in ) { return *this = **this << in; } | ||
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } | ||
|
||
EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } | ||
|
||
/** Prefix increment/decrement **/ | ||
EERef& operator++() { return *this += 1; } | ||
EERef& operator--() { return *this -= 1; } | ||
|
||
/** Postfix increment/decrement **/ | ||
uint8_t operator++ (int){ | ||
uint8_t ret = **this; | ||
return ++(*this), ret; | ||
} | ||
|
||
uint8_t operator-- (int){ | ||
uint8_t ret = **this; | ||
return --(*this), ret; | ||
} | ||
|
||
int index; //Index of current EEPROM cell. | ||
}; | ||
|
||
/*** | ||
EEPtr class. | ||
This object is a bidirectional pointer to EEPROM cells represented by EERef objects. | ||
Just like a normal pointer type, this can be dereferenced and repositioned using | ||
increment/decrement operators. | ||
***/ | ||
|
||
struct EEPtr{ | ||
|
||
EEPtr( const int index ) | ||
: index( index ) {} | ||
|
||
operator int() const { return index; } | ||
EEPtr &operator=( int in ) { return index = in, *this; } | ||
|
||
//Iterator functionality. | ||
bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } | ||
EERef operator*() { return index; } | ||
|
||
/** Prefix & Postfix increment/decrement **/ | ||
EEPtr& operator++() { return ++index, *this; } | ||
EEPtr& operator--() { return --index, *this; } | ||
EEPtr operator++ (int) { return index++; } | ||
EEPtr operator-- (int) { return index--; } | ||
|
||
int index; //Index of current EEPROM cell. | ||
}; | ||
|
||
/*** | ||
EEPROMClass class. | ||
This object represents the entire EEPROM space. | ||
It wraps the functionality of EEPtr and EERef into a basic interface. | ||
This class is also 100% backwards compatible with earlier Arduino core releases. | ||
***/ | ||
|
||
struct EEPROMClass{ | ||
|
||
//Basic user access methods. | ||
EERef operator[]( const int idx ) { return idx; } | ||
uint8_t read( int idx ) { return EERef( idx ); } | ||
void write( int idx, uint8_t val ) { (EERef( idx )) = val; } | ||
void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } | ||
|
||
//STL and C++11 iteration capability. | ||
EEPtr begin() { return 0x00; } | ||
EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. | ||
uint16_t length() { return E2END + 1; } | ||
|
||
//Functionality to 'get' and 'put' objects to and from EEPROM. | ||
template< typename T > T &get( int idx, T &t ){ | ||
EEPtr e = idx; | ||
uint8_t *ptr = (uint8_t*) &t; | ||
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; | ||
return t; | ||
} | ||
|
||
template< typename T > const T &put( int idx, const T &t ){ | ||
EEPtr e = idx; | ||
const uint8_t *ptr = (const uint8_t*) &t; | ||
for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); | ||
return t; | ||
} | ||
}; | ||
|
||
static EEPROMClass EEPROM; | ||
#endif |
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
Oops, something went wrong.