Skip to content

Commit

Permalink
riscv: telink: add customer mode .
Browse files Browse the repository at this point in the history
- add CUSTOMER_MODE define.
- adjust dual switch logic.
- add demo for cluster and nvs.

Signed-off-by: Haiwen Xia <[email protected]>
  • Loading branch information
haiwentelink committed Dec 24, 2024
1 parent f374f28 commit e2b48b2
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 25 deletions.
5 changes: 5 additions & 0 deletions config/telink/chip-module/Kconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ config COMPRESS_LZMA
default y if SOC_RISCV_TELINK_TL321X
default n

config CUSTOMER_MODE
bool "Disable application code and add demo code"
default n if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_B92
default n

config DUAL_MODE_SWTICH
bool "Control the dual mode switch part"
default y if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_B92
Expand Down
2 changes: 2 additions & 0 deletions examples/lighting-app/telink/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class AppTask : public AppTaskCommon
bool IsTurnedOn() const;
void SetInitiateAction(Fixture_Action aAction, int32_t aActor, uint8_t * value);
void UpdateClusterState(void);
void Init_cluster_info(void);
void Set_cluster_info(void);

private:
friend AppTask & GetAppTask(void);
Expand Down
91 changes: 82 additions & 9 deletions examples/lighting-app/telink/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include "ColorFormat.h"
#include "LEDManager.h"
#include "PWMManager.h"
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/kernel.h>

#include <app-common/zap-generated/attributes/Accessors.h>

Expand Down Expand Up @@ -55,22 +58,92 @@ void AppTask::PowerOnFactoryReset(void)
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

#if CONFIG_CUSTOMER_MODE
void i2c_demo_proc()
{
const uint8_t tx_buf[23] = { 0xc0, 0x63, 0x3f, 0x63, 0x63, 0x63, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x06, 0xbe };
/* add the i2c module here */
printk("i2c demo start \n.");
uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_CONTROLLER;
/* get i2c device */
int rc;
const struct i2c_dt_spec i2c = I2C_DT_SPEC_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(ledcontrol_i2c));
if (!device_is_ready(i2c.bus))
{
printf("Device %s is not ready\n", i2c.bus->name);
return;
}
rc = i2c_configure(i2c.bus, i2c_cfg);
if (rc != 0)
{
printf("Failed to configure i2c device\n");
return;
}
i2c_write(i2c.bus, tx_buf + 1, sizeof(tx_buf) - 1, tx_buf[0]);
printk("i2c demo stop ,finish transfer\n");
}

void AppTask::Init_cluster_info(void)
{
printk("%%%%%%Set_cluster_info!!!!%%%%%%\n");
light_para_t * p_para = &light_para;
Protocols::InteractionModel::Status status;
printk("%%%%%%Set_cluster_info:p_para->onoff:%d!!!!%%%%%%\n", p_para->onoff);
status = Clusters::OnOff::Attributes::OnOff::Set(1, p_para->onoff);
// Set brightness value
printk("%%%%%%Set_cluster_info:p_para->level:%d!!!!%%%%%%\n", p_para->level);
status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kExampleEndpointId, p_para->level);
// Set ColorMode value
/*
printk("%%%%%%Set_cluster_info:p_para->color_mode:%d!!!!%%%%%%\n",p_para->color_mode);
status = Clusters::ColorControl::Attributes::ColorMode::Set(1, p_para->color_mode);
*/
// Set ColorTemperatureMireds value
status = Clusters::ColorControl::Attributes::ColorTemperatureMireds::Set(1, p_para->color_temp_mireds);

// Set CurrentX value
status = Clusters::ColorControl::Attributes::CurrentX::Set(1, p_para->currentx);

// Set CurrentY value
status = Clusters::ColorControl::Attributes::CurrentY::Set(1, p_para->currenty);

// Set EnhancedCurrentHue value
status = Clusters::ColorControl::Attributes::EnhancedCurrentHue::Set(1, p_para->enhanced_current_hue);

// Set CurrentHue value
status = Clusters::ColorControl::Attributes::CurrentHue::Set(1, p_para->cur_hue);

// Set CurrentSaturation value
status = Clusters::ColorControl::Attributes::CurrentSaturation::Set(1, p_para->cur_saturation);

// Set OnOffTransitionTime value
status = Clusters::LevelControl::Attributes::OnOffTransitionTime::Set(1, p_para->onoff_transition);
}
#endif

CHIP_ERROR AppTask::Init(void)
{
SetExampleButtonCallbacks(LightingActionEventHandler);
InitCommonParts();

#if CONFIG_DUAL_MODE_SWTICH
if (sBoot_zb)
#if CONFIG_CUSTOMER_MODE
if (user_para.val == USER_ZB_SW_VAL)
{
/* Switch from the touch link, need to restore previous values */
sfixture_on = user_para.onoff;
sBrightness = user_para.lightness;
sAppTask.UpdateClusterState();
printk("Matter: Updated ZB On/Off state and brightness.\n");
/* switch from zigbee , which means uncommission state .*/
}
#endif
else if (user_para.val == USER_MATTER_PAIR_VAL)
{
/* start from matter , add cluster info demo here*/
Init_cluster_info();
}
else
{
/* start from matter , but without zigbee fw*/
}
/* if need , can call i2c_demo_proc here to see light works or not*/

#else
Protocols::InteractionModel::Status status;

app::DataModel::Nullable<uint8_t> brightness;
Expand All @@ -91,7 +164,7 @@ CHIP_ERROR AppTask::Init(void)
// Set actual state to stored before reboot
SetInitiateAction(storedValue ? ON_ACTION : OFF_ACTION, static_cast<int32_t>(AppEvent::kEventType_DeviceAction), nullptr);
}

#endif
return CHIP_NO_ERROR;
}

Expand Down
4 changes: 4 additions & 0 deletions examples/lighting-app/telink/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ using namespace chip::app::Clusters;
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
uint8_t * value)
{
#if CONFIG_CUTOMER_MODE

#else
static HsvColor_t hsv;
static XyColor_t xy;
ClusterId clusterId = attributePath.mClusterId;
Expand Down Expand Up @@ -116,4 +119,5 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
ChipLogDetail(Zcl, "Ignore ColorControl attribute (%u) that is not currently processed!", attributeId);
}
}
#endif
}
35 changes: 32 additions & 3 deletions examples/platform/telink/common/include/AppTaskCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,25 @@
#include <zephyr/storage/flash_map.h>
#include <zephyr/sys/reboot.h>

#if CONFIG_SOC_RISCV_TELINK_B92

#define ZB_NVS_PARTITION zigbee_partition
#define ZB_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZB_NVS_PARTITION)
#define ZB_NVS_START_ADR FIXED_PARTITION_OFFSET(ZB_NVS_PARTITION)
#define ZB_NVS_SEC_SIZE FIXED_PARTITION_SIZE(ZB_NVS_PARTITION)

#elif CONFIG_SOC_RISCV_TELINK_TL321X
#define ZB_NVS_PARTITION slot1_partition
#define ZB_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZB_NVS_PARTITION)
#define ZB_NVS_START_ADR FIXED_PARTITION_OFFSET(ZB_NVS_PARTITION)
/* zb para locate in the slot1 , and it will cost 104k size in slot1 */
#define ZB_NVS_SEC_SIZE (104 * 1024)
#endif

#define USER_INIT_VAL 0xff
#define USER_ZB_SW_VAL 0xaa
#define USER_MATTER_PAIR_VAL 0x55
#define USER_MATTER_BACK_ZB 0xa0 // only commisiion fail will back to zb
#define USER_PARA_MAC_OFFSET 0x100
#define USER_PARTITION user_para_partition
#define USER_PARTITION_DEVICE FIXED_PARTITION_DEVICE(USER_PARTITION)
Expand All @@ -55,11 +71,24 @@
typedef struct
{
uint8_t val;
uint8_t rfu;
uint8_t onoff;
uint8_t lightness;
uint8_t on_net;
} user_para_t;

typedef struct
{
uint8_t onoff;
uint8_t level;
uint16_t color_temp_mireds;
uint16_t currentx;
uint16_t currenty;
uint16_t enhanced_current_hue;
uint16_t onoff_transition;
uint8_t cur_hue;
uint8_t cur_saturation;
uint8_t color_mode;
} light_para_t;

extern light_para_t light_para;
extern user_para_t user_para;
extern uint8_t para_lightness;
extern uint8_t sBoot_zb;
Expand Down
58 changes: 48 additions & 10 deletions examples/platform/telink/common/src/AppTaskCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
#endif

#include <app-common/zap-generated/attributes/Accessors.h>
#include <zephyr/fs/nvs.h>
#include <zephyr/settings/settings.h>

#if CONFIG_DUAL_MODE_SWTICH
uint8_t sBoot_zb = 0;
user_para_t user_para;
uint8_t sBoot_zb = 0;
uint8_t para_lightness = 0;
user_para_t user_para;
light_para_t light_para;
#endif

using namespace chip::app;
Expand Down Expand Up @@ -143,6 +145,8 @@ void FactoryResetExtHandler(void)
{
// Erase the user parameters partition to reset mode settings
flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE);
// Need to erase zb nvs part in factory mode
flash_erase(flash_para_dev, ZB_NVS_START_ADR, ZB_NVS_SEC_SIZE);
}
#endif

Expand Down Expand Up @@ -232,15 +236,27 @@ void AppTaskCommon::PowerOnFactoryReset(void)
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

#if CONFIG_DUAL_MODE_SWTICH

void SwitchBackToZigbee()
{
uint8_t switch_flag = USER_MATTER_BACK_ZB;
// flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE);
flash_write(flash_para_dev, USER_PARTITION_OFFSET, &switch_flag, 1);
sys_reboot(0);
}

