This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Legacy Serial DFU error

I'm developing a C implementation for nrfutil to make a Serial DFU in bootloader of sdk11. But I'm having an issue in serial communication. I've used a serial sniffer to compare what has been sent to the nrf51 chip and both nrfutil and my implementation are sending and receiving the same thing until the first data package is sent. After that the nrfutil receive an aswer and continue the DFU and my implementation don't receive an answer of the bootloader. Is that any special configuration to make the DFU works in serial communication? I'm using a NRF51.d

#include "dfu_serial_legacy.h"
#include <stdio.h>
#include <string.h>
#include "checksum.h"
#include "uart_drv.h"
#include "hci_utils.h"
#include "unistd.h"
uint8_t slip_mark = 0xC0;
uint16_t sequence_number = 0;

uint32_t send_start_packet(uint8_t mode, uint32_t lenght_SD, uint32_t lenght_BL, uint32_t lenght_APP, uart_drv_t *p_uart)
{
    sequence_number = 0;
    dfu_start_packet_t start_packet;
    sequence_number = (sequence_number + 1) % 8;
    start_packet.packet_header = slip_parts_to_four_bytes(sequence_number,
                                                          DATA_INTEGRITY_CHECK_PRESENT,
                                                          RELIABLE_PACKET,
                                                          HCI_PACKET_TYPE,
                                                          (uint8_t)sizeof(dfu_start_packet_t) - 6);
    start_packet.dfu_packet_type = DFU_START_PACKET; // 3
    start_packet.dfu_update_type = mode;
    start_packet.sizeof_sd = lenght_SD;   // size of SoftDevice
    start_packet.sizeof_bl = lenght_BL;   // size of bootloader
    start_packet.sizeof_app = lenght_APP; // size of application

    start_packet.crc_value = crc_16((uint8_t *)&start_packet, (uint8_t)sizeof(dfu_start_packet_t) - 2);
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);
    uart_drv_send(p_uart, (uint8_t *)&start_packet, sizeof(dfu_start_packet_t));
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);

    uint8_t answer[10];
    uint32_t ans_len;
    uint8_t des_len = 6;
    while (des_len != 0)
    {
        uart_drv_receive(p_uart, answer, des_len, &ans_len);
        des_len -= ans_len;
    }
    sleep(10);

    return 0;
}

uint32_t send_init_packet(uint16_t d_tipe, uint16_t d_rev, uint16_t app_version, uint16_t valid_SD_lenght, uint16_t valid_SD, uint16_t img_crc, uart_drv_t *p_uart)
{
    dfu_init_packet_t init_packet;
    sequence_number = (sequence_number + 1) % 8;
    init_packet.packet_header = slip_parts_to_four_bytes(sequence_number,
                                                         DATA_INTEGRITY_CHECK_PRESENT,
                                                         RELIABLE_PACKET,
                                                         HCI_PACKET_TYPE,
                                                         (uint8_t)sizeof(dfu_init_packet_t) - 6);
    // init_packet.packet_header = 0xD7014EDA;
    init_packet.dfu_packet_type = DFU_INIT_PACKET; // 1
    init_packet.device_type = d_tipe;
    init_packet.device_revision = d_rev;
    init_packet.app_version = app_version;
    init_packet.valid_sd_lenght = valid_SD_lenght;
    init_packet.valid_sd = valid_SD;
    init_packet.image_crc = img_crc;
    init_packet.padding = 0x0000;

    init_packet.crc_value = crc_16((uint8_t *)&init_packet, sizeof(dfu_init_packet_t) - 2);
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);
    uart_drv_send(p_uart, (uint8_t *)&init_packet, sizeof(dfu_init_packet_t));
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);

    uint8_t answer[10];
    uint32_t ans_len;
    uint8_t des_len = 6;
    while (des_len != 0)
    {
        uart_drv_receive(p_uart, answer, des_len, &ans_len);
        des_len -= ans_len;
    }
    sleep(1);
    return 0;
}

uint32_t send_data_packet(uint8_t *p_data, uint16_t lenght, uart_drv_t *p_uart)
{
    dfu_data_packet_t data_packet;
    uint8_t aux[600];

    sequence_number = (sequence_number + 1) % 8;
    data_packet.packet_header = slip_parts_to_four_bytes(sequence_number,
                                                         DATA_INTEGRITY_CHECK_PRESENT,
                                                         RELIABLE_PACKET,
                                                         HCI_PACKET_TYPE,
                                                         sizeof(data_packet.dfu_packet_type) + lenght);

    memcpy((uint8_t *)aux, &data_packet.packet_header, sizeof(data_packet.packet_header));

    data_packet.dfu_packet_type = DFU_DATA_PACKET; // 4
    memcpy((uint8_t *)aux + 4, &data_packet.dfu_packet_type, sizeof(data_packet.dfu_packet_type));

    memcpy((uint8_t *)aux + 8, p_data, lenght);

    data_packet.crc_value = crc_16((uint8_t *)aux, lenght + 8);
    memcpy((uint8_t *)aux + 8 + lenght, &data_packet.crc_value, sizeof(data_packet.crc_value));

    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);
    uart_drv_send(p_uart, (uint8_t *)aux, lenght + 10);
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);

    uint8_t answer[10];
    uint32_t ans_len;
    uint8_t des_len = 6;
    while (des_len != 0)
    {
        uart_drv_receive(p_uart, answer, des_len, &ans_len);
        des_len -= ans_len;
    }
    return 0;
}

uint32_t send_stop_packet(uart_drv_t *p_uart)
{
    dfu_stop_packet_t stop_packet;
    sequence_number = (sequence_number + 1) % 8;
    stop_packet.packet_header = slip_parts_to_four_bytes(sequence_number,
                                                         DATA_INTEGRITY_CHECK_PRESENT,
                                                         RELIABLE_PACKET,
                                                         HCI_PACKET_TYPE,
                                                         (uint8_t)sizeof(dfu_stop_packet_t) - 6);
    stop_packet.dfu_packet_type = DFU_STOP_PACKET; // 5
    stop_packet.crc_value = crc_16((uint8_t *)&stop_packet, sizeof(dfu_stop_packet_t) - 2);
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);
    uart_drv_send(p_uart, (uint8_t *)&stop_packet, sizeof(dfu_stop_packet_t));
    uart_drv_send(p_uart, (uint8_t *)&slip_mark, 1);

    uint8_t answer[10];
    uint32_t ans_len;
    uint8_t des_len = 6;
    while (des_len != 0)
    {
        uart_drv_receive(p_uart, answer, des_len, &ans_len);
        des_len -= ans_len;
    }

    return 0;
}

This is the code I'm using to send each packet

Parents Reply Children
No Data
Related