📄 projectorctl.c
字号:
int powerOf2 = 1 << precision;
float result = fixed >> precision;
result += (fixed & (powerOf2-1)) * ( 1.0 / (float)powerOf2 );
return result;
}
/****************************************************************************/
/* Add command dictionary. */
/****************************************************************************/
BOOL pctl_addCmdDict( CMD_DICT_ENTRY *pDict, size_t dictSize )
{
size_t n;
CMD_DICT_ENTRY *pDE = pDict; /* pointer to dicionary entry */
/****************************************************/
/* Ensure dictionary is sorted. */
/****************************************************/
for( n = 1; n < dictSize; n++ )
{
if(( pDE + 1 ) -> key < pDE -> key )
{
dbmsg_ftrace( DBM_ALWAYS,
"Command dictionary key %06x is out of order\r\n", ( pDE +1 ) -> key );
return FALSE;
}
pDE++; /* bump to next */
}
/****************************************************/
/* Locate empty dictionary array member. */
/****************************************************/
for( n = 0; n < 4; n++ )
{
if( NULL == dictArray[n].pDict )
{
dictArray[n].pDict = pDict;
dictArray[n].dictSize = dictSize;
break;
}
}
if( n == 4 ) /* if dictionary array is full */
{
dbmsg_trace( DBM_ALWAYS, "Can't add projector control dictionary\r\n" );
return FALSE;
}
return TRUE;
}
/****************************************************************************/
/* Reset and open. */
/****************************************************************************/
EXEC_CC_ENUM pctl_init( void )
{
BOOL isFactoryMode; /* USB protocol is factory mode */
URTINIT uInitStruct; /* UART initialization structure */
int n; /* index */
/****************************************************/
/* Initialize command dictionary list. */
/****************************************************/
for( n = 0; n < DICTMAX; n++ )
dictArray[n].pDict = NULL;
pctl_addCmdDict( &refDictArray, refDictSize );
/****************************************************/
/* Examine the port configuration: */
/* - If a serial port, configure the serial port */
/* and start the serial interface task. */
/* - If the USB port, start the USB interface task. */
/****************************************************/
pctlConfig = gpConfiguration -> Peripherals.ProjectorControl;
isFactoryMode = ( USBMAIN_FACTORYMODE == gpConfiguration -> Peripherals.UsbMode );
uartPortPC = pctlConfig >> 5; /* port identifier */
/****************************************************/
/* If serial. */
/****************************************************/
if( uartPortPC < 0x02 ) /* if using a UART for projector control */
{
dbmsg_trace( DBM_ALWAYS, "Opening projector control on UART\r\n" );
uartTimeout = msTimeout[pctlConfig & 0x07]; /* receive timeout */
uInitStruct = urtTemplate; /* copy template */
if( pctlConfig & 0x10 ) /* if HW flow control */
uInitStruct.FlowControl = URT_HW;
uInitStruct.BaudRate = (URTBAUD)( pctlConfig & 0x07 ); /* BIT rate */
if( uartPortPC == URT_PORT1 ) /* if PORT1 */
{
GPIO_EnableAlternativeFunction( GPIO_UART1_TXD_RXD, TRUE );
GPIO_SetPinConfig( GIO_UART1TXD, GIOCFG_OUTPUT, TRUE, GIOCFG_ACTIVE );
}
URT_EnableFIFOs( uartPortPC, TRUE ); /* enable FIFOs */
if( PASS != URT_SetConfig( uartPortPC, &uInitStruct ))
dbmsg_trace( DBM_ALWAYS, "Projector Control UART init error\r\n" );
if( RTA_SUCCESS != RTA_TaskCreate( cmdTaskSerial, &cmdTaskID,
PRIORITY_COMMAND, STACK_COMMAND, "scmd", 0 ))
dbmsg_trace( DBM_ALWAYS, "Can't start Projector Control task\r\n" );
}
/****************************************************/
/* If USB. */
/****************************************************/
else if(( uartPortPC < 0x03 ) /* && factoryMode */ ) /* if using USB */
{
dbmsg_trace( DBM_ALWAYS, "Opening projector control on USB\r\n" );
if( RTA_SUCCESS != RTA_TaskCreate( cmdTaskUSB, &cmdTaskID,
PRIORITY_COMMAND, STACK_COMMAND, "ucmd", 0 ))
dbmsg_trace( DBM_ALWAYS, "Can't start Projector Control task\r\n" );
}
/****************************************************/
/* If no projector control. */
/****************************************************/
else /* no projector control configured */
{
dbmsg_trace( DBM_ALWAYS, "Projector Control not configured\r\n" );
}
return EXEC_CC_PASS;
}
/****************************************************************************/
/* Return task information. */
/****************************************************************************/
void pctl_info( TASKINFO_STRUCT *info )
{
info -> taskID = cmdTaskID;
info -> stackSize = STACK_COMMAND;
info -> taskName = cmdTaskName;
}
/****************************************************************************/
/* Projector control message processor. */
/* */
/* This function is called by the USB or serial port data link task when */
/* the data link has received what it belives to be a complete projector */
/* control message. The checksum of the message is verified and the header */
/* is examined to vector the message to the appropriate read/write handler. */
/* Errors in checksum or message header are handled by this function, Other */
/* errors are handled by the read/write handler or the individual command */
/* processors. */
/* */
/* The called message processor formats the text of the response, in the */
/* same message buffer as the request. Local functions add the response */
/* header/checksum and return the complete result to the caller. */
/* */
/* If the called message processor detects an error, it returns TRUE. In */
/* this event, this function formats and returns a CMD1_ACK response. */
/****************************************************************************/
static uint16 cmdExecute( void )
{
CMD1_TYPE cc; /* response message code */
if( _pctlCksumCheck()) /* if checksum error */
{
dbmsg_trace( DBM_MSG, "pctl: Message checksum error\r\n" );
return 0; /* return nothing */
}
else /* handle message */
{
readUnderFlag = FALSE;
writeOverFlag = FALSE;
switch( Msg.head.cmd1 )
{
case CMD1_WRITE:
cc = _pctlCmdWrite();
break;
case CMD1_READ:
cc = _pctlCmdRead();
break;
default: /* unknown CMD1 */
cc = CMD1_NACK;
break;
}
if( CMD1_ACK == cc ) /* if message handling error */
{
dbmsg_trace( DBM_MSG, "pctl: Message handler error\r\n" );
_pctlFormatAck();
}
else if( CMD1_NACK == cc ) /* if unknown message type */
{
dbmsg_trace( DBM_MSG, "pctl: Message type unknown\r\n" );
_pctlFormatNack();
}
else if( readUnderFlag )
{
dbmsg_trace( DBM_MSG, "pctl: Request message data underflow\r\n" );
_pctlFormatAck();
}
else if( writeOverFlag )
{
dbmsg_trace( DBM_MSG, "pctl: Response message data overflow\r\n" );
_pctlFormatAck();
}
_pctlCksumGen(); /* add a checksum */
}
return 6 + _pctlLengthGet();
}
/****************************************************************************/
/* Serial interface task. */
/* */
/* This task waits for command messages on a serial port and passes what it */
/* believes to be complete message buffers to the message handler for pro- */
/* cessing. Since the protocol provides no hard start- or end-of-message */
/* indicators, the following algorithm is used: */
/* */
/* - Wait forever to read a 5-byte message header. */
/* - Assume the length bytes have been properly received and read the ex- */
/* pected number of message text bytes + checksum. Wait for the worst */
/* case interval for the message text to appear. */
/* - Assume the message is complete and pass it to the message handler. */
/* - If the message response indicates a protocol error, wait another worst */
/* case interval to receive any extraneous data. */
/* - Clear the FIFOs prior to returning the response. */
/****************************************************************************/
static void cmdTaskSerial( void )
{
int08 cc; /* UART driver completion code */
uint16 count; /* error/byte count */
uint32 nbt; /* number of bytes transferred */
for(;;)
{
count = 0; /* initialize error count limiter */
/****************************************************/
/* Read 5-byte header. */
/****************************************************/
cc = URT_Read( uartPortPC, 5, (uint08*)&Msg.head, 0, &nbt );
if( PASS != cc )
{
dbmsg_ftrace( DBM_ALWAYS, "UART Read error %d\r\n", cc );
if( ++count > 20 )
{
dbmsg_trace ( DBM_ALWAYS, "UART excessive error exit...\r\n" );
return;
}
continue;
}
/****************************************************/
/* Read expected number of message body bytes. */
/****************************************************/
count = 1 + _pctlLengthGet();
cc = URT_Read( uartPortPC, count, Msg.text, uartTimeout, &nbt );
if( !(( cc == PASS ) || ( cc == URT_TIMEOUT ))) /* unexpected */
{
dbmsg_ftrace( DBM_ALWAYS, "UART Read error %d\r\n", cc );
}
else /* expected */
{
nbt = cmdExecute(); /* go execute command */
if( nbt > 0 ) /* if response to be sent */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -