ver 0.5, add flash_eep, support BTH01

This commit is contained in:
pvvx 2024-01-14 21:46:56 +03:00
parent 993db00e2e
commit 29e0e3283e
27 changed files with 6648 additions and 3037 deletions

2836
BTH01_v05.hex Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,22 @@
# THB2
Custom firmware for Tuya [THB2](https://pvvx.github.io/THB2).
# THB2 BTH01
Custom firmware for Tuya [THB2](https://pvvx.github.io/THB2) and [BTH01](https://pvvx.github.io/BTH01/).
* Проект в начальной стадии разработки, до появления функционального OTA.
В плане проекта предусматривается дальнейшая поддержка BTH01 и [TH-05](https://pvvx.github.io/TH-05).
Всё, кроме OTA работает стабильно.
Прошивка V0.4 для THB2 (файл TestTHB2.hex). Всё, кроме OTA работает стабильно.
В плане проекта предусматривается дальнейшая поддержка [TH-05](https://pvvx.github.io/TH-05).
Прошивка V0.5 для THB2 (файл THB2_v05.hex).
Прошивка V0.5 для BTH01 (файл BTH01_v05.hex).
## Основные характеристики:
* Интервал BLE рекламы в формате BTHome v2 составляет 5 секунд.
* Опрос датчика влажности и температуры производится каждый второй интервал BLE рекламы - период составляет 10 секунд.
* Измерение напряжения батареи производится каждые 3 минуты.
* Кнопка используется для быстрого подключения со старыми адаптерами. Нажатие кнопки переключает интервал BLE рекламы на более короткий период. Действие продолжится 60 секунд, затем интервал восстановится.
* Измеренное среднее потребление от источника в 3.3В при сканировании термометра в пассивном режиме составляет 7.9 мкА.
* Измерение напряжения батареи производится каждую минуту.
* Кнопка используется для быстрого подключения к старым BT-адаптерам. Нажатие кнопки переключает интервал BLE рекламы на более короткий период. Действие продолжится 60 секунд, затем интервал восстановится.
* Измеренное среднее потребление от источника в 3.3В при сканировании термометра в пассивном режиме составляет до 7.9 мкА.
## Прошивка:
@ -22,7 +25,7 @@ Custom firmware for Tuya [THB2](https://pvvx.github.io/THB2).
1. Соединить GND, TX, RX, RTSRESET, VCC (+3.3B).
2. Запустить:
```
python3 rdwr_phy62x2.py -p COM11 -e -r wh TestTHB2.hex
python3 rdwr_phy62x2.py -p COM11 -e -r wh THB2_v05.hex
```
3. Прошивка зашита. Устройство работает.

2827
THB2_v05.hex Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -322,6 +322,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="reset" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>${cross_make}</buildCommand>
<buildArguments>-j24</buildArguments>
<buildTarget>reset</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

View file

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View file

@ -1,8 +1,8 @@
##############################################################################
PROJECT_NAME = bthome_phy6222
PROJECT_NAME ?= bthome_phy6222
#POJECT_DEF ?= -DDEVICE=DEVICE_THB2
##############################################################################
COM_PORT = COM11
##############################################################################
# Source
@ -14,12 +14,13 @@ SRC_PRJ += battservice.c
SRC_PRJ += bthome_beacon.c
SRC_PRJ += osal_peripheral.c
SRC_PRJ += peripheral_main.c
SRC_PRJ += sbp_profile_ota.c
#SRC_PRJ += sbp_profile_ota.c
SRC_PRJ += devinfoservice.c
SRC_PRJ += sensors.c
SRC_PRJ += thb2_main.c
SRC_PRJ += thb2_peripheral.c
SRC_PRJ += thservice.c
SRC_PRJ += flash_eep.c
INCLUDES = -I$(SRC_PATH)
@ -100,7 +101,7 @@ INCLUDES += -I$(SDK_PATH)/components/driver/voice
INCLUDES += -I$(SDK_PATH)/components/driver/watchdog
INCLUDES += -I$(SDK_PATH)/components/libraries/crc16
INCLUDES += -I$(SDK_PATH)/components/libraries/cliface
INCLUDES += -I$(SDK_PATH)/components/libraries/fs
#INCLUDES += -I$(SDK_PATH)/components/libraries/fs
INCLUDES += -I$(SDK_PATH)/components/driver/watchdog
@ -189,6 +190,7 @@ STARTUP_OBJ =
##############################################################################
DEFINES = -D__GCC
DEFINES += $(POJECT_DEF)
DEFINES += -DDEBUG_INFO=0
DEFINES += -DMTU_SIZE=247
DEFINES += -DCFG_SLEEP_MODE=PWR_MODE_SLEEP
@ -266,6 +268,9 @@ flash:
erase_and_flash:
@$(PYTHON) ./rdwr_phy62x2.py -p$(COM_PORT) -b 1000000 -e -r wh $(OBJ_DIR)/$(PROJECT_NAME).hex
reset:
@$(PYTHON) ./rdwr_phy62x2.py -p$(COM_PORT) -r i
directory:
@mkdir -p $(OBJ_DIR)

View file

@ -573,9 +573,13 @@ int hal_fs_item_write(uint16_t id,uint8_t* buf,uint16_t len)
if((buf == NULL) || (len == 0)||(len > 4095))
return PPlus_ERR_FS_PARAMETER;
if(len > hal_fs_get_free_size())
return PPlus_ERR_FS_NOT_ENOUGH_SIZE;
if(len > hal_fs_get_free_size()) {
if(hal_fs_get_garbage_size(NULL) > len+32)
hal_fs_garbage_collect();
else
return PPlus_ERR_FS_NOT_ENOUGH_SIZE;
}
//if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS)
// return PPlus_ERR_FS_EXIST_SAME_ID;
if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS)

View file

@ -13,14 +13,10 @@
#ifndef USE_FS
#define USE_FS 1
#endif
#ifdef USE_FS
#include "fs.h"
#endif
#if (USE_FS == 0)
#define NVM_BASE_ADDR 0x1103C000 //16K bytes
#define NVM_BASE_ADDR 0x1103C000 //16K bytes
uint8 osal_snv_init( void )
{
@ -51,6 +47,8 @@ uint8 osal_snv_compact( uint8 threshold )
#else
#include "fs.h"
uint8 osal_snv_init( void )
{
if(!hal_fs_initialized())

View file

@ -486,7 +486,7 @@ bStatus_t GAPBondMgr_SetParameter( uint16 param, uint8 len, void* pValue )
}
break;
#if ( HOST_CONFIG & CENTRAL_CFG )
#if ( HOST_CONFIG & CENTRAL_CFG )
case GAPBOND_BOND_FAIL_ACTION:
if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAPBOND_FAIL_TERMINATE_ERASE_BONDS) )
@ -499,7 +499,7 @@ bStatus_t GAPBondMgr_SetParameter( uint16 param, uint8 len, void* pValue )
}
break;
#endif
#endif
default:
@ -669,7 +669,7 @@ bStatus_t GAPBondMgr_LinkEst( uint8 addrType, uint8* pDevAddr, uint16 connHandle
}
}
#if ( HOST_CONFIG & CENTRAL_CFG )
#if ( HOST_CONFIG & CENTRAL_CFG )
else if ( role == GAP_PROFILE_CENTRAL &&
gapBond_PairingMode[connHandle] == GAPBOND_PAIRING_MODE_INITIATE )
{
@ -683,8 +683,8 @@ bStatus_t GAPBondMgr_LinkEst( uint8 addrType, uint8* pDevAddr, uint16 connHandle
}
}
#endif
#if ( HOST_CONFIG & PERIPHERAL_CFG )
#endif
#if ( HOST_CONFIG & PERIPHERAL_CFG )
// If Peripheral and initiating, send a slave security request to
// initiate either pairing or encryption
@ -694,7 +694,7 @@ bStatus_t GAPBondMgr_LinkEst( uint8 addrType, uint8* pDevAddr, uint16 connHandle
gapBondMgrSlaveSecurityReq( connHandle );
}
#endif
#endif
return ( SUCCESS );
}
@ -993,7 +993,7 @@ uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t* pMsg )
// dropped at the LL because of a MIC failure, so again nothing to do.
{
gapBondCompleteEvent_t* pPkt = (gapBondCompleteEvent_t*)pMsg;
#if ( HOST_CONFIG & CENTRAL_CFG )
#if ( HOST_CONFIG & CENTRAL_CFG )
if ( pPkt->hdr.status == LL_ENC_KEY_REQ_REJECTED )
{
@ -1032,7 +1032,7 @@ uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t* pMsg )
}
}
#endif
#endif
if ( pGapBondCB && pGapBondCB->pairStateCB )
{
@ -1054,7 +1054,7 @@ uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t* pMsg )
}
}
break;
#if ( HOST_CONFIG & PERIPHERAL_CFG )
#if ( HOST_CONFIG & PERIPHERAL_CFG )
case GAP_PAIRING_REQ_EVENT:
{
@ -1110,8 +1110,8 @@ uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t* pMsg )
}
}
break;
#endif
#if ( HOST_CONFIG & CENTRAL_CFG )
#endif
#if ( HOST_CONFIG & CENTRAL_CFG )
case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
{
@ -1142,7 +1142,7 @@ uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t* pMsg )
}
}
break;
#endif
#endif
case GAP_LINK_TERMINATED_EVENT:
{
@ -1393,7 +1393,7 @@ static uint8 gapBondMgrAddBond( gapBondRec_t* pBondRec, gapAuthCompleteEvent_t*
bondIdx = gapBondMgrFindEmpty();
}
#if(GAP_BOND_MGR_INDEX_REPLACE)
#if(GAP_BOND_MGR_INDEX_REPLACE)
/*replace bondIdx*/
if(bondIdx==GAP_BONDINGS_MAX)
@ -1401,7 +1401,7 @@ static uint8 gapBondMgrAddBond( gapBondRec_t* pBondRec, gapAuthCompleteEvent_t*
bondIdx = (bondReplaceCnt++)%GAP_BONDINGS_MAX;
}
#endif
#endif
}
if ( bondIdx < GAP_BONDINGS_MAX )

