#include "fr30xx.h" #include "FreeRTOS.h" #include "SWD.h" #include "fdb_app.h" #include "controller.h" #define CONTROLLER_CODE_SPLIT #define HCI_UART UART0 #define HCI_UART_IRQn UART0_IRQn #define CONTROLLER_PARAM_DUMMY 0x00 #define CONTROLLER_PARAM_BAUDRATE 0x01 #define CONTROLLER_PARAM_KEY 0x02 #define CONTROLLER_PARAM_BT_ADDR 0x03 #define CONTROLLER_PARAM_BLE_ADDR 0x04 static const uint8_t app_boot_conn_req[] = {'f','r','e','q','c','h','i','p'};//from embedded to pc, request static const uint8_t app_boot_conn_ack[] = {'F','R','1','0','1','0','O','K'};//from pc to embedded,ack static const uint8_t app_boot_conn_success[] = {'o','k'}; static const uint8_t controller_param_header[] = {'f', 'r', 'e', 'q'}; static const uint8_t controller_param_tail[] = {'c', 'h', 'i', 'p'}; ///default feature //static uint8_t bt_feature_param[] = { // 0x41,0x08, // 0xaf,0x2a,0x4d,0xde,0xc3,0x2f,0x5b,0x87, //}; static uint8_t btdm_internal_param[] = { ///bt_feature:disable 3M(Byte3,bit3),0xde->0xda 0x41,0x08, 0xaf,0x2a,0x4d,0xda,0xc3,0x2f,0x5b,0x87, ///to add }; /* hardware handlers */ static UART_HandleTypeDef HCI_handle; bool controller_start(uint32_t baudrate, const uint8_t *ble_addr, const uint8_t *bt_addr, uint32_t src_addr) { GPIO_InitTypeDef gpio_config; uint8_t buffer[8]; uint32_t length; uint8_t *src, *dst; uint16_t tx_length; uint8_t opcode, param_type; struct { uint32_t dst; uint32_t len; } header; src_addr += 0x10; /* configure PA0, PA1, PA2, PA3 to UART0 function */ gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; gpio_config.Mode = GPIO_MODE_AF_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_1; gpio_init(GPIOA, &gpio_config); /* UART0: used for Log and AT command */ __SYSTEM_UART0_CLK_ENABLE(); HCI_handle.UARTx = HCI_UART; HCI_handle.Init.BaudRate = 115200; HCI_handle.Init.DataLength = UART_DATA_LENGTH_8BIT; HCI_handle.Init.StopBits = UART_STOPBITS_1; HCI_handle.Init.Parity = UART_PARITY_NONE; HCI_handle.Init.FIFO_Mode = UART_FIFO_ENABLE; HCI_handle.TxCpltCallback = NULL; HCI_handle.RxCpltCallback = NULL; uart_init(&HCI_handle); /* keep RTS is inactive before HCI is ready */ __UART_AUTO_FLOW_CONTROL_DISABLE(HCI_handle.UARTx); __UART_RTS_INACTIVE(HCI_handle.UARTx); /* reset controller */ /* configure PA15 GPIO function */ __SYSTEM_GPIOA_CLK_ENABLE(); gpio_config.Pin = GPIO_PIN_15; gpio_config.Mode = GPIO_MODE_OUTPUT_PP; gpio_config.Pull = GPIO_PULLUP; gpio_config.Alternate = GPIO_FUNCTION_0; gpio_init(GPIOA, &gpio_config); gpio_write_pin(GPIOA, GPIO_PIN_15, 0); system_delay_us(3000); gpio_write_pin(GPIOA, GPIO_PIN_15, 1); /* change PA15 to input mode, used to avoid current leakage */ gpio_config.Pin = GPIO_PIN_15; gpio_config.Mode = GPIO_MODE_INPUT; gpio_config.Pull = GPIO_NOPULL; gpio_config.Alternate = GPIO_FUNCTION_0; gpio_init(GPIOA, &gpio_config); /* hand shake with controller */ uart_receive(&HCI_handle, buffer, 8); while (memcmp(buffer, app_boot_conn_req, 8)) { memcpy(&buffer[0], &buffer[1], 7); uart_receive(&HCI_handle, &buffer[7], 1); } uart_transmit(&HCI_handle, (void *)app_boot_conn_ack, 8); uart_receive(&HCI_handle, buffer, 2); if (memcmp(buffer, app_boot_conn_success, 2)) { return false; } /* SWD Enable RAM */ SWD_W_SystemReg(); /* change uart baudrate */ opcode = 0x12; buffer[0] = 11; // 921600 buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&buffer, 6); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x13) { return false; } HCI_handle.Init.BaudRate = 921600; uart_config_baudRate(&HCI_handle); system_delay_us(5000); memcpy((void *)&header, (void *)src_addr, sizeof(header)); src_addr += sizeof(header); /* write code into RAM */ opcode = 0x04; src = (void *)src_addr; dst = (void *)header.dst; length = header.len; while (length) { tx_length = length > 256 ? 256 : length; uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); uart_transmit(&HCI_handle, (void *)&tx_length, 2); uart_transmit(&HCI_handle, src, tx_length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } length -= tx_length; src += tx_length; dst += tx_length; } src_addr += header.len; /* write parameters to exchange memory */ opcode = 0x04; dst = (void *)0x40014000; /* write header to remote device */ uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = sizeof(controller_param_header); dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&controller_param_header[0], length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } /* write baudrate to remote device */ uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = sizeof(baudrate) + 1 + 2; dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); param_type = CONTROLLER_PARAM_BAUDRATE; uart_transmit(&HCI_handle, (void *)¶m_type, 1); length = sizeof(baudrate); uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&baudrate, length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } /* write keys to remote device */ length = flashdb_get_length(FDB_KEY_CONTROLLER_INFO) + sizeof(btdm_internal_param); if (length) { uint8_t *tmp = pvPortMalloc(length); uint16_t sub_length = length; uint16_t key_len = length - sizeof(btdm_internal_param); if(key_len){ flashdb_get(FDB_KEY_CONTROLLER_INFO, tmp, key_len); memcpy(&tmp[key_len],btdm_internal_param,sizeof(btdm_internal_param)); } else{ memcpy(&tmp[0],btdm_internal_param,sizeof(btdm_internal_param)); } uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = sub_length + 1 + 2; dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); param_type = CONTROLLER_PARAM_KEY; uart_transmit(&HCI_handle, (void *)¶m_type, 1); length = sub_length; uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&tmp[0], length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { vPortFree(tmp); return false; } vPortFree(tmp); } /* write bt address to remote device */ uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = 6 + 1 + 2; dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); param_type = CONTROLLER_PARAM_BT_ADDR; uart_transmit(&HCI_handle, (void *)¶m_type, 1); length = 6; uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&bt_addr[0], length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } /* write parameter to remote device */ uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = 6 + 1 + 2; dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); param_type = CONTROLLER_PARAM_BLE_ADDR; uart_transmit(&HCI_handle, (void *)¶m_type, 1); length = 6; uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&ble_addr[0], length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } /* write tail to remote device */ uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); length = sizeof(controller_param_tail); dst += length; uart_transmit(&HCI_handle, (void *)&length, 2); uart_transmit(&HCI_handle, (void *)&controller_param_tail[0], length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } /* boot from RAM */ opcode = 0x2b; dst = (void *)header.dst; tx_length = 0; uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); uart_transmit(&HCI_handle, (void *)&tx_length, 2); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x2c) { return false; } memcpy((void *)&header, (void *)src_addr, sizeof(header)); src_addr += sizeof(header); system_delay_us(50000); opcode = 0x04; if (header.len) { src = (void *)src_addr; dst = (void *)header.dst; length = header.len; while (length) { tx_length = length > 256 ? 256 : length; uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); uart_transmit(&HCI_handle, (void *)&tx_length, 2); uart_transmit(&HCI_handle, src, tx_length); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x05) { return false; } length -= tx_length; src += tx_length; dst += tx_length; } src_addr += header.len; /* disconnect */ opcode = 0x10; dst = (void *)1; /* normal disconnect */ tx_length = 0; uart_transmit(&HCI_handle, (void *)&opcode, 1); uart_transmit(&HCI_handle, (void *)&dst, 4); uart_transmit(&HCI_handle, (void *)&tx_length, 2); uart_receive(&HCI_handle, buffer, 7); if (buffer[0] != 0x11) { return false; } } return true; }