cancel
Showing results for 
Search instead for 
Did you mean: 

How to convert BLE_TransparentModeVCP to use USART

AClif
Associate III

I have made my own board using the STM32WB55CGU processor (the 48 pin package, as used on the Nucleo Dongle, MB1293C.

I am now trying to get the BLE working and tuned. The first step, it seems, is to load the transparent mode firmware into the chip which passes the USART TX & RX through to the BLE stack. It seems the firmware in the title should do this, but it is currently using the VCP, and I don't have the USB broken out on my board, so I can't use this. I do, however, have the USART coming out.

Is there a simple way of switching this over to the USART in the sample code? I am using the STM32CubeIDE, and have imported the project, but it does not include the CubeMX file.

2 REPLIES 2
HRadt.1
Senior

I ended up rolling my own solution by calling hci_send_req(..)

#define OGF(hci_packet) (hci_packet[1] >> 2)
#define OCF(hci_packet) (hci_packet[0] | ((hci_packet[1] & 0x03) << 8))
 
extern UART_HandleTypeDef huart1;
 
tBleStatus genericHciCommand(uint8_t *hci_packet, uint8_t packet_length,
		uint8_t *ret_buffer, uint8_t *ret_buffer_len) {
	struct hci_request rq;
	tBleStatus *status = &ret_buffer[0];
	Osal_MemSet(&rq, 0, sizeof(rq));
	rq.ogf = OGF(hci_packet);
	rq.ocf = OCF(hci_packet);
	rq.cparam = &hci_packet[3];
	rq.clen = packet_length - 3; // 3 = 2 bytes opcode (ogf + ocf) and param 1 byte length
	rq.rparam = ret_buffer;
	rq.rlen = *ret_buffer_len;
	if (hci_send_req(&rq, FALSE) < 0)
		return BLE_STATUS_TIMEOUT;
	if (*status) {
		*ret_buffer_len = rq.rlen;
		return *status;
	}
	*ret_buffer_len = rq.rlen;
	return BLE_STATUS_SUCCESS;
}
 
#define HCI_PARAM_LEN(hci_packet) (hci_packet[2])
 
void testBle() {
	hci_reset();
	uint8_t ret_buffer[BLE_EVT_MAX_PARAM_LEN];
	uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN + 3];
	while (1) {
		HAL_StatusTypeDef error = HAL_OK;
		uint8_t hci_cmd_header = 0;
		error = HAL_UART_Receive(&huart1, &hci_cmd_header, 1, 1000);
		if (error != HAL_OK || hci_cmd_header != 0x01) {
			continue;
		}
		memset(cmd_buffer, 0, BLE_CMD_MAX_PARAM_LEN + 3);
		error = HAL_UART_Receive(&huart1, cmd_buffer, 3, 1000);
		if (error != HAL_OK) {
			continue;
		}
		if (HCI_PARAM_LEN(cmd_buffer)) {
			error = HAL_UART_Receive(&huart1, &cmd_buffer[3], cmd_buffer[2],
					1000);
			if (error != HAL_OK) {
				continue;
			}
		}
 
		uint8_t ret_param_len = BLE_EVT_MAX_PARAM_LEN;
		genericHciCommand(cmd_buffer, cmd_buffer[3], ret_buffer,
				&ret_param_len);
 
		// hci_send_req removes the event code, num commands and opcode and only delivers parameters in ret_buffer
		uint8_t cmd_cplt_resp_header[6] = { 0x04, 0x0E, ret_param_len + 3, 1,
				cmd_buffer[0], cmd_buffer[1] };
		HAL_UART_Transmit(&huart1, cmd_cplt_resp_header, 6, UINT32_MAX);
		HAL_UART_Transmit(&huart1, ret_buffer, ret_param_len, UINT32_MAX);
	}
}

This function runs in an endless loop. If you implement that differently you might want to make sure you don't call UTIL_SEQ_Run() to make sure this procedure is not disturbed by other actions.

@HRadt.1​  Thank you for that. I need to go through your code a bit at a time as it is beyond me at the moment! In the end, I took the transparent mode code from the actual nucleo board and copy and pasted all the differences from a basic project for the different chip, which (surprisingly) worked!

Thanks again for your help!