📄 iomodule.cpp
字号:
viaSDO = true;
else if( !doutPDO.Update( 2*id+1, (uint8)(value>>8) ) )
viaSDO = true;
// Output this using a PDO if requested and possible
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
return doutPDO.Transmit();
else
#endif
return sdo.Dnld16( IOOBJID_DOUT_16_VALUE, id+1, value );
}
/***************************************************************************/
/**
Write a group of 32 digital outputs.
The outputs may be written either by SDO or by PDO. The PDO method
is faster since it only requires a single message to be sent. SDO
transfers additionally require a response from the module.
If a PDO transfer is requested, but is not possible because the module is
not in an operational state, or because the output block isn't mapped to
the PDO, then an SDO transfer will be used.
@param id Identifies which group of outputs to write.
@param value The new value of the output lines.
@param viaSDO If true, the outputs will be written using SDO messages.
If false (default), then a PDO will be used if possible.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Dout32Write( uint8 id, uint32 value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
if( id >= 63 )
viaSDO = true;
else if( !doutPDO.Update( 4*id, (uint8)value ) )
viaSDO = true;
else if( !doutPDO.Update( 4*id+1, (uint8)(value>>8) ) )
viaSDO = true;
else if( !doutPDO.Update( 4*id+2, (uint8)(value>>16) ) )
viaSDO = true;
else if( !doutPDO.Update( 4*id+3, (uint8)(value>>24) ) )
viaSDO = true;
// Output this using a PDO if requested and possible
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
return doutPDO.Transmit();
else
#endif
return sdo.Dnld32( IOOBJID_DOUT_32_VALUE, id+1, value );
}
/***************************************************************************/
/**
Write to a 16-bit analog output. Since 16-bit outputs are mapped to the
default PDOs of the I/O module, these outputs may be written using either
PDOs or SDOs.
@param id The analog input channel ID
@param value The value to write.
@param viaSDO If true, the outputs will be written using SDO messages.
If false (default), then a PDO will be used if possible.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Aout16Write( uint8 id, int16 value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
// Update the local copies stored by the PDOs regardless of whether
// we are using the PDO for output. This keeps me synchronized.
int pdo = -1;
for( int i=0; i<3; i++ )
{
if( aoutPDO[i].Update( id, value ) )
pdo = i;
}
// Output this using a PDO if requested and possible
if( (!viaSDO) && (pdo>=0) && (GetState() == NODESTATE_OPERATIONAL) )
return aoutPDO[pdo].Transmit();
else
#endif
return sdo.Dnld16( IOOBJID_AOUT_16_VALUE, id+1, value );
}
/***************************************************************************/
/**
Read a single digital input.
@param id Identifies the digital input to read.
@param value The value of the input.
@param viaSDO If true, an SDO will be used to read the input pin. If false
(default), the latest value returned via PDO will be returned, if
available.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::DinRead( uint16 id, bool &value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
if( !dinIntEna || !dinPDO.GetBitVal( id, value ) )
viaSDO = true;
if( (!viaSDO) && (GetState()==NODESTATE_OPERATIONAL) )
return 0;
else
#endif
return BitUpld(IOOBJID_DIN_1_VALUE, id, value );
}
/***************************************************************************/
/**
Read a group of 8 digital inputs.
@param id Identifies which group of 8 inputs to read.
@param value The value of the 8 input lines is returned here.
@param viaSDO If true, read the inputs using SDO transfers. If false
(default) use the most recently received PDO data if this input
group is mapped to a transmit PDO and the PDO is active.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Din8Read( uint8 id, uint8 &value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
if( !dinIntEna || !dinPDO.GetInVal( id, value ) )
viaSDO = true;
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
return 0;
else
#endif
return sdo.Upld8( IOOBJID_DIN_8_VALUE, id+1, value );
}
/***************************************************************************/
/**
Read a group of 16 digital inputs.
@param id Identifies which group of 16 inputs to read.
@param value The value of the 16 input lines is returned here.
@param viaSDO If true, read the inputs using SDO transfers. If false
(default) use the most recently received PDO data if this input
group is mapped to a transmit PDO and the PDO is active.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Din16Read( uint8 id, uint16 &value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
uint8 v[2];
if( id >= 127 ) viaSDO = true;
else if( !dinIntEna ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id, v[0] ) ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id+1, v[1] ) ) viaSDO = true;
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
{
value = ((uint16)v[1]<<8) | v[0];
return 0;
}
else
#endif
return sdo.Upld16( IOOBJID_DIN_16_VALUE, id+1, value );
}
/***************************************************************************/
/**
Read a group of 32 digital inputs.
@param id Identifies which group of 32 inputs to read.
@param value The value of the 32 input lines is returned here.
@param viaSDO If true, read the inputs using SDO transfers. If false
(default) use the most recently received PDO data if this input
group is mapped to a transmit PDO and the PDO is active.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Din32Read( uint8 id, uint32 &value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
uint8 v[4];
if( id >= 63 ) viaSDO = true;
else if( !dinIntEna ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id, v[0] ) ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id+1, v[1] ) ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id+2, v[2] ) ) viaSDO = true;
else if( !dinPDO.GetInVal( 2*id+3, v[3] ) ) viaSDO = true;
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
{
value = ((uint32)v[3]<<24) | ((uint32)v[2]<<16) |
((uint32)v[1]<< 8) | ((uint32)v[0]);
return 0;
}
else
#endif
return sdo.Upld32( IOOBJID_DIN_32_VALUE, id+1, value );
}
/***************************************************************************/
/**
Read a 16-bit analog input.
@param id The analog input channel ID
@param value The analog input value
@param viaSDO If true, read the input using SDO transfers. If false
(default) use the most recently received PDO data if this input
is mapped to a transmit PDO and the PDO is active.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::Ain16Read( uint8 id, int16 &value, bool viaSDO )
{
#ifdef CML_ENABLE_IOMODULE_PDOS
if( !ainIntEna )
viaSDO = true;
else
{
bool ok = false;
for( int i=0; i<3 && !ok; i++ )
ok = ainPDO[i].GetInVal( id, value );
if( !ok ) viaSDO = true;
}
if( (!viaSDO) && (GetState() == NODESTATE_OPERATIONAL) )
return 0;
else
#endif
return sdo.Upld16( IOOBJID_AIN_16_VALUE, id+1, value );
}
/***************************************************************************/
/**
Wait on an event associated with this I/O module. The standard events are
used to indicate that a new transmit PDO has been received. A thread may
wait on such an event by calling this function.
@param event The event(s) to wait on. Multiple events may be ORed together
and in this case this function will return when any of them occure.
@param timeout The timeout for the wait (milliseconds). Negative values
indicate that no timeout should be used (wait forever). The default
value is -1.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::WaitIOEvent( IOMODULE_EVENTS event, int32 timeout )
{
EventAny any = (uint32)event;
return any.Wait( eventMap, timeout );
}
/***************************************************************************/
/**
Wait for an event associated with this I/O module. This function can be used
to wait on any generic event associated with the I/O module.
@param e The event to wait on.
@param timeout The timeout for the wait (milliseconds). If < 0, then
wait forever.
@param match Returns the matching event condition.
@return A pointer to an error object, or NULL on success.
*/
/***************************************************************************/
const Error *IOModule::WaitIOEvent( Event &e, int32 timeout, IOMODULE_EVENTS &match )
{
return e.Wait( eventMap, timeout );
}
#ifdef CML_ENABLE_IOMODULE_PDOS
/***************************************************************************/
/**
Initialize a digital output PDO object.
@param io Pointer to the I/O module to which this PDO is assigned.
@param cobID The CAN ID for this PDO message.
@param ct The number of output blocks to be mapped (1 to 8)
@param id An array of ct output block ID numbers. These will be mapped
(in order) to the PDO.
@return A pointer to an error object, or NULL on success
*/
/***************************************************************************/
const Error *IOModule::DigOutPDO::Init( IOModule *io, uint32 cobID, uint8 ct, uint8 id[] )
{
if( ct < 1 || ct > 8 )
return &IOError::BadIOCount;
this->io = io;
const Error *err = RPDO::Init( cobID );
if( !err ) err = SetType( 255 );
for( uint8 i=0; i<ct; i++ )
{
if( !err ) err = out[i].Init( IOOBJID_DOUT_8_VALUE, id[i]+1 );
if( !err ) err = AddVar( out[i] );
}
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -