Showing posts with label CC2530. Show all posts
Showing posts with label CC2530. Show all posts

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;
     ...

Sunday, July 29, 2018

660 Zigbee devices in the same Zigbee network!


660 Zigbee devices in the same Zigbee network now!!! This time, we have total 660 Zigbee devices, including 130 ZRs (Smart Plugs) and 530 ZEDs (PIR motion sensors, Door Contact sensors, and Smoke Detectors), joined to a single Zigbee network. The solution is based on TI CC2530.




Sunday, September 3, 2017

Secure Zigbee Pairing Using NFC

As we all know that Zigbee protocol is vulnerable when a new device join the network. If a non-preconfigured device joins a network, a single key may be sent unprotected and enable encrypted communication. This one-time transmission of the unprotected key results in a short time frame of exploitation in which the key could be sniffed by an attacker. We implement a more secure Zigbee Pairing Using NFC and all of implementations are based on TI CC2530-CC2592 and TRF7963A as the following block diagram. The network key is send through TRF7963A from Zigbee coordinator (connecting to IOT GW) to NFC tag which is connected to Zigbee device. So, network key won't go over the air during Zigbee pairing and it won't be captured by any Zigbee sniffer.



The following video gives a demonstration about the process.




Friday, February 10, 2017

Use ZTool + Z-Stack 3.0 ZNP to set up a basic Zigbee 3.0 network

The following steps show you how to use ZTool + Z-Stack 3.0 ZNP to set up Zigbee 3.0 network:

1. You have to prepare two CC253x EVBs (CC2530DK, CC2531EMK, or CC2538EM) and run Z-Stack ZNP 3.0 FW on it.

2. You can run the following MT commands (TX in red) to setup Zigbee 3.0 coordinator.

10:36:58.53 COM1 SYS_OSAL_NV_WRITE (0x2109) --> Write startup option to clear NV when reset
    Id: 0x0003
    Offset: 0x00
    Len: 0x01
    Value: . (0x03)

10:36:58.55 COM1 SYS_OSAL_NV_WRITE_SRSP (0x6109)
    Status: SUCCESS (0x0)

10:37:06.11 COM1 SYS_RESET (0x4100) --> Do reset to clear NV
    Type: 0x00 (HARD RESET) (0x0)

10:37:08.18 COM1 SYS_RESET_RESPONSE (0x4180)
    Reason: 0x02
    TransportRev: 0x02
    Product: 0x00
    MajorRel: 0x02
    MinorRel: 0x07
    HwRev: 0x00

10:37:42.94 COM1 SYS_OSAL_NV_WRITE (0x2109) --> Write ZCD_NV_LOGICAL_TYPE to 0 which means coordinator
    Id: 0x0087
    Offset: 0x00
    Len: 0x01
    Value: . (0x00)

10:37:42.97 COM1 SYS_OSAL_NV_WRITE_SRSP (0x6109)
    Status: SUCCESS (0x0)



10:38:32.55 COM1 APP_CNF_BDB_SET_CHANNEL (0x2F08) --> Set Primary channel mask to channel 13 only
    isPrimary: TRUE (0x1)
    Channel: CHNL_0x00002000 (0x2000)

1
0:38:32.55 COM1 APP_CNF_BDB_SET_CHANNEL_SRSP (0x6F08)
    Status: SUCCESS (0x0)

10:38:34.43 COM1 APP_CNF_BDB_SET_CHANNEL (0x2F08) --> Set Secondary channel to 0x0 to disable secondary channel mask
    isPrimary: FALSE (0x0)
    Channel: NONE (0x0)

10:49:01.44 COM1 APP_CNF_BDB_SET_CHANNEL_SRSP (0x6F08)
    Status: SUCCESS (0x0)

10:38:45.58 COM1 APP_CNF_BDB_START_COMMISSIONING (0x2F05)
--> Start commissioning using network formation as parameter to start coordinator
    CommissioningMode: (0x04) Network Formation (0x4)

10:38:47.35 COM1 APP_CNF_BDB_START_COMMISSIONING_SRSP (0x6F05)
    Status: SUCCESS (0x0)

10:38:47.35 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:47.36 COM1 APP_CNF_BDB_COMMISSIONING_NOTIFICATION (0x4F80)
    Status: 1 (0x1)
    Commissioning Mode: 0x02 (Formation) (0x2)
    Commissioning Mode: 254 (0xFE)

10:38:47.62 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:47.88 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:48.15 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:48.41 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:48.68 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:48.94 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 8 (0x8)

10:38:49.49 COM1 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 9 (0x9)

10:38:49.49 COM1 APP_CNF_BDB_COMMISSIONING_NOTIFICATION (0x4F80)
    Status: 0x00 (Success) (0x0)
    Commissioning Mode: 0x02 (Formation) (0x2)
    Commissioning Mode: 69 (0x45)

10:39:11.49 COM1 UTIL_GET_DEVICE_INFO (0x2700) --> Get device info to confirm coordinator is setup correctly

10:39:11.5 COM1 UTIL_GET_DEVICE_INFO_RESPONSE (0x6700)
    Status: SUCCESS (0x0)
    IEEEAddr: 0x00124B0001025822
    ShortAddress: 0x0000
    DeviceType: COORDINATOR, ROUTER, END_DEVICE (0x7)
    DeviceState: DEV_ZB_COORD (0x9)
    NumAssocDevices: 0x00
    AssocDevicesList

10:39:26.7 COM1 SYS_OSAL_NV_WRITE (0x2109) --> Write ZCD_NV_ZDO_DIRECT_CB to 1 to receive ZDO related messages
    Id: 0x008F
    Offset: 0x00
    Len: 0x01
    Value: . (0x01)

10:39:26.71 COM1 SYS_OSAL_NV_WRITE_SRSP (0x6109)
    Status: SUCCESS (0x0) 


10:44:16.54 COM1 APP_CNF_BDB_START_COMMISSIONING (0x2F05) --> Start commissioning using network steering as parameter to be ready for device to join
    CommissioningMode: (0x02) Network Steering (0x2)

10:44:16.55 COM1 APP_CNF_BDB_START_COMMISSIONING_SRSP (0x6F05)
    Status: SUCCESS (0x0)

10:44:16.56 COM1 ZDO_MGMT_PERMIT_JOIN_RSP (0x45B6)
    SrcAddr: 0x0000
    Status: ZDP_SUCCESS (0x0)

10:44:16.57 COM1 APP_CNF_BDB_COMMISSIONING_NOTIFICATION (0x4F80)
    Status: 0x00 (Success) (0x0)
    Commissioning Mode: 0x01 (Network Steering) (0x1)
    Commissioning Mode: 67 (0x43)


3. You can run the following MT commands to setup Zigbee 3.0 router.

10:43:43.75 COM99 SYS_OSAL_NV_WRITE (0x2109) --> Write ZCD_NV_LOGICAL_TYPE to 1 which means router
    Id: 0x0087
    Offset: 0x00
    Len: 0x01
    Value: . (0x01)

10:43:59.35 COM1 APP_CNF_BDB_SET_CHANNEL (0x2F08) --> Set Primary channel mask to channel 13 only
    isPrimary: TRUE (0x1)
    Channel: CHNL_0x00002000 (0x2000)
10:43:59.35 COM1 APP_CNF_BDB_SET_CHANNEL_SRSP (0x6F08)
    Status: SUCCESS (0x0)

10:44:11.43 COM1 APP_CNF_BDB_SET_CHANNEL (0x2F08) --> Set Secondary channel to 0x0 to disable secondary channel mask
    isPrimary: FALSE (0x0)
    Channel: NONE (0x0)
10:44:11.45 COM1 APP_CNF_BDB_SET_CHANNEL_SRSP (0x6F08)
    Status: SUCCESS (0x0)

