cwIo.h/cpp,cwIoTest.cpp : Fixed serial port monitor example in cwIoTest.cpp

This commit is contained in:
kevin 2021-10-11 11:53:36 -04:00
parent 46191195b1
commit e128a1dd38
3 changed files with 134 additions and 43 deletions

136
cwIo.cpp
View File

@ -51,10 +51,10 @@ namespace cw
typedef struct serialPort_str typedef struct serialPort_str
{ {
char* label; char* label;
unsigned userId;
char* device; char* device;
unsigned baudRate; unsigned baudRate;
unsigned flags; unsigned flags;
unsigned pollPeriodMs;
serialPortSrv::handle_t serialH; serialPortSrv::handle_t serialH;
} serialPort_t; } serialPort_t;
@ -107,6 +107,7 @@ namespace cw
serialPort_t* serialA; serialPort_t* serialA;
unsigned serialN; unsigned serialN;
serialPortSrv::handle_t serialPortSrvH;
midi::device::handle_t midiH; midi::device::handle_t midiH;
@ -239,13 +240,32 @@ namespace cw
// Serial // Serial
// //
void _serialPortCb( void* arg, const void* byteA, unsigned byteN ) void _serialPortCb( void* arg, unsigned serialCfgIdx, const void* byteA, unsigned byteN )
{ {
//io_t* p = reinterpret_cast<io_t*>(arg); const io_t* p = (const io_t*)arg;
if( serialCfgIdx > p->serialN )
cwLogError(kAssertFailRC,"The serial cfg index %i is out of range %i in serial port callback.", serialCfgIdx, p->serialN );
else
{
const serialPort_t* sp = p->serialA + serialCfgIdx;
msg_t m;
serial_msg_t sm;
sm.label = sp->label;
sm.userId = sp->userId;
sm.dataA = byteA;
sm.byteN = byteN;
m.tid = kSerialTId;
m.u.serial = &sm;
p->cbFunc( p->cbArg, &m );
}
} }
rc_t _serialPortParseCfg( const object_t& e, serialPort_t* port )
rc_t _serialPortParseCfg( const object_t& e, serialPort_t* port, bool& enableFlRef )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
char* parityLabel = nullptr; char* parityLabel = nullptr;
@ -261,13 +281,13 @@ namespace cw
}; };
if((rc = e.getv( if((rc = e.getv(
"enable_flag", enableFlRef,
"label", port->label, "label", port->label,
"device", port->device, "device", port->device,
"baud", port->baudRate, "baud", port->baudRate,
"bits", bits, "bits", bits,
"stop", stop, "stop", stop,
"parity", parityLabel, "parity", parityLabel )) != kOkRC )
"pollPeriodMs", port->pollPeriodMs )) != kOkRC )
{ {
rc = cwLogError(kSyntaxErrorRC,"Serial configuration parse failed."); rc = cwLogError(kSyntaxErrorRC,"Serial configuration parse failed.");
} }
@ -308,19 +328,39 @@ namespace cw
rc_t _serialPortCreate( io_t* p, const object_t* c ) rc_t _serialPortCreate( io_t* p, const object_t* c )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
const object_t* cfgL = nullptr; const object_t* cfg = nullptr;
const object_t* port_array = nullptr;
unsigned pollPeriodMs = 50;
unsigned recvBufByteN = 512;
// get the serial port list node // get the serial port list node
if((cfgL = c->find("serial")) == nullptr || !cfgL->is_list()) if((cfg = c->find("serial")) == nullptr)
return cwLogError(kSyntaxErrorRC,"Unable to locate the 'serial' configuration list."); return cwLogError(kSyntaxErrorRC,"Unable to locate the 'serial' configuration.");
p->serialN = cfgL->child_count(); // the serial header values
if((rc = cfg->getv("pollPeriodMs", pollPeriodMs,
"recvBufByteN", recvBufByteN,
"array", port_array)) != kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"Serial cfg header parse failed.");
goto errLabel;
}
p->serialN = port_array->child_count();
p->serialA = mem::allocZ<serialPort_t>(p->serialN); p->serialA = mem::allocZ<serialPort_t>(p->serialN);
// create the serial server
if((rc = serialPortSrv::create(p->serialPortSrvH,pollPeriodMs,recvBufByteN)) != kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"Serial port server failed.");
goto errLabel;
}
// for each serial port cfg // for each serial port cfg
for(unsigned i=0; i<p->serialN; ++i) for(unsigned i=0; i<p->serialN; ++i)
{ {
const object_t* e = cfgL->child_ele(i); const object_t* e = port_array->child_ele(i);
serialPort_t* r = p->serialA + i; serialPort_t* r = p->serialA + i;
if( e == nullptr ) if( e == nullptr )
@ -330,23 +370,51 @@ namespace cw
} }
else else
{ {
bool enableFl = false;
// parse the cfg record // parse the cfg record
if((rc = _serialPortParseCfg(*e,r)) != kOkRC ) if((rc = _serialPortParseCfg(*e,r,enableFl)) != kOkRC )
{ {
rc = cwLogError(rc,"Serial configuration parse failed on record index:%i.", i ); rc = cwLogError(rc,"Serial configuration parse failed on record index:%i.", i );
break; break;
} }
/* if( enableFl )
{
r->userId = i; // default the serial port userId to the index into serialA[]
serialPort::handle_t spH = serialPortSrv::serialHandle(p->serialPortSrvH);
// create the serial port object // create the serial port object
if((rc = serialPortSrv::create( r->serialH, r->device, r->baudRate, r->flags, _serialPortCb, p, r->pollPeriodMs )) != kOkRC ) if((rc = serialPort::createPort( spH, i, r->device, r->baudRate, r->flags, _serialPortCb, p )) != kOkRC )
{ {
rc = cwLogError(rc,"Serial port create failed on record index:%i.", i ); rc = cwLogError(rc,"Serial port create failed on record index:%i.", i );
break; break;
} }
*/
} }
} }
}
errLabel:
return rc;
}
void _serialPortDestroy( io_t* p )
{
serialPortSrv::destroy(p->serialPortSrvH);
mem::free(p->serialA);
p->serialN = 0;
}
rc_t _serialPortStart( io_t* p )
{
rc_t rc;
if((rc =serialPortSrv::start( p->serialPortSrvH )) != kOkRC )
rc = cwLogError(rc,"The serial port server start failed.");
return rc; return rc;
} }
@ -1568,15 +1636,7 @@ namespace cw
mem::free(p->timerA); mem::free(p->timerA);
p->timerN = 0; p->timerN = 0;
for(unsigned i=0; i<p->serialN; ++i) _serialPortDestroy(p);
serialPortSrv::destroy( p->serialA[i].serialH );
mem::free(p->serialA);
p->serialN = 0;
// TODO: clean up the audio system more systematically
// by first stopping all the devices and then
// reversing the creating process.
_audioDestroy(p); _audioDestroy(p);
@ -1722,6 +1782,8 @@ cw::rc_t cw::io::start( handle_t h )
_audioDeviceStartStop(p,true); _audioDeviceStartStop(p,true);
_serialPortStart(p);
return thread_mach::start( p->threadMachH ); return thread_mach::start( p->threadMachH );
} }
@ -1903,12 +1965,6 @@ unsigned cw::io::serialDeviceCount( handle_t h )
return p->serialN; return p->serialN;
} }
const char* cw::io::serialDeviceLabel( handle_t h, unsigned devIdx )
{
io_t* p = _handleToPtr(h);
return p->serialA[devIdx].label;
}
unsigned cw::io::serialDeviceIndex( handle_t h, const char* label ) unsigned cw::io::serialDeviceIndex( handle_t h, const char* label )
{ {
io_t* p = _handleToPtr(h); io_t* p = _handleToPtr(h);
@ -1919,6 +1975,26 @@ unsigned cw::io::serialDeviceIndex( handle_t h, const char* label )
return kInvalidIdx; return kInvalidIdx;
} }
const char* cw::io::serialDeviceLabel( handle_t h, unsigned devIdx )
{
io_t* p = _handleToPtr(h);
return p->serialA[devIdx].label;
}
unsigned cw::io::serialDeviceId( handle_t h, unsigned devIdx )
{
io_t* p = _handleToPtr(h);
return p->serialA[devIdx].userId;
}
void cw::io::serialDeviceSetId( handle_t h, unsigned devIdx, unsigned id )
{
io_t* p = _handleToPtr(h);
p->serialA[devIdx].userId = id;
}
cw::rc_t cw::io::serialDeviceSend( handle_t h, unsigned devIdx, const void* byteA, unsigned byteN ) cw::rc_t cw::io::serialDeviceSend( handle_t h, unsigned devIdx, const void* byteA, unsigned byteN )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;