View file

@ -3912,7 +3912,7 @@ void llSetupConn( void )
uint16 winOffset;
uint16 adjustment;
uint32 initST = initInfo.llTask->t2e1.coarse;
#if defined(LL_MANUAL_WINOFFSET)
#if defined(LL_MANUAL_WINOFFSET)
// Note: Normally, the window offset is managed dynamically so that precise
// connection start times can be achieved (necessary for multiple
// connnections). However, sometimes it is useful to force the window
@ -3942,9 +3942,9 @@ void llSetupConn( void )
// interval and an offset associated with the connection, less the adjustment
// Note: connST can never be less than or equal to initTask start time.
connST = (initST + connCI - adjustment + (initInfo.connId * NUM_SLOTS_PER_MASTER)) & 0x00FFFFFF;
#ifdef DEBUG
#ifdef DEBUG
LL_ASSERT( connST > initST );
#endif // DEBUG
#endif // DEBUG
// calc the window offset for the new connection
// Note: Subtract the 1.25ms the Slave will add on per the spec, plus
// additional time to ensure the Slave starts before the Masters
@ -3979,7 +3979,7 @@ void llSetupConn( void )
//newWinOffset_debug = winOffset;
//initST_debug = initST;
return;
#endif
#endif
}
/*******************************************************************************
@ -4363,7 +4363,7 @@ uint8 llLtTwoChangesInLastSixBits( uint32 accessAddr )
uint8 llEqAlreadyValidAddr( uint32 accessAddr )
{
(void) accessAddr;
#if 0
#if 0
uint8 i;
// check any already existing connections don't have the same access address
@ -4375,7 +4375,7 @@ uint8 llEqAlreadyValidAddr( uint32 accessAddr )
}
}
#endif
#endif
return( FALSE );
}

View file

@ -39,13 +39,13 @@
/**
GATT Services
*/
// Generic Access Profile Service UUID
// Generic Access Profile Service UUID 0x1800
CONST uint8 gapServiceUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GAP_SERVICE_UUID ), HI_UINT16( GAP_SERVICE_UUID )
};
// Generic Attribute Profile Service UUID
// Generic Attribute Profile Service UUID 0x1801
CONST uint8 gattServiceUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_SERVICE_UUID ), HI_UINT16( GATT_SERVICE_UUID )
@ -54,25 +54,25 @@ CONST uint8 gattServiceUUID[ATT_BT_UUID_SIZE] =
/**
GATT Declarations
*/
// Primary Service UUID
// Primary Service UUID 0x2801
CONST uint8 primaryServiceUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_PRIMARY_SERVICE_UUID ), HI_UINT16( GATT_PRIMARY_SERVICE_UUID )
};
// Secondary Service UUID
// Secondary Service UUID 0x2801
CONST uint8 secondaryServiceUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_SECONDARY_SERVICE_UUID ), HI_UINT16( GATT_SECONDARY_SERVICE_UUID )
};
// Include UUID
// Include UUID 0x2802
CONST uint8 includeUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_INCLUDE_UUID ), HI_UINT16( GATT_INCLUDE_UUID )
};
// Characteristic UUID
// Characteristic UUID 0x2803
CONST uint8 characterUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CHARACTER_UUID ), HI_UINT16( GATT_CHARACTER_UUID )
@ -81,37 +81,37 @@ CONST uint8 characterUUID[ATT_BT_UUID_SIZE] =
/**
GATT Descriptors
*/
// Characteristic Extended Properties UUID
// Characteristic Extended Properties UUID 0x2900
CONST uint8 charExtPropsUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CHAR_EXT_PROPS_UUID ), HI_UINT16( GATT_CHAR_EXT_PROPS_UUID )
};
// Characteristic User Description UUID
// Characteristic User Description UUID 0x2901
CONST uint8 charUserDescUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CHAR_USER_DESC_UUID ), HI_UINT16( GATT_CHAR_USER_DESC_UUID )
};
// Client Characteristic Configuration UUID
// Client Characteristic Configuration UUID 0x2902
CONST uint8 clientCharCfgUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CLIENT_CHAR_CFG_UUID ), HI_UINT16( GATT_CLIENT_CHAR_CFG_UUID )
};
// Server Characteristic Configuration UUID
// Server Characteristic Configuration UUID 0x2903
CONST uint8 servCharCfgUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_SERV_CHAR_CFG_UUID ), HI_UINT16( GATT_SERV_CHAR_CFG_UUID )
};
// Characteristic Presentation Format UUID
// Characteristic Presentation Format UUID 0x2904
CONST uint8 charFormatUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CHAR_FORMAT_UUID ), HI_UINT16( GATT_CHAR_FORMAT_UUID )
};
// Characteristic Aggregate Format UUID
// Characteristic Aggregate Format UUID 0x2905
CONST uint8 charAggFormatUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16( GATT_CHAR_AGG_FORMAT_UUID ), HI_UINT16( GATT_CHAR_AGG_FORMAT_UUID )

View file

@ -53,12 +53,13 @@
// #define __BUILD_PATCH_CFG__ __BUILD_RF_LIB_MST__
//#endif
#ifndef USE_CODED_PHY
#define USE_CODED_PHY 1
#endif
#define DBG_BUILD_LL_TIMING 0 //0x01 for enable LL timing debug
// ======================
//#define DBG_GPIO_WRITE(a,b) gpio_write((a),(b))
#define DBG_GPIO_WRITE(a,b)
@ -3787,10 +3788,10 @@ uint8 llProcessMasterControlProcedures1( llConnState_t* connPtr )
// Note: Unreachable statement generates compiler warning!
//break;
default:
#ifdef DEBUG
#ifdef DEBUG
// fatal error - a unknown control procedure value was used
LL_ASSERT( FALSE );
#endif // DEBUG
#endif // DEBUG
break;
}
}
@ -6195,9 +6196,9 @@ llStatus_t LL_SetAdvControl1( uint8 advMode )
return( LL_STATUS_ERROR_BAD_PARAMETER );
}
#ifdef DEBUG_LL
#ifdef DEBUG_LL
LOG("llState = %d\n", llState);
#endif
#endif
// check if we should begin advertising
switch( advMode )
@ -6348,7 +6349,7 @@ llStatus_t LL_SetAdvControl1( uint8 advMode )
}
#if 0
#if USE_CODED_PHY
//2020.10.22,Jie,fix phyupdate issue
llStatus_t LL_PhyUpdate1( uint16 connId )
{
@ -6747,7 +6748,7 @@ uint16 ll_generateTxBuffer1(int txFifo_vacancy, uint16* pSave_ptr)
}
#if 0
#if USE_CODED_PHY
//2020.10.23 Jie,fix setphymode issue
llStatus_t LL_SetPhyMode1( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy,uint16 phyOptions)
{
@ -6910,7 +6911,7 @@ llStatus_t LL_CreateConn1( uint16 scanInterval,
maxLength );
}
#if 0
#if USE_CODED_PHY
//2020.11.12, add case LL_REJECT_IND_EXT
void llProcessMasterControlPacket1( llConnState_t* connPtr,
uint8* pBuf )
@ -7890,9 +7891,13 @@ void init_config(void)
extern void l2capPocessFragmentTxData(uint16 connHandle);
JUMP_FUNCTION(L2CAP_PROCESS_FREGMENT_TX_DATA) = (uint32_t)&l2capPocessFragmentTxData;
//BQB bug fix,2020.11.17
//JUMP_FUNCTION(LL_PHY_MODE_UPDATE) = (uint32_t)&LL_PhyUpdate1;
#if USE_CODED_PHY
JUMP_FUNCTION(LL_PHY_MODE_UPDATE) = (uint32_t)&LL_PhyUpdate1;
#endif
JUMP_FUNCTION(LL_SET_DATA_LENGTH) = (uint32_t)&LL_SetDataLengh1;
//JUMP_FUNCTION(LL_SET_PHY_MODE) = (uint32_t)&LL_SetPhyMode1;
#if USE_CODED_PHY
JUMP_FUNCTION(LL_SET_PHY_MODE) = (uint32_t)&LL_SetPhyMode1;
#endif
JUMP_FUNCTION(LL_PROCESS_TX_DATA) = (uint32_t)&llProcessTxData1;
JUMP_FUNCTION(LL_GENERATE_TX_BUFFER) = (uint32_t)&ll_generateTxBuffer1;
JUMP_FUNCTION(LL_ADP_ADJ_NEXT_TIME) = (uint32_t)&ll_adptive_adj_next_time1;
@ -7923,7 +7928,9 @@ void ll_patch_master(void)
JUMP_FUNCTION(LL_MASTER_EVT_ENDOK) = (uint32_t)&llMasterEvt_TaskEndOk1;
JUMP_FUNCTION(LL_SET_SCAN_PARAM) = (uint32_t)&LL_SetScanParam1;
JUMP_FUNCTION(LL_SET_SCAN_CTRL) = (uint32_t)&LL_SetScanControl1;
//JUMP_FUNCTION(LL_PROCESS_MASTER_CTRL_PKT) = (uint32_t)&llProcessMasterControlPacket1;
#if USE_CODED_PHY
JUMP_FUNCTION(LL_PROCESS_MASTER_CTRL_PKT) = (uint32_t)&llProcessMasterControlPacket1;
#endif
JUMP_FUNCTION(LL_CREATE_CONN) = (uint32_t)&LL_CreateConn1;
JUMP_FUNCTION(LL_START_ENCRYPT) = (uint32_t)&LL_StartEncrypt1;
JUMP_FUNCTION(LL_ENC_DECRYPT) = (uint32_t)&LL_ENC_Decrypt1;

View file

@ -15,6 +15,9 @@ MEMORY
gcfgtbl (rw) : ORIGIN = 0x1fff0400, LENGTH = 0x00400
sram (rwx) : ORIGIN = 0x1fff1838, LENGTH = 0x0E7C8
flash (rx) : ORIGIN = 0x11020000, LENGTH = 0x20000
sram2 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
sram3 (rwx) : ORIGIN = 0x20010000, LENGTH = 0x02000
sram4 (rwx) : ORIGIN = 0x20012000, LENGTH = 0x00800
}
OUTPUT_ARCH(arm)

View file

@ -1,5 +1,16 @@
set PATH=D:\MCU\GNU_Tools_ARM_Embedded\13.2.rel1\bin;%PATH%
make -s clean
make -s -j24
@set PATH=D:\MCU\GNU_Tools_ARM_Embedded\13.2.rel1\bin;%PATH%
@set SWVER=_v05
@del /Q "THB2%SWVER%.hex"
@mkdir .\bin
@make -s clean
@make -s -j PROJECT_NAME=THB2%SWVER% POJECT_DEF="-DDEVICE=DEVICE_THB2"
@if not exist "build\THB2%SWVER%.hex" goto :error
@copy "build\THB2%SWVER%.hex" .\bin
@del /Q "build\BTH01%SWVER%.hex"
@make -s clean
@make -s -j PROJECT_NAME=BTH01%SWVER% POJECT_DEF="-DDEVICE=DEVICE_BTH01"
@if not exist "build\BTH01%SWVER%.hex" goto :error
@copy "build\BTH01%SWVER%.hex" .\bin
@exit
:error
@echo "Error!"

View file