10:44:26.46 COM99 APP_CNF_BDB_START_COMMISSIONING (0x2F05) --> Start commissioning using network steering as parameter to make device to start scan Zigbee network to join
    CommissioningMode: (0x02) Network Steering (0x2)

10:44:26.46 COM99 APP_CNF_BDB_START_COMMISSIONING_SRSP (0x6F05)
    Status: SUCCESS (0x0)

10:44:26.56 COM99 APP_CNF_BDB_COMMISSIONING_NOTIFICATION (0x4F80)
    Status: 1 (0x1)
    Commissioning Mode: 0x01 (Network Steering) (0x1)
    Commissioning Mode: 0 (0x0)

10:44:26.8 COM99 ZDO_STATE_CHANGE_IND (0x45C0)
    State: INVALID_PARAMETER (0x2)

10:44:27.11 COM99 ZDO_STATE_CHANGE_IND (0x45C0)
    State: INVALID_PARAMETER (0x2)

10:44:27.37 COM99 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 3 (0x3)

10:44:27.88 COM99 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 5 (0x5)

10:44:28.24 COM99 ZDO_STATE_CHANGE_IND (0x45C0)
    State: 7 (0x7)

10:44:28.9 COM99 APP_CNF_BDB_COMMISSIONING_NOTIFICATION (0x4F80)
    Status: 0x00 (Success) (0x0)
--> Router joins coordinator successfully
    Commissioning Mode: 0x01 (Network Steering) (0x1)
    Commissioning Mode: 0 (0x0)

11:03:22.81 COM99 UTIL_GET_DEVICE_INFO (0x2700)--> Get device info to confirm router is setup correctly

11:03:22.81 COM99 UTIL_GET_DEVICE_INFO_RESPONSE (0x6700)
    Status: SUCCESS (0x0)
    IEEEAddr: 0x00124B0000E50127
    ShortAddress: 0x4EE6
    DeviceType: COORDINATOR, ROUTER, END_DEVICE (0x7)
    DeviceState: DEV_ROUTER (0x7)
    NumAssocDevices: 0x00
    AssocDevicesList
 

4. On Ztool of coordinator, you should see ZDO_END_DEVICE_ANNCE_IND pops when router joins coordinator.

10:44:28.84 COM1 ZDO_END_DEVICE_ANNCE_IND (0x45C1)
    SrcAddr: 0x4EE6
    NwkAddr: 0x4EE6
    IEEEAddr: 0x00124B0000E50127
    Capabilities: 0x8E

Thursday, October 27, 2016

How to create a periodic event for CC253x/CC254x Z-Stack and BLE Stack.

The following codes show example to create a periodic event that is triggered every 5 seconds for CC253x in Z-Stack and you can do it accordingly for CC254x in BLE Stack.

1. Add "#define PERIODIC_EVT 0x0001"in your code. Please note that event define has to be an unused bit mask of uint16.

2. Put  the following line at where you want to start PERIODIC_EVT

osal_start_timerEx( zcl_XXX_TaskID, PERIODIC_EVT, 10 );


2. Create PERIODIC_EVT processing in zcl_XXX_event_loop
if( events & PERIODIC_EVT )
{
  //Do things that need periodic processing here!
  ...
  osal_start_timerEx( zcl_XXX_TaskID, PERIODIC_EVT, 5000 );
  return (events ^ PERIODIC_EVT);
}

Thursday, September 8, 2016

How to use two UART ports in CC2530 Z-Stack

The following steps show how to use two UART ports in CC2530 Z-Stack

1. Define HAL_UART=TRUE, HAL_UART_ISR=1, and HAL_UART_DMA=2 in compile options.
2. Initialize and use UART0 (P0_2 as RX/P0_3 as TX)  as the followings:

void initUart0(halUARTCBack_t pf)
{
  halUARTCfg_t uartConfig;
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = HAL_UART_BR_115200;
  uartConfig.flowControl          = FALSE;
  uartConfig.flowControlThreshold = 48;
  uartConfig.rx.maxBufSize        = 128;
  uartConfig.tx.maxBufSize        = 128;
  uartConfig.idleTimeout          = 6; 
  uartConfig.intEnable            = TRUE;            
  uartConfig.callBackFunc         = pf;
  HalUARTOpen (HAL_UART_PORT_0, &uartConfig);
}

