Hi MT_dialog,
Recap from my last posthttp://support.dialog-semiconductor.com/dsps-large-current-consumption, may I continue to ask the question how to achieve low current consumption in DSPS project?
I'm using official DA14580EVKT-B now. I have tested the current consumption by using HW or SW flow control. If HW flow control is used, the current consumption is below 1mA. If SW flow control is used, the current consumption is nearly 2.x mA. Because the limitation of I/O pins of MCU master, I can't use the approach of HW flow control. But the current consumption of using SW flow control is still quite high, how to lower the current consumption below 1mA?
Also, if I configure UART1_TX, UART1_RX, UART1_RTS & UART1_CTS to port 2, 2mA more current will be consumed, please kindly advise.
Thanks.
Hi Jackiechau,
利用SW流控制其耗费更多权力的罪ce you have to be awake more often in order send the flow control signals, wait for additional bytes to receive etc, the SW flow control is more elaborated than the HW flow control and keeps the 580 awake more frequently. You can't reduce the power consumption, since if you do there are going to be sideffects of loosing data. The DSPS is allready optimized from power consumption perspective as long as it doesn't compromizes the data send, with some limitations as well when operating in sleep mode that are mentioned in the DSPS application note.
On which pins on port 2 you placed the UART pins?
Thanks MT_dialog
Hi MT_dialog,
Actually I have undefined h/w & s/w flow control, and would like to use a GPIO of external MCU to wake up 14580 for data reception and transmission later (rising edge to wake up 14580 and falling edge to let it sleep). All features of 14580 have been implemented but the current consumption is around 1x mA. Would you mind if I send you my whole project's source codes and you help me to take a look? Thanks.
Hi MT_dialog,
In my project, 14580 broadcasts SSID periodically and receives data from external MCU via UART1. Because it always consumes 1x mA current after undefined h/w and s/w flow control (UART TX and RX FIFO should be empty),
1. Can I force 14580 to sleep mode after broadcasting SSID? How to do it?
2. One of GPIO of 14580 is configured as interrupt pin to detect logic high or low, if logic high is detected, 14580 is forced to active forever. If logic low is detected, 14580 is forced to sleep. Is it possible to do it? Should I use app_force_active_mode and app_restore_sleep_mode?
3. If h/w flow control must be defined in order that 14580 can be entered into sleep mode (I think h/w flow control and whether 14580 can be slept shouldn't be related), according to AN-B-026, can I use a "GPIO 1" of external MCU to provide a reset pulse to CTS of 14580 in order to wake up 14580, and use "GPIO 2" of external MCU to detect the lower edge of RTS of 14580 in order to transmit and receive data?
Thanks.
Hi Jackiechau,
1)你的意思是设置你的设备在永恒的睡眠智慧hout advertising or just enable the sleeping feature ? You can issue a stop advertising command after the SSID is sent and set a timer or a push button in order for your device to wake up (that will put your device in permanent sleep, you will also have to set the device in a sleep mode by invoking) arch_set_extended_sleep() or you can just invoke the arch_set_extended_sleep() and dynamically change the sleep mode (this will set your device in sleep mode between advertising).
2) app_force_active_mode()和app_restore_sleep_mode() lets you toggle between sleep modes that different tasks have requested, it keeps count from different invcations of the app_force_active_mode() and when each task invokes the restore_sleep() it reduces the count, when the count is zero the device can freelly fall to sleep, you can find the function's documentation in the UM-B-006 document. The arch_set_extended_sleep (SDK5) or app_set_extended_sleep (SDK3) can force the device immidiatelly to be set in the sleep mode.
3) The DSPS isn't designed to work without flow control due to data loss, the sleep and the flow control are deeply related since the DSPS doesn't implement external wakeup, when the device falls to sleep it keeps the RTS high in order to prevent the external MCU from sending any data.If data are sent while the 580 is sleeping, there will be data loss. Yes, i suppose that you can implement a case where the 580 will use flow control and also the external MCU will trigger the 580 to wake up and wait until the 580 is ready in order to start sending data.
The local team will contact you via your registered email address.
Thanks MT_dialog
Hi MT_DIALOG,
I will contact your distributer next week but I would like to know why master Mcu can't wake up BLE by RTS if hardware flow control is defined and ext_sleep is enabled. When ext_sleep is disabled, I check CTS interrupt can be triggered and correct data can be received, it seems BLE can't be woke up, please kindly advise.
Hi jackiechau,
The DSPS as is, doesn't implement, by design, external wake up via the wake up controller, it just wakes up in regural intervals in order to keep the connection alive, when it is awake it pulls low its RTS in order for the other side to know that it is awake and that is capable of receiving data. You will have to enable the external wake up controller and set it to the appropriate pin in order to wake up via the RTS signal of your MCU and also will need further modifications in order to override the previous functionallity and adapt the wakeup via interrupt.
Thanks MT_dialog
Hi MT_DIALOG,
You mentioned
1. I found "Enable wake up controller" by EXTERNAL_WAKEUP but do you mean RTS of master Mcu should also connect to another pin of BLE, BLE sleep can be disabled in this gpio interrupt handler and BLE sleep can be enabled somewhere?
2. Futher modification, please provide the example.
Thanks.
Hi MT_dialog,
Refer tohttp://support.dialog-semiconductor.com/dsps-use-gpio-control-its-extend..., I have followed the smart tag reference design in the app_button_press_cb() function, connected RTS of master MCU to P1_0 for external wake up interrupt and reserved P0_2 for CTS of BLE. However, it seemed BLE couldn't be woke up and nothing was printed in app_cts_logi_high_cb(void).
In periph_setup.c
void GPIO_reservations(void)
{
RESERVE_GPIO( PUSH_BUTTON, GPIO_PORT_1, GPIO_PIN_0, PID_GPIO);
RESERVE_GPIO( UART1_TX, UART1_TX_PORT, UART1_TX_PIN, PID_UART1_TX);
RESERVE_GPIO( UART1_RX, UART1_RX_PORT, UART1_RX_PIN, PID_UART1_RX);
#if (UART_HW_FLOW_ENABLED)
RESERVE_GPIO( UART1_RTS, UART1_RTS_PORT, UART1_RTS_PIN, PID_UART1_RTSN);
RESERVE_GPIO( UART1_CTS, UART1_CTS_PORT, UART1_CTS_PIN, PID_UART1_CTSN);
#endif /*UART_HW_FLOW_ENABLED*/
//reserve for UART2 debug
RESERVE_GPIO( UART2_TX, UART2_TX_PORT, UART2_TX_PIN, PID_UART2_TX);
RESERVE_GPIO( UART2_RX, UART2_RX_PORT, UART2_RX_PIN, PID_UART2_RX);
}
#endif //DEVELOPMENT_DEBUG
/**
****************************************************************************************
* @brief Map port pins
*
* The Uart and SPI port pins and GPIO ports are mapped
****************************************************************************************
*/
void set_pad_functions(void) // set gpio port function mode
{
GPIO_ConfigurePin( GPIO_PORT_1, GPIO_PIN_0, INPUT_PULLDOWN, PID_GPIO, false);
GPIO_ConfigurePin( UART1_TX_PORT, UART1_TX_PIN, OUTPUT, PID_UART1_TX, false );
GPIO_ConfigurePin( UART1_RX_PORT, UART1_RX_PIN, INPUT_PULLUP, PID_UART1_RX, false );
#if (UART_HW_FLOW_ENABLED)
GPIO_ConfigurePin( UART1_RTS_PORT, UART1_RTS_PIN, OUTPUT, PID_UART1_RTSN, false );
GPIO_ConfigurePin( UART1_CTS_PORT, UART1_CTS_PIN, INPUT_PULLUP, PID_UART1_CTSN, false );
#endif /*UART_HW_FLOW_ENABLED*/
//Init pads
GPIO_ConfigurePin(UART2_TX_PORT, UART2_TX_PIN, OUTPUT, PID_UART2_TX, false);
GPIO_ConfigurePin(UART2_RX_PORT, UART2_RX_PIN, INPUT, PID_UART2_RX, false);
/*
* Configure application ports.
i.e.
GPIO_ConfigurePin( GPIO_PORT_0, GPIO_PIN_1, OUTPUT, PID_GPIO, false ); // Set P_01 as Generic purpose Output
*/
}
app_sps_device_project.c
void app_cts_logic_high_cb(void)
{
if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
periph_init();
printf_string("\r\napp_cts_logic_high_cb\r\n");
/* Button is pressed, start 3sec gurd timer to detect button long press
** and revert polarity on the button GPIO to detect the release
*/
wkupct_register_callback(app_cts_logic_low_cb);
wkupct_enable_irq(0x100, 0x100, 1, 0x14); // P1_0, polarity low, 1 event, debouncing time = 20ms
app_button_status = 1;
if( ke_state_get(TASK_APP) == APP_CONNECTABLE )
{
//Wakeup BLE only if we are in advertising mode. Only in ADV mode the user can clear the bonding data.
app_ble_force_wakeup();
app_ble_ext_wakeup_off();
// Send message to TASK_APP. We should set the timer APP_BUTTON_PRESS_TIMER when BLE is awake
ke_msg_send_basic(APP_WAKEUP_MSG, TASK_APP, NULL);
}
}
void app_cts_logic_low_cb(void)
{
if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
periph_init();
printf_string("\r\napp_cts_logic_low_cb\r\n");
//Button is released, stop APP_BUTTON_PRESS_TIMER gurd timer
//and revert polarity on the button GPIO to detect the button press
wkupct_register_callback(app_cts_logic_high_cb);
wkupct_enable_irq(0x100, 0x000, 1, 0x14); // P1_0, polarity high, 1 event, debouncing time = 20ms
app_button_status = 0;
if( ke_state_get(TASK_APP) == APP_CONNECTABLE )
{
//Wakeup BLE only if we are in advertising mode. Only in ADV mode the user can clear the bonding data.
app_ble_force_wakeup();
app_ble_ext_wakeup_off();
// Send message to TASK_APP. We should clear the timer APP_BUTTON_PRESS_TIMER when BLE is awake
ke_msg_send_basic(APP_WAKEUP_MSG, TASK_APP, NULL);
}
}
void app_init_func(void)
{
app_set_rxirq_threshold(BLE_RX_BUFFER_CNT/4);
app_sps_init();
printf_string("\n\rapp_init_func\r\n");
wkupct_register_callback(app_cts_logic_high_cb);
wkupct_enable_irq(0x100, 0x000, 1, 0x14); // P1_0, polarity high, 1 event, debouncing time = 20ms
}
int app_wakeup_handler(ke_msg_id_t const msgid,
void *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// If state is not idle, ignore the message
if (ke_state_get(dest_id) == APP_CONNECTABLE)
{
/* Check if reason of wake up was button press or release and set or clear the long press timer.
** Note this should only happen when the device is advertising and not connected
*/
if( app_button_status )
{
app_timer_set(APP_BUTTON_PRESS_TIMER, TASK_APP, 300);
}
else
{
ke_timer_clear(APP_BUTTON_PRESS_TIMER, TASK_APP);
}
/*if( adv_count == 0 )
{
restart_adv = 0;
app_adv_start();
}*/
}
return (KE_MSG_CONSUMED);
}
int app_button_press_timer_handler( ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
/*if( GPIO_GetPinStatus( GPIO_BUTTON_PORT, GPIO_BUTTON_PIN ) )
{
// Clear bonding data from non-vlolatile memory
app_clear_bond_data();
// Play a tone to indicate that the bonding data have been deleted
app_proxr_pwm_enable(button_pwm_callback);
systick_usec_units(false);
systick_wait(APP_PWM_DISABLE_DELAY);
app_proxr_pwm_disable();
}*/
return (KE_MSG_CONSUMED);
}
Hi jackiechau,
A few comments regarding the code you ve pasted, the wakeup controller has a debouncing time of 20ms, if you are toggling the RTS of your MCU perhaps because of the debouncing time the wakeup interrupt is not triggered. To make sure that the device is taking the interrupt and wakes up, you can use the arch_set_pxact_gpio() function in the wake up callback and check if the interrupt is triggred in smart snippets (you should see a red vertical line when the function pxact is called). Also when the BLE is in sleep mode you can't use the UART immediately after wake up, since after waking up the 580 operates with the RC16 oscillator, this wont allow you to use the UART properly and you will have to switch to the XTAL16 before using the UART and off cource wait for the XTAL to settle.
You can find more information regarding the wakeup controller in the UM-B-051 document in the peripheral drivers section.
Thanks MT_dialog
Hi MT_dialog,
1. I'm using basic kit and burning image into EVB by smartsnippets, can I still see the red vertical line if function pxact is called? If so, which layout of smartsnippets should be used such that I can see the red vertical line? If basic kit can't show this line, what can I do to prove the system wakes up?
Also, should I shorten the debouncing time parameter of wkupct_enable_irq() and increase the toggle time of MCU's RTS signal?
2. If wkupct_register_callback and wkupct_enable_irq aren't called, and original api gpio0_callback() of periph_setup.c will be triggered if master MCU toggles its RTS signal, it's quite weird that dialog can receive and transmit data to master MCU. However, if app_timer_set(SPS_TIMER,TASK_APP, 100) is called per 1 second, nothing can be received or transmitted from dialog side. Is it still related to the wakeup issue?
Thanks.
Hi jackiechau,
1) Unfortunatelly not, if you are using the basic kit it doesn't support the power profiler, you can try to toggle the LED when waking up from sleep, this might be a bit tricky since the DSPS might trace that there are no data to send so it will fall back to sleep and when waking up will switch the led off, so you have to set a variable in the interrupt routine and when waking up check the variable in the periph_init to see if the pin was set or not, besides that, you can set the pin and trace it with an analyser in order to verify that your device wakes up. Yes shorten your debounce parameter, since your are using a pulse from an external proccessor a 20ms debounce time is not going to do any good, just set the debounce time to 0.
2) gpio0_callback()是一个平凡的中断,this interrupt can only be called when the system is awake, when the 580 is in sleep mode this interrupt is not going to wake up the system. When sleeping only the interrupt from the wake up timer can wake up the 580. There is no relation between the kernel timers and the wakeup timer.
Thanks MT_dialog
Hi MT_dialog,
Thanks for your help, it's done. But in my source code, I just wonder why I need to add several ms delay in gpio0_callback(), app_cts_logic_high_cb() and app_cts_logic_low_cb() in order that master MCU can transmit and receive UART data from 14580.
Hi jackiechau,
When the interrupt hits it takes some time for the waking up of the 580, it doesn't wake up instantly, it takes time until the XTAL switching and settling are proper.
Thanks MT_dialog
Hi MT_dialog,
I would like to know how to turn off radio before app_adv_start and turn on if in need, can I call SetBits16(PMU_CTRL_REG, RADIO_SLEEP) to on and off directly? Thanks.
BR,
Jackie
Hi jackiechau,
The radio is off when the device is not advertising, when you invoke app_adv_start the SDK and the BLE stack will switch on and off the radio when its time to receive/transmit data according to the advertising interval that you set, the same applies while you are connected.
Thanks MT_dialog