Rebase and changes for Dragonfly nano support

pull/7304/head
Leon Lindenfelser 2018-09-19 15:37:35 -05:00
parent 31d04b05b7
commit 5ff0eb9d92
12 changed files with 302 additions and 86 deletions

View File

@ -200,6 +200,10 @@ static void test_activate_context()
static void test_connect() static void test_connect()
{ {
TEST_ASSERT(nw->connect() == NSAPI_ERROR_OK); TEST_ASSERT(nw->connect() == NSAPI_ERROR_OK);
char count = 0;
while ((nw->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) && (count++ < 60)) {
wait(1);
}
nsapi_connection_status_t st = nw->get_connection_status(); nsapi_connection_status_t st = nw->get_connection_status();
TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP); TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP);
} }
@ -223,7 +227,7 @@ static void test_other()
// can't test values as they are optional // can't test values as they are optional
nsapi_error_t err = nw->get_rate_control(reports, timeUnit, uplinkRate); nsapi_error_t err = nw->get_rate_control(reports, timeUnit, uplinkRate);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) { // QUECTEL_BG96 does not give any specific reason for device error if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0 && strcmp(devi, "SARA4_PPP") != 0) { // QUECTEL_BG96 does not give any specific reason for device error
if (err == NSAPI_ERROR_DEVICE_ERROR) { if (err == NSAPI_ERROR_DEVICE_ERROR) {
TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem
((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem
@ -234,7 +238,7 @@ static void test_other()
err = nw->get_apn_backoff_timer(uplinkRate); err = nw->get_apn_backoff_timer(uplinkRate);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR || err == NSAPI_ERROR_PARAMETER); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR || err == NSAPI_ERROR_PARAMETER);
if (err == NSAPI_ERROR_DEVICE_ERROR) { if (err == NSAPI_ERROR_DEVICE_ERROR) {
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) { // QUECTEL_BG96 does not give any specific reason for device error if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0 && strcmp(devi, "SARA4_PPP") != 0) { // QUECTEL_BG96 does not give any specific reason for device error
TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem
((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem
} }
@ -320,7 +324,7 @@ static void test_other()
TEST_ASSERT(nw->set_blocking(true) == NSAPI_ERROR_OK); TEST_ASSERT(nw->set_blocking(true) == NSAPI_ERROR_OK);
if (strcmp(devi, "QUECTEL_BG96") != 0) { if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "SARA4_PPP") != 0) {
// QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout // QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout
CellularNetwork::operator_names_list op_names; CellularNetwork::operator_names_list op_names;
err = nw->get_operator_names(op_names); err = nw->get_operator_names(op_names);
@ -344,7 +348,7 @@ static void test_other()
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) { if (err == NSAPI_ERROR_DEVICE_ERROR) {
// if device error then we must check was that really device error or that modem/network does not support the commands // if device error then we must check was that really device error or that modem/network does not support the commands
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0 || strcmp(devi, "SARA4_PPP") == 0)) {
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem ((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands (((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
@ -358,7 +362,7 @@ static void test_other()
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
if (err == NSAPI_ERROR_DEVICE_ERROR) { if (err == NSAPI_ERROR_DEVICE_ERROR) {
// if device error then we must check was that really device error or that modem/network does not support the commands // if device error then we must check was that really device error or that modem/network does not support the commands
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0 || strcmp(devi, "SARA4_PPP") == 0)) {
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem ((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands (((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
@ -371,6 +375,8 @@ static void test_disconnect()
nsapi_connection_status_t st = nw->get_connection_status(); nsapi_connection_status_t st = nw->get_connection_status();
TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP); TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP);
TEST_ASSERT(nw->disconnect() == NSAPI_ERROR_OK); TEST_ASSERT(nw->disconnect() == NSAPI_ERROR_OK);
// wait to process URC's, received after disconnect
rtos::Thread::wait(500);
} }
static void test_detach() static void test_detach()
@ -384,7 +390,7 @@ static void test_detach()
TEST_ASSERT(nw->detach() == NSAPI_ERROR_OK); TEST_ASSERT(nw->detach() == NSAPI_ERROR_OK);
// wait to process URC's, received after detach // wait to process URC's, received after detach
rtos::Thread::wait(50); rtos::Thread::wait(500);
st = nw->get_connection_status(); st = nw->get_connection_status();
TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED);
} }

View File

@ -205,6 +205,7 @@ AT_CellularInformation *AT_CellularDevice::open_information_impl(ATHandler &at)
void AT_CellularDevice::close_network() void AT_CellularDevice::close_network()
{ {
if (_network) { if (_network) {
<<<<<<< HEAD
_network_ref_count--; _network_ref_count--;
if (_network_ref_count == 0) { if (_network_ref_count == 0) {
ATHandler *atHandler = &_network->get_at_handler(); ATHandler *atHandler = &_network->get_at_handler();
@ -212,6 +213,12 @@ void AT_CellularDevice::close_network()
_network = NULL; _network = NULL;
release_at_handler(atHandler); release_at_handler(atHandler);
} }
=======
ATHandler *at_handler = &_network->get_at_handler();
delete _network;
release_at_handler(at_handler);
_network = NULL;
>>>>>>> Rebase and changes for Dragonfly nano support
} }
} }

View File

@ -388,7 +388,6 @@ nsapi_error_t AT_CellularNetwork::open_data_channel()
{ {
#if NSAPI_PPP_AVAILABLE #if NSAPI_PPP_AVAILABLE
tr_info("Open data channel in PPP mode"); tr_info("Open data channel in PPP mode");
//<<<<<<< HEAD
if (is_supported(AT_CGDATA)) { if (is_supported(AT_CGDATA)) {
_at.cmd_start("AT+CGDATA=\"PPP\","); _at.cmd_start("AT+CGDATA=\"PPP\",");
_at.write_int(_cid); _at.write_int(_cid);
@ -398,16 +397,6 @@ nsapi_error_t AT_CellularNetwork::open_data_channel()
std::sprintf(cmd_buf, "ATD*99***%d#", _cid); std::sprintf(cmd_buf, "ATD*99***%d#", _cid);
_at.cmd_start(cmd_buf); _at.cmd_start(cmd_buf);
} }
//=======
//
//#ifdef TARGET_MTS_DRAGONFLY_L471QG
// _at.cmd_start("ATD*99***1#");
//#else
// _at.cmd_start("AT+CGDATA=\"PPP\",");
// _at.write_int(_cid);
//#endif
//
//>>>>>>> changes to support mts dragonfly nano ppp
_at.cmd_stop(); _at.cmd_stop();
_at.resp_start("CONNECT", true); _at.resp_start("CONNECT", true);

View File

@ -37,8 +37,8 @@ namespace mbed {
#endif #endif
#elif TARGET_UBLOX_C027 #elif TARGET_UBLOX_C027
#define CELLULAR_DEVICE UBLOX_PPP #define CELLULAR_DEVICE UBLOX_PPP
#elif TARGET_DRAGONFLY_L471QG #elif TARGET_MTS_DRAGONFLY_L471QG
#define CELLULAR_DEVICE UBLOX_PPP #define CELLULAR_DEVICE SARA4_PPP
//#else //#else
//#error Cellular target not defined, see cellular/targets.h //#error Cellular target not defined, see cellular/targets.h
//#define CELLULAR_TARGET <target-modem> //#define CELLULAR_TARGET <target-modem>

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SARA4_PPP.h"
#include "SARA4_PPP_CellularNetwork.h"
#include "SARA4_PPP_CellularPower.h"
using namespace mbed;
using namespace events;
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::AT_CGDATA,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
};
SARA4_PPP::SARA4_PPP(EventQueue &queue) : AT_CellularDevice(queue)
{
AT_CellularBase::set_unsupported_features(unsupported_features);
}
SARA4_PPP::~SARA4_PPP()
{
}
CellularNetwork *SARA4_PPP::open_network(FileHandle *fh)
{
if (!_network) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_network = new SARA4_PPP_CellularNetwork(*atHandler);
if (!_network) {
release_at_handler(atHandler);
}
}
}
return _network;
}
CellularPower *SARA4_PPP::open_power(FileHandle *fh)
{
if (!_power) {
ATHandler *atHandler = get_at_handler(fh);
if (atHandler) {
_power = new SARA4_PPP_CellularPower(*atHandler);
if (!_power) {
release_at_handler(atHandler);
}
}
}
return _power;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SARA4_PPP_H_
#define SARA4_PPP_H_
#include "AT_CellularDevice.h"
namespace mbed {
class SARA4_PPP : public AT_CellularDevice {
public:
SARA4_PPP(events::EventQueue &queue);
virtual ~SARA4_PPP();
public: // CellularDevice
virtual CellularNetwork *open_network(FileHandle *fh);
virtual CellularPower *open_power(FileHandle *fh);
};
} // namespace mbed
#endif // SARA4_PPP_H_

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SARA4_PPP_CellularNetwork.h"
using namespace mbed;
SARA4_PPP_CellularNetwork::SARA4_PPP_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
{
}
SARA4_PPP_CellularNetwork::~SARA4_PPP_CellularNetwork()
{
}
bool SARA4_PPP_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
{
return requested_stack == IPV4_STACK ? true : false;
}
AT_CellularNetwork::RegistrationMode SARA4_PPP_CellularNetwork::has_registration(RegistrationType reg_type)
{
//<<<<<<< HEAD
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
//=======
//#ifdef TARGET_DRAGONFLY_L471QG
// return (reg_type == C_REG || reg_type == C_EREG);
//#else
// return (reg_type == C_REG || reg_type == C_GREG || reg_type == C_EREG);
//#endif
//>>>>>>> Fixed spacing/tabs and clean up targets.json
}
nsapi_error_t SARA4_PPP_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
{
_op_act = RAT_CATM1;
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SARA4_PPP_CELLULAR_NETWORK_H_
#define SARA4_PPP_CELLULAR_NETWORK_H_
#include "AT_CellularNetwork.h"
namespace mbed {
class SARA4_PPP_CellularNetwork : public AT_CellularNetwork {
public:
SARA4_PPP_CellularNetwork(ATHandler &atHandler);
virtual ~SARA4_PPP_CellularNetwork();
protected:
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
virtual RegistrationMode has_registration(RegistrationType rat);
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
};
} // namespace mbed
#endif // SARA4_PPP_CELLULAR_NETWORK_H_

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SARA4_PPP_CellularPower.h"
#include "onboard_modem_api.h"
using namespace mbed;
SARA4_PPP_CellularPower::SARA4_PPP_CellularPower(ATHandler &atHandler) : AT_CellularPower(atHandler)
{
}
SARA4_PPP_CellularPower::~SARA4_PPP_CellularPower()
{
}
nsapi_error_t SARA4_PPP_CellularPower::on()
{
::onboard_modem_init();
::onboard_modem_power_up();
return NSAPI_ERROR_OK;
}
nsapi_error_t SARA4_PPP_CellularPower::off()
{
::onboard_modem_power_down();
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SARA4_PPP_CELLULARPOWER_H_
#define SARA4_PPP_CELLULARPOWER_H_
#include "AT_CellularPower.h"
namespace mbed {
class SARA4_PPP_CellularPower : public AT_CellularPower {
public:
SARA4_PPP_CellularPower(ATHandler &atHandler);
virtual ~SARA4_PPP_CellularPower();
public: //from CellularPower
virtual nsapi_error_t on();
virtual nsapi_error_t off();
};
} // namespace mbed
#endif // SARA4_PPP_CELLULARPOWER_H_

View File

@ -1,66 +0,0 @@
/**
******************************************************************************
* @file hal_tick.h
* @author MCD Application Team
* @brief Initialization of HAL tick
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
#ifndef __HAL_TICK_H
#define __HAL_TICK_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32l4xx.h"
#include "stm32l4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5
#define TIM_MST_IRQ TIM5_IRQn
#define TIM_MST_RCC __HAL_RCC_TIM5_CLK_ENABLE()
#define TIM_MST_DBGMCU_FREEZE __HAL_DBGMCU_FREEZE_TIM5()
#define TIM_MST_RESET_ON __HAL_RCC_TIM5_FORCE_RESET()
#define TIM_MST_RESET_OFF __HAL_RCC_TIM5_RELEASE_RESET()
#define TIM_MST_16BIT 0 // 1=16-bit timer, 0=32-bit timer
#define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2)
#define HAL_TICK_DELAY (1000) // 1 ms
#ifdef __cplusplus
}
#endif
#endif // __HAL_TICK_H
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -2258,7 +2258,6 @@
} }
}, },
"detect_code": ["0312"], "detect_code": ["0312"],
"macros_add": ["CELLULAR_DEVICE=UBLOX_PPP"],
"device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"], "device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"],
"release_versions": ["2", "5"], "release_versions": ["2", "5"],
"device_name": "STM32L471QG", "device_name": "STM32L471QG",