Update revision to use TI's mqtt and Freertos.
Dependencies: mbed client server
Fork of cc3100_Test_mqtt_CM3 by
cc3100.cpp
00001 /* 00002 * device.c - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. 00018 * 00019 * Neither the name of Texas Instruments Incorporated nor the names of 00020 * its contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 */ 00036 00037 00038 00039 /*****************************************************************************/ 00040 /* Include files */ 00041 /*****************************************************************************/ 00042 #include "cc3100_simplelink.h" 00043 #include "cc3100_protocol.h" 00044 #include "cc3100_sl_common.h" 00045 #include "cc3100.h" 00046 00047 #include "fPtr_func.h" 00048 #include "cli_uart.h" 00049 00050 namespace mbed_cc3100 { 00051 00052 uint32_t g_PingPacketsRecv; 00053 uint32_t g_GatewayIP; 00054 uint32_t g_StationIP; 00055 uint32_t g_DestinationIP; 00056 uint32_t g_BytesReceived; // variable to store the file size 00057 uint32_t g_Status; 00058 uint8_t g_buff[MAX_BUFF_SIZE+1]; 00059 int32_t g_SockID; 00060 00061 00062 cc3100::cc3100(PinName button1_irq, PinName button2_irq, PinName cc3100_irq, PinName cc3100_nHIB, PinName cc3100_cs, SPI cc3100_spi) 00063 : _spi(button1_irq, button2_irq, cc3100_irq, cc3100_nHIB, cc3100_cs, cc3100_spi, _driver), 00064 _driver(_spi, _nonos, _netapp, _flowcont), _nonos(_driver), _wlan(_driver, _wlan_filters), 00065 _wlan_filters(_driver), _netapp(_driver, _nonos), _fs(_driver), _netcfg(_driver), 00066 _socket(_driver, _nonos), _flowcont(_driver, _nonos) 00067 00068 00069 { 00070 00071 } 00072 00073 cc3100::~cc3100() 00074 { 00075 00076 } 00077 00078 /*! 00079 \brief This function initializes the application variables 00080 00081 \param[in] None 00082 00083 \return 0 on success, negative error-code on error 00084 */ 00085 int32_t cc3100::initializeAppVariables() 00086 { 00087 00088 g_Status = 0; 00089 g_PingPacketsRecv = 0; 00090 g_StationIP = 0; 00091 g_GatewayIP = 0; 00092 g_DestinationIP = 0; 00093 g_BytesReceived = 0; /* variable to store the file size */ 00094 g_SockID = 0; 00095 memset(g_buff, 0, sizeof(g_buff)); 00096 00097 return SUCCESS; 00098 } 00099 00100 /*! 00101 \brief Disconnecting from a WLAN Access point 00102 00103 This function disconnects from the connected AP 00104 00105 \param[in] None 00106 00107 \return none 00108 00109 \note 00110 00111 \warning If the WLAN disconnection fails, we will be stuck in this function forever. 00112 */ 00113 int32_t cc3100::disconnectFromAP() 00114 { 00115 int32_t retVal = -1; 00116 00117 /* 00118 * The function returns 0 if 'Disconnected done', negative number if already disconnected 00119 * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes 00120 */ 00121 retVal = _wlan.sl_WlanDisconnect(); 00122 if(0 == retVal) 00123 { 00124 /* Wait */ 00125 while(IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) { _nonos._SlNonOsMainLoopTask(); } 00126 } 00127 00128 return SUCCESS; 00129 } 00130 00131 /*! 00132 \brief This function configure the SimpleLink device in its default state. It: 00133 - Sets the mode to STATION 00134 - Configures connection policy to Auto and AutoSmartConfig 00135 - Deletes all the stored profiles 00136 - Enables DHCP 00137 - Disables Scan policy 00138 - Sets Tx power to maximum 00139 - Sets power policy to normal 00140 - Unregisters mDNS services 00141 - Remove all filters 00142 00143 \param[in] none 00144 00145 \return On success, zero is returned. On error, negative is returned 00146 */ 00147 int32_t cc3100::configureSimpleLinkToDefaultState() 00148 { 00149 00150 SlVersionFull ver = {0}; 00151 _WlanRxFilterOperationCommandBuff_t RxFilterIdMask = {0}; 00152 00153 uint8_t val = 1; 00154 uint8_t configOpt = 0; 00155 uint8_t configLen = 0; 00156 uint8_t power = 0; 00157 00158 int32_t retVal = -1; 00159 int32_t role = -1; 00160 00161 role = sl_Start(0, 0, 0); 00162 ASSERT_ON_ERROR(role); 00163 00164 /* If the device is not in station-mode, try configuring it in station-mode */ 00165 if (ROLE_STA != role) { 00166 if (ROLE_AP == role) { 00167 /* If the device is in AP mode, we need to wait for this event before doing anything */ 00168 while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED)) { 00169 _nonos._SlNonOsMainLoopTask(); 00170 } 00171 } 00172 00173 /* Switch to STA role and restart */ 00174 retVal = _wlan.sl_WlanSetMode(ROLE_STA); 00175 ASSERT_ON_ERROR(retVal); 00176 00177 retVal = sl_Stop(SL_STOP_TIMEOUT); 00178 ASSERT_ON_ERROR(retVal); 00179 00180 retVal = sl_Start(0, 0, 0); 00181 ASSERT_ON_ERROR(retVal); 00182 00183 /* Check if the device is in station again */ 00184 if (ROLE_STA != retVal) { 00185 /* We don't want to proceed if the device is not coming up in station-mode */ 00186 ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE); 00187 } 00188 } 00189 00190 /* Get the device's version-information */ 00191 configOpt = SL_DEVICE_GENERAL_VERSION; 00192 configLen = sizeof(ver); 00193 retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (uint8_t *)(&ver)); 00194 ASSERT_ON_ERROR(retVal); 00195 00196 /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */ 00197 retVal = _wlan.sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0); 00198 ASSERT_ON_ERROR(retVal); 00199 00200 /* Remove all profiles */ 00201 retVal = _wlan.sl_WlanProfileDel(0xFF); 00202 ASSERT_ON_ERROR(retVal); 00203 00204 /* 00205 * Device in station-mode. Disconnect previous connection if any 00206 * The function returns 0 if 'Disconnected done', negative number if already disconnected 00207 * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes 00208 */ 00209 retVal = _wlan.sl_WlanDisconnect(); 00210 if(0 == retVal) { 00211 /* Wait */ 00212 while(IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) { 00213 _nonos._SlNonOsMainLoopTask(); 00214 } 00215 } 00216 00217 /* Enable DHCP client*/ 00218 retVal = _netcfg.sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val); 00219 ASSERT_ON_ERROR(retVal); 00220 00221 /* Disable scan */ 00222 configOpt = SL_SCAN_POLICY(0); 00223 retVal = _wlan.sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0); 00224 ASSERT_ON_ERROR(retVal); 00225 00226 /* Set Tx power level for station mode 00227 Number between 0-15, as dB offset from maximum power - 0 will set maximum power */ 00228 power = 0; 00229 retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (uint8_t *)&power); 00230 ASSERT_ON_ERROR(retVal); 00231 00232 /* Set PM policy to normal */ 00233 retVal = _wlan.sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0); 00234 ASSERT_ON_ERROR(retVal); 00235 00236 /* Unregister mDNS services */ 00237 retVal = _netapp.sl_NetAppMDNSUnRegisterService(0, 0); 00238 ASSERT_ON_ERROR(retVal); 00239 00240 /* Remove all 64 filters (8*8) */ 00241 memset(RxFilterIdMask.FilterIdMask, 0xFF, 8); 00242 00243 retVal = _wlan_filters.sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (uint8_t *)&RxFilterIdMask, 00244 sizeof(_WlanRxFilterOperationCommandBuff_t )); 00245 ASSERT_ON_ERROR(retVal); 00246 00247 retVal = sl_Stop(SL_STOP_TIMEOUT); 00248 ASSERT_ON_ERROR(retVal); 00249 00250 retVal = initializeAppVariables(); 00251 ASSERT_ON_ERROR(retVal); 00252 00253 return retVal; /* Success */ 00254 } 00255 00256 /*! 00257 \brief Create UDP socket to communicate with server. 00258 00259 \param[in] none 00260 00261 \return Socket descriptor for success otherwise negative 00262 00263 \warning 00264 */ 00265 int32_t cc3100::createUDPConnection() 00266 { 00267 int32_t sd = 0; 00268 00269 sd = _socket.sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, IPPROTO_UDP); 00270 if( sd < 0 ) 00271 { 00272 Uart_Write((uint8_t*)"Error creating socket\n\r\n\r"); 00273 } 00274 00275 return sd; 00276 } 00277 00278 /*! 00279 \brief Create connection with server. 00280 00281 This function opens a socket and create the endpoint communication with server 00282 00283 \param[in] DestinationIP - IP address of the server 00284 00285 \return socket id for success and negative for error 00286 */ 00287 int32_t cc3100::createConnection(uint32_t DestinationIP) 00288 { 00289 SlSockAddrIn_t Addr = {0}; 00290 int32_t Status = 0; 00291 int32_t AddrSize = 0; 00292 int32_t SockID = 0; 00293 00294 Addr.sin_family = SL_AF_INET; 00295 Addr.sin_port = _socket.sl_Htons(80); 00296 Addr.sin_addr.s_addr = _socket.sl_Htonl(DestinationIP); 00297 00298 AddrSize = sizeof(SlSockAddrIn_t); 00299 00300 SockID = _socket.sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); 00301 ASSERT_ON_ERROR(SockID); 00302 00303 Status = _socket.sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize); 00304 if (Status < 0) 00305 { 00306 _socket.sl_Close(SockID); 00307 ASSERT_ON_ERROR(Status); 00308 } 00309 00310 return SockID; 00311 } 00312 00313 /*! 00314 \brief Convert hex to decimal base 00315 00316 \param[in] ptr - pointer to string containing number in hex 00317 00318 \return number in decimal base 00319 00320 */ 00321 int32_t cc3100::hexToi(unsigned char *ptr) 00322 { 00323 uint32_t result = 0; 00324 uint32_t len = 0; 00325 00326 int32_t idx = -1; 00327 00328 len = strlen((const char*) ptr); 00329 00330 /* convert characters to upper case */ 00331 for(idx = 0; ptr[idx] != '\0'; ++idx) 00332 { 00333 if( (ptr[idx] >= 'a') && 00334 (ptr[idx] <= 'f') ) 00335 { 00336 ptr[idx] -= 32; /* Change case - ASCII 'a' = 97, 'A' = 65 => 97-65 = 32 */ 00337 } 00338 } 00339 00340 for(idx = 0; ptr[idx] != '\0'; ++idx) 00341 { 00342 if(ptr[idx] >= '0' && ptr[idx] <= '9') 00343 { 00344 /* Converting '0' to '9' to their decimal value */ 00345 result += (ptr[idx] - '0') * (1 << (4 * (len - 1 - idx))); 00346 } 00347 else if(ptr[idx] >= 'A' && ptr[idx] <= 'F') 00348 { 00349 /* Converting hex 'A' to 'F' to their decimal value */ 00350 result += (ptr[idx] - 55) * (1 << (4 * (len -1 - idx))); /* .i.e. 'A' - 55 = 10, 'F' - 55 = 15 */ 00351 } 00352 else 00353 { 00354 ASSERT_ON_ERROR(INVALID_HEX_STRING); 00355 } 00356 } 00357 00358 return result; 00359 } 00360 00361 /*! 00362 \brief Calculate the file chunk size 00363 00364 \param[in] len - pointer to length of the data in the buffer 00365 \param[in] p_Buff - pointer to pointer of buffer containing data 00366 \param[out] chunk_size - pointer to variable containing chunk size 00367 00368 \return 0 for success, -ve for error 00369 00370 */ 00371 int32_t cc3100::getChunkSize(int32_t *len, uint8_t **p_Buff, uint32_t *chunk_size) 00372 { 00373 int32_t idx = -1; 00374 unsigned char lenBuff[10]; 00375 00376 idx = 0; 00377 memset(lenBuff, 0, sizeof(lenBuff)); 00378 while(*len >= 0 && **p_Buff != 13) /* check for <CR> */ 00379 { 00380 if(0 == *len) 00381 { 00382 memset(g_buff, 0, sizeof(g_buff)); 00383 *len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0); 00384 if(*len <= 0) 00385 ASSERT_ON_ERROR(TCP_RECV_ERROR); 00386 00387 *p_Buff = g_buff; 00388 } 00389 00390 lenBuff[idx] = **p_Buff; 00391 idx++; 00392 (*p_Buff)++; 00393 (*len)--; 00394 } 00395 00396 (*p_Buff) += 2; /* skip <CR><LF> */ 00397 (*len) -= 2; 00398 *chunk_size = hexToi(lenBuff); 00399 00400 return SUCCESS; 00401 } 00402 00403 /*! 00404 \brief Obtain the file from the server 00405 00406 This function requests the file from the server and save it on serial flash. 00407 To request a different file for different user needs to modify the 00408 PREFIX_BUFFER and POST_BUFFER macros. 00409 00410 \param[in] None 00411 00412 \return 0 for success and negative for error 00413 00414 */ 00415 /* 00416 int32_t cc3100::getFile() 00417 { 00418 uint32_t Token = 0; 00419 uint32_t recv_size = 0; 00420 uint8_t *pBuff = 0; 00421 uint8_t eof_detected = 0; 00422 uint8_t isChunked = 0; 00423 00424 int32_t transfer_len = -1; 00425 int32_t retVal = -1; 00426 int32_t fileHandle = -1; 00427 00428 memset(g_buff, 0, sizeof(g_buff)); 00429 00430 //Puts together the HTTP GET string. 00431 strcpy((char*)g_buff, PREFIX_BUFFER); 00432 strcat((char*)g_buff, POST_BUFFER); 00433 00434 //Send the HTTP GET string to the opened TCP/IP socket. 00435 transfer_len = _socket.sl_Send(g_SockID, g_buff, strlen((const char*)g_buff), 0); 00436 00437 if (transfer_len < 0) 00438 { 00439 // error 00440 printf(" Socket Send Error\r\n"); 00441 ASSERT_ON_ERROR(TCP_SEND_ERROR); 00442 } 00443 00444 memset(g_buff, 0, sizeof(g_buff)); 00445 00446 //get the reply from the server in buffer. 00447 transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0); 00448 00449 if(transfer_len <= 0) 00450 ASSERT_ON_ERROR(TCP_RECV_ERROR); 00451 00452 // Check for 404 return code 00453 if(strstr((const char*)g_buff, HTTP_FILE_NOT_FOUND) != 0) 00454 { 00455 printf(" File not found, check the file and try again\r\n"); 00456 ASSERT_ON_ERROR(FILE_NOT_FOUND_ERROR); 00457 } 00458 00459 // if not "200 OK" return error 00460 if(strstr((const char*)g_buff, HTTP_STATUS_OK) == 0) 00461 { 00462 printf(" Error during downloading the file\r\n"); 00463 ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE); 00464 } 00465 00466 // check if content length is transferred with headers 00467 pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONTENT_LENGTH); 00468 if(pBuff != 0) 00469 { 00470 // not supported 00471 printf(" Server response format is not supported\r\n"); 00472 ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED); 00473 } 00474 00475 // Check if data is chunked 00476 pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_TRANSFER_ENCODING); 00477 if(pBuff != 0) 00478 { 00479 pBuff += strlen(HTTP_TRANSFER_ENCODING); 00480 while(*pBuff == SPACE) 00481 pBuff++; 00482 00483 if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_ENCODING_CHUNKED)) == 0) 00484 { 00485 recv_size = 0; 00486 isChunked = 1; 00487 } 00488 } 00489 else 00490 { 00491 // Check if connection will be closed by after sending data 00492 // In this method the content length is not received and end of 00493 // connection marks the end of data 00494 pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONNECTION); 00495 if(pBuff != 0) 00496 { 00497 pBuff += strlen(HTTP_CONNECTION); 00498 while(*pBuff == SPACE) 00499 pBuff++; 00500 00501 if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_CONNECTION_CLOSE)) == 0) 00502 { 00503 // not supported 00504 printf(" Server response format is not supported\r\n"); 00505 ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED); 00506 } 00507 } 00508 } 00509 00510 // "\r\n\r\n" marks the end of headers 00511 pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_END_OF_HEADER); 00512 if(pBuff == 0) 00513 { 00514 printf(" Invalid response\r\n"); 00515 ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE); 00516 } 00517 // Increment by 4 to skip "\r\n\r\n" 00518 pBuff += 4; 00519 00520 // Adjust buffer data length for header size 00521 transfer_len -= (pBuff - g_buff); 00522 00523 // If data in chunked format, calculate the chunk size 00524 if(isChunked == 1) 00525 { 00526 retVal = getChunkSize(&transfer_len, &pBuff, &recv_size); 00527 if(retVal < 0) 00528 { 00529 // Error 00530 printf(" Problem with connection to server\r\n"); 00531 return retVal; 00532 } 00533 } 00534 00535 // Open file to save the downloaded file 00536 retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME, 00537 FS_MODE_OPEN_WRITE, &Token, &fileHandle); 00538 if(retVal < 0) 00539 { 00540 // File Doesn't exit create a new of 45 KB file 00541 retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME, 00542 _fs.FS_MODE_OPEN_CREATE(SIZE_45K,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE), 00543 &Token, &fileHandle); 00544 if(retVal < 0) 00545 { 00546 printf(" Error during opening the file\r\n"); 00547 return retVal; 00548 } 00549 } 00550 00551 while (0 < transfer_len) 00552 { 00553 // For chunked data recv_size contains the chunk size to be received 00554 // while the transfer_len contains the data in the buffer 00555 if(recv_size <= transfer_len) 00556 { 00557 // write the recv_size 00558 retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived, 00559 (uint8_t *)pBuff, recv_size); 00560 if(retVal < recv_size) 00561 { 00562 // Close file without saving 00563 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1); 00564 printf(" Error during writing the file\r\n"); 00565 return FILE_WRITE_ERROR; 00566 } 00567 transfer_len -= recv_size; 00568 g_BytesReceived +=recv_size; 00569 pBuff += recv_size; 00570 recv_size = 0; 00571 00572 if(isChunked == 1) 00573 { 00574 // if data in chunked format calculate next chunk size 00575 pBuff += 2; // 2 bytes for <CR> <LF> 00576 transfer_len -= 2; 00577 00578 if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0) 00579 { 00580 // Error 00581 break; 00582 } 00583 00584 // if next chunk size is zero we have received the complete file 00585 if(recv_size == 0) 00586 { 00587 eof_detected = 1; 00588 break; 00589 } 00590 00591 if(recv_size < transfer_len) 00592 { 00593 // Code will enter this section if the new chunk size is less then 00594 // then the transfer size. This will the last chunk of file received 00595 00596 retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived, 00597 (uint8_t *)pBuff, recv_size); 00598 if(retVal < recv_size) 00599 { 00600 // Close file without saving 00601 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1); 00602 printf(" Error during writing the file\r\n"); 00603 return FILE_WRITE_ERROR; 00604 } 00605 transfer_len -= recv_size; 00606 g_BytesReceived +=recv_size; 00607 pBuff += recv_size; 00608 recv_size = 0; 00609 00610 pBuff += 2; // 2bytes for <CR> <LF> 00611 transfer_len -= 2; 00612 00613 // Calculate the next chunk size, should be zero 00614 if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0) 00615 { 00616 // Error 00617 break; 00618 } 00619 00620 // if next chunk size is non zero error 00621 if(recv_size != 0) 00622 { 00623 // Error 00624 break; 00625 } 00626 eof_detected = 1; 00627 break; 00628 } 00629 else 00630 { 00631 // write data on the file 00632 retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived, 00633 (uint8_t *)pBuff, transfer_len); 00634 if(retVal < transfer_len) 00635 { 00636 // Close file without saving 00637 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1); 00638 printf(" Error during writing the file\r\n"); 00639 ASSERT_ON_ERROR(FILE_WRITE_ERROR); 00640 } 00641 recv_size -= transfer_len; 00642 g_BytesReceived +=transfer_len; 00643 } 00644 } 00645 // complete file received exit 00646 if(recv_size == 0) 00647 { 00648 eof_detected = 1; 00649 break; 00650 } 00651 } 00652 else 00653 { 00654 // write data on the file 00655 retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived, 00656 (uint8_t *)pBuff, transfer_len); 00657 if (retVal < 0) 00658 { 00659 // Close file without saving 00660 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1); 00661 printf(" Error during writing the file\r\n"); 00662 ASSERT_ON_ERROR(FILE_WRITE_ERROR); 00663 } 00664 g_BytesReceived +=transfer_len; 00665 recv_size -= transfer_len; 00666 } 00667 00668 memset(g_buff, 0, sizeof(g_buff)); 00669 00670 transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0); 00671 if(transfer_len <= 0) 00672 ASSERT_ON_ERROR(TCP_RECV_ERROR); 00673 00674 pBuff = g_buff; 00675 } 00676 00677 // If user file has checksum which can be used to verify the temporary 00678 // file then file should be verified 00679 // In case of invalid file (FILE_NAME) should be closed without saving to 00680 // recover the previous version of file 00681 if(0 > transfer_len || eof_detected == 0) 00682 { 00683 // Close file without saving 00684 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1); 00685 printf(" Error While File Download\r\n"); 00686 ASSERT_ON_ERROR(INVALID_FILE); 00687 } 00688 else 00689 { 00690 // Save and close file 00691 retVal = _fs.sl_FsClose(fileHandle, 0, 0, 0); 00692 ASSERT_ON_ERROR(retVal); 00693 } 00694 00695 return SUCCESS;; 00696 } 00697 */ 00698 00699 /*! 00700 \brief Connecting to a WLAN Access point 00701 00702 This function connects to the required AP (SSID_NAME). 00703 The function will return once we are connected and have acquired IP address 00704 00705 \param[in] None 00706 00707 \return 0 on success, negative error-code on error 00708 00709 \note 00710 00711 \warning If the WLAN connection fails or we don't acquire an IP address, 00712 We will be stuck in this function forever. 00713 */ 00714 int32_t cc3100::establishConnectionWithAP() 00715 { 00716 00717 SlSecParams_t secParams = {0}; 00718 int32_t retVal = 0; 00719 00720 secParams.Key = (signed char *)PASSKEY; 00721 secParams.KeyLen = strlen(PASSKEY); 00722 secParams.Type = SEC_TYPE; 00723 00724 retVal = _wlan.sl_WlanConnect((signed char *)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0); 00725 ASSERT_ON_ERROR(retVal); 00726 00727 /* Wait */ 00728 while((!IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) || (!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED))) { _nonos._SlNonOsMainLoopTask(); } 00729 00730 return SUCCESS; 00731 } 00732 00733 /*! 00734 \brief This function checks the LAN connection by pinging the AP's gateway 00735 00736 \param[in] None 00737 00738 \return 0 on success, negative error-code on error 00739 */ 00740 int32_t cc3100::checkLanConnection() 00741 { 00742 SlPingStartCommand_t pingParams = {0}; 00743 SlPingReport_t pingReport = {0}; 00744 00745 int32_t retVal = -1; 00746 00747 CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE); 00748 g_PingPacketsRecv = 0; 00749 00750 /* Set the ping parameters */ 00751 pingParams.PingIntervalTime = PING_INTERVAL; 00752 pingParams.PingSize = PING_PKT_SIZE; 00753 pingParams.PingRequestTimeout = PING_TIMEOUT; 00754 pingParams.TotalNumberOfAttempts = PING_ATTEMPTS; 00755 pingParams.Flags = 0; 00756 pingParams.Ip = g_GatewayIP; 00757 00758 /* Check for LAN connection */ 00759 retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET, 00760 (SlPingReport_t*)&pingReport, SimpleLinkPingReport); 00761 ASSERT_ON_ERROR(retVal); 00762 00763 /* Wait */ 00764 while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); } 00765 00766 if(0 == g_PingPacketsRecv) 00767 { 00768 /* Problem with LAN connection */ 00769 ASSERT_ON_ERROR(LAN_CONNECTION_FAILED); 00770 } 00771 00772 /* LAN connection is successful */ 00773 return SUCCESS; 00774 } 00775 00776 /*! 00777 \brief This function checks the internet connection by pinging 00778 the external-host (HOST_NAME) 00779 00780 \param[in] None 00781 00782 \return 0 on success, negative error-code on error 00783 */ 00784 int32_t cc3100::checkInternetConnection() 00785 { 00786 SlPingStartCommand_t pingParams = {0}; 00787 SlPingReport_t pingReport = {0}; 00788 00789 uint32_t ipAddr = 0; 00790 00791 int32_t retVal = -1; 00792 00793 CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE); 00794 g_PingPacketsRecv = 0; 00795 00796 /* Set the ping parameters */ 00797 pingParams.PingIntervalTime = PING_INTERVAL; 00798 pingParams.PingSize = PING_PKT_SIZE; 00799 pingParams.PingRequestTimeout = PING_TIMEOUT; 00800 pingParams.TotalNumberOfAttempts = PING_ATTEMPTS; 00801 pingParams.Flags = 0; 00802 pingParams.Ip = g_GatewayIP; 00803 00804 /* Check for Internet connection */ 00805 retVal = _netapp.sl_NetAppDnsGetHostByName((unsigned char *)HOST_NAME, strlen(HOST_NAME), &ipAddr, SL_AF_INET); 00806 ASSERT_ON_ERROR(retVal); 00807 00808 /* Replace the ping address to match HOST_NAME's IP address */ 00809 pingParams.Ip = ipAddr; 00810 00811 /* Try to ping HOST_NAME */ 00812 retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET, 00813 (SlPingReport_t*)&pingReport, SimpleLinkPingReport); 00814 ASSERT_ON_ERROR(retVal); 00815 00816 /* Wait */ 00817 while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); } 00818 00819 if (0 == g_PingPacketsRecv) 00820 { 00821 /* Problem with internet connection*/ 00822 ASSERT_ON_ERROR(INTERNET_CONNECTION_FAILED); 00823 } 00824 00825 /* Internet connection is successful */ 00826 return SUCCESS; 00827 } 00828 00829 const int8_t StartResponseLUT[8] = 00830 { 00831 ROLE_UNKNOWN_ERR, 00832 ROLE_STA, 00833 ROLE_STA_ERR, 00834 ROLE_AP, 00835 ROLE_AP_ERR, 00836 ROLE_P2P, 00837 ROLE_P2P_ERR, 00838 ROLE_UNKNOWN_ERR 00839 }; 00840 00841 /*****************************************************************************/ 00842 /* Internal functions */ 00843 /*****************************************************************************/ 00844 00845 int16_t cc3100::_sl_GetStartResponseConvert(uint32_t Status) 00846 { 00847 return (int16_t)StartResponseLUT[Status & 0x7]; 00848 00849 } 00850 00851 /*****************************************************************************/ 00852 /* API Functions */ 00853 /*****************************************************************************/ 00854 00855 bool cc3100::IS_PING_DONE(uint32_t status_variable,const uint32_t bit){ 00856 00857 g_Status = status_variable; 00858 00859 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00860 return TRUE; 00861 }else{ 00862 return FALSE; 00863 } 00864 } 00865 00866 bool cc3100::IS_CONNECTED(uint32_t status_variable,const uint32_t bit){ 00867 00868 g_Status = status_variable; 00869 00870 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00871 return TRUE; 00872 }else{ 00873 return FALSE; 00874 } 00875 } 00876 00877 bool cc3100::IS_STA_CONNECTED(uint32_t status_variable,const uint32_t bit){ 00878 00879 g_Status = status_variable; 00880 00881 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00882 return TRUE; 00883 }else{ 00884 return FALSE; 00885 } 00886 } 00887 00888 bool cc3100::IS_IP_ACQUIRED(uint32_t status_variable,const uint32_t bit){ 00889 00890 g_Status = status_variable; 00891 00892 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00893 return TRUE; 00894 }else{ 00895 return FALSE; 00896 } 00897 } 00898 00899 bool cc3100::IS_IP_LEASED(uint32_t status_variable,const uint32_t bit){ 00900 00901 g_Status = status_variable; 00902 00903 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00904 return TRUE; 00905 }else{ 00906 return FALSE; 00907 } 00908 } 00909 00910 bool cc3100::IS_CONNECTION_FAILED(uint32_t status_variable,const uint32_t bit){ 00911 00912 g_Status = status_variable; 00913 00914 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00915 return TRUE; 00916 }else{ 00917 return FALSE; 00918 } 00919 } 00920 00921 bool cc3100::IS_P2P_NEG_REQ_RECEIVED(uint32_t status_variable,const uint32_t bit){ 00922 00923 g_Status = status_variable; 00924 00925 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00926 return TRUE; 00927 }else{ 00928 return FALSE; 00929 } 00930 } 00931 00932 bool cc3100::IS_SMARTCONFIG_DONE(uint32_t status_variable,const uint32_t bit){ 00933 00934 g_Status = status_variable; 00935 00936 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00937 return TRUE; 00938 }else{ 00939 return FALSE; 00940 } 00941 } 00942 00943 bool cc3100::IS_SMARTCONFIG_STOPPED(uint32_t status_variable,const uint32_t bit){ 00944 00945 g_Status = status_variable; 00946 00947 if(0 != (g_Status & ((uint32_t)1L<<(bit)))){ 00948 return TRUE; 00949 }else{ 00950 return FALSE; 00951 } 00952 } 00953 00954 void cc3100::CLR_STATUS_BIT(uint32_t status_variable, const uint32_t bit){ 00955 00956 g_Status = status_variable; 00957 g_Status &= ~((uint32_t)1L<<(bit)); 00958 00959 } 00960 00961 void cc3100::SET_STATUS_BIT(uint32_t status_variable, const uint32_t bit){ 00962 00963 g_Status = status_variable; 00964 g_Status |= ((uint32_t)1L<<(bit)); 00965 00966 } 00967 00968 /*****************************************************************************/ 00969 /* sl_Task */ 00970 /*****************************************************************************/ 00971 #if _SL_INCLUDE_FUNC(sl_Task) 00972 void cc3100::sl_Task(void) 00973 { 00974 #ifdef _SlTaskEntry 00975 // _nonos._SlNonOsMainLoopTask; 00976 _SlTaskEntry(); 00977 00978 #endif 00979 } 00980 #endif 00981 00982 /*****************************************************************************/ 00983 /* sl_Start */ 00984 /*****************************************************************************/ 00985 #if _SL_INCLUDE_FUNC(sl_Start) 00986 int16_t cc3100::sl_Start(const void* pIfHdl, int8_t* pDevName, const P_INIT_CALLBACK pInitCallBack) 00987 { 00988 00989 int16_t ObjIdx = MAX_CONCURRENT_ACTIONS; 00990 InitComplete_t AsyncRsp; 00991 00992 /* Perform any preprocessing before enable networking services */ 00993 sl_DeviceEnablePreamble();//stub only 00994 00995 /* ControlBlock init */ 00996 _driver._SlDrvDriverCBInit(); 00997 00998 /* open the interface: usually SPI or UART */ 00999 if (NULL == pIfHdl) 01000 { 01001 g_pCB->FD = _spi.spi_Open((int8_t *)pDevName, 0); 01002 } 01003 else 01004 { 01005 g_pCB->FD = (_SlFd_t)pIfHdl; 01006 } 01007 01008 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS); 01009 01010 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 01011 { 01012 Uart_Write((uint8_t*)"SL_POOL_IS_EMPTY\r\n"); 01013 return SL_POOL_IS_EMPTY; 01014 } 01015 01016 if( g_pCB->FD >= (_SlFd_t)0) { 01017 _spi.CC3100_disable(); 01018 01019 g_pCB->pInitCallback = pInitCallBack; 01020 01021 _spi.CC3100_enable(); 01022 01023 if (NULL == pInitCallBack) { 01024 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 01025 /*release Pool Object*/ 01026 _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); 01027 return _sl_GetStartResponseConvert(AsyncRsp.Status); 01028 } 01029 else 01030 { 01031 return SL_RET_CODE_OK; 01032 } 01033 } 01034 01035 return SL_BAD_INTERFACE; 01036 01037 01038 } 01039 #endif 01040 01041 /*************************************************************************** 01042 _sl_HandleAsync_InitComplete - handles init complete signalling to 01043 a waiting object 01044 ****************************************************************************/ 01045 void cc3100::_sl_HandleAsync_InitComplete(void *pVoidBuf) 01046 { 01047 01048 InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf); 01049 01050 _driver._SlDrvProtectionObjLockWaitForever(); 01051 01052 if(g_pCB->pInitCallback) { 01053 g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status)); 01054 } else { 01055 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t)); 01056 _driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 01057 } 01058 _driver._SlDrvProtectionObjUnLock(); 01059 01060 if(g_pCB->pInitCallback) { 01061 _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); 01062 } 01063 01064 } 01065 01066 /***************************************************************************** 01067 sl_stop 01068 ******************************************************************************/ 01069 typedef union { 01070 _DevStopCommand_t Cmd; 01071 _BasicResponse_t Rsp; 01072 } _SlStopMsg_u; 01073 01074 const _SlCmdCtrl_t _SlStopCmdCtrl = { 01075 SL_OPCODE_DEVICE_STOP_COMMAND, 01076 sizeof(_DevStopCommand_t), 01077 sizeof(_BasicResponse_t) 01078 }; 01079 01080 #if _SL_INCLUDE_FUNC(sl_Stop) 01081 int16_t cc3100::sl_Stop(const uint16_t timeout) 01082 { 01083 01084 int16_t RetVal=0; 01085 _SlStopMsg_u Msg; 01086 _BasicResponse_t AsyncRsp; 01087 int8_t ObjIdx = MAX_CONCURRENT_ACTIONS; 01088 /* if timeout is 0 the shutdown is forced immediately */ 01089 if( 0 == timeout ) { 01090 _spi.registerInterruptHandler(NULL, NULL); 01091 _spi.CC3100_disable(); 01092 RetVal = _spi.spi_Close(g_pCB->FD); 01093 01094 } else { 01095 /* let the device make the shutdown using the defined timeout */ 01096 Msg.Cmd.Timeout = timeout; 01097 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS); 01098 01099 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 01100 { 01101 return SL_POOL_IS_EMPTY; 01102 } 01103 01104 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL)); 01105 01106 if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status) 01107 { 01108 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 01109 Msg.Rsp.status = AsyncRsp.status; 01110 RetVal = Msg.Rsp.status; 01111 } 01112 01113 _driver._SlDrvReleasePoolObj((uint8_t)ObjIdx); 01114 _spi.registerInterruptHandler(NULL, NULL); 01115 _spi.CC3100_disable(); 01116 _spi.spi_Close(g_pCB->FD); 01117 01118 } 01119 01120 _driver._SlDrvDriverCBDeinit(); 01121 01122 return RetVal; 01123 } 01124 #endif 01125 01126 01127 /***************************************************************************** 01128 sl_EventMaskSet 01129 *****************************************************************************/ 01130 typedef union { 01131 _DevMaskEventSetCommand_t Cmd; 01132 _BasicResponse_t Rsp; 01133 } _SlEventMaskSetMsg_u; 01134 01135 #if _SL_INCLUDE_FUNC(sl_EventMaskSet) 01136 const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = { 01137 SL_OPCODE_DEVICE_EVENTMASKSET, 01138 sizeof(_DevMaskEventSetCommand_t), 01139 sizeof(_BasicResponse_t) 01140 }; 01141 01142 int16_t cc3100::sl_EventMaskSet(uint8_t EventClass , uint32_t Mask) 01143 { 01144 _SlEventMaskSetMsg_u Msg; 01145 Msg.Cmd.group = EventClass; 01146 Msg.Cmd.mask = Mask; 01147 01148 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL)); 01149 01150 return (int16_t)Msg.Rsp.status; 01151 } 01152 #endif 01153 01154 /****************************************************************************** 01155 sl_EventMaskGet 01156 ******************************************************************************/ 01157 typedef union { 01158 _DevMaskEventGetCommand_t Cmd; 01159 _DevMaskEventGetResponse_t Rsp; 01160 } _SlEventMaskGetMsg_u; 01161 01162 #if _SL_INCLUDE_FUNC(sl_EventMaskGet) 01163 const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = { 01164 SL_OPCODE_DEVICE_EVENTMASKGET, 01165 sizeof(_DevMaskEventGetCommand_t), 01166 sizeof(_DevMaskEventGetResponse_t) 01167 }; 01168 01169 int16_t cc3100::sl_EventMaskGet(uint8_t EventClass, uint32_t *pMask) 01170 { 01171 _SlEventMaskGetMsg_u Msg; 01172 01173 Msg.Cmd.group = EventClass; 01174 01175 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL)); 01176 01177 *pMask = Msg.Rsp.mask; 01178 return SL_RET_CODE_OK; 01179 } 01180 #endif 01181 01182 /****************************************************************************** 01183 sl_DevGet 01184 ******************************************************************************/ 01185 01186 typedef union { 01187 _DeviceSetGet_t Cmd; 01188 _DeviceSetGet_t Rsp; 01189 } _SlDeviceMsgGet_u; 01190 01191 #if _SL_INCLUDE_FUNC(sl_DevGet) 01192 const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = { 01193 SL_OPCODE_DEVICE_DEVICEGET, 01194 sizeof(_DeviceSetGet_t), 01195 sizeof(_DeviceSetGet_t) 01196 }; 01197 01198 int32_t cc3100::sl_DevGet(uint8_t DeviceGetId, uint8_t *pOption,uint8_t *pConfigLen, uint8_t *pValues) 01199 { 01200 _SlDeviceMsgGet_u Msg; 01201 _SlCmdExt_t CmdExt; 01202 01203 if (*pConfigLen == 0) { 01204 return SL_EZEROLEN; 01205 } 01206 01207 if( pOption ) { 01208 _driver._SlDrvResetCmdExt(&CmdExt); 01209 CmdExt.RxPayloadLen = *pConfigLen; 01210 01211 CmdExt.pRxPayload = (uint8_t *)pValues; 01212 01213 01214 Msg.Cmd.DeviceSetId = DeviceGetId; 01215 01216 Msg.Cmd.Option = (uint16_t)*pOption; 01217 01218 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt)); 01219 01220 if( pOption ) { 01221 *pOption = (uint8_t)Msg.Rsp.Option; 01222 } 01223 01224 if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) { 01225 *pConfigLen = (uint8_t)CmdExt.RxPayloadLen; 01226 return SL_ESMALLBUF; 01227 } else { 01228 *pConfigLen = (uint8_t)CmdExt.ActualRxPayloadLen; 01229 } 01230 01231 return (int16_t)Msg.Rsp.Status; 01232 } else { 01233 return -1; 01234 } 01235 } 01236 #endif 01237 01238 /****************************************************************************** 01239 sl_DevSet 01240 ******************************************************************************/ 01241 typedef union { 01242 _DeviceSetGet_t Cmd; 01243 _BasicResponse_t Rsp; 01244 } _SlDeviceMsgSet_u; 01245 01246 #if _SL_INCLUDE_FUNC(sl_DevSet) 01247 const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = { 01248 SL_OPCODE_DEVICE_DEVICESET, 01249 sizeof(_DeviceSetGet_t), 01250 sizeof(_BasicResponse_t) 01251 }; 01252 01253 int32_t cc3100::sl_DevSet(const uint8_t DeviceSetId, const uint8_t Option, const uint8_t ConfigLen, const uint8_t *pValues) 01254 { 01255 _SlDeviceMsgSet_u Msg; 01256 _SlCmdExt_t CmdExt; 01257 01258 _driver._SlDrvResetCmdExt(&CmdExt); 01259 CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); 01260 01261 CmdExt.pTxPayload = (uint8_t *)pValues; 01262 01263 01264 01265 Msg.Cmd.DeviceSetId = DeviceSetId; 01266 Msg.Cmd.ConfigLen = ConfigLen; 01267 Msg.Cmd.Option = Option; 01268 01269 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt)); 01270 01271 return (int16_t)Msg.Rsp.status; 01272 } 01273 #endif 01274 01275 /****************************************************************************** 01276 sl_UartSetMode 01277 ******************************************************************************/ 01278 #ifdef SL_IF_TYPE_UART 01279 typedef union { 01280 _DevUartSetModeCommand_t Cmd; 01281 _DevUartSetModeResponse_t Rsp; 01282 } _SlUartSetModeMsg_u; 01283 01284 #if _SL_INCLUDE_FUNC(sl_UartSetMode) 01285 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = { 01286 SL_OPCODE_DEVICE_SETUARTMODECOMMAND, 01287 sizeof(_DevUartSetModeCommand_t), 01288 sizeof(_DevUartSetModeResponse_t) 01289 }; 01290 01291 int16_t cc3100::sl_UartSetMode(const SlUartIfParams_t* pUartParams) 01292 { 01293 _SlUartSetModeMsg_u Msg; 01294 uint32_t magicCode = 0xFFFFFFFF; 01295 01296 Msg.Cmd.BaudRate = pUartParams->BaudRate; 01297 Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable; 01298 01299 01300 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL)); 01301 01302 /* cmd response OK, we can continue with the handshake */ 01303 if (SL_RET_CODE_OK == Msg.Rsp.status) { 01304 sl_IfMaskIntHdlr(); 01305 01306 /* Close the comm port */ 01307 sl_IfClose(g_pCB->FD); 01308 01309 /* Re-open the comm port */ 01310 sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN); 01311 sl_IfUnMaskIntHdlr(); 01312 01313 /* send the magic code and wait for the response */ 01314 sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4); 01315 01316 magicCode = UART_SET_MODE_MAGIC_CODE; 01317 sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4); 01318 01319 /* clear magic code */ 01320 magicCode = 0; 01321 01322 /* wait (blocking) till the magic code to be returned from device */ 01323 sl_IfRead(g_pCB->FD, (uint8_t* )&magicCode, 4); 01324 01325 /* check for the received magic code matching */ 01326 if (UART_SET_MODE_MAGIC_CODE != magicCode) { 01327 _SL_ASSERT(0); 01328 } 01329 } 01330 01331 return (int16_t)Msg.Rsp.status; 01332 } 01333 #endif 01334 #endif 01335 01336 }//namespace 01337 01338
Generated on Tue Jul 12 2022 18:55:10 by 1.7.2