void uart0RxCb( uint8 port, uint8 event )
{
  uint8  ch;
  while (Hal_UART_RxBufLen(port))
  {
    // Read one byte from UART to ch
    HalUARTRead (port, &ch, 1);
  }
}

initUart0(uart0RxCb);

//Output "UART0 output test" to P0.3
HalUARTWrite( HAL_UART_PORT_0, "UART0 output test", (byte)osal_strlen("UART0 output test"));

3. Initialize and use UART1 (P1_6 as TX/P1_7 as RX) as the followings:

void initUart1(halUARTCBack_t pf)
{
  halUARTCfg_t uartConfig;
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = HAL_UART_BR_115200;
  uartConfig.flowControl          = FALSE;
  uartConfig.flowControlThreshold = 48;
  uartConfig.rx.maxBufSize        = 128;
  uartConfig.tx.maxBufSize        = 128;
  uartConfig.idleTimeout          = 6; 
  uartConfig.intEnable            = TRUE;            
  uartConfig.callBackFunc         = pf;
  HalUARTOpen (HAL_UART_PORT_1, &uartConfig);
}

void uart1RxCb( uint8 port, uint8 event )
{
  uint8  ch;
  while (Hal_UART_RxBufLen(port))
  {
    // Read one byte from UART to ch
    HalUARTRead (port, &ch, 1);
  }
}

initUart1(uart0RxCb);

//Output "UART1 output test" to P1.6
HalUARTWrite( HAL_UART_PORT_1, "UART1 output test", (byte)osal_strlen("UART1 output test"));

Wednesday, August 31, 2016

How to handle end node announcement, active endpoint response, and simple descriptor response in Z-Stack for CC2530 and CC2538.

When a Zigbee device joins network, it would broadcast end node announcement with its short and IEEE address. We can register a callback event in Z-Stack to receive end node announcement and store short/IEEE address of device to a device list. Then, we usually call ZDP_ActiveEPReq to request active endpoint and register a callback event in Z-Stack to receive active endpoint response and store it to device list. Finally, we can call ZDP_SimpleDescReq to request simple descriptor and register a callback event in Z-Stack to receive simple descriptor response and store it to device list too.

The following steps show you how to handle end node announcement in Z-Stack SampleLight.

1. Add "ZDO_RegisterForZDOMsg(task_id, Device_annce);" in zclSampleLight_Init().

2. Add the following codes to process Device_annce event in zclSampleLight_ProcessZDOMsgs and you would get end node announcement  information in devAnnce structure.

  ZDO_DeviceAnnce_t devAnnce;

if ( pMsg->clusterID == Device_annce )
      ZDO_ParseDeviceAnnce( pMsg, &devAnnce );





The following steps show you how to handle active endpoint response in Z-Stack SampleLight.

1. Add "ZDO_RegisterForZDOMsg(task_id, Active_EP_rsp);" in zclSampleLight_Init().

2. Add the following codes to process Active_EP_rsp event in zclSampleLight_ProcessZDOMsgs and you would get end node announcement information in pActiveEndpointRsp pointer of ZDO_ActiveEndpointRsp_t structure.

  ZDO_ActiveEndpointRsp_t *pActiveEndpointRsp;

  if ( pMsg->clusterID == Active_EP_rsp )
      pActiveEndpointRsp = ZDO_ParseEPListRsp( pMsg );


The following steps show you how to handle simple descriptor response in Z-Stack SampleLight.

1. Add "ZDO_RegisterForZDOMsg(task_id, Simple_Desc_rsp);" in zclSampleLight_Init().

2. Add the following codes to process Simple_Desc_rsp event in zclSampleLight_ProcessZDOMsgs and you would get simple descriptor in simpleDescRsp structure.

  ZDO_SimpleDescRsp_t simpleDescRsp;

  if ( pMsg->clusterID == Simple_Desc_rsp )
      ZDO_ParseSimpleDescRsp( pMsg, &simpleDescRsp );

