⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb2uart.c

📁 To change pskey, convert USB bluetooth to UART
💻 C
📖 第 1 页 / 共 3 页
字号:
		while (!(chunk = get_hci_event (&buf[len])))
			Sleep(10);
	}

#ifdef PKT_DUMP
	printf("Event  [%d]:    ", len);
	for (chunk=0; chunk!=len; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	if (buf[0] != 0xFF)			/* manuf-specific HCI event */
		close_connection_on_error ("invalid packet received");

	if (buf[1] != 9 * 2 + 1)
		close_connection_on_error ("hci event has invalid length");

	if (buf[2] != 0xC2)			/* payload descriptor */
		close_connection_on_error ("invalid payload descriptor");
	
	if ((buf[3] + (buf[4] << 8)) != BCCMD_GETRESP)
		close_connection_on_error ("!= GETRESP");

	if ((buf[5] + (buf[6] << 8)) != 9)
		close_connection_on_error ("invalid length");

	if ((buf[7] + (buf[8] << 8)) != bccmd_seq)
		close_connection_on_error ("invalid sequence number");

	if ((buf[9] + (buf[10] << 8)) != bccmd_varid)
		close_connection_on_error ("invalid varid");

	switch  (buf[11] + (buf[12] << 8))
	{
		case 0x0000:
			/* OK status, continue */
			break;
		case 0x0001:
			close_connection_on_error ("status NO_SUCH_VARID");
			break;
		case 0x0002:
			close_connection_on_error ("status TOO_BIG");
			break;
		case 0x0003:
			close_connection_on_error ("status NO_VALUE");
			break;
		case 0x0004:
			close_connection_on_error ("status BAD_REQ");
			break;
		case 0x0005:
			close_connection_on_error ("status NO_ACCESS");
			break;
		case 0x0006:
			close_connection_on_error ("status READ_ONLY");
			break;
		case 0x0007:
			close_connection_on_error ("status WRITE_ONLY");
			break;
		case 0x0008:
			close_connection_on_error ("status ERROR");
			break;
		case 0x0009:
			close_connection_on_error ("status PERMISSION_DENIED");
			break;
		default:
			close_connection_on_error ("invalid status");
			break;
	}

	return;

}