void AppTaskCommon::DnssTimerTimeoutCallback(k_timer * timer)
{
if (!timer)
{
return;
}
/*If initialization of Dnss takes longer than 60 seconds, the device will reboot and revert to Zigbee mode*/
printk("Matter: DnssTimer expired.\r\n");
sys_reboot(0);
/*If initialization of Dnss takes longer than 90 seconds, the device will reboot and revert to Zigbee mode*/
if (sBoot_zb)
{
SwitchBackToZigbee();
}
}
#endif

Expand All @@ -254,19 +270,21 @@ CHIP_ERROR AppTaskCommon::StartApp(void)
if (user_para.val == USER_ZB_SW_VAL)
{
sBoot_zb = 1;
/* if switch from zb , need to get all the cluster info from zb */
flash_read(flash_para_dev, USER_PARTITION_OFFSET + sizeof(user_para), &light_para, sizeof(light_para));
/* Ensure lightness is at least 2 to avoid display error on HomePod Mini */
if (user_para.lightness < 2)
if (light_para.level < 2)
{
user_para.lightness = 2;
light_para.level = 2;
}
/* Pass the value to the init part to avoid gaps in pwm_pool init */
if (user_para.onoff)
if (light_para.onoff)
{
para_lightness = user_para.lightness;
para_lightness = light_para.level;
}
k_timer_init(&sDnssTimer, &AppTask::DnssTimerTimeoutCallback, nullptr);
k_timer_start(&sDnssTimer, K_MSEC(kDnssTimeout), K_NO_WAIT);
printk("Matter: start timer to protect Dnss initialized %x \r\n", *(int *) (&user_para));
printk("Matter: start timer to protect Dnss initialized \r\n");
}
#endif

Expand Down Expand Up @@ -324,13 +342,16 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void)
CHIP_ERROR err;

PrintFirmwareInfo();
#if CONFIG_CUSTOMER_MODE

#else
InitLeds();
UpdateStatusLED();

InitPwms();

InitButtons();
#endif

// Initialize function button timer
k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr);
Expand Down Expand Up @@ -814,6 +835,23 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /*
#if CONFIG_DUAL_MODE_SWTICH
case DeviceEventType::kCommissioningComplete: {
uint8_t val = USER_MATTER_PAIR_VAL;
#if CONFIG_CUSTOMER_MODE
/* need to add here to update the cluster information , only in the zb switch and touchlink is paired*/
if (user_para.val == USER_ZB_SW_VAL && user_para.on_net)
{
Protocols::InteractionModel::Status status;
/* Switch from the touch link, need to restore previous values */
status = Clusters::OnOff::Attributes::OnOff::Set(kExampleEndpointId, light_para.onoff);
if (status != Protocols::InteractionModel::Status::Success)
{
LOG_ERR("Update OnOff fail: %x", to_underlying(status));
}
status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kExampleEndpointId, light_para.level);
{
LOG_ERR("Update brightness fail: %x", to_underlying(status));
}
}
#endif
flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE);
flash_write(flash_para_dev, USER_PARTITION_OFFSET, &val, 1);
printk("Commissioning complete, set Matter commissionined flag");
Expand All @@ -824,7 +862,7 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /*
if (sBoot_zb)
{
printk("FailSafeTimer expired, Matter commissioning failed, rebooting to Zigbee mode.\r\n");
sys_reboot(0);
SwitchBackToZigbee();
}
else
{
Expand Down
37 changes: 37 additions & 0 deletions examples/platform/telink/common/src/mainCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,43 @@ static void FactoryResetOnBoot(void)
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

#if CONFIG_CUSTOMER_MODE

#define MATTER_NVS_DEMO_EN 0

#if MATTER_NVS_DEMO_EN
void matter_nvs_raw_demo(void)
{
static constexpr char kFactoryResetOnBootStoreKey[] = "TelinkFactoryResetOnBootCnt";
uint32_t test_flag = 0x55;

if (chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kFactoryResetOnBootStoreKey, &test_flag, sizeof(test_flag)) !=
CHIP_NO_ERROR)
{
printk("FactoryResetOnBootCnt write fail\n");
}

test_flag = 0xaa;
CHIP_ERROR FactoryResetOnBootErr =
chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(kFactoryResetOnBootStoreKey, &test_flag, sizeof(test_flag));
if (FactoryResetOnBootErr != CHIP_NO_ERROR)
{
printk("FactoryResetOnBootCnt get fail\n");
}
printk("nvs read value is %x \n", test_flag);
(void) chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(kFactoryResetOnBootStoreKey);
test_flag = 0xbb;
FactoryResetOnBootErr =
chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(kFactoryResetOnBootStoreKey, &test_flag, sizeof(test_flag));
if (FactoryResetOnBootErr != CHIP_NO_ERROR)
{
printk("FactoryResetOnBootCnt delete after read fail \n");
}
}
#endif

#endif

int main(void)
{
#if defined(CONFIG_USB_DEVICE_STACK) && !defined(CONFIG_CHIP_PW_RPC)
Expand Down
Loading

0 comments on commit e2b48b2

Please sign in to comment.