From 0723af368e73521c2abbc0ca224ade3172f7f0fb Mon Sep 17 00:00:00 2001 From: Chris Hocking Date: Thu, 3 Nov 2022 12:47:34 +1100 Subject: [PATCH] Added methods for RTS and DTR - Added methods to get and set the `RTS` and `DTR` values. - Fixed some inconsistencies in the documentation. - Fixed some typos where `LS_TNUMBER` was incorrectly used instead of `LS_TBOOLEAN`. - Closes #3310 --- extensions/serial/libserial.m | 102 ++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/extensions/serial/libserial.m b/extensions/serial/libserial.m index a0f51ee79..b830e9c65 100755 --- a/extensions/serial/libserial.m +++ b/extensions/serial/libserial.m @@ -106,6 +106,8 @@ @interface HSSerialPort : NSObject @property BOOL usesDTRDSRFlowControl; @property BOOL usesDCDOutputFlowControl; @property BOOL allowsNonStandardBaudRates; +@property BOOL rts; +@property BOOL dtr; @end @@ -134,6 +136,8 @@ - (instancetype)init _usesDTRDSRFlowControl = NO; _usesDCDOutputFlowControl = NO; _allowsNonStandardBaudRates = NO; + _rts = NO; + _dtr = NO; } return self; } @@ -230,7 +234,7 @@ - (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data - (void)serialPort:(ORSSerialPort *)serialPort didReceivePacket:(NSData *)packetData matchingDescriptor:(ORSSerialPacketDescriptor *)descriptor { - // TODO: Impliment `ORSSerialPacketDescriptor` functionality + // TODO: Implement `ORSSerialPacketDescriptor` functionality } - (void)serialPortWasRemovedFromSystem:(ORSSerialPort *)serialPort; @@ -409,6 +413,8 @@ - (BOOL)open self.serialPort.usesRTSCTSFlowControl = self.usesRTSCTSFlowControl; self.serialPort.usesDTRDSRFlowControl = self.usesDTRDSRFlowControl; self.serialPort.usesDCDOutputFlowControl = self.usesDCDOutputFlowControl; + self.serialPort.RTS = self.rts; + self.serialPort.DTR = self.dtr; [self.serialPort open]; } return self.serialPort && self.serialPort.isOpen; @@ -447,6 +453,22 @@ - (void)changeNumberOfDataBits:(NSUInteger)numberOfDataBits } } +- (void)changeRTS:(BOOL)rtsEnabled +{ + self.rts = rtsEnabled; + if ([self isOpen]) { + self.serialPort.RTS = rtsEnabled; + } +} + +- (void)changeDTR:(BOOL)dtrEnabled +{ + self.dtr = dtrEnabled; + if ([self isOpen]) { + self.serialPort.DTR = dtrEnabled; + } +} + - (void)changeUsesRTSCTSFlowControl:(BOOL)usesRTSCTSFlowControl { self.usesRTSCTSFlowControl = usesRTSCTSFlowControl; @@ -872,10 +894,12 @@ static int serial_parity(lua_State *L) { /// /// Returns: /// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: /// * The default value is `false`. static int serial_usesDCDOutputFlowControl(lua_State *L) { LuaSkin *skin = [LuaSkin sharedWithState:L]; - [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; if (lua_gettop(L) == 1) { // Get: @@ -898,10 +922,12 @@ static int serial_usesDCDOutputFlowControl(lua_State *L) { /// /// Returns: /// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: /// * The default value is `false`. static int serial_usesDTRDSRFlowControl(lua_State *L) { LuaSkin *skin = [LuaSkin sharedWithState:L]; - [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; if (lua_gettop(L) == 1) { // Get: @@ -924,10 +950,12 @@ static int serial_usesDTRDSRFlowControl(lua_State *L) { /// /// Returns: /// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: /// * The default value is `false`. static int serial_usesRTSCTSFlowControl(lua_State *L) { LuaSkin *skin = [LuaSkin sharedWithState:L]; - [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; if (lua_gettop(L) == 1) { // Get: @@ -941,6 +969,64 @@ static int serial_usesRTSCTSFlowControl(lua_State *L) { return 1; } +/// hs.serial:dtr([value]) -> boolean | serialPortObject +/// Method +/// Gets or sets the state of the serial port's DTR (Data Terminal Ready) pin. +/// +/// Parameters: +/// * value - An optional boolean. +/// +/// Returns: +/// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: +/// * The default value is `false`. +/// * Setting this to `true` is most likely required for Arduino devices prior to opening the serial port. +static int serial_dtr(lua_State *L) { + LuaSkin *skin = [LuaSkin sharedWithState:L]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; + HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; + if (lua_gettop(L) == 1) { + // Get: + BOOL dtrEnabled = serialPort.dtr; + lua_pushboolean(L, dtrEnabled); + } else { + BOOL dtrEnabled = lua_toboolean(L, 2); + [serialPort changeDTR:dtrEnabled]; + lua_pushvalue(L, 1); + } + return 1; +} + +/// hs.serial:rts([value]) -> boolean | serialPortObject +/// Method +/// Gets or sets the state of the serial port's RTS (Request to Send) pin. +/// +/// Parameters: +/// * value - An optional boolean. +/// +/// Returns: +/// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: +/// * The default value is `false`. +/// * Setting this to `true` is most likely required for Arduino devices prior to opening the serial port. +static int serial_rts(lua_State *L) { + LuaSkin *skin = [LuaSkin sharedWithState:L]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; + HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; + if (lua_gettop(L) == 1) { + // Get: + BOOL rtsEnabled = serialPort.rts; + lua_pushboolean(L, rtsEnabled); + } else { + BOOL rtsEnabled = lua_toboolean(L, 2); + [serialPort changeRTS:rtsEnabled]; + lua_pushvalue(L, 1); + } + return 1; +} + /// hs.serial:shouldEchoReceivedData([value]) -> boolean | serialPortObject /// Method /// Gets or sets whether the port should echo received data. @@ -950,10 +1036,12 @@ static int serial_usesRTSCTSFlowControl(lua_State *L) { /// /// Returns: /// * If a value is specified, then this method returns the serial port object. Otherwise this method returns a boolean. +/// +/// Notes: /// * The default value is `false`. static int serial_shouldEchoReceivedData(lua_State *L) { LuaSkin *skin = [LuaSkin sharedWithState:L]; - [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK]; + [skin checkArgs:LS_TUSERDATA, USERDATA_TAG, LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK]; HSSerialPort *serialPort = [skin toNSObjectAtIndex:1]; if (lua_gettop(L) == 1) { // Get: @@ -976,6 +1064,8 @@ static int serial_shouldEchoReceivedData(lua_State *L) { /// /// Returns: /// * If a value is specified, then this method returns the serial port object. Otherwise this method returns the number of stop bits as a number. +/// +/// Notes: /// * The default value is 1. static int serial_numberOfStopBits(lua_State *L) { LuaSkin *skin = [LuaSkin sharedWithState:L]; @@ -1227,6 +1317,8 @@ static int meta_gc(lua_State* L) { {"shouldEchoReceivedData", serial_shouldEchoReceivedData}, {"usesRTSCTSFlowControl", serial_usesRTSCTSFlowControl}, {"usesDTRDSRFlowControl", serial_usesDTRDSRFlowControl}, + {"rts", serial_rts}, + {"dtr", serial_dtr}, {"usesDCDOutputFlowControl", serial_usesDCDOutputFlowControl}, {"__tostring", userdata_tostring}, {"__eq", userdata_eq},