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"); } }
/** \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; }