/* Forces the module to reboot immediately
 *
 * Parameters:
 *
 * warm = 1 (warm reboot, RAM store is preserved) or 0 (cold reboot, the same as 
 *           power-cycling the module)
 *
 * It's most probable that response will never be able to make it back, so don't bother
*/
static void reboot(int warm)
{
	uint16 bccmd_req, bccmd_varid, bccmd_len;
	unsigned char buf[258];
	int len = 0, chunk = 0;

	bccmd_req = BCCMD_SETREQ;
	
	bccmd_seq++;
	
	if (warm == 0)
		bccmd_varid = 0x4001; 			/* varid: COLF_RESET */
	else if (warm == 1)
		bccmd_varid = 0x4002; 			/* varid: WARM_RESET */
	else
		close_connection_on_error ("invalid reset type");

	bccmd_len = 9;					/* minimum possible length, one uint16 is wasted */

	memset(&buf, 0, sizeof(buf));

	/* need to construct a hand-crafted HCI cmd pkt */
	buf[0] = 0x00; buf[1] = 0xFC;	/* OGF = 0x3F & OCF = 0x00 */

	buf[2] = bccmd_len * 2 + 1;		/* pkt len - 3 */

	buf[3] = 0xC2;					/* payload descriptor: last frag =1; 
									first frag = 1; channel = 2 */

	buf[4] = bccmd_req & 0xFF; buf[5] = bccmd_req >> 8;

	buf[6] = bccmd_len & 0xFF; buf[7] = bccmd_len >> 8;

	buf[8]  = bccmd_seq & 0xFF; buf[9] = bccmd_seq >> 8;

	buf[10] = bccmd_varid & 0xFF; buf[11] = bccmd_varid >> 8;

	buf[12] = 0x00; buf[13] = 0x00;	/* status */

	/*  FIXME: IOCTL_CSRBC01_SEND_HCI_COMMAND doesn't return the number of bytes written? */
	send_hci_command (&buf, buf[2] + 3);

#ifdef PKT_DUMP
	printf("HCI cmd[%d]: ", buf[2] + 3);
	for (chunk=0; chunk != buf[2] + 3; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	return;

}

static void usb_reset(void)
{
	unsigned long written;
	int status;

	status = DeviceIoControl(handle,
							IOCTL_CSRBC01_RESET_DEVICE,
							0,
							0,
							0,
							0,
							&written,
							0);

	if (!status)
		close_connection_on_error ("IOCTL_CSRBC01_RESET_DEVICE");

}

/* 
 * We only try to open the first CSR device found, if you have multiply
 * devices, please unplug all but the last one or change device name from
 * CSR0 to CSRn.
 */

int main (int arvc, char* arvgv)
{

	unsigned char buf[258];
	unsigned long written;
	dev_desc desc;
	uint16 len;
	int baud_rate;
	uint16 divisor, uart_conf, retries, host_if;
	int status;


	/* open device */
	handle = CreateFile("\\\\.\\CSR0",
						GENERIC_READ | GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						0,
						NULL);

	if ( handle == INVALID_HANDLE_VALUE)
		close_connection_on_error ("CreateFile");
	
	memset(&desc, 0, sizeof(desc));

	status = DeviceIoControl(handle,
							IOCTL_CSRBC01_GET_DEVICE_DESCRIPTOR,
							0,
							0,
							&desc,
							sizeof(desc), /* must be 18 */
							&written,
							0);

	if (!status)
		close_connection_on_error ("IOCTL_CSRBC01_GET_DEVICE_DESCRIPTOR");

	printf("Found CSR USB device:		VID=%04X, PID=%04X\n", desc.idVendor, desc.idProduct);

	/* reset device to known state */
	printf("Resetting...\n");
	usb_reset();

	if (handle != INVALID_HANDLE_VALUE)
		CloseHandle (handle);

	/* wait for hardware to settle */
	Sleep(500);	

	/* re-open device */
	handle = CreateFile("\\\\.\\CSR0",
						GENERIC_READ | GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						0,
						NULL);

	if ( handle == INVALID_HANDLE_VALUE)
		close_connection_on_error ("CreateFile");

	printf("CSR firmware build ID:		0x%X\n", buildid());

	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_BDADDR, buf, 0);
	if (len != 8)
		close_connection_on_error ("PSKEY_BDADDR");
	/* It's hard to make it more akward than that ;) */
	printf("read:PSKEY_BDADDR:		%02X-%02X-%02X-%02X-%02X-%02X\n\n", 0,
															buf[6] + (buf[7] << 8),
															buf[4] + (buf[5] << 8),
															buf[0] + (buf[1] << 8),
															buf[3],
															buf[2]);
/*
//	printf("read:PSKEY_BDADDR:		%02X %02X %02X %02X %02X %02X %02X %02X\n\n",
//									buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);

	buf[0] = 0x1c;
	buf[2] = 0x6a;
	buf[3] = 0x8d;
	buf[4] = 0xc7;
	buf[6] = 0x02;
	
//	printf("read:PSKEY_BDADDR:		%02X %02X %02X %02X %02X %02X %02X %02X\n\n",
//									buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);	
	pfkey(1, PSKEY_BDADDR, buf, 8);
	
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_BDADDR, buf, 0);
	if (len != 8)
		close_connection_on_error ("PSKEY_BDADDR");

	printf("read:PSKEY_BDADDR:		%02X-%02X-%02X-%02X-%02X-%02X\n\n", 0,
															buf[6] + (buf[7] << 8),
															buf[4] + (buf[5] << 8),
															buf[0] + (buf[1] << 8),
															buf[3],
															buf[2]);
	goto Exit;
*/



/* Here's the structure of PSKEY_HOSTIO_UART_PS_BLOCK:

PSKEY_HOSTIO_UART_PS_BLOCK (0x191):

0       1       2       3       4       5       6       7       8       9

3B0     A8      FA      14      4       0       4       1E      64      A


0. PSKEY_UART_BAUD_RATE (0x204)
   0x3B0 == 230400 bps
=> 0x1D8 == 115200 bps

1. PSKEY_UART_CONFIG (0x205)
   0xA8 == hardware flow control, RTS on 1st bit, non-BCSP hardware
=> 6    == one parity bit, even parity (BCSP)

2. PSKEY_UART_SEQ_TIMEOUT (0x405)
   0xFA == 250ms

3. PSKEY_UART_SEQ_RETRIES (0x406)
   0x14 == 20 retries.
=> 0 == retry indefinitely

4. PSKEY_UART_SEQ_WINSIZE (0x407)

   4 == number of unacknowledged packets that can be sent before waiting 
   for an acknowledgment

5. PSKEY_UART_USE_CRC_ON_TX (0x408)
   0 == disabled

6. PSKEY_UART_HOST_INITIAL_STATE (0x409)
   4 == host never sleeps

7. PSKEY_UART_HOST_ATTENTION_SPAN (0x40A) ????
   0x1E == 30 seconds

8. PSKEY_UART_HOST_WAKEUP_TIME (0x40B) ???
   0x64 == 100ms

9. PSKEY_UART_HOST_WAKEUP_WAIT (0x40C) ???
   0xA == 10ms

*/
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOSTIO_UART_PS_BLOCK, buf, 0);
	if (len != 20)
		close_connection_on_error ("PSKEY_HOST_INTERFACE");
	printf("read:PSKEY_HOSTIO_UART_PS_BLOCK:	");
	for (len = 0; len < 20; len = len + 2)
		printf("%02x ", buf[len] + (buf[len+1] << 8));
	printf("\n");

	baud_rate = 115200*8;
	divisor = (baud_rate * 64 + 7812) / 15625;
	buf[0] = divisor & 0xFF ; buf[1] = (divisor >> 8) & 0xFF; 

	uart_conf = 6; /* one stop bit, even parity, no RTS/CTS flow control,
					non-BCSP hardware disabled */
	buf[2] = uart_conf & 0xFF ; buf[3] = (uart_conf >> 8) & 0xFF; 

	retries = 0; /* retry indefinitely on BCSP packet transmission */
	buf[6] = retries & 0xFF ; buf[7] = (retries >> 8) & 0xFF; 