Wednesday, March 9, 2016

CC253x/CC254x IO Pin mapping to SmartRF05EB

CC253x/CC254x IO Pin mapping to SmartRF05EB are listed in the followings:



Wednesday, August 26, 2015

How to create a periodic event in TI Z-Stack or BLE-Stack

The following codes are example to start PERIODIC_EVT every second and you can do any periodic processing in PERIODIC_EVT.

//Put where you want to start PERIODIC_EVT
osal_start_timerEx( XXX_TaskID, SENSOR_READ_EVT, 1000 );

//For Z-Stack, create PERIODIC_EVT processing in zcl_XXX_event_loop
//For BLE-Stack, create PERIODIC_EVT processing in xxx_ProcessEvent
  if( events & PERIODIC_EVT )
  {
    //Do things that need periodic processing here!
    ...
    osal_start_timerEx( XXX_TaskID, PERIODIC_EVT, 1000 );
    return (events ^ PERIODIC_EVT);
  }

Tuesday, December 30, 2014

Demostrate more than 100 ZR/ZED nodes in a single Zigbee HA 1.2 Network


This demonstration creates a Zigbee HA 1.2 network and adds 102 ZR and 6 ZED in to this demonstration system. The ZRs are smart plugs that can be remotely controlled by a Zigbee Gateway and report power consumption data. All of 102 ZR smart plugs are divided into 5 groups and can be ON/OFF by group command. ZEDs are IAS zone motion detectors. I do binding to the IAS zone motion detection to trigger ON command for Group 5 smart plugs. You can see in the last part of embedded video that I use motion detector to turn on all of smart plugs in Group 5. The demonstration is based on TI CC2530 and Z-Stack.


More than 100 ZR/ZED node in a single Zigbee network



Wednesday, November 26, 2014

How to output PWM from CC2530/CC2541

Refer to CC253x/4x User's Guide. The following sample code can send PWM to P1_4.


  PERCFG &= (~(0x20)); // Select Timer 3 Alternative 1 location
  P2SEL |=0x20;
  P2DIR |= 0xC0;  // Give priority to Timer 1 channel2-3
  P1SEL |= BV(4);  // Set P1_4 to peripheral, Timer 1,channel 2
  P1DIR |= BV(4);

  T3CTL &= ~0x10;             // Stop timer 3 (if it was running)
  T3CTL |= 0x04;              // Clear timer 3
  T3CTL &= ~0x08;             // Disable Timer 3 overflow interrupts
  T3CTL |= 0x03;              // Timer 3 mode = 3 - Up/Down

  T3CCTL1 &= ~0x40;           // Disable channel 0 interrupts
  T3CCTL1 |= 0x04;            // Ch0 mode = compare
  T3CCTL1 |= 0x10;            // Ch0 output compare mode = toggle on compare

  T3CTL &= ~0xE0;   // Clear Prescaler divider value
  T3CTL |= 0xA0;    //Set Prescaler divider value = Tick frequency /32
  T3CC0 = 128;      //Set ticks = 128

  // Start timer
  T3CTL |= 0x10;

Then, the following example shows you how you output 6.5K PWM with 50% duty cycle to P1.1 with CC2530 Timer 1.

  PERCFG |= BV(6); // Select Timer 1 Alternative 2 location
  P2DIR = (P2DIR & ~0xC0) | 0x80; // Give priority to Timer 1
  P1SEL |= BV(1);  // Set P1_1 to peripheral

  T1CC0L = 0x3A;   // PWM signal period
  T1CC0H = 0x01;

  T1CC1L = 0x9D;  // PWM duty cycle
  T1CC1H = 0x00;

  T1CCTL1 = 0x1c;

  T1CTL |= (BV(2)|0x03); // divide with 128 and to do i up-down mode

How to do temperature monitoring using CC2530 with TI Z-Stack

