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 "hci.h"
|
||||
|
||||
#include "crc32.h"
|
||||
|
||||
// should go to some common place
|
||||
#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[] = {
|
||||
0,
|
||||
0,
|
||||
@ -74,6 +82,43 @@ static const uint32_t baudrates[] = {
|
||||
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){
|
||||
little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x02));
|
||||
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
|
||||
int i;
|
||||
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){
|
||||
found = i;
|
||||
break;
|
||||
@ -99,10 +144,88 @@ static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buf
|
||||
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 = {
|
||||
"EM9301",
|
||||
NULL, // chipset_init not used
|
||||
NULL, // chipset_next_command not used
|
||||
#ifdef HAVE_EM9304_PATCH_CONTAINER
|
||||
chipset_init,
|
||||
chipset_next_command,
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
chipset_set_baudrate_command,
|
||||
chipset_set_bd_addr_command,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user