/* it should look like the following:

	buf[0] = 0xD8;
	buf[1] = 1;
	buf[2] = 6;
	buf[3] = 0;
	buf[4] = 0xFA;
	buf[5] = 0;
	buf[6] = 0;
	buf[7] = 0;
	buf[8] = 4;
	buf[9] = 0;
	buf[10] = 0;
	buf[11] = 0;
	buf[12] = 4;
	buf[13] = 0;
	buf[14] = 0x1E;
	buf[15] = 0;
	buf[16] = 0x64;
	buf[17] = 0;
	buf[18] = 0xA;
	buf[19] = 0;
*/
	printf("write:PSKEY_HOSTIO_UART_PS_BLOCK:	");
	for (len = 0; len < 10*2; len = len + 2)
		printf("%02x ", buf[len] + (buf[len+1] << 8));
	printf("\n");
	pfkey(1, PSKEY_HOSTIO_UART_PS_BLOCK, buf, 20);

	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOSTIO_UART_PS_BLOCK, buf, 0);
	if (len != 20)
		close_connection_on_error ("PSKEY_HOST_INTERFACE");
	printf("read:PSKEY_HOSTIO_UART_PS_BLOCK:	");
	for (len = 0; len < 20; len = len + 2)
		printf("%02x ", buf[len] + (buf[len+1] << 8));
	printf("\n");

/* ---------------------------------------------------------------------------- */
	/* PSKEY_HOST_INTERFACE should be change at the same time as PSKEY_HOSTIO_UART_PS_BLOCK */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOST_INTERFACE, buf, 0);
	if (len != 2)
		close_connection_on_error ("PSKEY_HOST_INTERFACE");
	printf("read:PSKEY_HOST_INTERFACE:		%d\n", buf[0] + (buf[1] << 8));

	host_if = 1; /* UART in BCSP mode */
	buf[0] = host_if & 0xFF ; buf[1] = (host_if >> 8) & 0xFF; 

	printf("write:PSKEY_HOST_INTERFACE:		%d\n", buf[0] + (buf[1] << 8));
	pfkey(1, PSKEY_HOST_INTERFACE, buf, 2);

	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOST_INTERFACE, buf, 0);
	if (len != 2)
		close_connection_on_error ("PSKEY_HOST_INTERFACE");
	printf("read:PSKEY_HOST_INTERFACE:		%d\n", buf[0] + (buf[1] << 8));

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_DEEP_SLEEP_STATE, buf, 0);
	if (len != 2)
		close_connection_on_error ("PSKEY_DEEP_SLEEP_STATE");
	printf("read:PSKEY_DEEP_SLEEP_STATE:		%d\n", buf[0] + (buf[1] << 8));

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_DEEP_SLEEP_WAKE_CTS, buf, 0);
	if (len != 2)
		close_connection_on_error ("PSKEY_DEEP_SLEEP_WAKE_CTS");
	printf("read:PSKEY_DEEP_SLEEP_WAKE_CTS:		%d\n", buf[0] + (buf[1] << 8));

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_UART_SLEEP_TIMEOUT, buf, 0);
	if (len != 2)
		close_connection_on_error ("PSKEY_UART_SLEEP_TIMEOUT");
	printf("read:PSKEY_UART_SLEEP_TIMEOUT:		%d ms\n", buf[0] + (buf[1] << 8));

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_WD_PERIOD, buf, 0);
	if (len != 4)
		close_connection_on_error ("PSKEY_WD_PERIOD");
	printf("read:PSKEY_WD_PERIOD:			%d ms\n", ((buf[0] << 16) + (buf[1] << 24) + buf[2] + (buf[3] << 8))/1000);

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_WD_TIMEOUT, buf, 0);
	if (len != 4)
		close_connection_on_error ("PSKEY_WD_TIMEOUT");
	printf("read:PSKEY_WD_TIMEOUT:			%d ms\n", ((buf[0] << 16) + (buf[1] << 24) + buf[2] + (buf[3] << 8))/1000);

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOSTIO_UART_RESET_TIMEOUT, buf, 0);
	if (len != 4)
		close_connection_on_error ("PSKEY_HOSTIO_UART_RESET_TIMEOUT");
	printf("read:PSKEY_HOSTIO_UART_RESET_TIMEOUT:	%d ms\n", ((buf[0] << 16) + (buf[1] << 24) + buf[2] + (buf[3] << 8))/1000);

/* ---------------------------------------------------------------------------- */
	memset(&buf, 0, sizeof(buf));
	len = pfkey(0, PSKEY_HOSTIO_BREAK_POLL_PERIOD, buf, 0);
	if (len != 4)
		close_connection_on_error ("PSKEY_HOSTIO_BREAK_POLL_PERIOD");
	printf("read:PSKEY_HOSTIO_BREAK_POLL_PERIOD:	%d ms\n", ((buf[0] << 16) + (buf[1] << 24) + buf[2] + (buf[3] << 8))/1000);

	printf("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
	printf("!!!!  Rebooting device.... It should come up in UART BCSP mode now  !!!!\n");
	printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

Exit:
	/* warm reboot */
	reboot(1);

	if (handle != INVALID_HANDLE_VALUE)
		CloseHandle (handle);

	return 0;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -