Monday, May 6, 2019

How to check APS ack in TI Z-Stack

The following steps show you how to check APS ack in TI Z-Stack using ON/OFF cluster toggle command in SampleSwitch example.

1. Setup OnOffOptions and use zcl_registerClusterOptionList in  zclSampleSw_Init to register receiving APS ack on ZCL_CLUSTER_ID_GEN_ON_OFF cluster command.
   
    zclOptionRec_t OnOffOptions[] =
    {
      {
         ZCL_CLUSTER_ID_GEN_ON_OFF, ( AF_EN_SECURITY | AF_ACK_REQUEST ),
      },
    };
    ZStatus_t status = zcl_registerClusterOptionList ( SAMPLESW_ENDPOINT, 1,
                                                                                    OnOffOptions );
 2.  Add "case AF_DATA_CONFIRM_CMD:..." in SYS_EVENT_MSG case of zclSampleSw_event_loop

    uint16 zclSampleSw_event_loop( uint8 task_id, uint16 events )
    {
      ...
     
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleSw_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
            case AF_DATA_CONFIRM_CMD:
              afDataConfirm_t *SWafDataConfirm;
              SWafDataConfirm = (afDataConfirm_t *)MSGpkt;
              rcv_aps_ack_trans_id=SWafDataConfirm->transID;
              // You can use rcv_aps_ack_trans_id to check if it matches to APS_Counter when you send toggle command with zclGeneral_SendOnOff_CmdToggle
              break;
     ...

Tuesday, April 2, 2019

How to build and run EmberZnet Z3Gateway on Raspberry Pi.

The following steps show you how to build and run EmberZnet 6.50.3 Z3Gateway on Raspberry Pi.

1. Install the Raspbian OS and Gateway Software according to section 2.3 in UG-129.

2. Set Up/Build the EMberZnet 6.50.3 Z3Gateway Application and MQTT Broker according to section 6.1.1 in UG-129.

3. Run "sudo service siliconlabsgateway stop" on Raspberry Pi console to stop siliconlabsgateway.

4. Rename built Z3GatewayHost (under sdks/gecko_sdk_suite/v2.2/app/builder/Z3GatewayHost/build/exe directory) to siliconlabsgateway and copy it to /opt/siliconlabs/zigbeegateway/bin to overwrite siliconlabsgateway under /opt/siliconlabs/zigbeegateway/bin

5. Copy the ncp.py to replace the original one under /opt/siliconlabs/zigbeegateway/tools/ncp-updater

6. Download NCP image (under C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.5\protocol\zigbee\ncp-images\efr32mg12p432f1024gl125-brd4161a) to BRD4001+BRD4161A and connect it to Raspberry which will simulate ttyACM0 for Z3Gateway to communicate with.

7. Run "sudo service siliconlabsgateway start" on Raspberry Pi console to start siliconlabsgateway.

8. Open any browser and access to Raspberry Pi IP to test web UI of Z3Gateway


Thursday, January 17, 2019

How to output 32K crystal signal to specific pin on LAUNCHXL-CC2640R2

The following steps show you how to output 32K crystal signal to specific pin on LAUNCHXL-CC2640R2 using simple_peripheral example.

1. Add " #include  < driverlib/aon_ioc.h > " in simple_peripheral.c.

2. Add the following two lines in the end of SimplePeripheral_init() to output 32K crystal signal to DIO_10.

    IOCPortConfigureSet(IOID_10, IOC_PORT_AON_CLK32K, IOC_STD_OUTPUT);
    AONIOC32kHzOutputEnable();

3. Use scope to check wave form and frequency on DIO_10.

Thursday, January 3, 2019

How to generate PWM on EFR32

The following codes show you how to generate PWM on Silicon Labs EFR32 when button is pressed. In this example, I will use BRD4151A radio board with mainboard BRD4001A to output 1KHz PMW on PC10 pin

#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_timer.h"

/* Use 1 kHz for PWM frequency */
#define PWM_FREQ 1000

void emberAfHalButtonIsrCallback(uint8_t button, uint8_t state)
{
  uint32_t topValue;
       
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_TIMER0, true);
  /* set CC0 location 15 pin (PC10) as output, initially high */
  GPIO_PinModeSet (gpioPortC, 10, gpioModePushPull, 1);
 
  /* select CC channel parameters */
  TIMER_InitCC_TypeDef timerCCInit =
  {
    .eventCtrl  = timerEventEveryEdge,
    .edge       = timerEdgeBoth,
    .prsSel     = timerPRSSELCh0,
    .cufoa      = timerOutputActionNone,
    .cofoa      = timerOutputActionNone,
    .cmoa       = timerOutputActionToggle,
    .mode       = timerCCModePWM,
    .filter     = false,
    .prsInput   = false,
    .coist      = true,
    .outInvert  = false,
  };
 
  /* configure CC channel 0 */
  TIMER_InitCC (TIMER0, 0, &timerCCInit);

  /* route CC0 to location 15 (PC10) and enable pin */
  TIMER0->ROUTELOC0 |= TIMER_ROUTELOC0_CC0LOC_LOC15;
  TIMER0->ROUTEPEN |= TIMER_ROUTEPEN_CC0PEN;

  /* set PWM period */
  topValue = CMU_ClockFreqGet (cmuClock_HFPER) / PWM_FREQ;
  TIMER_TopSet (TIMER0, topValue);

  /* Set PWM duty cycle to 50% */
  TIMER_CompareSet (TIMER0, 0, topValue >> 1);

  /* set timer parameters */
  TIMER_Init_TypeDef timerInit =
  {
    .enable     = true,
    .debugRun   = true,
    .prescale   = timerPrescale1,
    .clkSel     = timerClkSelHFPerClk,
    .fallAction = timerInputActionNone,
    .riseAction = timerInputActionNone,
    .mode       = timerModeUp,
    .dmaClrAct  = false,
    .quadModeX4 = false,
    .oneShot    = false,
    .sync       = false,
  };

  /* configure and start timer */
  TIMER_Init (TIMER0, &timerInit); 
}





p.s. Here, we set route CC0 to location 15 (PC10) according to Table 6.6  Alternate Functionality Overview in efr32mg1 datasheet.