mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-24 19:20:40 +00:00
Reads a characteristic from a Bluetooth echo device
This commit is contained in:
parent
e1f5c41c6d
commit
8d1a7750f1
3 changed files with 76 additions and 16 deletions
|
@ -80,6 +80,7 @@ enum {
|
||||||
COMMAND_LOAD_FIRMWARE = 0x2e,
|
COMMAND_LOAD_FIRMWARE = 0x2e,
|
||||||
|
|
||||||
HCI_COMMAND_PKT = 0x01,
|
HCI_COMMAND_PKT = 0x01,
|
||||||
|
HCI_ACL_PKT = 0x02,
|
||||||
HCI_EVENT_PKT = 0x04,
|
HCI_EVENT_PKT = 0x04,
|
||||||
COMMAND_COMPLETE_CODE = 0x0e,
|
COMMAND_COMPLETE_CODE = 0x0e,
|
||||||
CONNECT_COMPLETE_CODE = 0x0f,
|
CONNECT_COMPLETE_CODE = 0x0f,
|
||||||
|
@ -193,6 +194,31 @@ void bt_getbdaddr(unsigned char *bdaddr) {
|
||||||
for (int c=0;c<6;c++) bdaddr[c] = bt_waitReadByte();
|
for (int c=0;c<6;c++) bdaddr[c] = bt_waitReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendACLreadreq(unsigned int handle)
|
||||||
|
{
|
||||||
|
bt_writeByte(HCI_ACL_PKT);
|
||||||
|
|
||||||
|
bt_writeByte(lo(handle));
|
||||||
|
bt_writeByte(hi(handle));
|
||||||
|
|
||||||
|
unsigned int length = 0x0007;
|
||||||
|
bt_writeByte(lo(length));
|
||||||
|
bt_writeByte(hi(length));
|
||||||
|
|
||||||
|
unsigned int data_length = 0x0003;
|
||||||
|
bt_writeByte(lo(data_length));
|
||||||
|
bt_writeByte(hi(data_length));
|
||||||
|
|
||||||
|
unsigned int channel = 0x0004;
|
||||||
|
bt_writeByte(lo(channel));
|
||||||
|
bt_writeByte(hi(channel));
|
||||||
|
|
||||||
|
unsigned char params[] = { 0x0a, 0x2a, 0x00 };
|
||||||
|
|
||||||
|
unsigned int c=0;
|
||||||
|
while (c++<data_length) bt_writeByte(params[c-1]);
|
||||||
|
}
|
||||||
|
|
||||||
void setLEeventmask(unsigned char mask)
|
void setLEeventmask(unsigned char mask)
|
||||||
{
|
{
|
||||||
unsigned char params[] = { mask, 0, 0, 0, 0, 0, 0, 0 };
|
unsigned char params[] = { mask, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
@ -230,12 +256,6 @@ void setLEadvertdata() {
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEwhitelist() {
|
|
||||||
static unsigned char params[] = { 0x00,
|
|
||||||
0xBC, 0xF2, 0xCA, 0x32, 0xBC, 0xAC };
|
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x11, params, 7)) uart_writeText("setLEwhitelist failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void createLEconnection(unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, unsigned char a5, unsigned char a6, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max) {
|
void createLEconnection(unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, unsigned char a5, unsigned char a6, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max) {
|
||||||
unsigned char params[26] = { linterval, hinterval, lwindow, hwindow,
|
unsigned char params[26] = { linterval, hinterval, lwindow, hwindow,
|
||||||
filter_policy,
|
filter_policy,
|
||||||
|
@ -262,8 +282,6 @@ void startActiveScanning() {
|
||||||
unsigned int p = BleScanInterval / BleScanDivisor;
|
unsigned int p = BleScanInterval / BleScanDivisor;
|
||||||
unsigned int q = BleScanWindow / BleScanDivisor;
|
unsigned int q = BleScanWindow / BleScanDivisor;
|
||||||
|
|
||||||
//setLEwhitelist();
|
|
||||||
//setLEscanparameters(LL_SCAN_ACTIVE, lo(p), hi(p), lo(q), hi(q), 0, 1);
|
|
||||||
setLEscanparameters(LL_SCAN_ACTIVE, lo(p), hi(p), lo(q), hi(q), 0, 0);
|
setLEscanparameters(LL_SCAN_ACTIVE, lo(p), hi(p), lo(q), hi(q), 0, 0);
|
||||||
setLEscanenable(1, 0);
|
setLEscanenable(1, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,11 @@ void bt_getbdaddr(unsigned char *bdaddr);
|
||||||
void bt_init();
|
void bt_init();
|
||||||
unsigned int bt_isReadByteReady();
|
unsigned int bt_isReadByteReady();
|
||||||
unsigned char bt_readByte();
|
unsigned char bt_readByte();
|
||||||
|
unsigned char bt_waitReadByte();
|
||||||
void setLEeventmask(unsigned char mask);
|
void setLEeventmask(unsigned char mask);
|
||||||
void startActiveScanning();
|
void startActiveScanning();
|
||||||
void stopScanning();
|
void stopScanning();
|
||||||
void startActiveAdvertising();
|
void startActiveAdvertising();
|
||||||
void connect(unsigned char *addr);
|
void connect(unsigned char *addr);
|
||||||
void bt_flushrx();
|
void bt_flushrx();
|
||||||
|
void sendACLreadreq(unsigned int handle);
|
||||||
|
|
|
@ -16,6 +16,7 @@ enum {
|
||||||
LE_EVENT_CODE = 0x3e,
|
LE_EVENT_CODE = 0x3e,
|
||||||
LE_CONNECT_CODE = 0x01,
|
LE_CONNECT_CODE = 0x01,
|
||||||
LE_ADREPORT_CODE = 0x02,
|
LE_ADREPORT_CODE = 0x02,
|
||||||
|
HCI_ACL_PKT = 0x02,
|
||||||
HCI_EVENT_PKT = 0x04
|
HCI_EVENT_PKT = 0x04
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,6 +150,43 @@ void bt_conn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acl_poll()
|
||||||
|
{
|
||||||
|
while (bt_isReadByteReady()) {
|
||||||
|
unsigned char byte = bt_readByte();
|
||||||
|
|
||||||
|
if (byte == HCI_EVENT_PKT) {
|
||||||
|
unsigned char opcode = bt_waitReadByte();
|
||||||
|
unsigned char length = bt_waitReadByte();
|
||||||
|
for (int i=0;i<length;i++) bt_waitReadByte();
|
||||||
|
} else if (byte == HCI_ACL_PKT) {
|
||||||
|
unsigned char h1 = bt_waitReadByte();
|
||||||
|
unsigned char h2 = bt_waitReadByte();
|
||||||
|
|
||||||
|
unsigned int handle = h1 | (h2 & 0x0f);
|
||||||
|
unsigned char flags = (h2 & 0xf0) >> 4;
|
||||||
|
|
||||||
|
h1 = bt_waitReadByte();
|
||||||
|
h2 = bt_waitReadByte();
|
||||||
|
|
||||||
|
unsigned int length = h1 | (h2 << 8);
|
||||||
|
unsigned char data[length];
|
||||||
|
|
||||||
|
for (int i=0;i<length;i++) data[i] = bt_waitReadByte();
|
||||||
|
|
||||||
|
length = data[0] | (data[1] << 8);
|
||||||
|
|
||||||
|
unsigned int channel = data[2] | (data[3] << 8);
|
||||||
|
|
||||||
|
unsigned char opcode = data[4];
|
||||||
|
if (opcode == 0x0b) {
|
||||||
|
for (int c=0;c<length-1;c++) uart_byte(data[5+c]);
|
||||||
|
uart_writeText("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
uart_init();
|
uart_init();
|
||||||
|
@ -179,15 +217,17 @@ void main()
|
||||||
uart_writeText("Connecting to echo: ");
|
uart_writeText("Connecting to echo: ");
|
||||||
connect(echo_addr);
|
connect(echo_addr);
|
||||||
while (!connected) bt_conn();
|
while (!connected) bt_conn();
|
||||||
uart_writeText("-> "); uart_hex(connection_handle); uart_writeText("\n");
|
uart_writeText("\n");
|
||||||
|
|
||||||
|
// Get the characteristic value
|
||||||
|
uart_writeText("Sending read request: ");
|
||||||
|
uart_hex(connection_handle); uart_writeText("\n");
|
||||||
|
sendACLreadreq(connection_handle);
|
||||||
|
|
||||||
// Into the main infinite loop
|
// Into the main infinite loop
|
||||||
uart_writeText("Waiting for input...\n");
|
uart_writeText("Waiting for input...\n");
|
||||||
while (1) uart_update();
|
while (1) {
|
||||||
|
acl_poll();
|
||||||
/*
|
uart_update();
|
||||||
// Get the Eddystone beacon going
|
}
|
||||||
uart_writeText("startActiveAdvertising()\n");
|
|
||||||
startActiveAdvertising();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue