Merge pull request #8862 from 0xc0170/dev_rollup

Rollup 5.11rc v3
pull/8790/head
Martin Kojtal 2018-11-25 11:25:54 +01:00 committed by GitHub
commit 7fd4692b32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 265 additions and 194 deletions

View File

@ -26,7 +26,7 @@ using namespace utest::v1;
namespace {
static const int SIGNAL_SIGIO = 0x1;
static const int SIGIO_TIMEOUT = 5000; //[ms]
static const int SIGIO_TIMEOUT = 20000; //[ms]
static const int BUFF_SIZE = 1200;
static const int PKTS = 22;

View File

@ -26,7 +26,7 @@ using namespace utest::v1;
namespace {
static const int SIGNAL_SIGIO = 0x1;
static const int SIGIO_TIMEOUT = 5000; //[ms]
static const int SIGIO_TIMEOUT = 20000; //[ms]
static const int BURST_CNT = 100;
static const int BURST_SIZE = 1220;

View File

@ -26,7 +26,7 @@ using namespace utest::v1;
namespace {
static const int SIGNAL_SIGIO = 0x1;
static const int SIGIO_TIMEOUT = 5000; //[ms]
static const int SIGIO_TIMEOUT = 20000; //[ms]
}
static void _sigio_handler(osThreadId id)

View File

@ -26,7 +26,7 @@ using namespace utest::v1;
namespace {
static const int SIGNAL_SIGIO = 0x1;
static const int SIGIO_TIMEOUT = 5000; //[ms]
static const int SIGIO_TIMEOUT = 20000; //[ms]
}
static void _sigio_handler(osThreadId id)

View File

@ -27,7 +27,7 @@ using namespace utest::v1;
namespace {
static const int SIGNAL_SIGIO1 = 0x1;
static const int SIGNAL_SIGIO2 = 0x2;
static const int SIGIO_TIMEOUT = 5000; //[ms]
static const int SIGIO_TIMEOUT = 20000; //[ms]
Thread thread(osPriorityNormal, tcp_global::TCP_OS_STACK_SIZE);
volatile bool running = true;

View File

@ -93,6 +93,11 @@ extern void (*fhss_bc_switch)(void);
#define CS_SELECT() {rf->CS = 0;}
#define CS_RELEASE() {rf->CS = 1;}
typedef enum {
RF_MODE_NORMAL = 0,
RF_MODE_SNIFFER = 1
} rf_mode_e;
class UnlockedSPI : public SPI {
public:
UnlockedSPI(PinName sdi, PinName sdo, PinName sclk) :
@ -164,7 +169,7 @@ RFPins::RFPins(PinName spi_sdi, PinName spi_sdo,
#endif //MBED_CONF_RTOS_PRESENT
}
static uint8_t rf_read_register_with_status(uint8_t addr, uint16_t *status_out);
static uint8_t rf_read_register(uint8_t addr);
static s2lp_states_e rf_read_state(void);
static void rf_write_register(uint8_t addr, uint8_t data);
static void rf_print_registers(void);
@ -200,6 +205,7 @@ static bool cca_enabled = true;
static uint8_t s2lp_PAN_ID[2] = {0xff, 0xff};
static uint8_t s2lp_short_address[2];
static uint8_t s2lp_MAC[8];
static rf_mode_e rf_mode = RF_MODE_NORMAL;
/* Channel configurations for sub-GHz */
static const phy_rf_channel_configuration_s phy_subghz = {868300000U, 500000U, 250000U, 11U, M_UNDEFINED};
@ -215,6 +221,7 @@ static const phy_device_channel_page_s phy_channel_pages[] = {
static void rf_irq_task_process_irq();
#define SIG_ALL (SIG_RADIO|SIG_TIMER_CCA|SIG_TIMER_BACKUP)
#define SIG_RADIO 1
#define SIG_TIMER_CCA 2
#define SIG_TIMER_BACKUP 4
@ -271,12 +278,12 @@ static void rf_unlock(void)
#ifdef MBED_CONF_RTOS_PRESENT
static void rf_cca_timer_signal(void)
{
rf->irq_thread.signal_set(SIG_TIMER_CCA);
rf->irq_thread.flags_set(SIG_TIMER_CCA);
}
static void rf_backup_timer_signal(void)
{
rf->irq_thread.signal_set(SIG_TIMER_BACKUP);
rf->irq_thread.flags_set(SIG_TIMER_BACKUP);
}
#endif //MBED_CONF_RTOS_PRESENT
@ -288,7 +295,7 @@ static void rf_spi_exchange(const void *tx, size_t tx_len, void *rx, size_t rx_l
rf->spi.write(static_cast<const char *>(tx), tx_len, static_cast<char *>(rx), rx_len);
}
static uint8_t rf_read_register_with_status(uint8_t addr, uint16_t *status_out)
static uint8_t rf_read_register(uint8_t addr)
{
const uint8_t tx[2] = {SPI_RD_REG, addr};
uint8_t rx[3];
@ -296,9 +303,6 @@ static uint8_t rf_read_register_with_status(uint8_t addr, uint16_t *status_out)
CS_SELECT();
rf_spi_exchange(tx, sizeof(tx), rx, sizeof(rx));
CS_RELEASE();
if (status_out) {
*status_out = (rx[0] << 8) | rx[1];
}
rf_unlock();
return rx[2];
}
@ -315,7 +319,7 @@ static void rf_write_register(uint8_t addr, uint8_t data)
static void rf_write_register_field(uint8_t addr, uint8_t field, uint8_t value)
{
uint8_t reg_tmp = rf_read_register_with_status(addr, NULL);
uint8_t reg_tmp = rf_read_register(addr);
reg_tmp &= ~field;
reg_tmp |= value;
rf_write_register(addr, reg_tmp);
@ -323,7 +327,7 @@ static void rf_write_register_field(uint8_t addr, uint8_t field, uint8_t value)
static s2lp_states_e rf_read_state(void)
{
return (s2lp_states_e)(rf_read_register_with_status(MC_STATE0, NULL) >> 1);
return (s2lp_states_e)(rf_read_register(MC_STATE0) >> 1);
}
static void rf_poll_state_change(s2lp_states_e state)
@ -423,8 +427,12 @@ static uint8_t rf_write_tx_fifo(uint8_t *ptr, uint16_t length, uint8_t max_write
return written_length;
}
static uint8_t rf_read_rx_fifo(uint8_t *ptr, uint16_t length)
static int rf_read_rx_fifo(uint16_t rx_index, uint16_t length)
{
if ((rx_index + length) > RF_MTU) {
return -1;
}
uint8_t *ptr = &rx_buffer[rx_index];
const uint8_t spi_header[SPI_HEADER_LENGTH] = {SPI_RD_REG, RX_FIFO};
CS_SELECT();
rf_spi_exchange(spi_header, SPI_HEADER_LENGTH, NULL, 0);
@ -565,7 +573,7 @@ static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_pt
csma_params = (phy_csma_params_t *)data_ptr;
if (csma_params->backoff_time == 0) {
rf_cca_timer_stop();
if (rf_read_register_with_status(TX_FIFO_STATUS, NULL)) {
if (rf_read_register(TX_FIFO_STATUS)) {
rf_send_command(S2LP_CMD_SABORT);
rf_poll_state_change(S2LP_STATE_READY);
rf_send_command(S2LP_CMD_FLUSHTXFIFO);
@ -611,6 +619,7 @@ static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_
break;
/*Enable PHY Interface driver*/
case PHY_INTERFACE_UP:
rf_mode = RF_MODE_NORMAL;
rf_receive(rf_channel);
break;
/*Enable wireless interface ED scan mode*/
@ -618,6 +627,8 @@ static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_
break;
/*Enable Sniffer state*/
case PHY_INTERFACE_SNIFFER_STATE:
rf_mode = RF_MODE_SNIFFER;
rf_receive(rf_channel);
break;
}
return ret_val;
@ -671,17 +682,17 @@ static void rf_start_tx(void)
static void rf_cca_timer_interrupt(void)
{
if (device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_PREPARE, 0, 0) != 0) {
if (rf_read_register_with_status(TX_FIFO_STATUS, NULL)) {
if (rf_read_register(TX_FIFO_STATUS)) {
rf_send_command(S2LP_CMD_FLUSHTXFIFO);
}
rf_state = RF_IDLE;
return;
}
if ((cca_enabled == true) && (rf_read_register_with_status(LINK_QUALIF1, NULL) & CARRIER_SENSE || (rf_state != RF_CSMA_STARTED && rf_state != RF_IDLE))) {
if ((cca_enabled == true) && (rf_read_register(LINK_QUALIF1) & CARRIER_SENSE || (rf_state != RF_CSMA_STARTED && rf_state != RF_IDLE))) {
if (rf_state == RF_CSMA_STARTED) {
rf_state = RF_IDLE;
}
if (rf_read_register_with_status(TX_FIFO_STATUS, NULL)) {
if (rf_read_register(TX_FIFO_STATUS)) {
rf_send_command(S2LP_CMD_FLUSHTXFIFO);
}
tx_finnish_time = rf_get_timestamp();
@ -717,7 +728,7 @@ static void rf_backup_timer_interrupt(void)
device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 0, 0);
}
}
if (rf_read_register_with_status(TX_FIFO_STATUS, NULL)) {
if (rf_read_register(TX_FIFO_STATUS)) {
rf_send_command(S2LP_CMD_FLUSHTXFIFO);
}
TEST_TX_DONE
@ -780,7 +791,7 @@ static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_h
static void rf_send_ack(uint8_t seq)
{
// If the reception started during CCA process, the TX FIFO may already contain a data packet
if (rf_read_register_with_status(TX_FIFO_STATUS, NULL)) {
if (rf_read_register(TX_FIFO_STATUS)) {
rf_send_command(S2LP_CMD_SABORT);
rf_poll_state_change(S2LP_STATE_READY);
rf_send_command(S2LP_CMD_FLUSHTXFIFO);
@ -817,20 +828,33 @@ static void rf_rx_ready_handler(void)
{
rf_backup_timer_stop();
TEST_RX_DONE
rx_data_length += rf_read_rx_fifo(&rx_buffer[rx_data_length], rf_read_register_with_status(RX_FIFO_STATUS, NULL));
uint8_t version = ((rx_buffer[1] & VERSION_FIELD_MASK) >> SHIFT_VERSION_FIELD);
if (((rx_buffer[0] & MAC_FRAME_TYPE_MASK) == MAC_TYPE_ACK) && (version < MAC_FRAME_VERSION_2)) {
rf_handle_ack(rx_buffer[2], rx_buffer[0] & MAC_DATA_PENDING);
} else if (rf_rx_filter(rx_buffer, s2lp_MAC, s2lp_short_address, s2lp_PAN_ID)) {
int rx_read_length = rf_read_rx_fifo(rx_data_length, rf_read_register(RX_FIFO_STATUS));
if (rx_read_length < 0) {
rf_receive(rf_rx_channel);
return;
}
rx_data_length += rx_read_length;
if (rf_mode != RF_MODE_SNIFFER) {
uint8_t version = ((rx_buffer[1] & VERSION_FIELD_MASK) >> SHIFT_VERSION_FIELD);
if (((rx_buffer[0] & MAC_FRAME_TYPE_MASK) == MAC_TYPE_ACK) && (version < MAC_FRAME_VERSION_2)) {
rf_handle_ack(rx_buffer[2], rx_buffer[0] & MAC_DATA_PENDING);
} else if (rf_rx_filter(rx_buffer, s2lp_MAC, s2lp_short_address, s2lp_PAN_ID)) {
rf_state = RF_IDLE;
int8_t rssi = (rf_read_register(RSSI_LEVEL) - RSSI_OFFSET);
if (device_driver.phy_rx_cb) {
device_driver.phy_rx_cb(rx_buffer, rx_data_length, 0xf0, rssi, rf_radio_driver_id);
}
// Check Ack request
if ((version != MAC_FRAME_VERSION_2) && (rx_buffer[0] & FC_AR)) {
rf_send_ack(rx_buffer[2]);
}
}
} else {
rf_state = RF_IDLE;
int8_t rssi = (rf_read_register_with_status(RSSI_LEVEL, NULL) - RSSI_OFFSET);
int8_t rssi = (rf_read_register(RSSI_LEVEL) - RSSI_OFFSET);
if (device_driver.phy_rx_cb) {
device_driver.phy_rx_cb(rx_buffer, rx_data_length, 0xf0, rssi, rf_radio_driver_id);
}
// Check Ack request
if ((version != MAC_FRAME_VERSION_2) && (rx_buffer[0] & FC_AR)) {
rf_send_ack(rx_buffer[2]);
}
}
if ((rf_state != RF_TX_ACK) && (rf_state != RF_CSMA_STARTED)) {
rf_receive(rf_rx_channel);
@ -839,7 +863,12 @@ static void rf_rx_ready_handler(void)
static void rf_rx_threshold_handler(void)
{
rx_data_length += rf_read_rx_fifo(&rx_buffer[rx_data_length], rf_read_register_with_status(RX_FIFO_STATUS, NULL));
int rx_read_length = rf_read_rx_fifo(rx_data_length, rf_read_register(RX_FIFO_STATUS));
if (rx_read_length < 0) {
rf_receive(rf_rx_channel);
return;
}
rx_data_length += rx_read_length;
}
static void rf_sync_detected_handler(void)
@ -879,24 +908,21 @@ static void rf_receive(uint8_t rx_channel)
#ifdef MBED_CONF_RTOS_PRESENT
static void rf_interrupt_handler(void)
{
rf->irq_thread.signal_set(SIG_RADIO);
rf->irq_thread.flags_set(SIG_RADIO);
}
void RFPins::rf_irq_task(void)
{
for (;;) {
osEvent event = irq_thread.signal_wait(0);
if (event.status != osEventSignal) {
continue;
}
uint32_t flags = ThisThread::flags_wait_any(SIG_ALL);
rf_lock();
if (event.value.signals & SIG_RADIO) {
if (flags & SIG_RADIO) {
rf_irq_task_process_irq();
}
if (event.value.signals & SIG_TIMER_CCA) {
if (flags & SIG_TIMER_CCA) {
rf_cca_timer_interrupt();
}
if (event.value.signals & SIG_TIMER_BACKUP) {
if (flags & SIG_TIMER_BACKUP) {
rf_backup_timer_interrupt();
}
rf_unlock();
@ -987,11 +1013,11 @@ static void rf_init(void)
rf_reset();
rf->spi.frequency(10000000);
CS_RELEASE();
if (PARTNUM != rf_read_register_with_status(DEVICE_INFO1, NULL)) {
tr_err("Invalid part number: %x", rf_read_register_with_status(DEVICE_INFO1, NULL));
if (PARTNUM != rf_read_register(DEVICE_INFO1)) {
tr_err("Invalid part number: %x", rf_read_register(DEVICE_INFO1));
}
if (VERSION != rf_read_register_with_status(DEVICE_INFO0, NULL)) {
tr_err("Invalid version: %x", rf_read_register_with_status(DEVICE_INFO0, NULL));
if (VERSION != rf_read_register(DEVICE_INFO0)) {
tr_err("Invalid version: %x", rf_read_register(DEVICE_INFO0));
}
rf_init_registers();
rf_enable_gpio_interrupt();
@ -1233,133 +1259,133 @@ static bool rf_rx_filter(uint8_t *mac_header, uint8_t *mac_64bit_addr, uint8_t *
static void rf_print_registers(void)
{
tr_debug("GPIO0_CONF: %x", rf_read_register_with_status(GPIO0_CONF, NULL));
tr_debug("GPIO1_CONF: %x", rf_read_register_with_status(GPIO1_CONF, NULL));
tr_debug("GPIO2_CONF: %x", rf_read_register_with_status(GPIO2_CONF, NULL));
tr_debug("GPIO3_CONF: %x", rf_read_register_with_status(GPIO3_CONF, NULL));
tr_debug("SYNT3: %x", rf_read_register_with_status(SYNT3, NULL));
tr_debug("SYNT2: %x", rf_read_register_with_status(SYNT2, NULL));
tr_debug("SYNT1: %x", rf_read_register_with_status(SYNT1, NULL));
tr_debug("SYNT0: %x", rf_read_register_with_status(SYNT0, NULL));
tr_debug("IF_OFFSET_ANA: %x", rf_read_register_with_status(IF_OFFSET_ANA, NULL));
tr_debug("IF_OFFSET_DIG: %x", rf_read_register_with_status(IF_OFFSET_DIG, NULL));
tr_debug("CHSPACE: %x", rf_read_register_with_status(CHSPACE, NULL));
tr_debug("CHNUM: %x", rf_read_register_with_status(CHNUM, NULL));
tr_debug("MOD4: %x", rf_read_register_with_status(MOD4, NULL));
tr_debug("MOD3: %x", rf_read_register_with_status(MOD3, NULL));
tr_debug("MOD2: %x", rf_read_register_with_status(MOD2, NULL));
tr_debug("MOD1: %x", rf_read_register_with_status(MOD1, NULL));
tr_debug("MOD0: %x", rf_read_register_with_status(MOD0, NULL));
tr_debug("CHFLT: %x", rf_read_register_with_status(CHFLT, NULL));
tr_debug("AFC2: %x", rf_read_register_with_status(AFC2, NULL));
tr_debug("AFC1: %x", rf_read_register_with_status(AFC1, NULL));
tr_debug("AFC0: %x", rf_read_register_with_status(AFC0, NULL));
tr_debug("RSSI_FLT: %x", rf_read_register_with_status(RSSI_FLT, NULL));
tr_debug("RSSI_TH: %x", rf_read_register_with_status(RSSI_TH, NULL));
tr_debug("AGCCTRL4: %x", rf_read_register_with_status(AGCCTRL4, NULL));
tr_debug("AGCCTRL3: %x", rf_read_register_with_status(AGCCTRL3, NULL));
tr_debug("AGCCTRL2: %x", rf_read_register_with_status(AGCCTRL2, NULL));
tr_debug("AGCCTRL1: %x", rf_read_register_with_status(AGCCTRL1, NULL));
tr_debug("AGCCTRL0: %x", rf_read_register_with_status(AGCCTRL0, NULL));
tr_debug("ANT_SELECT_CONF: %x", rf_read_register_with_status(ANT_SELECT_CONF, NULL));
tr_debug("CLOCKREC2: %x", rf_read_register_with_status(CLOCKREC2, NULL));
tr_debug("CLOCKREC1: %x", rf_read_register_with_status(CLOCKREC1, NULL));
tr_debug("PCKTCTRL6: %x", rf_read_register_with_status(PCKTCTRL6, NULL));
tr_debug("PCKTCTRL5: %x", rf_read_register_with_status(PCKTCTRL5, NULL));
tr_debug("PCKTCTRL4: %x", rf_read_register_with_status(PCKTCTRL4, NULL));
tr_debug("PCKTCTRL3: %x", rf_read_register_with_status(PCKTCTRL3, NULL));
tr_debug("PCKTCTRL2: %x", rf_read_register_with_status(PCKTCTRL2, NULL));
tr_debug("PCKTCTRL1: %x", rf_read_register_with_status(PCKTCTRL1, NULL));
tr_debug("PCKTLEN1: %x", rf_read_register_with_status(PCKTLEN1, NULL));
tr_debug("PCKTLEN0: %x", rf_read_register_with_status(PCKTLEN0, NULL));
tr_debug("SYNC3: %x", rf_read_register_with_status(SYNC3, NULL));
tr_debug("SYNC2: %x", rf_read_register_with_status(SYNC2, NULL));
tr_debug("SYNC1: %x", rf_read_register_with_status(SYNC1, NULL));
tr_debug("SYNC0: %x", rf_read_register_with_status(SYNC0, NULL));
tr_debug("QI: %x", rf_read_register_with_status(QI, NULL));
tr_debug("PCKT_PSTMBL: %x", rf_read_register_with_status(PCKT_PSTMBL, NULL));
tr_debug("PROTOCOL2: %x", rf_read_register_with_status(PROTOCOL2, NULL));
tr_debug("PROTOCOL1: %x", rf_read_register_with_status(PROTOCOL1, NULL));
tr_debug("PROTOCOL0: %x", rf_read_register_with_status(PROTOCOL0, NULL));
tr_debug("FIFO_CONFIG3: %x", rf_read_register_with_status(FIFO_CONFIG3, NULL));
tr_debug("FIFO_CONFIG2: %x", rf_read_register_with_status(FIFO_CONFIG2, NULL));
tr_debug("FIFO_CONFIG1: %x", rf_read_register_with_status(FIFO_CONFIG1, NULL));
tr_debug("FIFO_CONFIG0: %x", rf_read_register_with_status(FIFO_CONFIG0, NULL));
tr_debug("PCKT_FLT_OPTIONS: %x", rf_read_register_with_status(PCKT_FLT_OPTIONS, NULL));
tr_debug("PCKT_FLT_GOALS4: %x", rf_read_register_with_status(PCKT_FLT_GOALS4, NULL));
tr_debug("PCKT_FLT_GOALS3: %x", rf_read_register_with_status(PCKT_FLT_GOALS3, NULL));
tr_debug("PCKT_FLT_GOALS2: %x", rf_read_register_with_status(PCKT_FLT_GOALS2, NULL));
tr_debug("PCKT_FLT_GOALS1: %x", rf_read_register_with_status(PCKT_FLT_GOALS1, NULL));
tr_debug("PCKT_FLT_GOALS0: %x", rf_read_register_with_status(PCKT_FLT_GOALS0, NULL));
tr_debug("TIMERS5: %x", rf_read_register_with_status(TIMERS5, NULL));
tr_debug("TIMERS4: %x", rf_read_register_with_status(TIMERS4, NULL));
tr_debug("TIMERS3: %x", rf_read_register_with_status(TIMERS3, NULL));
tr_debug("TIMERS2: %x", rf_read_register_with_status(TIMERS2, NULL));
tr_debug("TIMERS1: %x", rf_read_register_with_status(TIMERS1, NULL));
tr_debug("TIMERS0: %x", rf_read_register_with_status(TIMERS0, NULL));
tr_debug("CSMA_CONF3: %x", rf_read_register_with_status(CSMA_CONF3, NULL));
tr_debug("CSMA_CONF2: %x", rf_read_register_with_status(CSMA_CONF2, NULL));
tr_debug("CSMA_CONF1: %x", rf_read_register_with_status(CSMA_CONF1, NULL));
tr_debug("CSMA_CONF0: %x", rf_read_register_with_status(CSMA_CONF0, NULL));
tr_debug("IRQ_MASK3: %x", rf_read_register_with_status(IRQ_MASK3, NULL));
tr_debug("IRQ_MASK2: %x", rf_read_register_with_status(IRQ_MASK2, NULL));
tr_debug("IRQ_MASK1: %x", rf_read_register_with_status(IRQ_MASK1, NULL));
tr_debug("IRQ_MASK0: %x", rf_read_register_with_status(IRQ_MASK0, NULL));
tr_debug("FAST_RX_TIMER: %x", rf_read_register_with_status(FAST_RX_TIMER, NULL));
tr_debug("PA_POWER8: %x", rf_read_register_with_status(PA_POWER8, NULL));
tr_debug("PA_POWER7: %x", rf_read_register_with_status(PA_POWER7, NULL));
tr_debug("PA_POWER6: %x", rf_read_register_with_status(PA_POWER6, NULL));
tr_debug("PA_POWER5: %x", rf_read_register_with_status(PA_POWER5, NULL));
tr_debug("PA_POWER4: %x", rf_read_register_with_status(PA_POWER4, NULL));
tr_debug("PA_POWER3: %x", rf_read_register_with_status(PA_POWER3, NULL));
tr_debug("PA_POWER2: %x", rf_read_register_with_status(PA_POWER2, NULL));
tr_debug("PA_POWER1: %x", rf_read_register_with_status(PA_POWER1, NULL));
tr_debug("PA_POWER0: %x", rf_read_register_with_status(PA_POWER0, NULL));
tr_debug("PA_CONFIG1: %x", rf_read_register_with_status(PA_CONFIG1, NULL));
tr_debug("PA_CONFIG0: %x", rf_read_register_with_status(PA_CONFIG0, NULL));
tr_debug("SYNTH_CONFIG2: %x", rf_read_register_with_status(SYNTH_CONFIG2, NULL));
tr_debug("VCO_CONFIG: %x", rf_read_register_with_status(VCO_CONFIG, NULL));
tr_debug("VCO_CALIBR_IN2: %x", rf_read_register_with_status(VCO_CALIBR_IN2, NULL));
tr_debug("VCO_CALIBR_IN1: %x", rf_read_register_with_status(VCO_CALIBR_IN1, NULL));
tr_debug("VCO_CALIBR_IN0: %x", rf_read_register_with_status(VCO_CALIBR_IN0, NULL));
tr_debug("XO_RCO_CONF1: %x", rf_read_register_with_status(XO_RCO_CONF1, NULL));
tr_debug("XO_RCO_CONF0: %x", rf_read_register_with_status(XO_RCO_CONF0, NULL));
tr_debug("RCO_CALIBR_CONF3: %x", rf_read_register_with_status(RCO_CALIBR_CONF3, NULL));
tr_debug("RCO_CALIBR_CONF2: %x", rf_read_register_with_status(RCO_CALIBR_CONF2, NULL));
tr_debug("PM_CONF4: %x", rf_read_register_with_status(PM_CONF4, NULL));
tr_debug("PM_CONF3: %x", rf_read_register_with_status(PM_CONF3, NULL));
tr_debug("PM_CONF2: %x", rf_read_register_with_status(PM_CONF2, NULL));
tr_debug("PM_CONF1: %x", rf_read_register_with_status(PM_CONF1, NULL));
tr_debug("PM_CONF0: %x", rf_read_register_with_status(PM_CONF0, NULL));
tr_debug("MC_STATE1: %x", rf_read_register_with_status(MC_STATE1, NULL));
tr_debug("MC_STATE0: %x", rf_read_register_with_status(MC_STATE0, NULL));
tr_debug("TX_FIFO_STATUS: %x", rf_read_register_with_status(TX_FIFO_STATUS, NULL));
tr_debug("RX_FIFO_STATUS: %x", rf_read_register_with_status(RX_FIFO_STATUS, NULL));
tr_debug("RCO_CALIBR_OUT4: %x", rf_read_register_with_status(RCO_CALIBR_OUT4, NULL));
tr_debug("RCO_CALIBR_OUT3: %x", rf_read_register_with_status(RCO_CALIBR_OUT3, NULL));
tr_debug("VCO_CALIBR_OUT1: %x", rf_read_register_with_status(VCO_CALIBR_OUT1, NULL));
tr_debug("VCO_CALIBR_OUT0: %x", rf_read_register_with_status(VCO_CALIBR_OUT0, NULL));
tr_debug("TX_PCKT_INFO: %x", rf_read_register_with_status(TX_PCKT_INFO, NULL));
tr_debug("RX_PCKT_INFO: %x", rf_read_register_with_status(RX_PCKT_INFO, NULL));
tr_debug("AFC_CORR: %x", rf_read_register_with_status(AFC_CORR, NULL));
tr_debug("LINK_QUALIF2: %x", rf_read_register_with_status(LINK_QUALIF2, NULL));
tr_debug("LINK_QUALIF1: %x", rf_read_register_with_status(LINK_QUALIF1, NULL));
tr_debug("RSSI_LEVEL: %x", rf_read_register_with_status(RSSI_LEVEL, NULL));
tr_debug("RX_PCKT_LEN1: %x", rf_read_register_with_status(RX_PCKT_LEN1, NULL));
tr_debug("RX_PCKT_LEN0: %x", rf_read_register_with_status(RX_PCKT_LEN0, NULL));
tr_debug("CRC_FIELD3: %x", rf_read_register_with_status(CRC_FIELD3, NULL));
tr_debug("CRC_FIELD2: %x", rf_read_register_with_status(CRC_FIELD2, NULL));
tr_debug("CRC_FIELD1: %x", rf_read_register_with_status(CRC_FIELD1, NULL));
tr_debug("CRC_FIELD0: %x", rf_read_register_with_status(CRC_FIELD0, NULL));
tr_debug("RX_ADDRE_FIELD1: %x", rf_read_register_with_status(RX_ADDRE_FIELD1, NULL));
tr_debug("RX_ADDRE_FIELD0: %x", rf_read_register_with_status(RX_ADDRE_FIELD0, NULL));
tr_debug("RSSI_LEVEL_RUN: %x", rf_read_register_with_status(RSSI_LEVEL_RUN, NULL));
tr_debug("DEVICE_INFO1: %x", rf_read_register_with_status(DEVICE_INFO1, NULL));
tr_debug("DEVICE_INFO0: %x", rf_read_register_with_status(DEVICE_INFO0, NULL));
tr_debug("IRQ_STATUS3: %x", rf_read_register_with_status(IRQ_STATUS3, NULL));
tr_debug("IRQ_STATUS2: %x", rf_read_register_with_status(IRQ_STATUS2, NULL));
tr_debug("IRQ_STATUS1: %x", rf_read_register_with_status(IRQ_STATUS1, NULL));
tr_debug("IRQ_STATUS0: %x", rf_read_register_with_status(IRQ_STATUS0, NULL));
tr_debug("GPIO0_CONF: %x", rf_read_register(GPIO0_CONF));
tr_debug("GPIO1_CONF: %x", rf_read_register(GPIO1_CONF));
tr_debug("GPIO2_CONF: %x", rf_read_register(GPIO2_CONF));
tr_debug("GPIO3_CONF: %x", rf_read_register(GPIO3_CONF));
tr_debug("SYNT3: %x", rf_read_register(SYNT3));
tr_debug("SYNT2: %x", rf_read_register(SYNT2));
tr_debug("SYNT1: %x", rf_read_register(SYNT1));
tr_debug("SYNT0: %x", rf_read_register(SYNT0));
tr_debug("IF_OFFSET_ANA: %x", rf_read_register(IF_OFFSET_ANA));
tr_debug("IF_OFFSET_DIG: %x", rf_read_register(IF_OFFSET_DIG));
tr_debug("CHSPACE: %x", rf_read_register(CHSPACE));
tr_debug("CHNUM: %x", rf_read_register(CHNUM));
tr_debug("MOD4: %x", rf_read_register(MOD4));
tr_debug("MOD3: %x", rf_read_register(MOD3));
tr_debug("MOD2: %x", rf_read_register(MOD2));
tr_debug("MOD1: %x", rf_read_register(MOD1));
tr_debug("MOD0: %x", rf_read_register(MOD0));
tr_debug("CHFLT: %x", rf_read_register(CHFLT));
tr_debug("AFC2: %x", rf_read_register(AFC2));
tr_debug("AFC1: %x", rf_read_register(AFC1));
tr_debug("AFC0: %x", rf_read_register(AFC0));
tr_debug("RSSI_FLT: %x", rf_read_register(RSSI_FLT));
tr_debug("RSSI_TH: %x", rf_read_register(RSSI_TH));
tr_debug("AGCCTRL4: %x", rf_read_register(AGCCTRL4));
tr_debug("AGCCTRL3: %x", rf_read_register(AGCCTRL3));
tr_debug("AGCCTRL2: %x", rf_read_register(AGCCTRL2));
tr_debug("AGCCTRL1: %x", rf_read_register(AGCCTRL1));
tr_debug("AGCCTRL0: %x", rf_read_register(AGCCTRL0));
tr_debug("ANT_SELECT_CONF: %x", rf_read_register(ANT_SELECT_CONF));
tr_debug("CLOCKREC2: %x", rf_read_register(CLOCKREC2));
tr_debug("CLOCKREC1: %x", rf_read_register(CLOCKREC1));
tr_debug("PCKTCTRL6: %x", rf_read_register(PCKTCTRL6));
tr_debug("PCKTCTRL5: %x", rf_read_register(PCKTCTRL5));
tr_debug("PCKTCTRL4: %x", rf_read_register(PCKTCTRL4));
tr_debug("PCKTCTRL3: %x", rf_read_register(PCKTCTRL3));
tr_debug("PCKTCTRL2: %x", rf_read_register(PCKTCTRL2));
tr_debug("PCKTCTRL1: %x", rf_read_register(PCKTCTRL1));
tr_debug("PCKTLEN1: %x", rf_read_register(PCKTLEN1));
tr_debug("PCKTLEN0: %x", rf_read_register(PCKTLEN0));
tr_debug("SYNC3: %x", rf_read_register(SYNC3));
tr_debug("SYNC2: %x", rf_read_register(SYNC2));
tr_debug("SYNC1: %x", rf_read_register(SYNC1));
tr_debug("SYNC0: %x", rf_read_register(SYNC0));
tr_debug("QI: %x", rf_read_register(QI));
tr_debug("PCKT_PSTMBL: %x", rf_read_register(PCKT_PSTMBL));
tr_debug("PROTOCOL2: %x", rf_read_register(PROTOCOL2));
tr_debug("PROTOCOL1: %x", rf_read_register(PROTOCOL1));
tr_debug("PROTOCOL0: %x", rf_read_register(PROTOCOL0));
tr_debug("FIFO_CONFIG3: %x", rf_read_register(FIFO_CONFIG3));
tr_debug("FIFO_CONFIG2: %x", rf_read_register(FIFO_CONFIG2));
tr_debug("FIFO_CONFIG1: %x", rf_read_register(FIFO_CONFIG1));
tr_debug("FIFO_CONFIG0: %x", rf_read_register(FIFO_CONFIG0));
tr_debug("PCKT_FLT_OPTIONS: %x", rf_read_register(PCKT_FLT_OPTIONS));
tr_debug("PCKT_FLT_GOALS4: %x", rf_read_register(PCKT_FLT_GOALS4));
tr_debug("PCKT_FLT_GOALS3: %x", rf_read_register(PCKT_FLT_GOALS3));
tr_debug("PCKT_FLT_GOALS2: %x", rf_read_register(PCKT_FLT_GOALS2));
tr_debug("PCKT_FLT_GOALS1: %x", rf_read_register(PCKT_FLT_GOALS1));
tr_debug("PCKT_FLT_GOALS0: %x", rf_read_register(PCKT_FLT_GOALS0));
tr_debug("TIMERS5: %x", rf_read_register(TIMERS5));
tr_debug("TIMERS4: %x", rf_read_register(TIMERS4));
tr_debug("TIMERS3: %x", rf_read_register(TIMERS3));
tr_debug("TIMERS2: %x", rf_read_register(TIMERS2));
tr_debug("TIMERS1: %x", rf_read_register(TIMERS1));
tr_debug("TIMERS0: %x", rf_read_register(TIMERS0));
tr_debug("CSMA_CONF3: %x", rf_read_register(CSMA_CONF3));
tr_debug("CSMA_CONF2: %x", rf_read_register(CSMA_CONF2));
tr_debug("CSMA_CONF1: %x", rf_read_register(CSMA_CONF1));
tr_debug("CSMA_CONF0: %x", rf_read_register(CSMA_CONF0));
tr_debug("IRQ_MASK3: %x", rf_read_register(IRQ_MASK3));
tr_debug("IRQ_MASK2: %x", rf_read_register(IRQ_MASK2));
tr_debug("IRQ_MASK1: %x", rf_read_register(IRQ_MASK1));
tr_debug("IRQ_MASK0: %x", rf_read_register(IRQ_MASK0));
tr_debug("FAST_RX_TIMER: %x", rf_read_register(FAST_RX_TIMER));
tr_debug("PA_POWER8: %x", rf_read_register(PA_POWER8));
tr_debug("PA_POWER7: %x", rf_read_register(PA_POWER7));
tr_debug("PA_POWER6: %x", rf_read_register(PA_POWER6));
tr_debug("PA_POWER5: %x", rf_read_register(PA_POWER5));
tr_debug("PA_POWER4: %x", rf_read_register(PA_POWER4));
tr_debug("PA_POWER3: %x", rf_read_register(PA_POWER3));
tr_debug("PA_POWER2: %x", rf_read_register(PA_POWER2));
tr_debug("PA_POWER1: %x", rf_read_register(PA_POWER1));
tr_debug("PA_POWER0: %x", rf_read_register(PA_POWER0));
tr_debug("PA_CONFIG1: %x", rf_read_register(PA_CONFIG1));
tr_debug("PA_CONFIG0: %x", rf_read_register(PA_CONFIG0));
tr_debug("SYNTH_CONFIG2: %x", rf_read_register(SYNTH_CONFIG2));
tr_debug("VCO_CONFIG: %x", rf_read_register(VCO_CONFIG));
tr_debug("VCO_CALIBR_IN2: %x", rf_read_register(VCO_CALIBR_IN2));
tr_debug("VCO_CALIBR_IN1: %x", rf_read_register(VCO_CALIBR_IN1));
tr_debug("VCO_CALIBR_IN0: %x", rf_read_register(VCO_CALIBR_IN0));
tr_debug("XO_RCO_CONF1: %x", rf_read_register(XO_RCO_CONF1));
tr_debug("XO_RCO_CONF0: %x", rf_read_register(XO_RCO_CONF0));
tr_debug("RCO_CALIBR_CONF3: %x", rf_read_register(RCO_CALIBR_CONF3));
tr_debug("RCO_CALIBR_CONF2: %x", rf_read_register(RCO_CALIBR_CONF2));
tr_debug("PM_CONF4: %x", rf_read_register(PM_CONF4));
tr_debug("PM_CONF3: %x", rf_read_register(PM_CONF3));
tr_debug("PM_CONF2: %x", rf_read_register(PM_CONF2));
tr_debug("PM_CONF1: %x", rf_read_register(PM_CONF1));
tr_debug("PM_CONF0: %x", rf_read_register(PM_CONF0));
tr_debug("MC_STATE1: %x", rf_read_register(MC_STATE1));
tr_debug("MC_STATE0: %x", rf_read_register(MC_STATE0));
tr_debug("TX_FIFO_STATUS: %x", rf_read_register(TX_FIFO_STATUS));
tr_debug("RX_FIFO_STATUS: %x", rf_read_register(RX_FIFO_STATUS));
tr_debug("RCO_CALIBR_OUT4: %x", rf_read_register(RCO_CALIBR_OUT4));
tr_debug("RCO_CALIBR_OUT3: %x", rf_read_register(RCO_CALIBR_OUT3));
tr_debug("VCO_CALIBR_OUT1: %x", rf_read_register(VCO_CALIBR_OUT1));
tr_debug("VCO_CALIBR_OUT0: %x", rf_read_register(VCO_CALIBR_OUT0));
tr_debug("TX_PCKT_INFO: %x", rf_read_register(TX_PCKT_INFO));
tr_debug("RX_PCKT_INFO: %x", rf_read_register(RX_PCKT_INFO));
tr_debug("AFC_CORR: %x", rf_read_register(AFC_CORR));
tr_debug("LINK_QUALIF2: %x", rf_read_register(LINK_QUALIF2));
tr_debug("LINK_QUALIF1: %x", rf_read_register(LINK_QUALIF1));
tr_debug("RSSI_LEVEL: %x", rf_read_register(RSSI_LEVEL));
tr_debug("RX_PCKT_LEN1: %x", rf_read_register(RX_PCKT_LEN1));
tr_debug("RX_PCKT_LEN0: %x", rf_read_register(RX_PCKT_LEN0));
tr_debug("CRC_FIELD3: %x", rf_read_register(CRC_FIELD3));
tr_debug("CRC_FIELD2: %x", rf_read_register(CRC_FIELD2));
tr_debug("CRC_FIELD1: %x", rf_read_register(CRC_FIELD1));
tr_debug("CRC_FIELD0: %x", rf_read_register(CRC_FIELD0));
tr_debug("RX_ADDRE_FIELD1: %x", rf_read_register(RX_ADDRE_FIELD1));
tr_debug("RX_ADDRE_FIELD0: %x", rf_read_register(RX_ADDRE_FIELD0));
tr_debug("RSSI_LEVEL_RUN: %x", rf_read_register(RSSI_LEVEL_RUN));
tr_debug("DEVICE_INFO1: %x", rf_read_register(DEVICE_INFO1));
tr_debug("DEVICE_INFO0: %x", rf_read_register(DEVICE_INFO0));
tr_debug("IRQ_STATUS3: %x", rf_read_register(IRQ_STATUS3));
tr_debug("IRQ_STATUS2: %x", rf_read_register(IRQ_STATUS2));
tr_debug("IRQ_STATUS1: %x", rf_read_register(IRQ_STATUS1));
tr_debug("IRQ_STATUS0: %x", rf_read_register(IRQ_STATUS0));
}
#if MBED_CONF_S2LP_PROVIDE_DEFAULT

View File

@ -230,7 +230,7 @@ public:
*/
virtual nsapi_error_t get_attach(AttachStatus &status) = 0;
/** Request detach from a network.
/** Request detach and deregister from a network.
*
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure

View File

@ -72,7 +72,6 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
_previous_at_timeout(timeout),
_at_send_delay(send_delay),
_last_response_stop(0),
_fh_sigio_set(false),
_processing(false),
_ref_count(1),
_is_fh_usable(true),
@ -109,9 +108,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
set_tag(&_info_stop, CRLF);
set_tag(&_elem_stop, ")");
_fileHandle->set_blocking(false);
set_filehandle_sigio();
set_file_handle(fh);
}
void ATHandler::set_debug(bool debug_on)
@ -154,6 +151,8 @@ FileHandle *ATHandler::get_file_handle()
void ATHandler::set_file_handle(FileHandle *fh)
{
_fileHandle = fh;
_fileHandle->set_blocking(false);
set_filehandle_sigio();
}
void ATHandler::set_is_filehandle_usable(bool usable)
@ -312,11 +311,7 @@ void ATHandler::process_oob()
void ATHandler::set_filehandle_sigio()
{
if (_fh_sigio_set) {
return;
}
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
_fh_sigio_set = true;
}
void ATHandler::reset_buffer()
@ -1230,3 +1225,26 @@ void ATHandler::debug_print(const char *p, int len)
}
#endif // MBED_CONF_CELLULAR_DEBUG_AT
}
bool ATHandler::sync(int timeout_ms)
{
tr_debug("AT sync");
// poll for 10 seconds
for (int i = 0; i < 10; i++) {
lock();
set_at_timeout(timeout_ms, false);
// For sync use an AT command that is supported by all modems and likely not used frequently,
// especially a common response like OK could be response to previous request.
cmd_start("AT+CMEE?");
cmd_stop();
resp_start("+CMEE:");
resp_stop();
restore_at_timeout();
unlock();
if (!_last_err) {
return true;
}
}
tr_error("AT sync failed");
return false;
}

View File

@ -181,6 +181,13 @@ public:
*/
void set_is_filehandle_usable(bool usable);
/** Synchronize AT command and response handling to modem.
*
* @param timeout_ms ATHandler timeout when trying to sync. Will be restored when function returns.
* @return true is synchronization was successful, false in case of failure
*/
bool sync(int timeout_ms);
protected:
void event();
#ifdef AT_HANDLER_MUTEX
@ -211,8 +218,6 @@ private:
uint16_t _at_send_delay;
uint64_t _last_response_stop;
bool _fh_sigio_set;
bool _processing;
int32_t _ref_count;
bool _is_fh_usable;

View File

@ -28,6 +28,7 @@
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
#if NSAPI_PPP_AVAILABLE
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
#include "nsapi_ppp.h"
#endif
@ -557,6 +558,8 @@ void AT_CellularContext::do_connect()
tr_error("Failed to open data channel!");
call_network_cb(NSAPI_STATUS_DISCONNECTED);
_is_connected = false;
} else {
_is_context_activated = true;
}
}
#else
@ -630,13 +633,17 @@ nsapi_error_t AT_CellularContext::disconnect()
_at.lock();
_at.set_file_handle(_at.get_file_handle());
_at.set_is_filehandle_usable(true);
//_at.sync(); // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
#endif // NSAPI_PPP_AVAILABLE
_at.lock();
// deactivate a context only if we have activated
if (_is_context_activated) {
// CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000);
_is_context_active = false;
size_t active_contexts_count = 0;
_at.cmd_start("AT+CGACT?");
@ -662,16 +669,26 @@ nsapi_error_t AT_CellularContext::disconnect()
// 3GPP TS 27.007:
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
_at.clear_error();
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
if (_new_context_set) {
_at.clear_error();
_at.cmd_start("AT+CGDCONT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
_at.clear_error();
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.restore_at_timeout();
}
if (!_at.get_last_error()) {
_is_connected = false;
call_network_cb(NSAPI_STATUS_DISCONNECTED);
}
_is_connected = false;
call_network_cb(NSAPI_STATUS_DISCONNECTED);
return _at.unlock_return_error();
}

View File

@ -361,6 +361,9 @@ nsapi_error_t AT_CellularNetwork::detach()
_at.cmd_start("AT+CGATT=0");
_at.cmd_stop_read_resp();
_at.cmd_start("AT+COPS=2");
_at.cmd_stop_read_resp();
call_network_cb(NSAPI_STATUS_DISCONNECTED);
return _at.unlock_return_error();

View File

@ -36,8 +36,8 @@ AT_CellularNetwork::RegistrationMode QUECTEL_BC95_CellularNetwork::has_registrat
nsapi_error_t QUECTEL_BC95_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
{
if (opRat != RAT_NB1) {
//TODO: Set as unknown or force to NB1?
_op_act = RAT_UNKNOWN;
// only rat that is supported by this modem
_op_act = RAT_NB1;
return NSAPI_ERROR_UNSUPPORTED;
}

View File

@ -117,7 +117,6 @@ typedef enum {
// ADC internal channels
ADC_TEMP = 0xF0,
ADC_VREF = 0xF1,
ADC_VBAT = 0xF2,
// Arduino connector namings
A0 = PA_0,

View File

@ -115,7 +115,6 @@ typedef enum {
// ADC internal channels
ADC_TEMP = 0xF0,
ADC_VREF = 0xF1,
ADC_VBAT = 0xF2,
// Arduino connector namings
A0 = PA_0,

View File

@ -30,6 +30,7 @@
**/
#include "stm32f7xx.h"
#include "nvic_addr.h"
#include "mbed_error.h"
/*!< Uncomment the following line if you need to relocate your vector Table in
@ -92,7 +93,7 @@ void SystemInit(void)
#ifdef VECT_TAB_SRAM
SCB->VTOR = RAMDTCM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
SCB->VTOR = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */
#endif
}

View File

@ -100,7 +100,6 @@ typedef enum {
// ADC internal channels
ADC_TEMP = 0xF0,
ADC_VREF = 0xF1,
ADC_VBAT = 0xF2,
// Arduino connector namings
A0 = PA_0,

View File

@ -3460,6 +3460,7 @@
],
"release_versions": ["2", "5"],
"device_name": "STM32F746NG",
"bootloader_supported": true,
"overrides": {
"network-default-interface-type": "ETHERNET"
}
@ -7299,7 +7300,7 @@
"USTICKER"
],
"device_name": "TMPM4G9F15FG",
"detect_code": ["7016"],
"detect_code": ["7015"],
"release_versions": ["5"],
"bootloader_supported": true
},

View File

@ -129,6 +129,9 @@
"STM32F439ZI": {
"OGChipSelectEditMenu": "STM32F439ZI\tST STM32F439ZI"
},
"STM32F439VI": {
"OGChipSelectEditMenu": "STM32F439VI\tST STM32F439VI"
},
"LPC1768": {
"OGChipSelectEditMenu": "LPC1768\tNXP LPC1768"
},