8
cwIo.h
View File

@ -44,7 +44,8 @@ namespace cw
typedef struct serial_msg_str typedef struct serial_msg_str
{ {
unsigned devId; const char* label; // label from cfg
unsigned userId; // defaults to index into internal serial cfg. array - reset vial serialDeviceSetId().
const void* dataA; const void* dataA;
unsigned byteN; unsigned byteN;
} serial_msg_t; } serial_msg_t;
@ -174,8 +175,11 @@ namespace cw
// //
unsigned serialDeviceCount( handle_t h ); unsigned serialDeviceCount( handle_t h );
const char* serialDeviceLabel( handle_t h, unsigned devIdx );
unsigned serialDeviceIndex( handle_t h, const char* label ); unsigned serialDeviceIndex( handle_t h, const char* label );
const char* serialDeviceLabel( handle_t h, unsigned devIdx );
unsigned serialDeviceId( handle_t h, unsigned devIdx );
void serialDeviceSetId( handle_t h, unsigned devIdx, unsigned id );
rc_t serialDeviceSend( handle_t h, unsigned devIdx, const void* byteA, unsigned byteN ); rc_t serialDeviceSend( handle_t h, unsigned devIdx, const void* byteA, unsigned byteN );
//---------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------

View File

@ -156,6 +156,16 @@ namespace cw
return rc; return rc;
} }
rc_t serialCb( app_t* app, const serial_msg_t* m )
{
if( m->byteN > 0 && m->dataA != nullptr )
{
for(unsigned i=0; i<m->byteN; ++i)
printf("%c",((const char*)m->dataA)[i]);
}
return kOkRC;
}
// The main application callback // The main application callback
rc_t testCb( void* arg, const msg_t* m ) rc_t testCb( void* arg, const msg_t* m )
@ -175,6 +185,7 @@ namespace cw
switch( m->tid ) switch( m->tid )
{ {
case kSerialTId: case kSerialTId:
serialCb(app,m->u.serial);
break; break;
case kMidiTId: case kMidiTId: