Update to v087r02 release.

byuu says:

Changelog:
- extended USART with quit(), readable(), writable() [both emulation and
  hardware]
    - quit() returns true on hardware when Ctrl+C (SIGINT) is generated
      (breaks main loop); no effect under emulation yet (hard to
      simulate)
    - readable() returns true when data is ready to be read
      (non-blocking support for read())
    - writable() returns true when data can be written (non-blocking
      support for write()) [always true under emulation, since we have
      no buffer size limit]
This commit is contained in:
Tim Allen 2012-03-10 23:47:19 +11:00
parent cbfbec4dc3
commit 06e83c6154
5 changed files with 110 additions and 17 deletions

View File

@ -1,7 +1,7 @@
#ifndef BASE_HPP #ifndef BASE_HPP
#define BASE_HPP #define BASE_HPP
const char Version[] = "087.01"; const char Version[] = "087.02";
#include <nall/platform.hpp> #include <nall/platform.hpp>
#include <nall/algorithm.hpp> #include <nall/algorithm.hpp>

View File

@ -9,14 +9,39 @@
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
namespace nall { namespace nall {
class serial { struct serial {
public: bool readable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
}
//-1 on error, otherwise return bytes read //-1 on error, otherwise return bytes read
int read(uint8_t *data, unsigned length) { int read(uint8_t *data, unsigned length) {
if(port_open == false) return -1; if(port_open == false) return -1;
return ::read(port, (void*)data, length); return ::read(port, (void*)data, length);
} }
bool writable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, nullptr, &fdset, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
}
//-1 on error, otherwise return bytes written //-1 on error, otherwise return bytes written
int write(const uint8_t *data, unsigned length) { int write(const uint8_t *data, unsigned length) {
if(port_open == false) return -1; if(port_open == false) return -1;

View File

@ -6,19 +6,32 @@
#include <nall/serial.hpp> #include <nall/serial.hpp>
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#define usartproc dllexport #define usartproc dllexport
static nall::function<bool ()> usart_quit;
static nall::function<void (unsigned milliseconds)> usart_usleep; static nall::function<void (unsigned milliseconds)> usart_usleep;
static nall::function<bool ()> usart_readable;
static nall::function<uint8_t ()> usart_read; static nall::function<uint8_t ()> usart_read;
static nall::function<bool ()> usart_writable;
static nall::function<void (uint8_t data)> usart_write; static nall::function<void (uint8_t data)> usart_write;
extern "C" usartproc void usart_init( extern "C" usartproc void usart_init(
nall::function<bool ()> quit,
nall::function<void (unsigned milliseconds)> usleep, nall::function<void (unsigned milliseconds)> usleep,
nall::function<bool ()> readable,
nall::function<uint8_t ()> read, nall::function<uint8_t ()> read,
nall::function<bool ()> writable,
nall::function<void (uint8_t data)> write nall::function<void (uint8_t data)> write
) { ) {
usart_quit = quit;
usart_usleep = usleep; usart_usleep = usleep;
usart_readable = readable;
usart_read = read; usart_read = read;
usart_writable = writable;
usart_write = write; usart_write = write;
} }
@ -28,6 +41,7 @@ extern "C" usartproc void usart_main();
static nall::serial usart; static nall::serial usart;
static bool usart_is_virtual = true; static bool usart_is_virtual = true;
static bool usart_sigint = false;
static bool usart_virtual() { static bool usart_virtual() {
return usart_is_virtual; return usart_is_virtual;
@ -35,10 +49,18 @@ static bool usart_virtual() {
// //
static bool usarthw_quit() {
return usart_sigint;
}
static void usarthw_usleep(unsigned milliseconds) { static void usarthw_usleep(unsigned milliseconds) {
usleep(milliseconds); usleep(milliseconds);
} }
static bool usarthw_readable() {
return usart.readable();
}
static uint8_t usarthw_read() { static uint8_t usarthw_read() {
while(true) { while(true) {
uint8_t buffer[1]; uint8_t buffer[1];
@ -47,12 +69,25 @@ static uint8_t usarthw_read() {
} }
} }
static bool usarthw_writable() {
return usart.writable();
}
static void usarthw_write(uint8_t data) { static void usarthw_write(uint8_t data) {
uint8_t buffer[1] = { data }; uint8_t buffer[1] = { data };
usart.write((uint8_t*)&buffer, 1); usart.write((uint8_t*)&buffer, 1);
} }
static void sigint(int) {
signal(SIGINT, SIG_DFL);
usart_sigint = true;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
//requires superuser privileges; otherwise priority = +0
setpriority(PRIO_PROCESS, 0, -20);
signal(SIGINT, sigint);
bool result = false; bool result = false;
if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true); if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true);
if(argc == 2) result = usart.open(argv[1], 57600, true); if(argc == 2) result = usart.open(argv[1], 57600, true);
@ -61,7 +96,7 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
usart_is_virtual = false; usart_is_virtual = false;
usart_init(usarthw_usleep, usarthw_read, usarthw_write); usart_init(usarthw_quit, usarthw_usleep, usarthw_readable, usarthw_read, usarthw_writable, usarthw_write);
usart_main(); usart_main();
usart.close(); usart.close();
return 0; return 0;

View File

@ -7,37 +7,59 @@
//AT90USB1286 //AT90USB1286
//Connection Diagram: //Connection Diagram:
//[SNES] [Teensy] //SNES GND <> Teensy GND
// +5v --- //SNES IOBit <> Teensy B0
// Clock D5 //SNES Latch <> Teensy D2
// Latch D2 //SNES Data1 <> Teensy D3
// Data1 D3 //SNES Clock <> 1Kohm Resistor <> Teensy D5
// Data2 --- //Teensy D5 <> Teensy D7
// IOBit ---
// GND GND
void USART::enter() { void USART::enter() {
if(init && main) { if(init && main) {
init({ &USART::usleep, this }, { &USART::read, this }, { &USART::write, this }); init(
{&USART::quit, this},
{&USART::usleep, this},
{&USART::readable, this},
{&USART::read, this},
{&USART::writable, this},
{&USART::write, this}
);
main(); main();
} }
while(true) step(1000000); //fallback; main should never return while(true) step(10000000);
}
bool USART::quit() {
step(1);
return false;
} }
void USART::usleep(unsigned milliseconds) { void USART::usleep(unsigned milliseconds) {
step(milliseconds); step(10 * milliseconds);
}
bool USART::readable() {
step(1);
return txbuffer.size();
} }
//SNES -> USART //SNES -> USART
uint8 USART::read() { uint8 USART::read() {
step(1);
while(txbuffer.size() == 0) step(1); while(txbuffer.size() == 0) step(1);
uint8 data = txbuffer[0]; uint8 data = txbuffer[0];
txbuffer.remove(0); txbuffer.remove(0);
return data; return data;
} }
bool USART::writable() {
step(1);
return true;
}
//USART -> SNES //USART -> SNES
void USART::write(uint8 data) { void USART::write(uint8 data) {
step(1);
rxbuffer.append(data ^ 0xff); rxbuffer.append(data ^ 0xff);
} }
@ -103,7 +125,7 @@ USART::USART(bool port) : Controller(port) {
if(open_absolute(filename)) { if(open_absolute(filename)) {
init = sym("usart_init"); init = sym("usart_init");
main = sym("usart_main"); main = sym("usart_main");
if(init && main) create(Controller::Enter, 1000000); if(init && main) create(Controller::Enter, 10000000);
} }
} }

View File

@ -1,7 +1,11 @@
struct USART : Controller, public library { struct USART : Controller, public library {
void enter(); void enter();
bool quit();
void usleep(unsigned milliseconds); void usleep(unsigned milliseconds);
bool readable();
uint8 read(); uint8 read();
bool writable();
void write(uint8 data); void write(uint8 data);
uint2 data(); uint2 data();
@ -24,6 +28,13 @@ private:
uint8 txdata; uint8 txdata;
vector<uint8> txbuffer; vector<uint8> txbuffer;
function<void (function<void (unsigned)>, function<uint8 ()>, function<void (uint8)>)> init; function<void (
function<bool ()>, //quit
function<void (unsigned)>, //usleep
function<bool ()>, //readable
function<uint8 ()>, //read
function<bool ()>, //writable
function<void (uint8)> //write
)> init;
function<void ()> main; function<void ()> main;
}; };