@ -41,9 +41,11 @@ void __attribute__((used)) hal_ADC_IRQHandler(void) {
if (g_system_clk != SYS_CLK_DBL_32M) {
AP_PCRM->CLKHF_CTL1 &= ~BIT(13);
}
hal_gpio_cfg_analog_io(ADC_PIN, Bit_DISABLE);
hal_gpio_pin_init(ADC_PIN, GPIO_INPUT); // ie=0, oen=1 set to imput
hal_gpio_pull_set(ADC_PIN, GPIO_FLOATING);
AP_IOMUX->Analog_IO_en &= ~BIT(ADC_PIN - P11); // hal_gpio_cfg_analog_io(ADC_PIN, Bit_DISABLE);
#if !ADC_PIN_USE_OUT
// hal_gpio_pin_init(ADC_PIN, GPIO_INPUT); // ie=0, oen=1 set to imput
// hal_gpio_pull_set(ADC_PIN, GPIO_FLOATING);
#endif
AP_PCRM->ANA_CTL &= ~BIT(0); // Power down analog LDO
hal_clk_reset(MOD_ADCC);
hal_clk_gate_disable(MOD_ADCC);
@ -115,7 +117,11 @@ static void init_adc_batt(void) {
AP_PCRM->ADC_CTL2 &= ~(BIT(20) | BIT(4));
AP_PCRM->ADC_CTL3 &= ~(BIT(20) | BIT(4));
AP_PCRM->ANA_CTL &= ~BIT(23); //disable micbias
hal_gpio_pull_set(ADC_PIN, GPIO_FLOATING);
hal_gpio_ds_control(ADC_PIN, Bit_ENABLE);
hal_gpio_cfg_analog_io(ADC_PIN, Bit_ENABLE);
#if ADC_PIN_USE_OUT
hal_gpio_pin_init(ADC_PIN, GPIO_OUTPUT);
hal_gpio_write(ADC_PIN, 1);
AP_IOMUX->pad_ps0 |= BIT(ADC_PIN); // hal_gpio_ds_control(ADC_PIN, Bit_ENABLE);
#else
AP_IOMUX->Analog_IO_en |= BIT(ADC_PIN - P11); // hal_gpio_cfg_analog_io(ADC_PIN, Bit_ENABLE);
#endif
}

View file

@ -43,12 +43,12 @@ extern "C"
#define DEFAULT_CONN_PAUSE_PERIPHERAL 2
// Simple BLE Peripheral Task Events
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_RESET_ADV_EVT 0x0002
#define SBP_DEALDATA 0x0004
#define TIMER_BATT_EVT 0x0008 //for battery detect
#define BATT_VALUE_EVT 0x0010 //event for battery voltage value update
#define ADV_BROADCAST_EVT 0x0020
#define SBP_START_DEVICE_EVT 0x0001 // start
#define SBP_RESET_ADV_EVT 0x0002 // enable adv (from gaprole_start)
#define SBP_DEALDATA 0x0004 // receive command data
#define TIMER_BATT_EVT 0x0008 // for battery detect
#define BATT_VALUE_EVT 0x0010 // Event for battery voltage value update
#define ADV_BROADCAST_EVT 0x0020 // Advent. Event Done Notice
/*********************************************************************
* MACROS

View file

@ -8,32 +8,56 @@
#ifndef SOURCE_CONFIG_H_
#define SOURCE_CONFIG_H_
#ifndef APP_VERSION
#define APP_VERSION 0x05 // BCD
#endif
#define APP_VERSION 0x04 // BCD
#define DEVICE_BTH2 1
#define DEVICE_THB2 1
#define DEVICE_BTH01 2
#define DEVICE_TH05 3
#ifndef DEVICE
#define DEVICE DEVICE_BTH2
#define DEVICE DEVICE_THB2
#endif
#define DEF_SOFTWARE_REVISION {'V', '0'+ (APP_VERSION >> 4), '.' , '0'+ (APP_VERSION & 0x0F), 0}
#if DEVICE == DEVICE_BTH2
#if DEVICE == DEVICE_THB2
/* Model: THB2 */
#define ADC_PIN_USE_OUT 0
#define ADC_PIN GPIO_P11
#define ADC_CHL ADC_CH1N_P11
#define I2C_SDA GPIO_P18
#define I2C_SCL GPIO_P20
#define GPIO_KEY GPIO_P07
#define GPIO_LED GPIO_P26
#define LED_ON 0
#define LED_OFF 1
#define DEF_MODEL_NUMBER_STR "THB2"
#define DEF_HARDWARE_REVISION "0001"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_BTH01
/* Model: BTH01 */
#define ADC_PIN_USE_OUT 1 // hal_gpio_write(ADC_PIN, 1);
#define ADC_PIN GPIO_P11
#define ADC_CHL ADC_CH1N_P11
#define I2C_SDA GPIO_P33 // CHT8305_SDA
#define I2C_SCL GPIO_P34 // CHT8305_SCL
#define GPIO_SPWR GPIO_P00 // питание сенсора CHT8305_VDD
#define GPIO_KEY GPIO_P14
#define GPIO_LED GPIO_P15
#define LED_ON 1
#define LED_OFF 0
#define DEF_MODEL_NUMBER_STR "BTH01"
#define DEF_HARDWARE_REVISION "0001"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#else
#error "DEVICE Not released!"
#endif
@ -44,12 +68,8 @@
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 24 // 30 ms
// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY 29
#define DEFAULT_DESIRED_SLAVE_LATENCY 29 // (29+1)*30 = 900 ms
// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT 400 // 4s
// fs ids
#define FS_ID_MAC 0xACAD
#endif /* SOURCE_CONFIG_H_ */

View file

@ -157,7 +157,7 @@ const uint8 devInfoModelNumber[] = DEF_MODEL_NUMBER_STR;
#if SERIAL_NUMBER_STR_ENABLE
// Serial Number String characteristic
static uint8 devInfoSerialNumberProps = GATT_PROP_READ;
uint8 devInfoSerialNumber[17]; // = "000000-0000-0000"; // FLASH_ID-SENSOR_ID-EFUSE
uint8 devInfoSerialNumber[19]; // = "000000-00000000-0000"; // FLASH_ID-SENSOR_ID-EFUSE
#endif
#if FIRMWARE_REVISION_ENABLE

View file

@ -99,7 +99,7 @@ bStatus_t DevInfo_SetParameter( uint8 param, uint8 len, void* value );
extern bStatus_t DevInfo_GetParameter( uint8 param, void* value );
extern uint8 devInfoSerialNumber[17];
extern uint8 devInfoSerialNumber[19];
extern const uint8 devInfoModelNumber[];
/*********************************************************************
*********************************************************************/

View file

@ -0,0 +1,456 @@
/*
* flash_eep.c
*
* Created on: 19/01/2015
* Author: pvvx
*/
#include <string.h>
#include "types.h"
//#include "config.h"
#include "flash.h"
#include "flash_eep.h"
//-----------------------------------------------------------------------------
#define FEEP_ERR_PREFIX "[FEEP Err]"
#define FEEP_WARN_PREFIX "[FEEP Wrn]"
#define FEEP_INFO_PREFIX "[FEEP Inf]"
#ifdef CONFIG_DEBUG_ERR_MSG
#define DBG_FEEP_ERR(...) do {\
if (likely(ConfigDebugErr & _DBG_FEEP_)) \
dbg_printf(FEEP_ERR_PREFIX __VA_ARGS__); \
}while(0)
#else
#define DBG_FEEP_ERR(...)
#endif
#ifdef CONFIG_DEBUG_WARN_MSG
#define DBG_FEEP_WARN(...) do {\
if (likely(ConfigDebugWarn & _DBG_FEEP_)) \
dbg_printf(FEEP_WARN_PREFIX __VA_ARGS__); \
}while(0)
#else
#define DBG_FEEP_WARN(...)
#endif
#ifdef CONFIG_DEBUG_INFO_MSG
#define DBG_FEEP_INFO(...) do {\
if (unlikely(ConfigDebugInfo & _DBG_FEEP_)) \
dbg_printf(FEEP_INFO_PREFIX __VA_ARGS__); \
}while(0)
#else
#define DBG_FEEP_INFO(...)
#endif
#define _flash_mutex_lock()
#define _flash_mutex_unlock()
#define _flash_clear_cache() // TLRS8xxx ?
#define _flash_erase_sector(addr) hal_flash_erase_sector(FLASH_BASE_ADDR + addr)
#define _flash_write_dword(addr, wd) flash_write_word(FLASH_BASE_ADDR + addr,wd)
#if MAX_FOBJ_SIZE > 256
// wraddr, len, pbuf
#define _flash_write(addr,len,pbuf) hal_flash_write(FLASH_BASE_ADDR + addr,(unsigned char *)pbuf, len)
#else
// wraddr, len, pbuf
#define _flash_write(addr,len,pbuf) hal_flash_write(FLASH_BASE_ADDR + addr,(unsigned char *)pbuf, len)
#endif
#ifndef LOCAL
#define LOCAL static
#endif
#ifndef true
#define true (1)
#endif
#ifndef false
#define false (0)
#endif
#ifndef mMIN
#define mMIN(a, b) ((a < b)? a : b)
#endif
#define align(a) ((a + 3) & 0xFFFFFFFC)
#define FEEP_CODE_ATTR __ATTR_SECTION_XIP__
#define FEEP_DATA_ATTR
typedef union __attribute__((packed)) // заголовок объекта сохранения feep
{
struct {
unsigned short size;
unsigned short id;
} __attribute__((packed)) n;
unsigned int x;
} fobj_head;
#define fobj_head_size 4
#define fobj_x_free 0xffffffff
#define FMEM_ERROR_MAX 5
#define USE_BUFFER_RAM 0 // =1 RAM, =0 Stack
#if USE_BUFFER_RAM
//extern void *pvPortMalloc( size_t xWantedSize );
//extern void vPortFree( void *pv );
FEEP_DATA_ATTR
unsigned char buf_epp[MAX_FOBJ_SIZE+fobj_head_size];
#define eep_malloc(a) buf_epp // pvPortMalloc(a)
#define eep_free(a) // vPortFree(a)
#endif
#if 1 // =1 Use XIP
#define _flash_read_dword(a) (*(volatile uint32_t*)(FLASH_BASE_ADDR + (a)))
#define _flash_read(a,b,c) memcpy((void *)c, (void *)(FLASH_BASE_ADDR + (unsigned int)a), b) // _flash_read(rdaddr, len, pbuf);
#define _flash_memcmp(a,b,c) memcmp((void *)(FLASH_BASE_ADDR + (unsigned int)a), c, b) // _flash_memcmp(xfaddr + fobj_head_size, size, ptr) == 0)
#else
#define _flash_read(aadr,len,pbuf) hal_flash_read(FLASH_BASE_ADDR + addr, (u8 *) pbuf, len)
inline unsigned int _flash_read_dword(unsigned int addr) {
unsigned int ret;
_flash_read(FLASH_BASE_ADDR + addr, 4, &ret);
return ret;
}
inline unsigned int _flash_memcmp(unsigned int addr, unsigned int len, unsigned char * buf) {
_flash_read(FLASH_BASE_ADDR + addr, len, &buf_epp);
return memcmp(buf_epp, buf, len);
}
#endif
/*
void flash_erase_sector_bt(unsigned int addr) {
if(bls_ll_requestConnBrxEventDisable() > 256) {
bls_ll_disableConnBrxEvent();
flash_erase_sector(addr);
bls_ll_restoreConnBrxEvent();
} else
flash_erase_sector(addr);
}
*/
//-----------------------------------------------------------------------------
// FunctionName : get_addr_bscfg
// поиск текушего сегмента
// Return : адрес сегмента
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
LOCAL unsigned int get_addr_bscfg(void)
{
unsigned int x1 = 0xFFFFFFFF, x2;
unsigned int faddr = FMEMORY_SCFG_BASE_ADDR;
unsigned int reta = FMEMORY_SCFG_BASE_ADDR;
do {
x2 = _flash_read_dword(faddr); // if (flash_read(faddr, &x2, 4)) return -(FMEM_FLASH_ERR);
if (x2 < x1) { // поиск текущего сегмента
x1 = x2;
reta = faddr; // новый адрес сегмента для записи
};
faddr += FMEMORY_SCFG_BANK_SIZE;
} while (faddr < (FMEMORY_SCFG_BASE_ADDR + FMEMORY_SCFG_BANKS * FMEMORY_SCFG_BANK_SIZE));
if ((x1 == 0xFFFFFFFF)&&(reta == FMEMORY_SCFG_BASE_ADDR)) { // первый старт?
_flash_write_dword(reta, 0x7FFFFFFF); // if (flash_write(reta, &x1, 4)) return -(FMEM_FLASH_ERR);
}
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("base seg: %p [%p]\n", reta, _flash_read_dword(reta));
#endif
return reta;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fobj
// Опции:
// false - Поиск последней записи объекта по id и size
// true - Поиск присуствия записи объекта по id и size
// Returns : адрес записи данных объекта
// 0 - не найден
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
LOCAL unsigned int get_addr_fobj(unsigned int base, fobj_head *obj, bool flg)
{
// if (base == 0) return 0;
fobj_head fobj;
unsigned int faddr = base + 4;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size);
unsigned int reta = 0;
do {
fobj.x = _flash_read_dword(faddr); // if (flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if (fobj.x == fobj_x_free) break;
if (fobj.n.size <= MAX_FOBJ_SIZE) {
if (fobj.n.id == obj->n.id) {
if (flg) {
return faddr;
}
obj->n.size = fobj.n.size;
reta = faddr;
}
faddr += align(fobj.n.size + fobj_head_size);
}
else faddr += align(MAX_FOBJ_SIZE + fobj_head_size);
}
while (faddr < fend);
return reta;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fend
// Поиск последнего адреса в сегменте для записи объекта
// Returns : адрес для записи объекта
// ret < FMEM_ERROR_MAX - ошибка
// ret = 0 - не влезет, на pack
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
LOCAL unsigned int get_addr_fobj_save(unsigned int base, fobj_head obj)
{
fobj_head fobj;
unsigned int faddr = base + 4;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(obj.n.size + fobj_head_size);
do {
fobj.x = _flash_read_dword(faddr); // if (flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if (fobj.x == fobj_x_free) {
if (faddr < fend) {
return faddr;
}
return 0; // не влезет, на pack
}
if (fobj.n.size <= MAX_FOBJ_SIZE) {
faddr += align(fobj.n.size + fobj_head_size);
}
else faddr += align(MAX_FOBJ_SIZE + fobj_head_size);
}
while (faddr < fend);
return 0; // не влезет, на pack
}
//=============================================================================
// FunctionName : pack_cfg_fmem
// Returns : адрес для записи объекта
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
LOCAL unsigned int pack_cfg_fmem(fobj_head obj)
{
fobj_head fobj;
unsigned int foldseg = get_addr_bscfg(); // поиск текушего сегмента
// if (foldseg < FMEM_ERROR_MAX) return fnewseg; // error
unsigned int fnewseg = foldseg + FMEMORY_SCFG_BANK_SIZE;
if (fnewseg >= (FMEMORY_SCFG_BASE_ADDR + FMEMORY_SCFG_BANKS * FMEMORY_SCFG_BANK_SIZE))
fnewseg = FMEMORY_SCFG_BASE_ADDR;
unsigned int faddr = foldseg;
unsigned int rdaddr, wraddr;
unsigned short len;
#if USE_BUFFER_RAM
unsigned int * pbuf = (unsigned int *) eep_malloc(align(MAX_FOBJ_SIZE + fobj_head_size) >> 2);
if (pbuf == NULL) {
DBG_FEEP_ERR("pack malloc error!\n");
return -(FMEM_MEM_ERR);
}
#else
unsigned int eep_buf[(MAX_FOBJ_SIZE + fobj_head_size) >> 2];
unsigned int * pbuf = eep_buf;
#endif
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("repack base to new seg: %p\n", fnewseg);
#endif
if (_flash_read_dword(fnewseg) != 0xFFFFFFFF)
_flash_erase_sector(fnewseg); // if (flash_erase_sector(fnewseg)) return -(FMEM_FLASH_ERR);
_flash_write_dword(fnewseg, 0x7FFFFFFF); // сегмент занят
faddr += 4;
wraddr = fnewseg + 4;
do {
fobj.x = _flash_read_dword(faddr); //if (flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); // последовательное чтение id из старого сегмента
if (fobj.x == fobj_x_free) break;
if (fobj.n.size > MAX_FOBJ_SIZE) len = align(MAX_FOBJ_SIZE + fobj_head_size);
else len = align(fobj.n.size + fobj_head_size);
if (fobj.n.id != obj.n.id && fobj.n.size <= MAX_FOBJ_SIZE) { // объект валидный
if (get_addr_fobj(fnewseg, &fobj, true) == 0) { // найдем, сохранили ли мы его уже? нет
rdaddr = get_addr_fobj(foldseg, &fobj, false); // найдем последнее сохранение объекта в старом сенгменте, size изменен
if (rdaddr < FMEM_ERROR_MAX) return rdaddr; // ???
if (wraddr + len >= fnewseg + FMEMORY_SCFG_BANK_SIZE) {
DBG_FEEP_ERR("pack segment overflow!\n");
return -(FMEM_OVR_ERR);
};
_flash_read(rdaddr, len, pbuf);
// перепишем данные obj в новый сектор
_flash_write(wraddr, len, pbuf);
};
};
faddr += len;
} while (faddr < (foldseg + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size+1)));
#if USE_BUFFER_RAM
eep_free(pbuf);
#endif
// обратный счетчик стираний/записей секторов как id
_flash_write_dword(fnewseg, (_flash_read_dword(foldseg) - 1)); // if (flash_write(fnewseg, &foldseg + SPI_FLASH_BASE, 4)) return -(FMEM_FLASH_ERR);
_flash_erase_sector(foldseg);
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("free: %d\n", FMEMORY_SCFG_BANK_SIZE - (faddr & (FMEMORY_SCFG_BANK_SIZE-1)));
#endif
return get_addr_fobj_save(fnewseg, obj); // адрес для записи объекта;
}
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
LOCAL signed short _flash_write_cfg(void *ptr, unsigned short id, unsigned short size)
{
fobj_head fobj;
fobj.n.id = id;
fobj.n.size = size;
// bool retb = false;
unsigned int faddr = get_addr_bscfg();
if (faddr >= FMEM_ERROR_MAX) {
unsigned int xfaddr = get_addr_fobj(faddr, &fobj, false);
if (xfaddr > FMEM_ERROR_MAX && size == fobj.n.size) {
if (size == 0
|| _flash_memcmp(xfaddr + fobj_head_size, size, ptr) == 0) {
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("write obj is identical, id: %04x [%d]\n", id, size);
#endif
return size; // уже записано то-же самое
}
#if CONFIG_DEBUG_LOG > 100
else {
int i;
uint8_t * p = (uint8_t *)(SPI_FLASH_BASE + xfaddr + fobj_head_size);
uint8_t * r = (uint8_t *) ptr;
for(i=0; i < size; i+=8) {
dbg_printf("buf[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i, r[i], r[i+1], r[i+2], r[i+3], r[i+4], r[i+5], r[i+6], r[i+7]);
dbg_printf("obj[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i, p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7]);
}
}
#endif
}
}
DBG_FEEP_INFO("write obj id: %04x [%d]\n", id, size);
fobj.n.size = size;
// flash_write_protect(&flashobj, 0); // Flash Unprotect
faddr = get_addr_fobj_save(faddr, fobj);
if (faddr == 0) {
faddr = pack_cfg_fmem(fobj);
if (faddr == 0) {
DBG_FEEP_ERR("banks overflow!\n");
return FMEM_NOT_FOUND;
}
}
else if (faddr < FMEM_ERROR_MAX) return - faddr - 1; // error
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("write obj to faddr %p\n", faddr);
#endif
_flash_write_dword(faddr, fobj.x); // if (flash_write(faddr, &fobj.x, 4)) return FMEM_FLASH_ERR;
faddr+=4;
#if 1
uint32_t len = (size + 3) & (~3);
if (len) _flash_write(faddr, len, ptr);
#else
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
uint32_t len = (size + 3) >> 2;
unsigned char * ps = ptr;
while (len--) {
tmp.uc[0] = *ps++;
tmp.uc[1] = *ps++;
tmp.uc[2] = *ps++;
tmp.uc[3] = *ps++;
_flash_write_dword(faddr, tmp.ud); // if (flash_write(faddr, &tmp.ud, 4)) return FMEM_FLASH_ERR;
faddr += 4;
}
#endif
_flash_clear_cache();
return size;
}
//=============================================================================
//- Сохранить объект в flash --------------------------------------------------
// Returns : false/true
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
bool flash_write_cfg(void *ptr, unsigned short id, unsigned short size)
{
bool retb = false;
if (size > MAX_FOBJ_SIZE) return retb;
_flash_mutex_lock();
if (_flash_write_cfg(ptr, id, size) >= 0) {
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("saved ok\n");
#endif
retb = true;
}
_flash_mutex_unlock();
return retb;
}
//=============================================================================
//- Прочитать объект из flash -------------------------------------------------
// Параметры:
// prt - указатель, куда сохранить
// id - идентификатор искомого объекта
// maxsize - сколько байт сохранить максимум из найденного объекта, по ptr
// Returns:
// -3 - error
// -2 - flash rd/wr/clr error
// -1 - не найден
// 0..MAX_FOBJ_SIZE - ok, сохраненный размер объекта
//-----------------------------------------------------------------------------
FEEP_CODE_ATTR
signed short flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize)
{
signed short rets = FMEM_ERROR;
if (maxsize <= MAX_FOBJ_SIZE) {
_flash_mutex_lock();
fobj_head fobj;
fobj.n.id = id;
fobj.n.size = 0;
DBG_FEEP_INFO("read obj id: %04x[%d]\n", id, maxsize);
unsigned int faddr = get_addr_bscfg();
if (faddr >= FMEM_ERROR_MAX) {
faddr = get_addr_fobj(faddr, &fobj, false);
if (faddr >= FMEM_ERROR_MAX) {
if (maxsize != 0 && ptr != NULL)
_flash_read(faddr + fobj_head_size, mMIN(fobj.n.size, maxsize), ptr);
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("read ok, faddr: %p, size: %d\n", faddr, fobj.n.size);
#endif
rets = fobj.n.size;
}
else {
#if CONFIG_DEBUG_LOG > 3
DBG_FEEP_INFO("obj not found\n");
#endif
rets = -faddr-1;
}
}
else rets = -faddr-1;
_flash_mutex_unlock();
}
return rets;
}
//=============================================================================
FEEP_CODE_ATTR
bool flash_supported_eep_ver(unsigned int min_ver, unsigned int new_ver) {
unsigned int tmp;
unsigned int faddr = FMEMORY_SCFG_BASE_ADDR;
_flash_mutex_lock();
// flash_unlock(); // Flash Unprotect, in user_init_normal()
if (flash_read_cfg(&tmp, EEP_ID_VER, sizeof(tmp)) == sizeof(tmp) && tmp >= min_ver) {
if(tmp != new_ver) {
tmp = new_ver;
flash_write_cfg(&tmp, EEP_ID_VER, sizeof(tmp));
}
_flash_mutex_unlock();
return true;
}
do{
tmp = _flash_read_dword(faddr);
_flash_erase_sector(faddr);
_flash_write_dword(faddr, --tmp);
faddr += FLASH_SECTOR_SIZE;
} while (faddr < FLASH_SIZE);
_flash_clear_cache();
tmp = new_ver;
flash_write_cfg(&tmp, EEP_ID_VER, sizeof(tmp));
_flash_mutex_unlock();
return false;
}

View file

@ -0,0 +1,61 @@
/******************************************************************************
* FileName: flash_eep.h
* Description: FLASH
* Alternate SDK
* Author: PV`
* (c) PV` 2015
*******************************************************************************/
#ifndef __FLASH_EEP_H_
#define __FLASH_EEP_H_
#ifdef __cplusplus
extern "C" {
#endif
// EEPROM IDs
#define EEP_ID_MAC (0xACAD) // EEP ID MAC
#define EEP_ID_CFG (0x0CFC) // EEP ID config data
#define EEP_ID_TRG (0x0DFE) // EEP ID trigger data
#define EEP_ID_RPC (0x0DF5) // EEP ID reed switch pulse counter
#define EEP_ID_PCD (0xC0DE) // EEP ID pincode
#define EEP_ID_CMF (0x0FCC) // EEP ID comfort data
#define EEP_ID_DVN (0xDEAE) // EEP ID device name
#define EEP_ID_TIM (0x0ADA) // EEP ID time adjust
#define EEP_ID_KEY (0xBC0D) // EEP ID bkey
#define EEP_ID_VER (0x5555) // EEP ID blk: unsigned int = minimum supported version
//-----------------------------------------------------------------------------
#ifndef FLASH_BASE_ADDR
#define FLASH_BASE_ADDR 0x11000000
#endif
#ifndef FLASH_SIZE
#define FLASH_SIZE (512*1024)
#endif
#ifndef FLASH_SECTOR_SIZE
#define FLASH_SECTOR_SIZE 4096
#endif
#define FMEMORY_SCFG_BANK_SIZE FLASH_SECTOR_SIZE // размер сектора, 4096 bytes
#define FMEMORY_SCFG_BANKS 4 // кол-во секторов для работы - min 2
#define FMEMORY_SCFG_BASE_ADDR (FLASH_SIZE - (FMEMORY_SCFG_BANKS*FMEMORY_SCFG_BANK_SIZE)) // 0x7C000
//-----------------------------------------------------------------------------
enum eFMEMORY_ERRORS {
FMEM_NOT_FOUND = -1, // -1 - не найден
FMEM_FLASH_ERR = -2, // -2 - flash rd/wr/erase error
FMEM_ERROR = -3, // -3 - error
FMEM_OVR_ERR = -4, // -4 - переполнение FMEMORY_SCFG_BANK_SIZE
FMEM_MEM_ERR = -5 // -5 - heap alloc error
};
//-----------------------------------------------------------------------------
#define MAX_FOBJ_SIZE 64 // максимальный размер сохраняемых объeктов (32,64,..512)
signed short flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize); // возврат: размер объекта последнего сохранения, -1 - не найден, -2 - error
bool flash_write_cfg(void *ptr, unsigned short id, unsigned short size);
bool flash_supported_eep_ver(unsigned int min_ver, unsigned int new_ver);
//-----------------------------------------------------------------------------
#ifdef __cplusplus
}
#endif
#endif /* __FLASH_EEP_H_ */

