/********************************************************************* * @fn simpleProfileChangeCB * * @brief Callback from SimpleBLEProfile indicating a value change * * @param paramID - parameter ID of the value that was changed. * * @return none */ static void simpleProfileChangeCB( uint8 paramID ) { uint8 newValue, intval[3]; switch( paramID ) { case SIMPLEPROFILE_CHAR1: SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR1, &newValue ); #if (defined HAL_LCD) && (HAL_LCD == TRUE) HalLcdWriteStringValue( "Char 1:", (uint16)(newValue), 10, HAL_LCD_LINE_3 ); #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) //发射功率有四个级别,-23dbm,-6dbm,0dbm, 4dbm, newValue为0~3,当连接的时候,只能设置-6, 0 if(newValue == LL_EXT_TX_POWER_MINUS_6_DBM || newValue == LL_EXT_TX_POWER_0_DBM) { HCI_EXT_SetTxPowerCmd(newValue); ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &newValue ); } break; case SIMPLEPROFILE_CHAR2: SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR2, &newValue ); #if (defined HAL_LCD) && (HAL_LCD == TRUE) HalLcdWriteStringValue( "Char 2:", (uint16)(newValue), 10, HAL_LCD_LINE_3 ); #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) if( newValue == 1 && gOpenDoorStep == 0 ){ gOpenDoorStep++; osal_set_event( simpleBLEPeripheral_TaskID, SBP_OPENDOOR_DEVICE_EVT ); } break; case SIMPLEPROFILE_CHAR3: SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, intval ); #if (defined HAL_LCD) && (HAL_LCD == TRUE) HalLcdWriteStringValue( "Char 3:", (uint16)(newValue), 10, HAL_LCD_LINE_3 ); #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) advert_internal = (intval[0] - 0x30) *100 + (intval[1] - 0x30) * 10 + (intval[2] - 0x30); break; default: // should not reach here! break; } }
/*--------------------------------------------------------------------------- * Initialization of GAP properties. *-------------------------------------------------------------------------*/ static void gapApplicationInit(void) { // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed uint8 initial_advertising_enable = TRUE; // By setting this to zero, the device will go into the waiting state after // being discoverable for 30.72 second, and will not being advertising again // until the enabler is set back to TRUE uint16 gapRole_AdvertOffTime = 0; uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; // Set the GAP Role Parameters GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( deviceName ), deviceName ); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); // Set the GAP Attributes GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName ); // Setup the GAP Bond Manager { uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = TRUE; uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; uint8 bonding = TRUE; GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding ); } // Set max output power and reciever gain HCI_EXT_SetTxPowerCmd(HCI_EXT_TX_POWER_4_DBM); HCI_EXT_SetRxGainCmd(HCI_EXT_RX_GAIN_HIGH); }
/********************************************************************* * @fn SimpleBLEPeripheral_Init * * @brief Initialization function for the Simple BLE Peripheral App Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notificaiton ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void SimpleBLEPeripheral_Init( uint8 task_id ) { HCI_EXT_SetTxPowerCmd(LL_EXT_TX_POWER_MINUS_6_DBM); simpleBLEPeripheral_TaskID = task_id; if(osal_snv_read(0xfe,1,&gMP)!=NV_OPER_FAILED){ advertData[29]=gMP; } // Setup the GAP VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );//连接间隙 // Setup the GAP Peripheral Role Profile { #if defined( CC2540_MINIDK ) // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed uint8 initial_advertising_enable = FALSE; #else // For other hardware platforms, device starts advertising upon initialization uint8 initial_advertising_enable = TRUE; #endif // By setting this to zero, the device will go into the waiting state after // being discoverable for 30.72 second, and will not being advertising again // until the enabler is set back to TRUE uint16 gapRole_AdvertOffTime = 0; uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; uint16 desired_rssi_rate=DEFAULT_DESIRED_REEI_RATE; // Set the GAP Role Parameters GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); //GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); GAPRole_SetParameter(GAPROLE_RSSI_READ_RATE,sizeof(uint16),&desired_rssi_rate);//设定RSSI的参数值 GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); } // Set the GAP Characteristics GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName ); // Set advertising interval { uint16 advInt = DEFAULT_ADVERTISING_INTERVAL; GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt ); GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt ); } // Setup the GAP Bond Manager { uint32 passkey = 0; // passkey "000000" uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = TRUE; uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; uint8 bonding = TRUE; GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey ); GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding ); } // Initialize GATT attributes GGS_AddService( GATT_ALL_SERVICES ); // GAP GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes DevInfo_AddService(); // Device Information Service SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile #if defined FEATURE_OAD VOID OADTarget_AddService(); // OAD Profile #endif // Setup the SimpleProfile Characteristic Values { uint8 charValue1 = 1; uint8 charValue2 = 0; uint8 charValue3 = 3; uint8 charValue4 = 4; uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 }; SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &gMP ); SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 ); SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 ); SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 ); SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 ); } #if defined( CC2540_MINIDK ) SK_AddService( GATT_ALL_SERVICES ); // Simple Keys Profile // Register for all key events - This app will handle all key events RegisterForKeys( simpleBLEPeripheral_TaskID ); // makes sure LEDs are off HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF ); // For keyfob board set GPIO pins into a power-optimized state // Note that there is still some leakage current from the buzzer, // accelerometer, LEDs, and buttons on the PCB. P0SEL = 0; // Configure Port 0 as GPIO P1SEL = 0; // Configure Port 1 as GPIO P2SEL = 0; // Configure Port 2 as GPIO P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons), // all others (P0.2-P0.7) as output P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons) P1 = 0; // All pins on port 1 to low P2 = 0; // All pins on port 2 to low #endif // #if defined( CC2540_MINIDK ) #if (defined HAL_LCD) && (HAL_LCD == TRUE) #if defined FEATURE_OAD #if defined (HAL_IMAGE_A) HalLcdWriteStringValue( "BLE Peri-A", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 ); #else HalLcdWriteStringValue( "BLE Peri-B", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 ); #endif // HAL_IMAGE_A #else HalLcdWriteString( "iBeacon", HAL_LCD_LINE_1 ); #endif // FEATURE_OAD #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) // Register callback with SimpleGATTprofile VOID SimpleProfile_RegisterAppCBs( &simpleBLEPeripheral_SimpleProfileCBs ); // Enable clock divide on halt // This reduces active current while radio is active and CC254x MCU // is halted HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT ); #if defined ( DC_DC_P0_7 ) // Enable stack to toggle bypass control on TPS62730 (DC/DC converter) HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 ); #endif // defined ( DC_DC_P0_7 ) // Setup a delayed profile startup osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT ); }
/********************************************************************* * @fn txrxServiceChangeCB * * @brief Callback from SimpleBLEProfile indicating a value change * * @param paramID - parameter ID of the value that was changed. * * @return none */ static void txrxServiceChangeCB( uint8 paramID ) { uint8 data[20]; uint8 len; if (paramID == TXRX_RX_DATA_READY) { TXRX_GetParameter(RX_DATA_CHAR, &len, data); HalUARTWrite(NPI_UART_PORT, (uint8*)data, len); } else if (paramID == TXRX_RX_NOTI_ENABLED) { GAPRole_SendUpdateParam( DEFAULT_DESIRED_MAX_CONN_INTERVAL, DEFAULT_DESIRED_MIN_CONN_INTERVAL, DEFAULT_DESIRED_SLAVE_LATENCY, DEFAULT_DESIRED_CONN_TIMEOUT, GAPROLE_RESEND_PARAM_UPDATE ); } else if (paramID == BAUDRATE_SET) { uint8 newValue; TXRX_GetParameter(BAUDRATE_CHAR, &len, &newValue); switch(newValue) { case 0: //9600 { U0GCR &= 0xE0; U0GCR |= 0x08; U0BAUD = 59; break; } case 1: //19200 { U0GCR &= 0xE0; U0GCR |= 0x09; U0BAUD = 59; break; } case 2: //38400 { U0GCR &= 0xE0; U0GCR |= 0x0A; U0BAUD = 59; break; } case 3: //57600 { U0GCR &= 0xE0; U0GCR |= 0x0A; U0BAUD = 216; break; } case 4: //115200 { U0GCR &= 0xE0; U0GCR |= 0x0B; U0BAUD = 216; break; } default: break; } eeprom_write(1, newValue); } else if (paramID == DEV_NAME_CHANGED) { uint8 newDevName[GAP_DEVICE_NAME_LEN]; TXRX_GetParameter(DEV_NAME_CHAR, &len, newDevName); uint8 devNamePermission = GATT_PERMIT_READ|GATT_PERMIT_WRITE; GGS_SetParameter( GGS_W_PERMIT_DEVICE_NAME_ATT, sizeof ( uint8 ), &devNamePermission ); newDevName[ len ] = '\0'; GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, newDevName ); advertData[3] = len + 1; osal_memcpy(&advertData[5], newDevName, len); osal_memset(&advertData[len+5], 0, 31-5-len); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); eeprom_write(5, len); for(uint8 i=0; i<len; i++) { eeprom_write(i+8, newDevName[i]); } } else if (paramID == TX_POWER_CHANGED) { uint8 newValue; TXRX_GetParameter(TX_POWER_CHAR, &len, &newValue); if(newValue < 4 && newValue >= 0) { HCI_EXT_SetTxPowerCmd( newValue ); } eeprom_write(3, newValue); } }
/********************************************************************* * @fn SimpleBLEPeripheral_Init * * @brief Initialization function for the Simple BLE Peripheral App Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notificaiton ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void Biscuit_Init( uint8 task_id ) { biscuit_TaskID = task_id; // Setup the GAP VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL ); // Setup the GAP Peripheral Role Profile { // Device starts advertising upon initialization uint8 initial_advertising_enable = TRUE; // By setting this to zero, the device will go into the waiting state after // being discoverable for 30.72 second, and will not being advertising again // until the enabler is set back to TRUE uint16 gapRole_AdvertOffTime = 0; uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; // Set the GAP Role Parametersuint8 initial_advertising_enable = TRUE; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); } i2c_init(); // Set the GAP Characteristics uint8 nameFlag = eeprom_read(4); uint8 nameLen = eeprom_read(5); if( (nameFlag!=1) || (nameLen>20) ) // First time power up after burning firmware { GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName ); uint8 len = strlen( (char const *)attDeviceName ); TXRX_SetParameter( DEV_NAME_CHAR, len, attDeviceName ); eeprom_write(4, 1); eeprom_write(5, len); for(uint8 i=0; i<len; i++) { eeprom_write(i+8, attDeviceName[i]); } } else { uint8 devName[GAP_DEVICE_NAME_LEN]; for(uint8 i=0; i<nameLen; i++) { devName[i] = eeprom_read(i+8); } devName[nameLen] = '\0'; GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, devName ); TXRX_SetParameter( DEV_NAME_CHAR, nameLen, devName ); } uint8 LocalName[GAP_DEVICE_NAME_LEN]; nameLen = eeprom_read(5); for(uint8 i=0; i<nameLen; i++) { LocalName[i] = eeprom_read(i+8); } advertData[3] = nameLen + 1; osal_memcpy(&advertData[5], LocalName, nameLen); osal_memset(&advertData[nameLen+5], 0, 31-5-nameLen); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); // Set advertising interval { uint16 advInt = DEFAULT_ADVERTISING_INTERVAL; GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt ); GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt ); } // Setup the GAP Bond Manager { uint32 passkey = 0; // passkey "000000" uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = TRUE; uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; uint8 bonding = TRUE; GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey ); GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding ); } // Initialize GATT attributes GGS_AddService( GATT_ALL_SERVICES ); // GAP GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes //DevInfo_AddService(); // Device Information Service TXRX_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile #if defined FEATURE_OAD VOID OADTarget_AddService(); // OAD Profile #endif #if defined( CC2540_MINIDK ) // Register for all key events - This app will handle all key events RegisterForKeys( biscuit_TaskID ); // makes sure LEDs are off HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF ); // For keyfob board set GPIO pins into a power-optimized state // Note that there is still some leakage current from the buzzer, // accelerometer, LEDs, and buttons on the PCB. P0SEL = 0; // Configure Port 0 as GPIO P1SEL = 0; // Configure Port 1 as GPIO P2SEL = 0; // Configure Port 2 as GPIO P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons), // all others (P0.2-P0.7) as output P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons) P1 = 0; // All pins on port 1 to low P2 = 0; // All pins on port 2 to low #endif // #if defined( CC2540_MINIDK ) // Register callback with TXRXService VOID TXRX_RegisterAppCBs( &biscuit_TXRXServiceCBs ); // Enable clock divide on halt // This reduces active current while radio is active and CC254x MCU // is halted // HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT ); // Initialize serial interface P1SEL = 0x30; P1DIR |= 0x02; P1_1 = 1; PERCFG |= 1; NPI_InitTransport(dataHandler); uint8 flag, baud; uint8 value; flag = eeprom_read(0); baud = eeprom_read(1); if( flag!=1 || baud>4 ) // First time power up after burning firmware { U0GCR &= 0xE0; // Default baudrate 57600 U0GCR |= 0x0A; U0BAUD = 216; value = 3; eeprom_write(0, 1); eeprom_write(1, 3); } else { switch(baud) { case 0: //9600 { U0GCR &= 0xE0; U0GCR |= 0x08; U0BAUD = 59; value = 0; break; } case 1: //19200 { U0GCR &= 0xE0; U0GCR |= 0x09; U0BAUD = 59; value = 1; break; } case 2: //38400 { U0GCR &= 0xE0; U0GCR |= 0x0A; U0BAUD = 59; value = 2; break; } case 3: //57600 { U0GCR &= 0xE0; U0GCR |= 0x0A; U0BAUD = 216; value = 3; break; } case 4: //115200 { U0GCR &= 0xE0; U0GCR |= 0x0B; U0BAUD = 216; value = 4; break; } default: break; } } TXRX_SetParameter( BAUDRATE_CHAR, 1, &value ); uint8 flag2, txpwr; flag2 = eeprom_read(2); txpwr = eeprom_read(3); if( flag2!=1 || txpwr>3 ) // First time power up after burning firmware { HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_0_DBM ); txpwr = HCI_EXT_TX_POWER_0_DBM; eeprom_write(2, 1); eeprom_write(3, HCI_EXT_TX_POWER_0_DBM); } else { HCI_EXT_SetTxPowerCmd( txpwr ); } TXRX_SetParameter( TX_POWER_CHAR, 1, &txpwr ); // Setup a delayed profile startup osal_set_event( biscuit_TaskID, SBP_START_DEVICE_EVT ); }
/** * SNP_executeHCIcmd */ uint8_t SNP_executeHCIcmd(snpHciCmdReq_t *pReq, uint16_t dataLen) { bStatus_t stat; uint16_t opcode = pReq->opcode; uint8_t *pData = (uint8_t*)&pReq->pData; uint8_t status = blePending; if(snp_HCIstore.validity) { return SNP_CMD_ALREADY_IN_PROGRESS; } switch (opcode) { case SNP_HCI_OPCODE_EXT_RESET_SYSTEM: { stat = HCI_EXT_ResetSystemCmd(LL_EXT_RESET_SYSTEM_HARD); if(stat == SUCCESS) { status = SNP_SUCCESS; } else { status = bleIncorrectMode; } } break; case SNP_HCI_OPCODE_READ_BDADDR: { stat = HCI_ReadBDADDRCmd(); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_SET_BDADDR: { if(dataLen != B_ADDR_LEN) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetBDADDRCmd(pData); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } } break; case SNP_HCI_OPCODE_EXT_SET_TX_POWER: { if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetTxPowerCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } } break; case SNP_HCI_OPCODE_EXT_SET_SCA: if(dataLen != sizeof(uint16_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetSCACmd((pData[0] &0xFF) + (pData[1] << 8)); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_MODEM_TEST_TX: if(dataLen != 2*sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_ModemTestTxCmd(pData[0], pData[1]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_MODEM_HOP_TEST_TX: stat = HCI_EXT_ModemHopTestTxCmd(); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } break; case SNP_HCI_OPCODE_EXT_MODEM_TEST_RX: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_ModemTestRxCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_END_MODEM_TEST: stat = HCI_EXT_EndModemTestCmd(); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } break; case SNP_HCI_OPCODE_EXT_ENABLE_PTM: stat = HCI_EXT_EnablePTMCmd(); if(stat == SUCCESS) { status = SNP_SUCCESS; } else { status = stat; } break; case SNP_HCI_OPCODE_EXT_SET_MAX_DTM_TX_POWER: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetMaxDtmTxPowerCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_READ_RSSI: if(dataLen != sizeof(uint16_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_ReadRssiCmd((pData[0] &0xFF) + (pData[1] << 8)); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_LE_RECEIVER_TEST: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_LE_ReceiverTestCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_LE_TRANSMITTER_TEST: if(dataLen != 3 * sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_LE_TransmitterTestCmd(pData[0], pData[1], pData[2]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_LE_TEST_END: stat = HCI_LE_TestEndCmd(); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } break; case SNP_HCI_OPCODE_EXT_PER: if(dataLen != (sizeof(uint8_t) + sizeof(uint16_t))) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_PacketErrorRateCmd(pData[0] + (pData[1] << 8), pData[2]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_DECRYPT: if(dataLen != (KEYLEN + KEYLEN)) { status = SNP_INVALID_PARAMS; } else { // reverse byte order of key (MSB..LSB required) SNP_ReverseBytes(&pData[0], KEYLEN); // reverse byte order of encText (MSB..LSB required) SNP_ReverseBytes(&pData[KEYLEN], KEYLEN); stat = HCI_EXT_DecryptCmd(&pData[0], &pData[KEYLEN]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_LE_ENCRYPT: if(dataLen != (KEYLEN + KEYLEN)) { status = SNP_INVALID_PARAMS; } else { // reverse byte order of key (MSB..LSB required) SNP_ReverseBytes(&pData[0], KEYLEN); // reverse byte order of encText (MSB..LSB required) SNP_ReverseBytes(&pData[KEYLEN], KEYLEN); stat = HCI_LE_EncryptCmd(&pData[0], &pData[KEYLEN]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_OVERRIDE_SL: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetSlaveLatencyOverrideCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_SET_FAST_TX_RESP_TIME: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_SetFastTxResponseTimeCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_ONE_PKT_PER_EVT: if(dataLen != sizeof(uint8_t)) { status = SNP_INVALID_PARAMS; } else { stat = HCI_EXT_OnePktPerEvtCmd(pData[0]); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } } break; case SNP_HCI_OPCODE_EXT_GET_CONNECTION_INFO: stat = HCI_EXT_GetConnInfoCmd(NULL, NULL, NULL); if(stat == SUCCESS) { // Set state to wait for the HCI event with the address snp_HCIstore.validity = TRUE; snp_HCIstore.opcode = opcode; status = blePending; } else { status = stat; } break; default: status = SNP_HCI_CMD_UNKNOWN; break; } return status; }
/********************************************************************* * @fn keyfobapp_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void keyfobapp_HandleKeys( uint8 shift, uint8 keys ) { uint8 SK_Keys = 0; (void)shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_1 ) { SK_Keys |= SK_KEY_LEFT; // if is active, pressing the left key should toggle // stop the alert if( keyfobAlertState != ALERT_STATE_OFF ) { keyfobapp_StopAlert(); } // if device is in a connection, toggle the Tx power level between 0 and // -6 dBm if( gapProfileState == GAPROLE_CONNECTED ) { int8 currentTxPowerLevel; int8 newTxPowerLevel; ProxReporter_GetParameter( PP_TX_POWER_LEVEL, ¤tTxPowerLevel ); switch ( currentTxPowerLevel ) { case 0: newTxPowerLevel = -6; // change power to -6 dBm HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_MINUS_6_DBM ); // Update Tx powerl level in Proximity Reporter (and send notification) // if enabled) ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &newTxPowerLevel ); break; case (-6): newTxPowerLevel = 0; // change power to 0 dBm HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_0_DBM ); // Update Tx powerl level in Proximity Reporter (and send notification) // if enabled) ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &newTxPowerLevel ); break; default: // do nothing break; } } } if ( keys & HAL_KEY_SW_2 ) { SK_Keys |= SK_KEY_RIGHT; // if device is not in a connection, pressing the right key should toggle // advertising on and off if( gapProfileState != GAPROLE_CONNECTED ) { uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; //Find the current GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status ); if( current_adv_enabled_status == FALSE ) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } //change the GAP advertisement status to opposite of current status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); } } SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys ); }
/********************************************************************* * @fn SimpleBLEPeripheral_ProcessEvent * * @brief Simple BLE Peripheral Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return events not processed */ uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events ) { VOID task_id; // OSAL required parameter that isn't used in this function if ( events & SYS_EVENT_MSG ) { uint8 *pMsg; if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL ) { simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg ); // Release the OSAL message VOID osal_msg_deallocate( pMsg ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } if ( events & SBP_START_DEVICE_EVT ) { // << Wayne >> << -23dB TX Power >> ++ HCI_EXT_SetTxPowerCmd(LL_EXT_TX_POWER_MINUS_23_DBM); // << Wayne >> << -23dB TX Power >> -- // Start the Device VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs ); // Start Bond Manager VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs ); // Set timer for first periodic event osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); return ( events ^ SBP_START_DEVICE_EVT ); } if ( events & SBP_PERIODIC_EVT ) { // Restart timer if ( SBP_PERIODIC_EVT_PERIOD ) { osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); } // Perform periodic application task performPeriodicTask(); return (events ^ SBP_PERIODIC_EVT); } // << Wayne >> << Clock >> ++ if ( events & SBP_CLOCK_UPDATE_EVT ) { if ( DEFAULT_CLOCK_UPDATE_PERIOD ) { osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_CLOCK_UPDATE_EVT, DEFAULT_CLOCK_UPDATE_PERIOD ); } timeAppClockDisplay(); if(storeCloseTime(23,59)) { UART_SEND_DEBUG_MSG( "Action > CleanCounter\r\n", 23 ); dbExchangeCounter = 0; } // Restart clock tick timer return (events ^ SBP_CLOCK_UPDATE_EVT); } // << Wayne >> << Clock >> -- // << Wayne >> << Check Connect Overtime> > ++ if ( events & SBP_CONNECT_OVERTIME_EVT ) { Application_TerminateConnection(); UART_SEND_DEBUG_MSG( "Action > Terminate\r\n", 20 ); return (events ^ SBP_CONNECT_OVERTIME_EVT); } // << Wayne >> << Check Connect Overtime> > -- // Discard unknown events return 0; }