续前面的
接下来是spp.c
//其他的我也没动过
/////////////////////////////////////blc_register_hci_handler for spp////////////////////////////
/**
* @brief this function is used to process rx uart data.
* @param[in] none
* @return 0 is ok
* 先调试吧 调试完批量修改为串口发送模式
*
*/
void debug_uart(char *data)
{
uart_data_t uart_tx_buf;
u16 len = 0;
char *original_data = data;
while(*data != '\0')
{
len++;
data++;
}
printf("len = %d",len);
uart_tx_buf.len = len;
for(u8 i = 0;i < uart_tx_buf.len;i++)
{
uart_tx_buf.data[i] = original_data[i];
}
uart_send_dma((unsigned char*) (&uart_tx_buf));
sleep_ms(5);
if (Tr_isUartTxDone()) {
memset(uart_tx_buf.data,0,uart_tx_buf.len);
}
}
void ble_TT(u8 *p,u8 rx_len)
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
const int packet_size = 20;
int sent_length = 0;
while (sent_length < rx_len) {
int remaining_length = rx_len - sent_length;
int current_packet_size = (remaining_length >= packet_size) ? packet_size : remaining_length;
// 准备一个当前数据包
unsigned char packet[packet_size];
memcpy(packet, &p[sent_length], current_packet_size);
// 发送当前数据包
if (blc_gatt_pushWriteCommand(cur_conn_device.conn_handle, SPP_HANDLE_DATA_C2S,packet, current_packet_size) != 0x00) {
// 发送失败,处理错误(例如打印错误信息并退出)
printf("data failed to send error\n");
debug_uart("data failed to send error\n");
break;
}
// 更新已发送的字节数
sent_length += current_packet_size;
sleep_ms(50);
}
if (sent_length == rx_len) {
printf("All data sent successfully\n");
//debug_uart("All data sent successfully\n");
}
else {
printf("Some data failed to send\n");
//debug_uart("Some data failed to send\n");
}
//blc_gatt_pushWriteCommand (cur_conn_device.conn_handle, SPP_HANDLE_DATA_C2S, p, rx_len);
}
}
u8 nmea[64];
int rx_from_uart_cb(void) {
// UART data send to Master, we will handler the data as CMD or DATA
if (my_fifo_get(&spp_rx_fifo) == 0) {
return 0; // FIFO 为空,没有数据
}
u8* p = my_fifo_get(&spp_rx_fifo);
u32 rx_len = p[0]; // 通常 <= 255,所以 1 字节应该足够
if (rx_len) {
memcpy(&nmea, &p[4], rx_len);
if ((nmea[0] == 'A') &&
(nmea[1] == 'T')) { // 判断开头是不是 "AT"
if (rx_len <= 2) {
gpio_toggle(LED_RED); // LED 反转
printf("OK\n");
debug_uart("OK\n");
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'B') &&
(nmea[4] == 'A') &&
(nmea[5] == 'U') &&
(nmea[6] == 'D') &&
(nmea[7] == '=')) {
// 处理 AT+BAUD= 命令
if ((nmea[8] == '9') &&
(nmea[9] == '6') &&
(nmea[10] == '0') &&
(nmea[11] == '0')) {
gpio_toggle(LED_RED); // LED 反转
//debug_uart("9600");
uart_init_baudrate(9600, CLOCK_SYS_CLOCK_HZ, PARITY_NONE, STOP_BIT_ONE);
printf("AT+BAUD=OK\n");
debug_uart("AT+BAUD=OK\n");
}
else if ((nmea[8] == '1') &&
(nmea[9] == '9') &&
(nmea[10] == '2') &&
(nmea[11] == '0') &&
(nmea[12] == '0')) {
gpio_toggle(LED_RED); // LED 反转
printf("AT+BAUD=GET_DATA_19200\n");
//debug_uart("19200");
uart_init_baudrate(19200, CLOCK_SYS_CLOCK_HZ, PARITY_NONE, STOP_BIT_ONE);
printf("AT+BAUD=OK\n");
debug_uart("AT+BAUD=OK\n");
}
else if ((nmea[8] == '1') &&
(nmea[9] == '1') &&
(nmea[10] == '5') &&
(nmea[11] == '2') &&
(nmea[12] == '0') &&
(nmea[13] == '0')) {
gpio_toggle(LED_RED); // LED 反转
printf("AT+BAUD=GET_DATA_115200\n");
//debug_uart("115200");
uart_init_baudrate(115200, CLOCK_SYS_CLOCK_HZ, PARITY_NONE, STOP_BIT_ONE);
printf("AT+BAUD=OK\n");
debug_uart("AT+BAUD=OK\n");
}
else { //at设置buad不对 不是上面三种
gpio_toggle(LED_RED); // LED 反转
printf("AT+BAUD=FALL\n");
debug_uart("AT+BAUD=FALL\n");
}
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'N') &&
(nmea[4] == 'E') &&
(nmea[5] == 'T') &&
(nmea[6] == 'N') &&
(nmea[7] == 'A') &&
(nmea[8] == 'M') &&
(nmea[9] == 'E') &&
(nmea[10] == '=')) {
// 处理 AT+NETNAME= 命令 //已知名字长度固定20位
gpio_toggle(LED_RED); // LED 反转
//memset(user_adv,0,22);
for(u8 num = 0;num <20;num++)
{
user_adv[num] = 0;
}
sleep_us(500);
for(u8 len = 0;len<20;len++)
{
user_adv[len+2] = nmea[len+11];
}
user_adv[0] = 21; //广播包开头的包长
user_adv[1] = 9; //广播包类型 9是名字
printf("AT+NETNAME=OK \n");
debug_uart("AT+NETNAME=OK\n");
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'P') &&
(nmea[4] == 'I') &&
(nmea[5] == 'N') &&
(nmea[6] == '=')) {
//AT+PIN=
//因为通信用的是无安全模式的所以没pin
gpio_toggle(LED_RED);//led反转
printf("AT+PIN = OK \n");
debug_uart("AT+PIN=OK\n");
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'L') &&
(nmea[4] == 'I') &&
(nmea[5] == 'N') &&
(nmea[6] == 'K') &&
(nmea[7] == '=') )
{
//AT+LINK
if(nmea[8] == '1')
{
//这里是连接命令
gpio_toggle(LED_RED);//led反转
central_pairing_enable = 1; //连接
printf("AT_LINK_CONN SEND\n");
debug_uart("AT_LINK_CONN_SEND\n");
}
else if(nmea[8] == '0')
{
//这里是断开连接的命令
gpio_toggle(LED_RED);//led反转
central_unpair_enable = 1;//断开连接
printf("AT_LINK_UNPAIR SEND\n");
debug_uart("AT_LINK_UNPAIR_SEND\n");
}
else
{
//这里是其他命令
gpio_toggle(LED_RED);//led反转
printf("AT_LINK_ERROR \n");
debug_uart("AT_LINK_ERROR\n");
}
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'G') &&
(nmea[4] == 'E') &&
(nmea[5] == 'T')) {
//AT+GET
gpio_toggle(LED_RED);//led反转
switch (blc_ll_getCurrentState())
{
case BLS_LINK_STATE_IDLE :
{
//空闲状态
printf("BLS_LINK_STATE_IDLE");
debug_uart("BLS_LINK_STATE_IDLE\n");
break;
}
case BLS_LINK_STATE_ADV :
{
//广播状态
printf("BLS_LINK_STATE_ADV");
debug_uart("BLS_LINK_STATE_ADV\n");
break;
}
case BLS_LINK_STATE_SCAN :
{
//扫描状态
printf("BLS_LINK_STATE_SCAN");
debug_uart("BLS_LINK_STATE_SCAN\n");
break;
}
case BLS_LINK_STATE_INIT :
{
//连接状态
printf("BLS_LINK_STATE_INIT");
debug_uart("BLS_LINK_STATE_INIT\n");
break;
}
case BLS_LINK_STATE_CONN :
{
//连接完成状态
printf("BLS_LINK_STATE_CONN");
debug_uart("BLS_LINK_STATE_CONN\n");
break;
}
default:
printf("getCurrentState_error \n");
debug_uart("getCurrentState_error\n");
break;
}
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'V') &&
(nmea[4] == 'E') &&
(nmea[5] == 'R') &&
(nmea[6] == 'S') &&
(nmea[7] == 'I') &&
(nmea[8] == 'O') &&
(nmea[9] == 'N') &&
(nmea[10] == '?')) {
//AT+VERSION?
gpio_toggle(LED_RED);//led反转
printf("AT+VERSION = SCOMBLE1000\n");
debug_uart("SCOMBLE1000\n");
}
else if ((nmea[2] == '+') &&
(nmea[3] == 'S') &&
(nmea[4] == 'C') &&
(nmea[5] == 'A') &&
(nmea[6] == 'N')) {
//AT+GETSCAN
gpio_toggle(LED_RED);//led反转
char scan_name[20] = {};
for(u8 scan_name_len = 0;scan_name_len<20;scan_name_len++)
{
scan_name[scan_name_len] = user_adv[scan_name_len+2];
}
printf("scan_name = %s\n",scan_name);
debug_uart(scan_name);
}
else {//不是at 返回fail
gpio_toggle(LED_RED);//led反转
printf("NOT AT CODE RETURN FALL \n");
debug_uart("NOT_AT_CODE_RETURN_FALL\n");
}
}
if(blc_ll_getCurrentState() ==BLS_LINK_STATE_CONN) //连接上了 发送其他数据
{
gpio_toggle(LED_RED);//led反转
printf("UART_GET_DATA \n");
//debug_uart("UART_GET_DATA\n");
ble_TT(nmea,rx_len); //透传函数
}
my_fifo_pop(&spp_rx_fifo); //最后清除fifo
}
return 0; // 处理完成
}
int tx_to_uart_cb(void) {
//检测发送的fifo是否为空
if(spp_tx_fifo.wptr == spp_tx_fifo.rptr){
return 0;//have no data 没数据
}
//检查串口发送是否完成
if (Tr_isUartTxDone()) {
return 0;//没完成
}
//从fifo取数据
u8 *p = my_fifo_get(&spp_tx_fifo);
//复制数据到发送缓冲区,数据长度由前两个字节决定
memcpy(&T_txdata_buf.data, p + 2, p[0] | (p[1] << 8));
//设置发送缓冲区长度
T_txdata_buf.len = p[0] | (p[1] << 8);
#if (BLE_MODULE_INDICATE_DATA_TO_MCU)
//If the MCU side is designed to have low power consumption and the module has data to pull up
//the GPIO_WAKEUP_MCU will only wake up the MCU, then you need to consider whether MCU needs a
//reply time T from wakeup to a stable receive UART data. If you need a response time of T, ch-
//ange the following 100US to the actual time required by user.
if(module_wakeup_module_tick){
while( !clock_time_exceed(module_wakeup_module_tick, 100) );
}
#endif
//清除发送完成标志
Tr_clrUartTxDone();
//通过dma发送串口数据
uart_send_dma(UART_CONVERT((unsigned char*) (&T_txdata_buf)));
//从fifo中弹出发送完成的数据
my_fifo_pop(&spp_tx_fifo);
return 1;
}
接下来的是spp.h
//我自己封装了一个
void debug_uart(char *data);
void ble_TT(u8 *p,u8 rx_len);
3.app_att.c
我好像在这里添加了一些东西的在底下说到spp那
// 000c - 000e device Information Service
{3,ATT_PERMISSIONS_READ,2,2,(u8*)(&my_primaryServiceUUID), (u8*)(&my_devServiceUUID), 0},
{0,ATT_PERMISSIONS_READ,2,sizeof(my_PnCharVal),(u8*)(&my_characterUUID), (u8*)(my_PnCharVal), 0},
{0,ATT_PERMISSIONS_READ,2,sizeof (my_PnPtrs),(u8*)(&my_PnPUUID), (u8*)(my_PnPtrs), 0},
// 000f - 0016 SPP
{8,ATT_PERMISSIONS_READ,2,16,(u8*)(&my_primaryServiceUUID), (u8*)(&TelinkSppServiceUUID), 0},
{0,ATT_PERMISSIONS_READ,2,sizeof(TelinkSppDataServer2ClientCharVal),(u8*)(&my_characterUUID), (u8*)(TelinkSppDataServer2ClientCharVal), 0}, //prop
{0,ATT_PERMISSIONS_READ,16,sizeof(SppDataServer2ClientData),(u8*)(&TelinkSppDataServer2ClientUUID), (u8*)(SppDataServer2ClientData), 0}, //value
{0,ATT_PERMISSIONS_RDWR,2,2,(u8*)&clientCharacterCfgUUID,(u8*)(&SppDataServer2ClientDataCCC)},
{0,ATT_PERMISSIONS_READ,2,sizeof(TelinkSPPS2CDescriptor),(u8*)&userdesc_UUID,(u8*)(&TelinkSPPS2CDescriptor)},
{0,ATT_PERMISSIONS_READ,2,sizeof(TelinkSppDataClient2ServerCharVal),(u8*)(&my_characterUUID), (u8*)(TelinkSppDataClient2ServerCharVal), 0}, //prop
{0,ATT_PERMISSIONS_RDWR,16,sizeof(SppDataClient2ServerData),(u8*)(&TelinkSppDataClient2ServerUUID), (u8*)(SppDataClient2ServerData), (att_readwrite_callback_t)&module_onReceiveData}, //value
{0,ATT_PERMISSIONS_READ,2,sizeof(TelinkSPPC2SDescriptor),(u8*)&userdesc_UUID,(u8*)(&TelinkSPPC2SDescriptor)},
2万+

被折叠的 条评论
为什么被折叠?