View file

@ -3,6 +3,7 @@
*/
#include "bus_dev.h"
#include "config.h"
#include "gpio.h"
#include "clock.h"
#include "global_config.h"
@ -14,9 +15,9 @@
#include "log.h"
#include "rf_phy_driver.h"
#include "flash.h"
#include "flash_eep.h"
#include "version.h"
#include "watchdog.h"
#include "fs.h"
#include "adc.h"
#define DEFAULT_UART_BAUD 115200
@ -103,9 +104,10 @@ volatile sysclk_t g_spif_clk_config;
//extern uint32_t __initial_sp;
static void hal_low_power_io_init(void) {
//========= disable all gpio pullup/down to preserve juice
const ioinit_cfg_t ioInit[] = {
//========= disable all gpio pullup/down to preserve juice
const ioinit_cfg_t ioInit[] = {
#if(SDK_VER_CHIP == __DEF_CHIP_QFN32__)
#if DEVICE == DEVICE_THB2
{ GPIO_P00, GPIO_PULL_DOWN },
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_DOWN },
@ -129,6 +131,33 @@ static void hal_low_power_io_init(void) {
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_PULL_DOWN },
{ GPIO_P34, GPIO_PULL_DOWN }
#elif DEVICE == DEVICE_BTH01
{ GPIO_P00, GPIO_PULL_UP }, // Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_DOWN },
{ GPIO_P03, GPIO_PULL_DOWN },
{ GPIO_P07, GPIO_PULL_DOWN },
{ GPIO_P09, GPIO_PULL_UP }, // TX1
{ GPIO_P10, GPIO_PULL_UP }, // RX1
{ GPIO_P11, GPIO_PULL_UP }, // ADC Vbat
{ GPIO_P14, GPIO_PULL_UP }, // KEY
{ GPIO_P15, GPIO_FLOATING }, // LED
{ GPIO_P16, GPIO_PULL_DOWN },
{ GPIO_P17, GPIO_PULL_DOWN },
{ GPIO_P18, GPIO_PULL_UP }, // RX2
{ GPIO_P20, GPIO_PULL_UP }, // TX2
{ GPIO_P23, GPIO_PULL_DOWN },
{ GPIO_P24, GPIO_PULL_DOWN },
{ GPIO_P25, GPIO_PULL_DOWN }, // P25
{ GPIO_P26, GPIO_PULL_DOWN },
// {GPIO_P27, GPIO_FLOATING },
{ GPIO_P31, GPIO_PULL_DOWN },
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_FLOATING }, // I2C_SDA
{ GPIO_P34, GPIO_FLOATING } // // I2C_SCL
#else
#error "DEVICE Not released!"
#endif
#else
{GPIO_P02, GPIO_FLOATING },
{GPIO_P03, GPIO_FLOATING },
@ -147,26 +176,31 @@ static void hal_low_power_io_init(void) {
for (uint8_t i = 0; i < sizeof(ioInit) / sizeof(ioinit_cfg_t); i++)
hal_gpio_pull_set(ioInit[i].pin, ioInit[i].type);
#if DEVICE == DEVICE_BTH01
hal_gpio_pin_init(GPIO_SPWR, GPIO_OUTPUT);
hal_gpio_write(GPIO_SPWR, 1);
#endif
hal_gpio_write(GPIO_LED, LED_ON);
DCDC_CONFIG_SETTING(0x0a);
DCDC_REF_CLK_SETTING(1);
DIG_LDO_CURRENT_SETTING(0x01);
#if defined ( __GNUC__ )
extern uint32 g_irqstack_top;
// Check IRQ STACK (1KB) location
if ((uint32_t) &g_irqstack_top > 0x1fff8000) {
hal_pwrmgr_RAM_retention(RET_SRAM0 | RET_SRAM1);
// pGlobal_config[INITIAL_STACK_PTR] = 0x1fffC000;
} else if ((uint32_t) &g_irqstack_top > 0x1fffc000) {
/*
if ((uint32_t) &g_irqstack_top > 0x1fffc000) {
hal_pwrmgr_RAM_retention(RET_SRAM0 | RET_SRAM1 | RET_SRAM2);
} else
*/
if ((uint32_t) &g_irqstack_top > 0x1fff8000) {
hal_pwrmgr_RAM_retention(RET_SRAM0 | RET_SRAM1);
} else {
hal_pwrmgr_RAM_retention(RET_SRAM0); // RET_SRAM0|RET_SRAM1|RET_SRAM2
// pGlobal_config[INITIAL_STACK_PTR] = 0x1fff8000;
}
#else
#if DEBUG_INFO || SDK_VER_RELEASE_ID != 0x03010102
hal_pwrmgr_RAM_retention(RET_SRAM0|RET_SRAM1); // RET_SRAM0|RET_SRAM1|RET_SRAM2
hal_pwrmgr_RAM_retention(RET_SRAM0 | RET_SRAM1); // RET_SRAM0|RET_SRAM1|RET_SRAM2
#else
hal_pwrmgr_RAM_retention(RET_SRAM0); // RET_SRAM0|RET_SRAM1|RET_SRAM2
#endif
@ -240,7 +274,8 @@ static void hal_init(void) {
hal_spif_cache_init(SYS_CLK_DLL_64M, XFRD_FCMD_READ_DUAL);
hal_gpio_init();
LOG_INIT();
hal_fs_init(0x1103C000, 2);
//hal_fs_init(0x1103C000, 2);
flash_supported_eep_ver(0, APP_VERSION);
hal_adc_init();
}

View file

@ -75,27 +75,29 @@ static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
* Profile Attributes - variables
*/
// Simple Profile Service attribute
// Simple Profile Service attribute 0xFFF0
static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
// Simple Profile Characteristic 1 Properties
static uint8 simpleProfileChar1Props = GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
static uint8 simpleProfileChar1[BLE_ATT_CMD_LED]= {0,}; // Characteristic 1 Value
static uint8 simpleProfileChar1UserDesp[] = "Commond\0"; // Simple Profile Characteristic 1 User Description
static CONST uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
static CONST uint8 simpleProfileChar1UserDesp[] = "OTA\0"; // Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1[20]= {0,}; // Characteristic 1 Value
// Simple Profile Characteristic 2 Properties
static uint8 simpleProfileChar2Props = GATT_PROP_READ |GATT_PROP_NOTIFY;
static uint8 simpleProfileChar2[BLE_ATT_CMD_LED]= {0,}; // Characteristic 2 Value
static uint8 simpleProfileChar2UserDesp[] = "Response\0"; // Simple Profile Characteristic 2 User Description
static CONST uint8 simpleProfileChar2Props = GATT_PROP_READ | GATT_PROP_NOTIFY;
static CONST uint8 simpleProfileChar2UserDesp[] = "CMD\0"; // Simple Profile Characteristic 2 User Description
static gattCharCfg_t simpleProfileChar2Config[GATT_MAX_NUM_CONN]; //
static uint8 simpleProfileChar2[20]= {0,}; // Characteristic 2 Value
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
static CONST gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
/* type */ /* permissions */ /* handle */ /* pValue */
// Simple Profile Service
@ -214,17 +216,19 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
switch ( param )
{
case SIMPLEPROFILE_CHAR1:
if ( len <= BLE_ATT_CMD_LED ){
osal_memcpy(simpleProfileChar1, value, len);
}else{
ret = bleInvalidRange;
}
break;
if ( len <= sizeof(simpleProfileChar1) )
len = sizeof(simpleProfileChar1);
osal_memcpy(simpleProfileChar1, value, len);
break;
case SIMPLEPROFILE_CHAR2:
if ( len <= sizeof(simpleProfileChar2) )
len = sizeof(simpleProfileChar2);
osal_memcpy(simpleProfileChar2, value, len);
break;
default:
ret = INVALIDPARAMETER;
break;
}
return ( ret );
}
@ -246,14 +250,12 @@ bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
bStatus_t ret = SUCCESS;
switch ( param )
{
// case SIMPLEPROFILE_CHAR1:
// VOID osal_memcpy( value, simpleProfileChar1, BLE_ATT_CMD_LED);
// break;
case SIMPLEPROFILE_CHAR1:
osal_memcpy( value, simpleProfileChar1, sizeof(simpleProfileChar1));
break;
case SIMPLEPROFILE_CHAR2:
VOID osal_memcpy( value, simpleProfileChar2, BLE_ATT_CMD_LED );
break;
osal_memcpy( value, simpleProfileChar2, sizeof(simpleProfileChar2));
break;
default:
ret = INVALIDPARAMETER;
break;
@ -303,18 +305,23 @@ static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *p
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
case SIMPLEPROFILE_CHAR1_UUID:
*pLen = sizeof(simpleProfileChar1);
VOID osal_memcpy( pValue, pAttr->pValue, *pLen );
LOG("Read_UUID1:\n");
break;
case SIMPLEPROFILE_CHAR2_UUID:
*pLen = BLE_ATT_CMD_LED;
*pLen = sizeof(simpleProfileChar2);
VOID osal_memcpy( pValue, pAttr->pValue, *pLen );
LOG("Read_UUID2:\n");
break;
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}else{
} else {
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
@ -345,8 +352,8 @@ static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *
// If attribute permissions require authorization to write, return error
if ( gattPermitAuthorWrite( pAttr->permissions ) )
{
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
}
if ( pAttr->type.len == ATT_BT_UUID_SIZE )
@ -356,16 +363,16 @@ static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *
switch ( uuid )
{
case SIMPLEPROFILE_CHAR1_UUID:
//Validate the value
// Validate the value
// Make sure it's not a blob oper
if ( offset == 0 ){
if ( len > BLE_ATT_CMD_LED){
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}else{
} else {
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
// Write the value
if ( status == SUCCESS ){
uint8 *pCurValue = (uint8 *)pAttr->pValue;
VOID osal_memcpy(pCurValue, pValue, len );
@ -434,9 +441,11 @@ bStatus_t simpleProfile_Notify( uint8 param, uint8 len, void *value )
if ( notfEnable & GATT_CLIENT_CFG_NOTIFY ){
VOID osal_memcpy( simpleProfileChar2, value, len );
// ReadNotify_Len = len;
/*
ret = GATTServApp_ProcessCharCfg( simpleProfileChar2Config, simpleProfileChar2, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID );
*/
}else{
ret = bleNotReady;
}

View file

@ -8,12 +8,12 @@
#include <stdint.h>
// Timing
#define SENSOR_POWER_TIMEOUT_ms 5
#define SENSOR_RESET_TIMEOUT_ms 5
#define SENSOR_POWER_TIMEOUT_ms 3
#define SENSOR_RESET_TIMEOUT_ms 3
#define SENSOR_MEASURING_TIMEOUT_ms 7
/* CHT8310 https://github.com/pvvx/pvvx.github.io/blob/master/THB2/CHT8310.Advanced.Datasheet_Ver1.0.20230407.pdf */
// I2C addres
#define CHT8310_I2C_ADDR0 0x40
#define CHT8310_I2C_ADDR1 0x44
@ -32,7 +32,8 @@
#define CHT8310_REG_HLM 0x08
#define CHT8310_REG_OST 0x0f
#define CHT8310_REG_RST 0xfc
#define CHT8310_REG_ID 0xfe
#define CHT8310_REG_MID 0xfe
#define CHT8310_REG_VID 0xff
// Status register mask
#define CHT8310_STA_BUSY 0x8000
@ -53,6 +54,60 @@
#define CHT8310_CFG_CONSEC_FQ 0x0006
#define CHT8310_CFG_ATM 0x0001
#define CHT8310_ID 0x5959
/* CHT8305 https://github.com/pvvx/pvvx.github.io/blob/master/BTH01/CHT8305.pdf */
// I2C addres
#define CHT8305_I2C_ADDR0 0x40
#define CHT8305_I2C_ADDR1 0x41
#define CHT8305_I2C_ADDR2 0x42
#define CHT8305_I2C_ADDR3 0x43
#define CHT8305_I2C_ADDR_MAX 0x43
// Registers
#define CHT8305_REG_TMP 0x00
#define CHT8305_REG_HMD 0x01
#define CHT8305_REG_CFG 0x02
#define CHT8305_REG_ALR 0x03
#define CHT8305_REG_VLT 0x04
#define CHT8305_REG_MID 0xfe
#define CHT8305_REG_VID 0xff
// Config register mask
#define CHT8305_CFG_SOFT_RESET 0x8000
#define CHT8305_CFG_CLOCK_STRETCH 0x4000
#define CHT8305_CFG_HEATER 0x2000
#define CHT8305_CFG_MODE 0x1000
#define CHT8305_CFG_VCCS 0x0800
#define CHT8305_CFG_TEMP_RES 0x0400
#define CHT8305_CFG_HUMI_RES 0x0300
#define CHT8305_CFG_ALERT_MODE 0x00C0
#define CHT8305_CFG_ALERT_PENDING 0x0020
#define CHT8305_CFG_ALERT_HUMI 0x0010
#define CHT8305_CFG_ALERT_TEMP 0x0008
#define CHT8305_CFG_VCC_ENABLE 0x0004
#define CHT8305_CFG_RESERVED 0x0003
/*
struct __attribute__((packed)) _cht8305_config_t{
uint16_t reserved : 2;
uint16_t vccen : 1;
uint16_t talt : 1;
uint16_t halt : 1;
uint16_t aps : 1;
uint16_t altm : 2;
uint16_t h_res : 2;
uint16_t t_res : 1;
uint16_t vccs : 1;
uint16_t mode : 1;
uint16_t heater : 1;
uint16_t clkstr : 1;
uint16_t srst : 1;
} cht8305_config_t;
*/
#define CHT8305_ID 0x5959
typedef struct _measured_data_t {
uint16_t count;
@ -62,8 +117,18 @@ typedef struct _measured_data_t {
uint8_t battery; // 0..100 %
} measured_data_t;
typedef struct _thsensor_cfg_t {
union {
uint32_t id;
uint16_t _id[2];
};
int16_t temp_offset;
int16_t humi_offset;
uint8_t i2c_addr;
} thsensor_cfg_t;
extern measured_data_t measured_data;
extern unsigned short th_sensor_id;
extern thsensor_cfg_t thsensor_cfg;
void init_sensor(void);
int read_sensor(void);

View file

@ -10,14 +10,11 @@
#include "i2c.h"
#include "sensor.h"
#ifndef I2C_SDA
#define I2C_SDA GPIO_P18
#define I2C_SCL GPIO_P20
#endif
#define SET_I2C_SPEED 400 // 100 or 400 kHz
#define I2C_WAIT_ms 1
measured_data_t measured_data;
unsigned short th_sensor_id;
thsensor_cfg_t thsensor_cfg;
void init_i2c(void) {
hal_gpio_fmux_set(I2C_SCL, FMUX_IIC0_SCL);
@ -31,32 +28,45 @@ void init_i2c(void) {
hal_clk_gate_enable(MOD_I2C0);
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_CON = 0x61;
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9)|(0x02 << 1);
if(pclk == 16000000)
{
#if SET_I2C_SPEED == 100
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x01 << 1); // SPEED_STANDARD
if (pclk == 16000000) {
pi2cdev->IC_SS_SCL_HCNT = 70; //16
pi2cdev->IC_SS_SCL_LCNT = 76; //32)
} else if (pclk == 32000000) {
pi2cdev->IC_SS_SCL_HCNT = 148; //16
pi2cdev->IC_SS_SCL_LCNT = 154; //32)
} else if (pclk == 48000000) {
pi2cdev->IC_SS_SCL_HCNT = 230; //16
pi2cdev->IC_SS_SCL_LCNT = 236; //32)
} else if (pclk == 64000000) {
pi2cdev->IC_SS_SCL_HCNT = 307; //16
pi2cdev->IC_SS_SCL_LCNT = 320; //32)
} else if (pclk == 96000000) {
pi2cdev->IC_SS_SCL_HCNT = 460; //16
pi2cdev->IC_SS_SCL_LCNT = 470; //32)
}
#elif SET_I2C_SPEED == 400
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x02 << 1); // SPEED_FAST
if (pclk == 16000000) {
pi2cdev->IC_FS_SCL_HCNT = 10;
pi2cdev->IC_FS_SCL_LCNT = 17;
}
else if(pclk == 32000000)
{
} else if (pclk == 32000000) {
pi2cdev->IC_FS_SCL_HCNT = 30;
pi2cdev->IC_FS_SCL_LCNT = 35;
}
else if(pclk == 48000000)
{
} else if (pclk == 48000000) {
pi2cdev->IC_FS_SCL_HCNT = 48;
pi2cdev->IC_FS_SCL_LCNT = 54;
}
else if(pclk == 64000000)
{
} else if (pclk == 64000000) {
pi2cdev->IC_FS_SCL_HCNT = 67;
pi2cdev->IC_FS_SCL_LCNT = 75;
}
else if(pclk == 96000000)
{
} else if (pclk == 96000000) {
pi2cdev->IC_FS_SCL_HCNT = 105;
pi2cdev->IC_FS_SCL_LCNT = 113;
}
#else
#error SET_I2C_SPEED = ?
#endif
// pi2cdev->IC_TAR = I2C_MASTER_ADDR_DEF;
pi2cdev->IC_INTR_MASK = 0;
pi2cdev->IC_RX_TL = 0x0;
@ -99,7 +109,34 @@ int read_i2c_bytes(uint8 addr, uint8 reg, uint8 * data, uint8 size) {
data++;
i--;
}
if(osal_sys_tick - to > 10)
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
int read_noreg_i2c_bytes(uint8 addr, uint8 * data, uint8 size) {
int i = size;
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
while(i--)
pi2cdev->IC_DATA_CMD = 0x100;
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
i = size;
while(i) {
if(pi2cdev->IC_STATUS & 0x08) { // fifo not empty
*data = pi2cdev->IC_DATA_CMD & 0xff;
data++;
i--;
}
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
@ -118,7 +155,7 @@ int send_i2c_byte(uint8 addr, uint8 data) {
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > 10)
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
@ -140,7 +177,7 @@ int send_i2c_wreg(uint8 addr, uint8 reg, uint16 data) {
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > 10)
if(osal_sys_tick - to > 2)
return 1;
}
return 0;
@ -148,34 +185,87 @@ int send_i2c_wreg(uint8 addr, uint8 reg, uint16 data) {
__ATTR_SECTION_XIP__ void init_sensor(void) {
init_i2c();
#if DEVICE == DEVICE_THB2
send_i2c_byte(0, 0x06); // Reset command using the general call address
WaitMs(3);
send_i2c_wreg(CHT8310_I2C_ADDR0, CHT8310_REG_CRT, 0x0300); // Set conversion ratio 5 sec
WaitMs(SENSOR_RESET_TIMEOUT_ms);
thsensor_cfg.i2c_addr = CHT8310_I2C_ADDR0;
read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_MID, (uint8 *)&thsensor_cfg._id[0], 2); // 0x5959
read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_VID, (uint8 *)&thsensor_cfg._id[1], 2);
//WaitMs(1);
read_i2c_bytes(CHT8310_I2C_ADDR0, CHT8310_REG_ID, (uint8 *)&th_sensor_id, 2);
send_i2c_wreg(CHT8310_I2C_ADDR0, CHT8310_REG_CRT, 0x0300); // Set conversion ratio 5 sec
#elif DEVICE == DEVICE_BTH01
#define USE_DEFAULT_SETS_SENSOR 0 // for CHT8305
#if USE_DEFAULT_SETS_SENSOR
hal_gpio_write(GPIO_SPWR, 0);
WaitMs(SENSOR_POWER_TIMEOUT_ms);
hal_gpio_write(GPIO_SPWR, 1);
#endif
thsensor_cfg.i2c_addr = CHT8305_I2C_ADDR0;
if(!read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_MID, (uint8 *)&thsensor_cfg._id[0], 2) // 0x5959
&& !read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_VID, (uint8 *)&thsensor_cfg._id[1], 2)) { // 0x8305
#if !USE_DEFAULT_SETS_SENSOR
// Soft reset command
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG,
CHT8305_CFG_SOFT_RESET
| CHT8305_CFG_MODE
);
WaitMs(SENSOR_RESET_TIMEOUT_ms);
// Configure
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG,
CHT8305_CFG_MODE
);
#endif
// WaitMs(SENSOR_MEASURING_TIMEOUT_ms);
send_i2c_byte(thsensor_cfg.i2c_addr, CHT8305_REG_TMP); // start measure T/H
}
#endif // DEVICE == DEVICE_BTH01
deinit_i2c();
}
int read_sensor(void) {
int32 _r32;
int16 _r16;
uint8 reg_data[4];
init_i2c();
_r32 = read_i2c_bytes(CHT8310_I2C_ADDR0, CHT8310_REG_TMP, reg_data, 2);
#if DEVICE == DEVICE_THB2
int32 _r32;
int16 _r16;
_r32 = read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_TMP, reg_data, 2);
//? WaitUs(100);
_r32 |= read_i2c_bytes(CHT8310_I2C_ADDR0, CHT8310_REG_HMD, &reg_data[2], 2);
_r32 |= read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_HMD, &reg_data[2], 2);
deinit_i2c();
if (!_r32) {
_r16 = (reg_data[0] << 8) | reg_data[1];
measured_data.temp = (int32)(_r16 * 25606 + 0x7fff) >> 16; // x 0.01 C
measured_data.temp = ((int32)(_r16 * 25606 + 0x7fff) >> 16) + thsensor_cfg.temp_offset;; // x 0.01 C
_r32 = ((reg_data[2] << 8) | reg_data[3]) & 0x7fff;
measured_data.humi = (uint32)(_r32 * 20000 + 0x7fff) >> 16; // x 0.01 %
if (measured_data.humi > 9999)
measured_data.humi = ((uint32)(_r32 * 20000 + 0x7fff) >> 16) + + thsensor_cfg.humi_offset; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
measured_data.count++;
return 0;
}
#elif DEVICE == DEVICE_BTH01
uint16_t _temp;
if (!read_noreg_i2c_bytes(thsensor_cfg.i2c_addr, reg_data, 4)) {
_temp = (reg_data[0] << 8) | reg_data[1];
measured_data.temp = ((uint32_t)(_temp * 16500) >> 16) - 4000 + thsensor_cfg.temp_offset; // x 0.01 C
_temp = (reg_data[2] << 8) | reg_data[3];
measured_data.humi = ((uint32_t)(_temp * 10000) >> 16) + thsensor_cfg.humi_offset; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
send_i2c_byte(thsensor_cfg.i2c_addr, CHT8305_REG_TMP); // start measure T/H
deinit_i2c();
return 0;
}
// deinit_i2c();
#else
#error "DEVICE Not released!"
#endif
init_sensor();
return 1;
}

View file

@ -33,7 +33,8 @@
#include "ll_def.h"
#include "hci_tl.h"
#include "flash.h"
#include "fs.h"
//#include "fs.h"
#include "flash_eep.h"
#include "battservice.h"
#include "thservice.h"
#include "thb2_peripheral.h"
@ -126,15 +127,17 @@ static void set_def_name(uint8_t * mac)
static void set_mac(void)
{
extern uint8 ownPublicAddr[LL_DEVICE_ADDR_LEN];
uint16 len;
if (read_chip_mAddr(ownPublicAddr) != CHIP_ID_VALID) {
if(hal_fs_item_read(FS_ID_MAC, ownPublicAddr, LL_DEVICE_ADDR_LEN, &len) != PPlus_SUCCESS) {
//uint16 len;
//if(hal_fs_item_read(FS_ID_MAC, ownPublicAddr, LL_DEVICE_ADDR_LEN, &len) != PPlus_SUCCESS) {
if(flash_read_cfg(ownPublicAddr, EEP_ID_MAC, LL_DEVICE_ADDR_LEN) != LL_DEVICE_ADDR_LEN) {
LL_Rand(ownPublicAddr,3);
// Tuya mac[0:3]
ownPublicAddr[3] = 0x8d;
ownPublicAddr[4] = 0x1f;
ownPublicAddr[5] = 0x38;
hal_fs_item_write(0xACAD, ownPublicAddr, LL_DEVICE_ADDR_LEN);
flash_write_cfg(ownPublicAddr, EEP_ID_MAC, LL_DEVICE_ADDR_LEN);
//hal_fs_item_write(FS_ID_MAC, ownPublicAddr, LL_DEVICE_ADDR_LEN);
}
}
set_def_name(ownPublicAddr);
@ -158,7 +161,7 @@ static void set_serial_number(void)
efuse_read(EFUSE_BLOCK_0, temp_rd);
uint8_t *p = str_bin2hex(devInfoSerialNumber, (uint8_t *)&phy_flash.IdentificationID, 3);
*p++ = '-';
p = str_bin2hex(p, (uint8_t *)&th_sensor_id, 2);
p = str_bin2hex(p, (uint8_t *)&thsensor_cfg.id, 4);
*p++ = '-';
p = str_bin2hex(p, (uint8_t *)&temp_rd[0], 2);
}
@ -221,8 +224,8 @@ static void posedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
if(type == POSEDGE)
{
adv_con_count = 30000/DEF_CON_ADV_INERVAL_MS; // 60 sec
LOG("int or wakeup(pos):gpio:%d type:%d\n",pin,type);
hal_gpio_write(GPIO_LED,1);
LOG("int or wakeup(pos):gpio:%d type:%d\n", pin, type);
hal_gpio_write(GPIO_LED, LED_OFF);
if(gapRole_AdvEnabled) {
set_new_adv_interval(DEF_CON_ADV_INERVAL); // actual time = advInt * 625us
}
@ -238,8 +241,8 @@ static void negedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
(void) pin;
if(type == NEGEDGE)
{
LOG("int or wakeup(neg):gpio:%d type:%d\n",pin,type);
hal_gpio_write(GPIO_LED,0);
LOG("int or wakeup(neg):gpio:%d type:%d\n", pin, type);
hal_gpio_write(GPIO_LED, LED_ON);
}
else
{
@ -251,7 +254,11 @@ void init_led_key(void)
{
hal_gpioin_register(GPIO_KEY, posedge_int_wakeup_cb, negedge_int_wakeup_cb);
hal_gpioretention_register(GPIO_LED);//enable this pin retention
hal_gpio_write(GPIO_LED, 1);
hal_gpio_write(GPIO_LED, LED_ON);
#if DEVICE == DEVICE_BTH01
hal_gpioretention_register(GPIO_SPWR);//enable this pin retention
hal_gpio_write(GPIO_SPWR, 1);
#endif
}
/*********************************************************************
@ -359,7 +366,7 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
GAP_UpdateAdvertisingData( gapRole_TaskID, FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
gapRole_ParamUpdateEnable = DEFAULT_ENABLE_UPDATE_REQUEST;
/* already set default
/* already set default -> config.h
// extern gapPeriConnectParams_t periConnParameters;
gapRole_MinConnInterval = periConnParameters.intervalMin;
gapRole_MaxConnInterval = periConnParameters.intervalMax;
@ -404,12 +411,22 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
// ota_app_AddService();
#if (1)
#if 1 // CODED PHY not work?
deviceFeatureSet.featureSet[1] |= (uint8)(
LL_FEATURE_2M_PHY
| LL_FEATURE_CODED_PHY
| LL_FEATURE_CSA2);
// CSA2 feature setting
pGlobal_config[LL_SWITCH] |= CONN_CSA2_ALLOW;
llInitFeatureSetCodedPHY(TRUE);
#endif
llInitFeatureSet2MPHY(TRUE);
llInitFeatureSetDLE(TRUE);
#else
llInitFeatureSet2MPHY(FALSE);
llInitFeatureSetDLE(FALSE);
#endif
HCI_LE_SetDefaultPhyMode(0,0x03,0x01,0x01);
#ifdef MTU_SIZE
ATT_SetMTUSizeMax(MTU_SIZE);
@ -421,7 +438,6 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
// for receive HCI complete message
GAP_RegisterForHCIMsgs(simpleBLEPeripheral_TaskID);
LL_PLUS_PerStats_Init(&g_perStatsByChanTest);
batt_start_measure();
LOG("=====SimpleBLEPeripheral_Init Done=======\n");
@ -466,7 +482,7 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
return (events ^ SYS_EVENT_MSG);
}
// enable adv
// enable adv (from gaprole start)
if ( events & SBP_RESET_ADV_EVT )
{
LOG("SBP_RESET_ADV_EVT\n");
@ -508,6 +524,7 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
#endif
HCI_LE_ReadResolvingListSizeCmd();
hal_gpio_write(GPIO_LED, LED_OFF);
// return unprocessed events
return ( events ^ SBP_START_DEVICE_EVT );
}