ulisp/builder/streams.lisp

984 lines
30 KiB
Common Lisp

;;;-*- Mode: Lisp; Package: cl-user -*-
(in-package :cl-user)
(defparameter *i2c-interface* '(
#+avr-nano
#"
// I2C interface for AVR platforms, uses much less RAM than Arduino Wire
#if defined(CPU_ATmega328P)
uint8_t const TWI_SDA_PIN = 18;
uint8_t const TWI_SCL_PIN = 19;
#elif defined(CPU_ATmega1280) || defined(CPU_ATmega2560)
uint8_t const TWI_SDA_PIN = 20;
uint8_t const TWI_SCL_PIN = 21;
#elif defined(CPU_ATmega644P) || defined(CPU_ATmega1284P)
uint8_t const TWI_SDA_PIN = 17;
uint8_t const TWI_SCL_PIN = 16;
#elif defined(CPU_ATmega32U4)
uint8_t const TWI_SDA_PIN = 6;
uint8_t const TWI_SCL_PIN = 5;
#endif
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
uint32_t const FREQUENCY = 400000L; // Hardware I2C clock in Hz
uint32_t const T_RISE = 300L; // Rise time
#else
uint32_t const F_TWI = 400000L; // Hardware I2C clock in Hz
uint8_t const TWSR_MTX_DATA_ACK = 0x28;
uint8_t const TWSR_MTX_ADR_ACK = 0x18;
uint8_t const TWSR_MRX_ADR_ACK = 0x40;
uint8_t const TWSR_START = 0x08;
uint8_t const TWSR_REP_START = 0x10;
uint8_t const I2C_READ = 1;
uint8_t const I2C_WRITE = 0;
#endif
void I2Cinit (bool enablePullup) {
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
#if defined(CPU_ATmega4809)
if (enablePullup) {
pinMode(SDA, INPUT_PULLUP);
pinMode(SCL, INPUT_PULLUP);
}
#else
(void) enablePullup;
#endif
uint32_t baud = ((F_CPU/FREQUENCY) - (((F_CPU*T_RISE)/1000)/1000)/1000 - 10)/2;
TWI0.MBAUD = (uint8_t)baud;
TWI0.MCTRLA = TWI_ENABLE_bm; // Enable as master, no interrupts
TWI0.MSTATUS = TWI_BUSSTATE_IDLE_gc;
#else
TWSR = 0; // no prescaler
TWBR = (F_CPU/F_TWI - 16)/2; // set bit rate factor
if (enablePullup) {
digitalWrite(SDA, HIGH);
digitalWrite(SCL, HIGH);
}
#endif
}
int I2Cread () {
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
if (I2Ccount != 0) I2Ccount--;
while (!(TWI0.MSTATUS & TWI_RIF_bm)); // Wait for read interrupt flag
uint8_t data = TWI0.MDATA;
// Check slave sent ACK?
if (I2Ccount != 0) TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // ACK = more bytes to read
else TWI0.MCTRLB = TWI_ACKACT_NACK_gc; // Send NAK
return data;
#else
if (I2Ccount != 0) I2Ccount--;
TWCR = 1<<TWINT | 1<<TWEN | ((I2Ccount == 0) ? 0 : (1<<TWEA));
while (!(TWCR & 1<<TWINT));
return TWDR;
#endif
}
bool I2Cwrite (uint8_t data) {
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // Prime transaction
TWI0.MDATA = data; // Send data
while (!(TWI0.MSTATUS & TWI_WIF_bm)); // Wait for write to complete
if (TWI0.MSTATUS & (TWI_ARBLOST_bm | TWI_BUSERR_bm)) return false; // Fails if bus error or arblost
return !(TWI0.MSTATUS & TWI_RXACK_bm); // Returns true if slave gave an ACK
#else
TWDR = data;
TWCR = 1<<TWINT | 1 << TWEN;
while (!(TWCR & 1<<TWINT));
return (TWSR & 0xF8) == TWSR_MTX_DATA_ACK;
#endif
}
bool I2Cstart (uint8_t address, uint8_t read) {
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
TWI0.MADDR = address<<1 | read; // Send START condition
while (!(TWI0.MSTATUS & (TWI_WIF_bm | TWI_RIF_bm))); // Wait for write or read interrupt flag
if (TWI0.MSTATUS & TWI_ARBLOST_bm) { // Arbitration lost or bus error
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
return false;
} else if (TWI0.MSTATUS & TWI_RXACK_bm) { // Address not acknowledged by client
TWI0.MCTRLB |= TWI_MCMD_STOP_gc; // Send stop condition
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
return false;
}
return true; // Return true if slave gave an ACK
#else
uint8_t addressRW = address<<1 | read;
TWCR = 1<<TWINT | 1<<TWSTA | 1<<TWEN; // Send START condition
while (!(TWCR & 1<<TWINT));
if ((TWSR & 0xF8) != TWSR_START && (TWSR & 0xF8) != TWSR_REP_START) return false;
TWDR = addressRW; // send device address and direction
TWCR = 1<<TWINT | 1<<TWEN;
while (!(TWCR & 1<<TWINT));
if (addressRW & I2C_READ) return (TWSR & 0xF8) == TWSR_MRX_ADR_ACK;
else return (TWSR & 0xF8) == TWSR_MTX_ADR_ACK;
#endif
}
bool I2Crestart (uint8_t address, uint8_t read) {
return I2Cstart(address, read);
}
void I2Cstop (uint8_t read) {
#if defined(CPU_ATmega4809) || defined(CPU_ATtiny3227) || defined(CPU_AVR64DD28)
(void) read;
TWI0.MCTRLB |= TWI_MCMD_STOP_gc; // Send STOP
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
#else
(void) read;
TWCR = 1<<TWINT | 1<<TWEN | 1<<TWSTO;
while (TWCR & 1<<TWSTO); // wait until stop and bus released
#endif
}"#
#+avr
#"
// I2C interface for AVR platforms, uses much less RAM than Arduino Wire
#if defined(CPU_AVR128DX48)
uint32_t const FREQUENCY = 400000L; // Hardware I2C clock in Hz
uint32_t const T_RISE = 300L; // Rise time
#else
uint32_t const F_TWI = 400000L; // Hardware I2C clock in Hz
uint8_t const TWSR_MTX_DATA_ACK = 0x28;
uint8_t const TWSR_MTX_ADR_ACK = 0x18;
uint8_t const TWSR_MRX_ADR_ACK = 0x40;
uint8_t const TWSR_START = 0x08;
uint8_t const TWSR_REP_START = 0x10;
uint8_t const I2C_READ = 1;
uint8_t const I2C_WRITE = 0;
#endif
void I2Cinit (bool enablePullup) {
#if defined(CPU_AVR128DX48)
#if defined(CPU_ATmega4809)
if (enablePullup) {
pinMode(SDA, INPUT_PULLUP);
pinMode(SCL, INPUT_PULLUP);
}
#else
(void) enablePullup;
#endif
uint32_t baud = ((F_CPU/FREQUENCY) - (((F_CPU*T_RISE)/1000)/1000)/1000 - 10)/2;
TWI0.MBAUD = (uint8_t)baud;
TWI0.MCTRLA = TWI_ENABLE_bm; // Enable as master, no interrupts
TWI0.MSTATUS = TWI_BUSSTATE_IDLE_gc;
#else
TWSR = 0; // no prescaler
TWBR = (F_CPU/F_TWI - 16)/2; // set bit rate factor
if (enablePullup) {
digitalWrite(SDA, HIGH);
digitalWrite(SCL, HIGH);
}
#endif
}
int I2Cread () {
#if defined(CPU_AVR128DX48)
if (I2Ccount != 0) I2Ccount--;
while (!(TWI0.MSTATUS & TWI_RIF_bm)); // Wait for read interrupt flag
uint8_t data = TWI0.MDATA;
// Check slave sent ACK?
if (I2Ccount != 0) TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // ACK = more bytes to read
else TWI0.MCTRLB = TWI_ACKACT_NACK_gc; // Send NAK
return data;
#else
if (I2Ccount != 0) I2Ccount--;
TWCR = 1<<TWINT | 1<<TWEN | ((I2Ccount == 0) ? 0 : (1<<TWEA));
while (!(TWCR & 1<<TWINT));
return TWDR;
#endif
}
bool I2Cwrite (uint8_t data) {
#if defined(CPU_AVR128DX48)
TWI0.MCTRLB = TWI_MCMD_RECVTRANS_gc; // Prime transaction
TWI0.MDATA = data; // Send data
while (!(TWI0.MSTATUS & TWI_WIF_bm)); // Wait for write to complete
if (TWI0.MSTATUS & (TWI_ARBLOST_bm | TWI_BUSERR_bm)) return false; // Fails if bus error or arblost
return !(TWI0.MSTATUS & TWI_RXACK_bm); // Returns true if slave gave an ACK
#else
TWDR = data;
TWCR = 1<<TWINT | 1 << TWEN;
while (!(TWCR & 1<<TWINT));
return (TWSR & 0xF8) == TWSR_MTX_DATA_ACK;
#endif
}
bool I2Cstart (uint8_t address, uint8_t read) {
#if defined(CPU_AVR128DX48)
TWI0.MADDR = address<<1 | read; // Send START condition
while (!(TWI0.MSTATUS & (TWI_WIF_bm | TWI_RIF_bm))); // Wait for write or read interrupt flag
if (TWI0.MSTATUS & TWI_ARBLOST_bm) { // Arbitration lost or bus error
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
return false;
} else if (TWI0.MSTATUS & TWI_RXACK_bm) { // Address not acknowledged by client
TWI0.MCTRLB |= TWI_MCMD_STOP_gc; // Send stop condition
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
return false;
}
return true; // Return true if slave gave an ACK
#else
uint8_t addressRW = address<<1 | read;
TWCR = 1<<TWINT | 1<<TWSTA | 1<<TWEN; // Send START condition
while (!(TWCR & 1<<TWINT));
if ((TWSR & 0xF8) != TWSR_START && (TWSR & 0xF8) != TWSR_REP_START) return false;
TWDR = addressRW; // send device address and direction
TWCR = 1<<TWINT | 1<<TWEN;
while (!(TWCR & 1<<TWINT));
if (addressRW & I2C_READ) return (TWSR & 0xF8) == TWSR_MRX_ADR_ACK;
else return (TWSR & 0xF8) == TWSR_MTX_ADR_ACK;
#endif
}
bool I2Crestart (uint8_t address, uint8_t read) {
return I2Cstart(address, read);
}
void I2Cstop (uint8_t read) {
#if defined(CPU_AVR128DX48)
(void) read;
TWI0.MCTRLB |= TWI_MCMD_STOP_gc; // Send STOP
while (!((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_IDLE_gc)); // Wait for bus to return to idle state
#else
(void) read;
TWCR = 1<<TWINT | 1<<TWEN | 1<<TWSTO;
while (TWCR & 1<<TWSTO); // wait until stop and bus released
#endif
}"#
#+(or arm esp)
#"
// I2C interface for up to two ports, using Arduino Wire
void I2Cinit (TwoWire *port, bool enablePullup) {
(void) enablePullup;
port->begin();
}
int I2Cread (TwoWire *port) {
return port->read();
}
void I2Cwrite (TwoWire *port, uint8_t data) {
port->write(data);
}
bool I2Cstart (TwoWire *port, uint8_t address, uint8_t read) {
int ok = true;
if (read == 0) {
port->beginTransmission(address);
ok = (port->endTransmission(true) == 0);
port->beginTransmission(address);
}
else port->requestFrom(address, I2Ccount);
return ok;
}
bool I2Crestart (TwoWire *port, uint8_t address, uint8_t read) {
int error = (port->endTransmission(false) != 0);
if (read == 0) port->beginTransmission(address);
else port->requestFrom(address, I2Ccount);
return error ? false : true;
}
void I2Cstop (TwoWire *port, uint8_t read) {
if (read == 0) port->endTransmission(); // Check for error?
// Release pins
port->end();
}"#
#-(or avr avr-nano badge arm esp)
#"
// I2C interface for one port, using Arduino Wire
void I2Cinit (bool enablePullup) {
(void) enablePullup;
Wire.begin();
}
int I2Cread () {
return Wire.read();
}
void I2Cwrite (uint8_t data) {
Wire.write(data);
}
bool I2Cstart (uint8_t address, uint8_t read) {
int ok = true;
if (read == 0) {
Wire.beginTransmission(address);
ok = (Wire.endTransmission(true) == 0);
Wire.beginTransmission(address);
}
else Wire.requestFrom(address, I2Ccount);
return ok;
}
bool I2Crestart (uint8_t address, uint8_t read) {
int error = (Wire.endTransmission(false) != 0);
if (read == 0) Wire.beginTransmission(address);
else Wire.requestFrom(address, I2Ccount);
return error ? false : true;
}
void I2Cstop (uint8_t read) {
if (read == 0) Wire.endTransmission(); // Check for error?
}"#
#+badge
#"
// I2C interface for AVR platforms, uses much less RAM than Arduino Wire
uint8_t const TWI_SDA_PIN = 17;
uint8_t const TWI_SCL_PIN = 16;
uint32_t const F_TWI = 400000L; // Hardware I2C clock in Hz
uint8_t const TWSR_MTX_DATA_ACK = 0x28;
uint8_t const TWSR_MTX_ADR_ACK = 0x18;
uint8_t const TWSR_MRX_ADR_ACK = 0x40;
uint8_t const TWSR_START = 0x08;
uint8_t const TWSR_REP_START = 0x10;
uint8_t const I2C_READ = 1;
uint8_t const I2C_WRITE = 0;
void I2Cinit (bool enablePullup) {
TWSR = 0; // no prescaler
TWBR = (F_CPU/F_TWI - 16)/2; // set bit rate factor
if (enablePullup) {
digitalWrite(TWI_SDA_PIN, HIGH);
digitalWrite(TWI_SCL_PIN, HIGH);
}
}
int I2Cread () {
if (I2Ccount != 0) I2Ccount--;
TWCR = 1<<TWINT | 1<<TWEN | ((I2Ccount == 0) ? 0 : (1<<TWEA));
while (!(TWCR & 1<<TWINT));
return TWDR;
}
bool I2Cwrite (uint8_t data) {
TWDR = data;
TWCR = 1<<TWINT | 1 << TWEN;
while (!(TWCR & 1<<TWINT));
return (TWSR & 0xF8) == TWSR_MTX_DATA_ACK;
}
bool I2Cstart (uint8_t address, uint8_t read) {
uint8_t addressRW = address<<1 | read;
TWCR = 1<<TWINT | 1<<TWSTA | 1<<TWEN; // Send START condition
while (!(TWCR & 1<<TWINT));
if ((TWSR & 0xF8) != TWSR_START && (TWSR & 0xF8) != TWSR_REP_START) return false;
TWDR = addressRW; // send device address and direction
TWCR = 1<<TWINT | 1<<TWEN;
while (!(TWCR & 1<<TWINT));
if (addressRW & I2C_READ) return (TWSR & 0xF8) == TWSR_MRX_ADR_ACK;
else return (TWSR & 0xF8) == TWSR_MTX_ADR_ACK;
}
bool I2Crestart (uint8_t address, uint8_t read) {
return I2Cstart(address, read);
}
void I2Cstop (uint8_t read) {
(void) read;
TWCR = 1<<TWINT | 1<<TWEN | 1<<TWSTO;
while (TWCR & 1<<TWSTO); // wait until stop and bus released
}"#))
(defparameter *stream-interface* '(
#+avr-nano
#"
// Streams
inline int spiread () { return SPI.transfer(0); }
#if defined(CPU_AVR64DD28)
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
#endif
#if defined(sdcardsupport)
File SDpfile, SDgfile;
inline int SDread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
return SDgfile.read();
}
#endif
void serialbegin (int address, int baud) {
(void) address; (void) baud;
error(PSTR("port not supported"), number(address));
}"#
#+avr
#"
// Streams
inline int spiread () { return SPI.transfer(0); }
#if defined(CPU_ATmega1284P) || defined(CPU_AVR128DX48)
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
#elif defined(CPU_ATmega2560)
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
inline int serial2read () { while (!Serial2.available()) testescape(); return Serial2.read(); }
inline int serial3read () { while (!Serial3.available()) testescape(); return Serial3.read(); }
#endif
#if defined(sdcardsupport)
File SDpfile, SDgfile;
inline int SDread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
return SDgfile.read();
}
#endif
void serialbegin (int address, int baud) {
(void) address; (void) baud;
}"#
#+(or avr avr-nano)
#"
void serialend (int address) {
(void) address;
}
gfun_t gstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
gfun_t gfun = gserial;
if (args != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) gfun = (gfun_t)I2Cread;
else if (streamtype == SPISTREAM) gfun = spiread;
else if (streamtype == SERIALSTREAM) {
if (address == 0) gfun = gserial;
#if defined(CPU_ATmega1284P) || defined(CPU_AVR128DX48)
else if (address == 1) gfun = serial1read;
#elif defined(CPU_ATmega2560)
else if (address == 1) gfun = serial1read;
else if (address == 2) gfun = serial2read;
else if (address == 3) gfun = serial3read;
#endif
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) gfun = (gfun_t)SDread;
#endif
else error2(unknownstreamtype);
return gfun;
}
inline void spiwrite (char c) { SPI.transfer(c); }
#if defined(CPU_ATmega1284P) || defined(CPU_AVR128DX48)
inline void serial1write (char c) { Serial1.write(c); }
#elif defined(CPU_ATmega2560)
inline void serial1write (char c) { Serial1.write(c); }
inline void serial2write (char c) { Serial2.write(c); }
inline void serial3write (char c) { Serial3.write(c); }
#endif
#if defined(sdcardsupport)
inline void SDwrite (char c) { int w = SDpfile.write(c); if (w != 1) { Context = NIL; error2(PSTR("failed to write to file")); } }
#endif
pfun_t pstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
pfun_t pfun = pserial;
if (args != NULL && first(args) != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) pfun = (pfun_t)I2Cwrite;
else if (streamtype == SPISTREAM) pfun = spiwrite;
else if (streamtype == SERIALSTREAM) {
if (address == 0) pfun = pserial;
#if defined(CPU_ATmega1284P) || defined(CPU_AVR128DX48)
else if (address == 1) pfun = serial1write;
#elif defined(CPU_ATmega2560)
else if (address == 1) pfun = serial1write;
else if (address == 2) pfun = serial2write;
else if (address == 3) pfun = serial3write;
#endif
}
else if (streamtype == STRINGSTREAM) {
pfun = pstr;
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite;
#endif
else error2(unknownstreamtype);
return pfun;
}"#
#+arm
#"
// Streams
// Simplify board differences
#if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_GRAND_CENTRAL_M4) \
|| defined(ARDUINO_PYBADGE_M4) || defined(ARDUINO_PYGAMER_M4) || defined(ARDUINO_TEENSY40) \
|| defined(ARDUINO_TEENSY41) || defined(ARDUINO_RASPBERRY_PI_PICO) \
|| defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO_2) \
|| defined(ARDUINO_PIMORONI_PICO_PLUS_2)
#define ULISP_SPI1
#endif
#if defined(ARDUINO_WIO_TERMINAL) || defined(ARDUINO_BBC_MICROBIT_V2) \
|| defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(MAX32620) \
|| defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) \
|| defined(ARDUINO_ADAFRUIT_QTPY_RP2040) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) \
|| defined(ARDUINO_RASPBERRY_PI_PICO_2) || defined(ARDUINO_PIMORONI_PICO_PLUS_2) \
|| defined(ARDUINO_GRAND_CENTRAL_M4) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
#define ULISP_I2C1
#endif
#if defined(ARDUINO_SAM_DUE) || defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41)
#define ULISP_SERIAL3
#elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) \
|| defined(ARDUINO_RASPBERRY_PI_PICO_2) || defined(ARDUINO_PIMORONI_PICO_PLUS_2)
#define ULISP_SERIAL2
#elif !defined(CPU_NRF51822) && !defined(CPU_NRF52833) && !defined(ARDUINO_FEATHER_F405)
#define ULISP_SERIAL1
#endif
#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_UNOWIFIR4)
#define ULISP_WIFI
#endif
inline int spiread () { return SPI.transfer(0); }
#if defined(ULISP_SPI1)
inline int spi1read () { return SPI1.transfer(0); }
#endif
inline int i2cread () { return I2Cread(&Wire); }
#if defined(ULISP_I2C1)
inline int i2c1read () { return I2Cread(&Wire1); }
#endif
#if defined(ULISP_SERIAL3)
inline int serial3read () { while (!Serial3.available()) testescape(); return Serial3.read(); }
#endif
#if defined(ULISP_SERIAL3) || defined(ULISP_SERIAL2)
inline int serial2read () { while (!Serial2.available()) testescape(); return Serial2.read(); }
#endif
#if defined(ULISP_SERIAL3) || defined(ULISP_SERIAL2) || defined(ULISP_SERIAL1)
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
#endif
#if defined(sdcardsupport)
File SDpfile, SDgfile;
inline int SDread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
return SDgfile.read();
}
#endif
#if defined(ULISP_WIFI)
WiFiClient client;
WiFiServer server(80);
inline int WiFiread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
while (!client.available()) testescape();
return client.read();
}
#endif
void serialbegin (int address, int baud) {
#if defined(ULISP_SERIAL3)
if (address == 1) Serial1.begin((long)baud*100);
else if (address == 2) Serial2.begin((long)baud*100);
else if (address == 3) Serial3.begin((long)baud*100);
#elif defined(ULISP_SERIAL2)
if (address == 1) Serial1.begin((long)baud*100);
else if (address == 2) Serial2.begin((long)baud*100);
#elif defined(ULISP_SERIAL1)
if (address == 1) Serial1.begin((long)baud*100);
#else
(void) baud;
if (false);
#endif
else error("port not supported", number(address));
}
void serialend (int address) {
#if defined(ULISP_SERIAL3)
if (address == 1) {Serial1.flush(); Serial1.end(); }
else if (address == 2) {Serial2.flush(); Serial2.end(); }
else if (address == 3) {Serial3.flush(); Serial3.end(); }
#elif defined(ULISP_SERIAL2)
if (address == 1) {Serial1.flush(); Serial1.end(); }
else if (address == 2) {Serial2.flush(); Serial2.end(); }
#elif defined(ULISP_SERIAL1)
if (address == 1) {Serial1.flush(); Serial1.end(); }
#else
if (false);
#endif
else error("port not supported", number(address));
}
gfun_t gstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
gfun_t gfun = gserial;
if (args != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) {
if (address < 128) gfun = i2cread;
#if defined(ULISP_I2C1)
else gfun = i2c1read;
#endif
} else if (streamtype == SPISTREAM) {
if (address < 128) gfun = spiread;
#if defined(ULISP_SPI1)
else gfun = spi1read;
#endif
}
else if (streamtype == SERIALSTREAM) {
if (address == 0) gfun = gserial;
#if defined(ULISP_SERIAL3)
else if (address == 1) gfun = serial1read;
else if (address == 2) gfun = serial2read;
else if (address == 3) gfun = serial3read;
#elif defined(ULISP_SERIAL2)
else if (address == 1) gfun = serial1read;
else if (address == 2) gfun = serial2read;
#elif defined(ULISP_SERIAL1)
else if (address == 1) gfun = serial1read;
#endif
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) gfun = (gfun_t)SDread;
#endif
#if defined(ULISP_WIFI)
else if (streamtype == WIFISTREAM) gfun = (gfun_t)WiFiread;
#endif
else error2("unknown stream type");
return gfun;
}
inline void spiwrite (char c) { SPI.transfer(c); }
#if defined(ULISP_SPI1)
inline void spi1write (char c) { SPI1.transfer(c); }
#endif
inline void i2cwrite (char c) { I2Cwrite(&Wire, c); }
#if defined(ULISP_I2C1)
inline void i2c1write (char c) { I2Cwrite(&Wire1, c); }
#endif
#if defined(ULISP_SERIAL3)
inline void serial1write (char c) { Serial1.write(c); }
inline void serial2write (char c) { Serial2.write(c); }
inline void serial3write (char c) { Serial3.write(c); }
#elif defined(ULISP_SERIAL2)
inline void serial2write (char c) { Serial2.write(c); }
inline void serial1write (char c) { Serial1.write(c); }
#elif defined(ULISP_SERIAL1)
inline void serial1write (char c) { Serial1.write(c); }
#endif
#if defined(sdcardsupport)
inline void SDwrite (char c) { SDpfile.write(uint8_t(c)); } // Fix for RP2040
#endif
#if defined(ULISP_WIFI)
inline void WiFiwrite (char c) { client.write(c); }
#endif
#if defined(gfxsupport)
inline void gfxwrite (char c) { tft.write(c); }
#endif
pfun_t pstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
pfun_t pfun = pserial;
if (args != NULL && first(args) != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) {
if (address < 128) pfun = i2cwrite;
#if defined(ULISP_I2C1)
else pfun = i2c1write;
#endif
} else if (streamtype == SPISTREAM) {
if (address < 128) pfun = spiwrite;
#if defined(ULISP_SPI1)
else pfun = spi1write;
#endif
} else if (streamtype == SERIALSTREAM) {
if (address == 0) pfun = pserial;
#if defined(ULISP_SERIAL3)
else if (address == 1) pfun = serial1write;
else if (address == 2) pfun = serial2write;
else if (address == 3) pfun = serial3write;
#elif defined(ULISP_SERIAL2)
else if (address == 1) pfun = serial1write;
else if (address == 2) pfun = serial2write;
#elif defined(ULISP_SERIAL1)
else if (address == 1) pfun = serial1write;
#endif
}
else if (streamtype == STRINGSTREAM) {
pfun = pstr;
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite;
#endif
#if defined(gfxsupport)
else if (streamtype == GFXSTREAM) pfun = (pfun_t)gfxwrite;
#endif
#if defined(ULISP_WIFI)
else if (streamtype == WIFISTREAM) pfun = (pfun_t)WiFiwrite;
#endif
else error2("unknown stream type");
return pfun;
}"#
#+esp
#"
// Streams
// Simplify board differences
#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2)
#define ULISP_I2C1
#endif
inline int spiread () { return SPI.transfer(0); }
inline int i2cread () { return I2Cread(&Wire); }
#if defined(ULISP_I2C1)
inline int i2c1read () { return I2Cread(&Wire1); }
#endif
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
#if defined(sdcardsupport)
File SDpfile, SDgfile;
inline int SDread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
return SDgfile.read();
}
#endif
WiFiClient client;
WiFiServer server(80);
inline int WiFiread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
while (!client.available()) testescape();
return client.read();
}
void serialbegin (int address, int baud) {
if (address == 1) Serial1.begin((long)baud*100);
else error(PSTR("port not supported"), number(address));
}
void serialend (int address) {
if (address == 1) {Serial1.flush(); Serial1.end(); }
else error(PSTR("port not supported"), number(address));
}
gfun_t gstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
gfun_t gfun = gserial;
if (args != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) {
if (address < 128) gfun = i2cread;
#if defined(ULISP_I2C1)
else gfun = i2c1read;
#endif
} else if (streamtype == SPISTREAM) gfun = spiread;
else if (streamtype == SERIALSTREAM) {
if (address == 0) gfun = gserial;
else if (address == 1) gfun = serial1read;
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) gfun = (gfun_t)SDread;
#endif
else if (streamtype == WIFISTREAM) gfun = (gfun_t)WiFiread;
else error2(PSTR("unknown stream type"));
return gfun;
}
inline void spiwrite (char c) { SPI.transfer(c); }
inline void i2cwrite (char c) { I2Cwrite(&Wire, c); }
#if defined(ULISP_I2C1)
inline void i2c1write (char c) { I2Cwrite(&Wire1, c); }
#endif
inline void serial1write (char c) { Serial1.write(c); }
inline void WiFiwrite (char c) { client.write(c); }
#if defined(sdcardsupport)
inline void SDwrite (char c) { SDpfile.write(c); }
#endif
#if defined(gfxsupport)
inline void gfxwrite (char c) { tft.write(c); }
#endif
pfun_t pstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
pfun_t pfun = pserial;
if (args != NULL && first(args) != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) {
if (address < 128) pfun = i2cwrite;
#if defined(ULISP_I2C1)
else pfun = i2c1write;
#endif
} else if (streamtype == SPISTREAM) pfun = spiwrite;
else if (streamtype == SERIALSTREAM) {
if (address == 0) pfun = pserial;
else if (address == 1) pfun = serial1write;
}
else if (streamtype == STRINGSTREAM) {
pfun = pstr;
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite;
#endif
#if defined(gfxsupport)
else if (streamtype == GFXSTREAM) pfun = (pfun_t)gfxwrite;
#endif
else if (streamtype == WIFISTREAM) pfun = (pfun_t)WiFiwrite;
else error2(PSTR("unknown stream type"));
return pfun;
}"#
#+riscv
#"
// Streams
inline int spiread () { return SPI.transfer(0); }
#if defined(BOARD_SIPEED_MAIX_DUINO)
inline int serial1read () { while (!Serial1.available()) testescape(); return Serial1.read(); }
inline int serial2read () { while (!Serial2.available()) testescape(); return Serial2.read(); }
inline int serial3read () { while (!Serial3.available()) testescape(); return Serial3.read(); }
#endif
#if defined(sdcardsupport)
File SDpfile, SDgfile;
inline int SDread () {
if (LastChar) {
char temp = LastChar;
LastChar = 0;
return temp;
}
return SDgfile.read();
}
#endif
void serialbegin (int address, int baud) {
#if defined(BOARD_SIPEED_MAIX_DUINO)
if (address == 1) Serial1.begin((long)baud*100);
else if (address == 2) Serial2.begin((long)baud*100);
else if (address == 3) Serial3.begin((long)baud*100);
else error(PSTR("port not supported"), number(address));
#endif
}
void serialend (int address) {
#if defined(BOARD_SIPEED_MAIX_DUINO)
if (address == 1) {Serial1.flush(); Serial1.end(); }
else if (address == 2) {Serial2.flush(); Serial2.end(); }
else if (address == 3) {Serial3.flush(); Serial3.end(); }
#endif
}
gfun_t gstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
gfun_t gfun = gserial;
if (args != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) gfun = (gfun_t)I2Cread;
else if (streamtype == SPISTREAM) {
if (address < 128) gfun = spiread;
}
else if (streamtype == SERIALSTREAM) {
if (address == 0) gfun = gserial;
#if defined(BOARD_SIPEED_MAIX_DUINO)
else if (address == 1) gfun = serial1read;
else if (address == 2) gfun = serial2read;
else if (address == 3) gfun = serial3read;
#endif
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) gfun = (gfun_t)SDread;
#endif
else error2(PSTR("unknown stream type"));
return gfun;
}
inline void spiwrite (char c) { SPI.transfer(c); }
#if defined(BOARD_SIPEED_MAIX_DUINO)
inline void serial1write (char c) { Serial1.write(c); }
inline void serial2write (char c) { Serial2.write(c); }
inline void serial3write (char c) { Serial3.write(c); }
#endif
#if defined(sdcardsupport)
inline void SDwrite (char c) { SDpfile.write(c); }
#endif
#if defined(gfxsupport)
inline void gfxwrite (char c) { tft.write(c); }
#endif
pfun_t pstreamfun (object *args) {
int streamtype = SERIALSTREAM;
int address = 0;
pfun_t pfun = pserial;
if (args != NULL && first(args) != NULL) {
int stream = isstream(first(args));
streamtype = stream>>8; address = stream & 0xFF;
}
if (streamtype == I2CSTREAM) pfun = (pfun_t)I2Cwrite;
else if (streamtype == SPISTREAM) {
if (address < 128) pfun = spiwrite;
}
else if (streamtype == SERIALSTREAM) {
if (address == 0) pfun = pserial;
#if defined(BOARD_SIPEED_MAIX_DUINO)
else if (address == 1) pfun = serial1write;
else if (address == 2) pfun = serial2write;
else if (address == 3) pfun = serial3write;
#endif
}
else if (streamtype == STRINGSTREAM) {
pfun = pstr;
}
#if defined(sdcardsupport)
else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite;
#endif
#if defined(gfxsupport)
else if (streamtype == GFXSTREAM) pfun = (pfun_t)gfxwrite;
#endif
else error2(PSTR("unknown stream type"));
return pfun;
}"#))