mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-21 21:41:13 +00:00
em9304: upload container blob if HAVE_EM9304_PATCH_CONTAINER
This commit is contained in:
parent
1005167dec
commit
d080547ccf
@ -53,9 +53,17 @@
|
|||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include "hci.h"
|
#include "hci.h"
|
||||||
|
|
||||||
|
#include "crc32.h"
|
||||||
|
|
||||||
// should go to some common place
|
// should go to some common place
|
||||||
#define OPCODE(ogf, ocf) (ocf | ogf << 10)
|
#define OPCODE(ogf, ocf) (ocf | ogf << 10)
|
||||||
|
|
||||||
|
#define HCI_OPCODE_EM_WRITE_PATCH_START (0xFC27)
|
||||||
|
#define HCI_OPCODE_EM_WRITE_PATCH_CONTINUE (0xFC28)
|
||||||
|
#define HCI_OPCODE_EM_WRITE_PATCH_ABORT (0xFC29)
|
||||||
|
#define HCI_OPCODE_EM_CPU_RESET (0xFC32)
|
||||||
|
#define HCI_OPCODE_EM_PATCH_QUERY (0xFC34)
|
||||||
|
|
||||||
static const uint32_t baudrates[] = {
|
static const uint32_t baudrates[] = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -74,6 +82,43 @@ static const uint32_t baudrates[] = {
|
|||||||
1843200,
|
1843200,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// crc32 from 802.3 without table lookup to minimize code
|
||||||
|
uint32_t crc32(const uint8_t *data, uint16_t len) {
|
||||||
|
int i, j;
|
||||||
|
uint32_t byte, crc, mask;
|
||||||
|
crc = 0xFFFFFFFF;
|
||||||
|
for (i=0;i<len;i++){
|
||||||
|
byte = data[i];
|
||||||
|
crc = crc ^ byte;
|
||||||
|
for (j = 7; j >= 0; j--) {
|
||||||
|
mask = -(crc & 1);
|
||||||
|
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
||||||
|
}
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_EM9304_PATCH_CONTAINER
|
||||||
|
|
||||||
|
extern const uint8_t container_blob_data[];
|
||||||
|
extern const uint32_t container_blob_size;
|
||||||
|
|
||||||
|
static uint32_t container_blob_offset = 0;
|
||||||
|
static uint32_t container_end; // current container
|
||||||
|
static uint16_t patch_sequence_number;
|
||||||
|
static int em_cpu_reset_sent;
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
UPLOAD_IDLE,
|
||||||
|
UPLOAD_ACTIVE,
|
||||||
|
} upload_state;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
|
static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
|
||||||
little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x02));
|
little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x02));
|
||||||
hci_cmd_buffer[2] = 0x06;
|
hci_cmd_buffer[2] = 0x06;
|
||||||
@ -84,7 +129,7 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
|
|||||||
// lookup baudrates
|
// lookup baudrates
|
||||||
int i;
|
int i;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (i=0;i < sizeof(baudrates)/sizeof(uint32_t);i++){
|
for (i=0 ; i < sizeof(baudrates)/sizeof(uint32_t) ; i++){
|
||||||
if (baudrates[i] == baudrate){
|
if (baudrates[i] == baudrate){
|
||||||
found = i;
|
found = i;
|
||||||
break;
|
break;
|
||||||
@ -99,10 +144,88 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
|
|||||||
hci_cmd_buffer[3] = i;
|
hci_cmd_buffer[3] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_EM9304_PATCH_CONTAINER
|
||||||
|
static void chipset_init(const void * config){
|
||||||
|
UNUSED(config);
|
||||||
|
container_blob_offset = 0;
|
||||||
|
em_cpu_reset_sent = 0;
|
||||||
|
upload_state = UPLOAD_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
|
||||||
|
log_info("pos %u, container end %u, blob size %u", container_blob_offset, container_end, container_blob_size);
|
||||||
|
|
||||||
|
if (container_blob_offset >= container_blob_size) {
|
||||||
|
if (0 == em_cpu_reset_sent){
|
||||||
|
// send EM CPU Reset
|
||||||
|
little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_CPU_RESET);
|
||||||
|
hci_cmd_buffer[2] = 0;
|
||||||
|
em_cpu_reset_sent = 1;
|
||||||
|
return BTSTACK_CHIPSET_VALID_COMMAND;
|
||||||
|
} else {
|
||||||
|
return BTSTACK_CHIPSET_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tag;
|
||||||
|
uint16_t bytes_to_upload;
|
||||||
|
uint32_t crc;
|
||||||
|
|
||||||
|
switch (upload_state){
|
||||||
|
case UPLOAD_IDLE:
|
||||||
|
// check for 'em93' tag
|
||||||
|
tag = little_endian_read_32(container_blob_data, container_blob_offset);
|
||||||
|
if (0x656d3933 != tag) {
|
||||||
|
log_error("Expected 0x656d3933 ('em934') but got %08x", tag);
|
||||||
|
return BTSTACK_CHIPSET_DONE;
|
||||||
|
}
|
||||||
|
// fetch info for current container
|
||||||
|
container_end = container_blob_offset + little_endian_read_32(container_blob_data, container_blob_offset + 4);
|
||||||
|
// start uploading (<= 59 bytes)
|
||||||
|
patch_sequence_number = 1;
|
||||||
|
bytes_to_upload = btstack_min(59, container_end - container_blob_offset);
|
||||||
|
crc = crc32(&container_blob_data[container_blob_offset], bytes_to_upload);
|
||||||
|
// build command
|
||||||
|
little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_WRITE_PATCH_START);
|
||||||
|
hci_cmd_buffer[2] = 5 + bytes_to_upload;
|
||||||
|
hci_cmd_buffer[3] = 0; // upload to iRAM1
|
||||||
|
little_endian_store_32(hci_cmd_buffer, 4, crc);
|
||||||
|
memcpy(&hci_cmd_buffer[8], &container_blob_data[container_blob_offset], bytes_to_upload);
|
||||||
|
container_blob_offset += bytes_to_upload;
|
||||||
|
if (container_blob_offset < container_end){
|
||||||
|
upload_state = UPLOAD_ACTIVE;
|
||||||
|
}
|
||||||
|
return BTSTACK_CHIPSET_VALID_COMMAND;
|
||||||
|
case UPLOAD_ACTIVE:
|
||||||
|
// Upload next segement
|
||||||
|
bytes_to_upload = btstack_min(58, container_end - container_blob_offset);
|
||||||
|
crc = crc32(&container_blob_data[container_blob_offset], bytes_to_upload);
|
||||||
|
// build command
|
||||||
|
little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_WRITE_PATCH_CONTINUE);
|
||||||
|
hci_cmd_buffer[2] = 6 + bytes_to_upload;
|
||||||
|
little_endian_store_16(hci_cmd_buffer, 3, patch_sequence_number++);
|
||||||
|
little_endian_store_32(hci_cmd_buffer, 5, crc);
|
||||||
|
memcpy(&hci_cmd_buffer[9], &container_blob_data[container_blob_offset], bytes_to_upload);
|
||||||
|
container_blob_offset += bytes_to_upload;
|
||||||
|
if (container_blob_offset >= container_end){
|
||||||
|
log_info("container done maybe another one");
|
||||||
|
upload_state = UPLOAD_IDLE;
|
||||||
|
}
|
||||||
|
return BTSTACK_CHIPSET_VALID_COMMAND;
|
||||||
|
}
|
||||||
|
return BTSTACK_CHIPSET_DONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const btstack_chipset_t btstack_chipset_em9301 = {
|
static const btstack_chipset_t btstack_chipset_em9301 = {
|
||||||
"EM9301",
|
"EM9301",
|
||||||
NULL, // chipset_init not used
|
#ifdef HAVE_EM9304_PATCH_CONTAINER
|
||||||
NULL, // chipset_next_command not used
|
chipset_init,
|
||||||
|
chipset_next_command,
|
||||||
|
#else
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
chipset_set_baudrate_command,
|
chipset_set_baudrate_command,
|
||||||
chipset_set_bd_addr_command,
|
chipset_set_bd_addr_command,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user