示例#1
0
static void uartTxTask(void* unused) {
   INT8U      osErr;
   dn_error_t dnErr;
   INT8U      reply;
   INT32U     replyLen;
   
   // create a semaphore
   uart_app_v.uartTxSem = OSSemCreate(0);
   ASSERT (uart_app_v.uartTxSem!=NULL);
   
   // prepare TX buffer
   memset(uart_app_v.uartTxBuffer,TX_BUFFER_PATTERN,sizeof(uart_app_v.uartTxBuffer));
   
   while(1) { // this is a task, it executes forever
      
      // wait for the semaphore to be posted
      OSSemPend(
         uart_app_v.uartTxSem,         // pevent
         0,                            // timeout
         &osErr                        // perr
      );
      ASSERT (osErr == OS_ERR_NONE);
      
      // print
      dnm_ucli_printf("Sending %d UART packets, %d bytes, delay %d ms\r\n",
         uart_app_v.uartTxNumLeft,
         uart_app_v.uartTxLen,
         uart_app_v.uartTxDelay
      );
      
      while(uart_app_v.uartTxNumLeft>0) {
         
         // send packet
         dnErr = dn_sendSyncMsgByType(
             uart_app_v.uartTxBuffer,
             uart_app_v.uartTxLen,
             DN_MSG_TYPE_UART_TX_CTRL,
             (void*)&reply,
             sizeof(reply),
             &replyLen
         );
         ASSERT(dnErr==DN_ERR_NONE);
         ASSERT(replyLen==sizeof(INT8U));
         ASSERT(reply==DN_ERR_NONE);
         
         // decrement
         uart_app_v.uartTxNumLeft--;
         
         // wait a bit
         if (uart_app_v.uartTxDelay) {
            OSTimeDly(uart_app_v.uartTxDelay);
         }
      }
      
      // print
      dnm_ucli_printf("done.\r\n");
   }
}
示例#2
0
/**
\brief Send a frame to the serial API of the SmartMesh IP manager.

A response is expected from the manager if rxPayload!=NULL. In this case, this
function retries transmitting if no response is received after
SERIAL_ACK_TIMEOUT ms. If no response is received after SERIAL_MAX_RETRIES
retries, the function returns RC_WRITE_FAIL.

\param[in]  packetType The payload type.
\param[in]  txPayload Payload to transmit to the manager.
\param[in]  txPayloadLen Number of bytes into the payload to transmit to the
   manager.
\param[out] rxPayload Pointer to a buffer to write the received payload into.
   manager.
\param[in]  rxPayloadMaxLen Maximum number of bytes which fit in the rxPayload
   buffer. If the manager responds with more bytes, this function returns
   RC_NO_RESOURCES, and no bytes are written to the rxPayload buffer.
\param[out] rxPayloadLen Expected number of bytes returned by the manager.

\return RC_OK if the operation succeeded successfully.
\return RC_NO_RESOURCES if the manager returned a number of bytes different
   from rxPayloadLen.
\return RC_WRITE_FAIL if no answer from the manager is received after
   SERIAL_MAX_RETRIES retries.
*/
INT8U serial_tx(
      INT8U  packetType,
      INT8U* txPayload,
      INT8U  txPayloadLen,
      INT8U* rxPayload,
      INT8U  rxPayloadMaxLen,
      INT8U* rxPayloadLen
      ) {
   INT8U           osErr;
   dn_error_t      dnErr;
   INT8U           i;
   INT8U           len;
   INT8U           functionReply;
   INT8U           retryCounter;
   INT32U          functionReplyLen;
   serial_ht*      tx_frame;
   INT8U           returnVal;
   
   // I'm busy sending a DATA packet over serial
   OSSemPend(bridge_app_v.serialTxDataAvailable,0,&osErr);
   ASSERT(osErr==RC_OK);
   
   // create packet
   tx_frame                  = (serial_ht*)bridge_app_v.uartTxBuffer;
   tx_frame->control         = 0x00;
   tx_frame->packetType      = packetType;
   tx_frame->seqNum          = bridge_app_v.seqNoTx++;
   tx_frame->payloadLen      = txPayloadLen;
   if (txPayload!=NULL) {
      memcpy(tx_frame->payload,txPayload,txPayloadLen);
   }
   len                       = sizeof(serial_ht)+txPayloadLen;
   
   // store packet details
   bridge_app_v.requestPacketType           = packetType;
   bridge_app_v.responsePayload             = rxPayload;
   bridge_app_v.responsePayloadMaxLen       = rxPayloadMaxLen;
   
   retryCounter                             = SERIAL_MAX_RETRIES;
   while (retryCounter>0) {
   
#ifdef PRINT_TRACE
      dnm_ucli_printf("---TX--> (%d bytes)",len);
      for (i=0;i<len;i++) {
         dnm_ucli_printf(" %02x",bridge_app_v.uartTxBuffer[i]);
      }
      dnm_ucli_printf("\r\n");
      dnm_ucli_printf("   packetType %d\r\n",tx_frame->packetType);
      dnm_ucli_printf("   seqNum     %d\r\n",tx_frame->seqNum);
#endif
      
      // send packet
      dnErr = dn_sendSyncMsgByType(
         bridge_app_v.uartTxBuffer,
         len,
         DN_MSG_TYPE_UART_TX_CTRL,
         (void*)&functionReply,
         sizeof(functionReply),
         &functionReplyLen
      );
      ASSERT(functionReplyLen==sizeof(INT8U));
      ASSERT(functionReply==DN_ERR_NONE);
      
      // wait for response, if appropriate
      if (rxPayload!=NULL) {
         
         // wait for response
         OSSemPend(
             bridge_app_v.waitForResponseSem,
             SERIAL_ACK_TIMEOUT,
             &osErr
         );
         
         // return appropriate value
         switch (osErr) {
             case OS_ERR_NONE:
                 *rxPayloadLen = bridge_app_v.responsePayloadLen;
                 if (bridge_app_v.responsePayloadLen<=bridge_app_v.responsePayloadMaxLen) {
                    returnVal = RC_OK;
                 } else {
                    returnVal = RC_NO_RESOURCES;
                 }
                 retryCounter = 0;
                 break;
             case OS_ERR_TIMEOUT:
               dnm_ucli_printf("WARNING: serial API timeout.\r\n");
                 retryCounter--;
                 break;
             default:
                 ASSERT(0);
         }
      } else {
         retryCounter = 0;
      }
   }
   
   // reset packet details
   bridge_app_v.requestPacketType             = 0x00;
   
   // I'm NOT busy sending a DATA packet over serial
   OSSemPost(bridge_app_v.serialTxDataAvailable);
   
   return returnVal;
}