Hello,
I face at least 2 problems and need some support.
What I want to achieve is that the DTM runs at our customer hardware for radio and later on BLE certification. 3 years ago we made this with nRF52832 and it was absolutely no problem, that's why I can't really understand the problems I face now.
I have a PCA10056, a nRF52840 Dongle (PCA10059) and my customer hardware with a Taiyo Yuden module using nRF52840. The SW for the nRF52840 is built in Eclipse using gcc; for debugging I use a Segger JTracePro.
As 3 years ago I first tried to use the nRF Connect at my PC with the stick, the old nRF51 stick was compatible and worked well with nRF Connect. In the forum I read that with the nRF52840 Dongle this will not work, so I use the PC10056. I have erased this board and flashed the file direct_test_mode_pca10056.hex from SDK17.1\examples\dtm\direct_test_mode\hex. When powering this board I see a LED flickering; when selecting this board at nRF Connect (in Windows) the flickering changes a little bit; when I click at Start test the LED's behaivour changes a little bit. It seems that this works, but can I make a test with the nRF52840 Dongle for verifying?
Now coming to the main problem: I use a customer elecronics where our standard Software with BLE traffic (using SDK13; soon we will change to Zephyr) runs perfect. So I can assume that the HW is ok. Parallel to our standard project I have created a DTM project; here I use SDK17.1 to be sure that we meet the latest requirements for the radio certification. I have created a custom_board.h file which just contains:
#define LEDS_NUMBER 0
#define BUTTONS_NUMBER 0
#define RX_PIN_NUMBER 12
#define TX_PIN_NUMBER 17
#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED // 8
#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED // 30
#define HWFC false
RX is connected to P0.12 and Tx to P0.17.
I can build the project; when setting a breakpoint to the first line current_time = dtm_wait();in the endless-loop for (;;) the system behaves as expected. Pressing then several times F6 (Step over) will result in toggling between the mentioned current_time = dtm_wait() line and the next if(app_uart_get(&rx_byte) != NRF_SUCCESS) instruction; this seems still fine for me. When I press then 'Run' I see the supply current heavily increasing to about 4 times of the current before; when I start a test in nRF Connect I see just the same as if the customer board is switched off. When pressing 'Suspend' the program flow stops at the if(nrf_timer_event_check(..) function in dtm_wait().
A breakpoint set to the last line SystemCoreClockUpdate(); in void SystemInit(void) in system_nrf52.c is never reached...
What is here wrong?
Thanks in advance for your help
Best regards,
MatthK
Here is my main() function, copied from the SDK17.1:
int main(void)
{
uint32_t dtm_error_code;
uint32_t current_time;
uint32_t msb_time = 0; // Time when MSB of the DTM command was read. Used to catch stray bytes from "misbehaving" testers.
bool is_msb_read = false; // True when MSB of the DTM command has been read and the application is waiting for LSB.
uint16_t dtm_cmd_from_uart = 0; // Packed command containing command_code:freqency:length:payload in 2:6:6:2 bits.
uint8_t rx_byte; // Last byte read from UART.
dtm_event_t result; // Result of a DTM operation.
bsp_board_init(BSP_INIT_LEDS);
uart_init();
dtm_error_code = dtm_init();
#if defined(NRF21540_DRIVER_ENABLE) && (NRF21540_DRIVER_ENABLE == 1)
//Initialization of nRF21540 front-end Bluetooth range extender chip. Do not use if your hardware doesn't support it.
APP_ERROR_CHECK(nrf21540_init());
#endif
if (dtm_error_code != DTM_SUCCESS)
{
// If DTM cannot be correctly initialized, then we just return.
return -1;
}
for (;;)
{
// Will return every UART pool timeout,
current_time = dtm_wait();
if (app_uart_get(&rx_byte) != NRF_SUCCESS)
{
// Nothing read from the UART.
continue;
}
if (!is_msb_read)
{
// This is first byte of two-byte command.
is_msb_read = true;
dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
msb_time = current_time;
// Go back and wait for 2nd byte of command word.
continue;
}
// This is the second byte read; combine it with the first and process command
if (current_time > (msb_time + MAX_ITERATIONS_NEEDED_FOR_NEXT_BYTE))
{
// More than ~5mS after msb: Drop old byte, take the new byte as MSB.
// The variable is_msb_read will remains true.
// Go back and wait for 2nd byte of the command word.
dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
msb_time = current_time;
continue;
}
// 2-byte UART command received.
is_msb_read = false;
dtm_cmd_from_uart |= (dtm_cmd_t)rx_byte;
if (dtm_cmd(dtm_cmd_from_uart) != DTM_SUCCESS)
{
// Extended error handling may be put here.
// Default behavior is to return the event on the UART (see below);
// the event report will reflect any lack of success.
}
// Retrieve result of the operation. This implementation will busy-loop
// for the duration of the byte transmissions on the UART.
if (dtm_event_get(&result))
{
// Report command status on the UART.
// Transmit MSB of the result.
while (app_uart_put((result >> 8) & 0xFF));
// Transmit LSB of the result.
while (app_uart_put(result & 0xFF));
}
}
}