The battery monitor can also be used to do some simple temperature monitoring in CC2530. When the battery monitor is connected to the internal temperature sensor instead of the supply voltage AVDD5.

The following readTemperature function provides capability to read temperature using CC2530 internal ADC and sensor. When first time call this function, you have to keep temperature at 22oC for calibration.

int8 readTemperature(void)
{
  static uint16 voltageAtTemp22;
  static uint8 bCalibrate=TRUE; // Calibrate the first time the temp sensor is read
  uint16 value;
  int8 temp;

  ATEST = 0x01;
  TR0  |= 0x01;
 
  /* Clear ADC interrupt flag */
  ADCIF = 0;

  ADCCON3 = (HAL_ADC_REF_125V | HAL_ADC_DEC_512 | HAL_ADC_CHN_TEMP);

  /* Wait for the conversion to finish */
  while ( !ADCIF );

  /* Get the result */
  value = ADCL;
  value |= ((uint16) ADCH) << 8;

  // Use the 12 MSB of adcValue
  value >>= 4;
 
  /*
   * These parameters are typical values and need to be calibrated
   * See the datasheet for the appropriate chip for more details
   * also, the math below may not be very accurate
   */
    /* Assume ADC = 1480 at 25C and ADC = 4/C */
  #define VOLTAGE_AT_TEMP_25        1480
  #define TEMP_COEFFICIENT          4

  // Calibrate for 22C the first time the temp sensor is read.
  // This will assume that the demo is started up in temperature of 22C
  if(bCalibrate) {
    voltageAtTemp22=value;
    bCalibrate=FALSE;
  }
 
  temp = 22 + ( (value - voltageAtTemp22) / TEMP_COEFFICIENT );
 
  // Set 0C as minimum temperature, and 100C as max
  if( temp >= 100)
  {
    return 100;
  }
  else if (temp <= 0) {
    return 0;
  }
  else {
    return temp;
  }
}

Wednesday, December 4, 2013

CC2530/CC2541 ADC Howto in TI Z-Stack/BLE Stack

It is always a mystery to beginner to use ADC on CC2530/CC2541. Here, I post how to use TI Z-Stack/BLE Stack API to read ADC value on CC2530/CC2541. I hope this post can help anyone who struggles on CC2530/CC2541 ADC usage. In the followings, I show how to use P0_2 as ADC input, HAL_ADC_REF_125V as reference voltage, and HAL_ADC_RESOLUTION_10, HAL_ADC_RESOLUTION_12, HAL_ADC_RESOLUTION_14 as ADC resolution respectively.

1.  Read ADC value from P0_2 using HAL_ADC_REF_125V as reference voltage and HAL_ADC_RESOLUTION_10 as ADC resolution.

        uint16 adc_ain2=0;
        HalAdcSetReference(HAL_ADC_REF_125V);
        adc_ain2=HalAdcRead(HAL_ADC_CHN_AIN2,HAL_ADC_RESOLUTION_10);



The max measurable voltage of P0_2 is 1.15 because I am using HAL_ADC_REF_125V as reference voltage here. If the input voltage is larger than 1.15V, the ADC reading adc_ain2 will be always 511. If I connect P0_2 to 0.5V, I will have ADC reading adc_ain2=223. Then, we can convert the reading 223 to measured voltage using the following equation.
measured voltage = 1.15x223/511=0.501...

2. If I change  HAL_ADC_RESOLUTION_12 (the max reading is 2047) as ADC resolution and connect P0_2 to 0.5V, I will have ADC reading adc_ain2=886. Then, we can convert the reading 889 to measured voltage using the following equation.
measured voltage = 1.15x889/2047=0.499...


3. If I change  HAL_ADC_RESOLUTION_14 (the max reading is 8191) as ADC resolution and connect P0_2 to 0.5V, I will have ADC reading adc_ain2=3550. Then, we can convert the reading 3550 to measured voltage using the following equation.
measured voltage = 1.15x3550/8191=0.498...