2018年1月23日 星期二

nRF52840 in SDK14: disable NRF_LOG and activate UART

From SDK12, nRF5x series use NRF_LOG to replace printf( ) , which cause UART printf function can not be used. However, I still want to use UART function to print. This article is about how to disable NRF_LOG and use UART as usual.

This example is modified from ble_app_template
located in:
nRF5_SDK_14.2.0_17b948a\nRF5_SDK_14.2.0_17b948a\examples\ble_peripheral\ble_app_template

Board:nRF52840/SDK14/S140

STEP 0. project config

add  these files into nrf_library
"app_uart_fifo.c"
"app_fifo.c"
"retarget.c"


located in :
nRF5_SDK_14.2.0_17b948a\components\libraries\uart
nRF5_SDK_14.2.0_17b948a\components\libraries\fifo



next  include path to project option




STEP 1. modify "sdk_config"
I suggest first open sdk_config.h Text Editor

add these about line  3004 (after  nRF_Libraries )
//==========================================================
// <q> APP_FIFO_ENABLED  - app_fifo - Software FIFO implementation
 

#ifndef APP_FIFO_ENABLED
#define APP_FIFO_ENABLED 1
#endif


then add these about line 3080 (after APP_TWI_ENABLED )
// <e> APP_UART_ENABLED - app_uart - UART driver
//==========================================================
#ifndef APP_UART_ENABLED
#define APP_UART_ENABLED 1
#endif
// <o> APP_UART_DRIVER_INSTANCE  - UART instance used
 
// <0=> 0 

#ifndef APP_UART_DRIVER_INSTANCE
#define APP_UART_DRIVER_INSTANCE 0
#endif


then add these about line 3506(after NRF_QUEUE_ENABLED)
// <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions
 

#ifndef RETARGET_ENABLED
#define RETARGET_ENABLED 1
#endif


Then open sdk_config.h Configuration Wizard 
you can see:






Then open nRF_Drivers and check:



but if you prefer to add code , please add in sdk_config.h Text Editor
about line  2724 (after TWI_ENABLE)
// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver
//==========================================================
#ifndef UART_ENABLED
#define UART_ENABLED 1
#endif
// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
 
// <0=> Disabled 
// <1=> Enabled 

#ifndef UART_DEFAULT_CONFIG_HWFC
#define UART_DEFAULT_CONFIG_HWFC 0
#endif

// <o> UART_DEFAULT_CONFIG_PARITY  - Parity
 
// <0=> Excluded 
// <14=> Included 

#ifndef UART_DEFAULT_CONFIG_PARITY
#define UART_DEFAULT_CONFIG_PARITY 0
#endif

// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
 
// <323584=> 1200 baud 
// <643072=> 2400 baud 
// <1290240=> 4800 baud 
// <2576384=> 9600 baud 
// <3862528=> 14400 baud 
// <5152768=> 19200 baud 
// <7716864=> 28800 baud 
// <10289152=> 38400 baud 
// <15400960=> 57600 baud 
// <20615168=> 76800 baud 
// <30801920=> 115200 baud 
// <61865984=> 230400 baud 
// <67108864=> 250000 baud 
// <121634816=> 460800 baud 
// <251658240=> 921600 baud 
// <268435456=> 1000000 baud 

#ifndef UART_DEFAULT_CONFIG_BAUDRATE
#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
#endif

// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7
#endif

// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
 

#ifndef UART_EASY_DMA_SUPPORT
#define UART_EASY_DMA_SUPPORT 1
#endif

// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
 

#ifndef UART_LEGACY_SUPPORT
#define UART_LEGACY_SUPPORT 1
#endif

// <e> UART0_ENABLED - Enable UART0 instance
//==========================================================
#ifndef UART0_ENABLED
#define UART0_ENABLED 1
#endif
// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
 

#ifndef UART0_CONFIG_USE_EASY_DMA
#define UART0_CONFIG_USE_EASY_DMA 1
#endif

// </e>

// <e> UART1_ENABLED - Enable UART1 instance
//==========================================================
#ifndef UART1_ENABLED
#define UART1_ENABLED 0
#endif
// <q> UART1_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
 

#ifndef UART1_CONFIG_USE_EASY_DMA
#define UART1_CONFIG_USE_EASY_DMA 1
#endif

// </e>

// </e>

// <e> USBD_ENABLED - nrf_drv_usbd - USB driver
//==========================================================
#ifndef USBD_ENABLED
#define USBD_ENABLED 0
#endif
// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef USBD_CONFIG_IRQ_PRIORITY
#define USBD_CONFIG_IRQ_PRIORITY 7
#endif



STEP 2. disable NRF_LOG in UART
open sdk_config.h Configuration Wizard and check nrf_log Logger
disable them all






























STEP 3. modify main.c

add these include & #define in main.c
#include "app_uart.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif
 
#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED
#define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 256                         /**< UART RX buffer size. */


add below code  after buttons_leds_init( ) function :
void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
}


static void uart_init(void)
{
  uint32_t err_code;
  const app_uart_comm_params_t comm_params =
  {
   RX_PIN_NUMBER,
   TX_PIN_NUMBER,
   RTS_PIN_NUMBER,
   CTS_PIN_NUMBER,
   UART_HWFC,
   false,
   NRF_UART_BAUDRATE_115200
  };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);
}


in main( ) function
please #if(0) log_init( ) and add uart_init( ) as this :

int main(void)
{
    bool erase_bonds;

    // Initialize.
#if(0) 
    log_init();
#endif 
    timers_init();  
    buttons_leds_init(&erase_bonds);
 
    uart_init();   
    printf("agathakuan\r\n");
    printf("system start!!\r\n");
 
    ble_stack_init();
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();
    conn_params_init();
    peer_manager_init();

    // Start execution.
    NRF_LOG_INFO("Template example started.");
    application_timers_start();

    advertising_start(erase_bonds);

    // Enter main loop.
    for (;;)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            power_manage();
        }
    }
}

program and reset your device, then open your COM port, you can see:




NOTE:
1. in SDK14, the developer must assign UART, PWM,WDT...etc in sdk_config.h
otherwise, even they include all the paths and files needed, they still can not open UART.

2. if you activate NRF_LOG_BACKEND_UART, you should not use printf( ), else it will cause system fatal error.

3.The way to activate UART in SDK14 is NOT the same as SDK12


REFERENCE:
http://gaiger-programming.blogspot.tw/2016/12/nrf51-make-printf-works-well.html?m=1
http://programnoteagatha.blogspot.tw/2017/05/nrf52-printf-in-sdk12.html
























2018年1月18日 星期四

JN5169: software-implement I2C example with mpu6050

JN5169 hardware I2c pins are P0_14 & P0_15, which is the same as UART_1, so in some cases I have enabled pin 14,15 as UART_1,  I use 2 GPIOs (DIO in JN5169) to implement I2c, and print MPU6050 data.

my example is based on :
JN-AN-1171-ZigBee-LightLink-Demo/ Controller_ColorController


and I set :
pin 16 as SCL
pin 17 as SDA

STEP 0. my source code
myiic.h
/* myIIC.h
 *
 *  Created on: 2018.1.19
 *      Author: Agatha Kuan
 */

#ifndef MY_IIC_H_
#define MY_IIC_H_

#include <jendefs.h>
#include "zps_gen.h"
#include "AppHardwareApi.h"
#include <string.h>
#include "dbg.h"
#include "os.h"
#include "os_gen.h"



#define IIC_DATA_LEN    7
#define SI_TX      FALSE
#define SI_RX      TRUE

#define HW_DIO_CLK   16
#define HW_DIO_DATA   17
#define SI_CLK    (1<<HW_DIO_CLK)
#define SI_DATA    (1<<HW_DIO_DATA)
#define SI_SET_DELAY  6


#define BV(x)    (1<<(x))

#define SI_CLK_SET   vAHI_DioSetOutput(SI_CLK, 0)
#define SI_CLK_CLR   vAHI_DioSetOutput(0, SI_CLK)
#define SI_DATA_SET   vAHI_DioSetOutput(SI_DATA, 0)
#define SI_DATA_CLR   vAHI_DioSetOutput(0, SI_DATA)


PUBLIC void uI2C_Init ( void );

PUBLIC void uI2C_DIOConfig( bool_t wr );
PUBLIC void uI2C_Stop( void );
PUBLIC void uI2C_Start( void );
PUBLIC uint8 uI2C_Read_Data( bool_t tail );
PUBLIC void uI2C_Write_Data( uint8 ch );
PUBLIC void uI2C_Send_Ack( bool_t tail );
PUBLIC void uI2C_Read_Ack( void );

PUBLIC void uI2C_Read( uint8 *data, uint8 size );
PUBLIC void uI2C_Write( uint8 addr, uint8 *data, uint8 size );
PUBLIC void wDelayus(uint32 udelayus);


#endif /* MY_IIC_H_ */


myiic.c
/*
 * myiic.c
 *
 *  Created on: 2018.1.19
 *      Author: Agatha Kuan
 */

#include "myiic.h"


PUBLIC void uI2C_Stop( void );
PUBLIC void uI2C_Start( void );
PUBLIC uint8 uI2C_Read_Data( bool_t tail );
PUBLIC void uI2C_Write_Data( uint8 ch );
PUBLIC void uI2C_DIOConfig( bool_t wr );
PUBLIC void uI2C_Send_Ack( bool_t tail );
PUBLIC void uI2C_Read_Ack( void );

uint8 si_buff[32];


PUBLIC void uI2C_Init( void )
{
 vAHI_DioSetDirection(0, SI_CLK|SI_DATA);
 uI2C_Stop();
}


PUBLIC void uI2C_DIOConfig( bool_t wr )
{
 if ( wr )
 {
  /* read - input */
  vAHI_DioSetDirection(SI_DATA, 0);
 }
 else
 {
  /* write */
  vAHI_DioSetDirection(0, SI_DATA);
 }
}


PUBLIC void uI2C_Write_Data( uint8 ch )
{
 int idx;

 uI2C_DIOConfig( SI_TX );

 for (idx = 7; idx >= 0; idx-- )
 {
  if ((ch & BV(idx)) == BV(idx))
  {
   SI_DATA_SET;
   wDelayus(SI_SET_DELAY);
  }
  else
  {
   SI_DATA_CLR;
   wDelayus(SI_SET_DELAY);
  }
  SI_CLK_SET;
  wDelayus(SI_SET_DELAY);
  SI_CLK_CLR;
  wDelayus(SI_SET_DELAY);
 }
 /* wait for ack */
 uI2C_Read_Ack();
}

PUBLIC uint8 uI2C_Read_Data( bool_t tail )
{
 uint8 ret = 0;
 int x;
 volatile uint32 bitmap = 0;

 uI2C_DIOConfig( SI_RX );

 for ( x = 7; x >= 0; x-- )
 {
  ret <<= 1;
  SI_CLK_SET;
  wDelayus(SI_SET_DELAY);

  bitmap = u32AHI_DioReadInput();
  if ( (bitmap & BV(HW_DIO_DATA)) == BV(HW_DIO_DATA) )
  {
   ret |= 1;
  }

  SI_CLK_CLR;
  wDelayus(SI_SET_DELAY);
 }

 uI2C_Send_Ack( tail );
 return ret;
}

PUBLIC void uI2C_Start( void )
{
 SI_DATA_SET;
 SI_CLK_SET;
 wDelayus(SI_SET_DELAY);
 SI_DATA_CLR;
 wDelayus(SI_SET_DELAY);
 SI_CLK_CLR;
 wDelayus(SI_SET_DELAY);
}

PUBLIC void uI2C_Stop( void )
{
 SI_DATA_CLR;
 SI_CLK_SET;
 wDelayus(SI_SET_DELAY);
 SI_DATA_SET;
 wDelayus(SI_SET_DELAY);
}
PUBLIC void uI2C_Send_Ack( bool_t tail )
{
 uI2C_DIOConfig( SI_TX );

 if ( tail )
  SI_DATA_SET;
 else
  SI_DATA_CLR;
 wDelayus(SI_SET_DELAY);
 SI_CLK_SET;
 wDelayus(SI_SET_DELAY);
 SI_CLK_CLR;
 wDelayus(SI_SET_DELAY);

 uI2C_DIOConfig( SI_RX );
}

PUBLIC void uI2C_Read_Ack( void )
{
 uI2C_DIOConfig( SI_RX );

 SI_CLK_SET;
 wDelayus(SI_SET_DELAY);
 /* read slave ack */

 SI_CLK_CLR;
 wDelayus(SI_SET_DELAY);

 uI2C_DIOConfig( SI_TX );
}
                                                 
PUBLIC void wDelayus(uint32 udelayus)
{
    volatile uint32 u32Delay = 0;
    for(u32Delay=0;u32Delay< udelayus;u32Delay++);
}


and use this "myiic.c", I try to enable MPU6050 as IIC slave of JN5169.
and this is mpu6050.h

/*
 * mpu6050.h
 *
 * Created on: 2018.01.03
 * Author: Agatha Kuan
 */
 
#ifndef MPU6050_H_
#define MPU6050_H_

#include <jendefs.h>
#include "zps_gen.h"
#include "AppHardwareApi.h"
#include <string.h>
#include "dbg.h"
#include "os.h"
#include "os_gen.h"
#include "myiic.h"

#define MPU_SELF_TESTX_REG  0X0D 
#define MPU_SELF_TESTY_REG  0X0E 
#define MPU_SELF_TESTZ_REG  0X0F 
#define MPU_SELF_TESTA_REG  0X10 
#define MPU_SAMPLE_RATE_REG  0X19 
#define MPU_CFG_REG    0X1A 
#define MPU_GYRO_CFG_REG  0X1B 
#define MPU_ACCEL_CFG_REG  0X1C 

#define MPU_FIFO_EN_REG   0X23 
#define MPU_I2CMST_CTRL_REG  0X24 
#define MPU_I2CSLV0_REG   0X26 
#define MPU_I2CSLV1_ADDR_REG 0x28 
#define MPU_I2CSLV1_REG   0X29 
#define MPU_I2CSLV1_CTRL_REG 0X2A 
#define MPU_I2CSLV2_REG   0X2C 
#define MPU_I2CSLV2_CTRL_REG 0X2D 
#define MPU_I2CSLV3_REG   0X2F 
#define MPU_I2CSLV3_CTRL_REG 0X30 
#define MPU_I2CSLV4_ADDR_REG 0X31 
#define MPU_I2CSLV4_DO_REG  0X33 
#define MPU_I2CSLV4_REG   0X32 
#define MPU_I2CSLV4_DO_REG  0X33 
#define MPU_I2CSLV4_CTRL_REG 0X34 
#define MPU_I2CMST_STA_REG  0X36 
#define MPU_INTBP_CFG_REG  0X37 
#define MPU_INT_EN_REG   0X38 
#define MPU_INT_STA_REG   0X3A 


#define MPU_ACCEL_XOUTH_REG  0X3B 
#define MPU_ACCEL_XOUTL_REG  0X3C 
#define MPU_ACCEL_YOUTH_REG  0X3D 
#define MPU_ACCEL_YOUTL_REG  0X3E 
#define MPU_ACCEL_ZOUTH_REG  0X3F 
#define MPU_ACCEL_ZOUTL_REG  0X40 

#define MPU_TEMP_OUTH_REG  0X41 

#define MPU_GYRO_XOUTH_REG  0X43 
#define MPU_GYRO_XOUTL_REG  0X44 
#define MPU_GYRO_YOUTH_REG  0X45 
#define MPU_GYRO_YOUTL_REG  0X46 
#define MPU_GYRO_ZOUTH_REG  0X47 
#define MPU_GYRO_ZOUTL_REG  0X48 

#define MPU_I2CSLV0_DO_REG  0X63 
#define MPU_I2CSLV1_DO_REG  0X64 
#define MPU_I2CSLV2_DO_REG  0X65 
#define MPU_I2CSLV3_DO_REG  0X66 
#define MPU_I2CMST_DELAY_REG 0X67 

#define MPU_MDETECT_CTRL_REG 0X69 
#define MPU_USER_CTRL_REG  0X6A 
#define MPU_PWR_MGMT1_REG  0X6B 
#define MPU_PWR_MGMT2_REG  0X6C 

#define MPU_FIFO_CNTH_REG  0X72 
#define MPU_FIFO_CNTL_REG  0X73 
#define MPU_FIFO_RW_REG   0X74 

#define MPU_DEVICE_ID_REG  0X75 

#define MPU_ADDR    0X68
#define WHO_I_AM    0X68


PUBLIC uint8 mpu_init(void);
PUBLIC void mpu_get_accel(short *ax, short *ay, short *az);
PUBLIC void mpu_get_gyro(short *gx,short *gy,short *gz);
PUBLIC void mpu_get_temperature(short *temp);

PUBLIC uint8 mpu_restart(void);

#endif

mpu6050.c

/*
 * MPU6050.c
 *
 * Created on: 2018.01.03
 * Author: Agatha Kuan
 */
 
#include "myiic.h"
#include "mpu6050.h"

uint8 si_buff[32];


PUBLIC void mpu_read(uint8 register_addr, uint8 *data, uint8 size);
PUBLIC void mpu_write(uint8 register_addr, uint8 *data, uint8 size);
PUBLIC uint8 mpu_write_byte(uint8 register_addr, uint8 data);
PUBLIC uint8 mpu_set_rate(uint16 rate);
PUBLIC uint8 mpu_set_accel_fsr(uint8 fsr);
PUBLIC uint8 mpu_set_gyro_fsr(uint8 fsr);
PUBLIC uint8 mpu_init(void);


PUBLIC uint8 mpu_init(void)
{
 uint8 ret =0;

 mpu_write_byte(MPU_PWR_MGMT1_REG,0x80);
 wDelayus(100*100);
 mpu_write_byte(MPU_PWR_MGMT1_REG,0x00);

 mpu_set_gyro_fsr(3);
 mpu_set_accel_fsr(0);
 mpu_set_rate(50);

 mpu_write_byte(MPU_INT_EN_REG,0x00); 
 mpu_write_byte(MPU_USER_CTRL_REG,0x00); 
 mpu_write_byte(MPU_FIFO_EN_REG,0x00); 
 mpu_write_byte(MPU_INTBP_CFG_REG,0x80); 
 
 mpu_read(MPU_DEVICE_ID_REG,&ret,1);
 
 DBG_vPrintf(TRUE,"\r\nAgatha:Device mpu6050:%0x\r\n",ret);

 if(ret==WHO_I_AM)
 {
  mpu_write_byte(MPU_PWR_MGMT1_REG,0X01); 
  mpu_write_byte(MPU_PWR_MGMT2_REG,0X00); 
  mpu_set_rate(50);
 }
 else
  return 1;
 
 return 0;
}


PUBLIC uint8 mpu_restart(void)
{
 uint8 ret =0;
 

 mpu_read(MPU_DEVICE_ID_REG,&ret,1);
 if(ret==WHO_I_AM)
 {
  mpu_write_byte(MPU_PWR_MGMT1_REG,0X01); 
  mpu_write_byte(MPU_PWR_MGMT2_REG,0X00); 
  mpu_set_rate(50);
 }

 return 0;
}


PUBLIC uint8 mpu_set_gyro_fsr(uint8 fsr)
{
 uint8 data = 0;

 data =  fsr<<3;
 mpu_write(MPU_GYRO_CFG_REG,&data,1);
 return data;
}


PUBLIC uint8 mpu_set_accel_fsr(uint8 fsr)
{
 uint8 data = 0;

 data =  fsr<<3;
 mpu_write(MPU_ACCEL_CFG_REG,&data,1);

 return data;
}


PUBLIC uint8 mpu_set_lpf(uint16 lpf)
{
 uint8 data = 0;
 if(lpf>=188)data=1;
 else if(lpf>=98)data=2;
 else if(lpf>=42)data=3;
 else if(lpf>=20)data=4;
 else if(lpf>=10)data=5;
 else data=6; 

 mpu_write(MPU_CFG_REG,&data,1);

 return data;
}


PUBLIC uint8 mpu_set_rate(uint16 rate)
{
 uint8 data = 0;
 if(rate>1000)
  rate=1000;
 if(rate<4)rate=4;
  data=1000/rate-1;
 
 mpu_write(MPU_SAMPLE_RATE_REG,&data,1);

 return mpu_set_lpf(rate/2);
}

PUBLIC uint8 mpu_write_byte(uint8 register_addr, uint8 data)
{
 uI2C_Start();
 uI2C_Write_Data( (MPU_ADDR<<1)|0 );
 
 uI2C_Write_Data( register_addr );
 uI2C_Write_Data( data );
 
 uI2C_Stop();
 return 0;
}


PUBLIC void mpu_write(uint8 register_addr, uint8 *data, uint8 size)
{
 uint8 i;

 uI2C_DIOConfig( SI_TX );
 
 uI2C_Start();
 
 uI2C_Write_Data( (MPU_ADDR<<1)|0 ); 
 uI2C_Write_Data( register_addr );
 
 for (i = 0; i<size; i++)
 {
  uI2C_Write_Data( data[i] );
 }
 
 uI2C_Stop();
}


PUBLIC void mpu_read(uint8 register_addr, uint8 *data, uint8 size)
{
 uint8 i;

 uI2C_DIOConfig( SI_TX );
 
 uI2C_Start();
 
 uI2C_Write_Data( (MPU_ADDR<<1)|0 ); 
 uI2C_Write_Data( register_addr );
 
 uI2C_Start();
 
 uI2C_Write_Data( (MPU_ADDR<<1)|1);
 
 for (i = 0; i<size; i++)
 {
  if ( i == size-1 )
   si_buff[i] = uI2C_Read_Data( TRUE );
  else
   si_buff[i] = uI2C_Read_Data( FALSE );
 }
 
 uI2C_Stop();

 memcpy( data, si_buff, size );
 
}


PUBLIC void mpu_get_accel(short *ax, short *ay, short *az)
{
 uint8 ret[6];
 mpu_read(MPU_ACCEL_XOUTH_REG,&ret[0],6);

 *ax=((uint16)ret[0]<<8)|ret[1];
 *ay=((uint16)ret[2]<<8)|ret[3];
 *az=((uint16)ret[4]<<8)|ret[5];
}


PUBLIC void mpu_get_gyro(short *gx,short *gy,short *gz)
{
 uint8 ret[6];
 mpu_read(MPU_GYRO_XOUTH_REG,&ret[0],6);

 *gx=((uint16)ret[0]<<8)|ret[1];
 *gy=((uint16)ret[2]<<8)|ret[3];
 *gz=((uint16)ret[4]<<8)|ret[5];
}


PUBLIC void mpu_get_temperature(short *temp)
{
 uint8 buf[2];
 short raw;
 mpu_read(MPU_TEMP_OUTH_REG,&buf[0],2);
 raw=((uint16)buf[0]<<8)|buf[1];

 raw = 36.53+((double)raw)/340;

 *temp = raw*100;
}


STEP 1.  include "myiic.h" & "mpu6050.h"  to zll_remote_node.c

1.
add these 4 files to
C:\NXP\bstudio_nxp\workspace\JN-AN-1171-ZigBee-LightLink-Demo_NXP\Common_Controller\Source




2.
go to C:\NXP\bstudio_nxp\workspace\JN-AN-1171-ZigBee-LightLink-Demo_NXP\Common_Controller\Build
and open Makefile


at about line.180
add
APPSRC += myiic.c
APPSRC += mpu6050.c
to compile them.

2.
inlcude "mpu6050.h" & "myiic.h" in zll_remote_node.h


#include "myiic.h"
#include "mpu6050.h"




3.
add the following in "zll_remote_node.c" vStartUpHW

void vStartUpHW(void)
{

    uint8 u8Status;
 
 /*Agatha: initialized software implement I2C*/
    uI2C_Init();
    mpu_init(); 

    /* Restart the keyboard scanning timer as we've come up through */
    /* warm start via the Power Manager if we get here              */
    APP_wButtonInitialise();
    vConfigureScanTimer();

     DBG_vPrintf(TRACE_SLEEP, "\nWoken: start poll timer,");
     u8Status = ZPS_eAplZdoPoll();
     DBG_vPrintf(TRACE_SLEEP, " Wake poll %02x\n", u8Status);
     OS_eStartSWTimer(APP_PollTimer, APP_TIME_MS(200), NULL);
}

in the same file OS_TASK(APP_SleepAndPollTask)
so the device will continuous read data 

OS_TASK(APP_SleepAndPollTask)
{
 uint32 u32Time = APP_TIME_MS(1000);
 
 if (!bTLinkInProgress)
 {
  DBG_vPrintf(TRUE, "KeepAlive - %d, Deep Sleep - %d fast Poll - %d Rejoin - %d FailedTojoin %d \n",
          u8KeepAliveTime,
          u8DeepSleepTime,
          u16FastPoll,
          u8RejoinAttemptsRemaining,
          bFailedToJoin);
    
  /*Agatha: read MPU6050 data*/
  mpu_restart();
  mpu_get_gyro(&gyro_x,&gyro_y,&gyro_z);
  DBG_vPrintf(TRUE,"%d,%d,%d\r\n",gyro_x,gyro_y,gyro_z);


  switch (sZllState.eNodeState)
  {
   case E_REMOTE_WAIT_START:
    DBG_vPrintf(TRACE_REMOTE_NODE|TRACE_REJOIN, "Poll and Sleep: Wait Start \n");
    /* wait to form or to join network, if nothing happens deep sleep */
    u32Time = APP_TIME_MS(1000);
    if (bFailedToJoin)
    {
     if(u8RejoinAttemptsRemaining == 0)
     {
      bFailedToJoin = FALSE;
      u8RejoinAttemptsRemaining = TRY_JOIN_FAIL_TIME;
      u8KeepAliveTime = KEEP_ALIVETIME;//KEEP_ALIVE_FACTORY_NEW
      DBG_vPrintf(TRACE_REJOIN, "Wait start: no more retries\n");
     }
     else
     {
      u8RejoinAttemptsRemaining--;
      DBG_vPrintf(TRACE_REJOIN, "Wait start: try a rejoin\n");
      vSetRejoinFilter();
      ZPS_eAplZdoRejoinNetwork(TRUE);
     }
    }
                  else
                  {
                   if(TESTDONE ==u8SaveFlash[0])
     {
      if(u8KeepAliveTime == 0)
      {
       /* waited long enough without forming or joining,
       * give up and deep sleep to save the  battery
       */
       vStopAllTimers();
       /*PWRM_vInit(E_AHI_SLEEP_DEEP);
       bDeepSleep = TRUE;
       DBG_vPrintf(TRACE_SLEEP, "Wait start: go deep\n");
       DBG_vPrintf(TRACE_SLEEP,"\n Activity %d\n",PWRM_u16GetActivityCount());
       */
       if (u8DeepSleepTime)
       {
        PWRM_eScheduleActivity(&sWake, (SLEEP_DURATION_MS * SLEEP_TIMER_TICKS_PER_MS) , vWakeCallBack);
        PWRM_vInit(E_AHI_SLEEP_OSCOFF_RAMON);
        DBG_vPrintf(TRACE_SLEEP, "poll task: schedule sleep\n");
       }
       else
       {
        PWRM_vInit(E_AHI_SLEEP_DEEP);
        bDeepSleep = TRUE;
        DBG_vPrintf(TRACE_SLEEP, "poll task: go deep\n");
       }
       DBG_vPrintf(TRACE_SLEEP,"\n Activity %d\n",PWRM_u16GetActivityCount());
       return;
      }
      else
      {
       if(!App_CheckButtonStatus())
       {
        u8KeepAliveTime--;
       }
      }
                   }
                  }
                  break;
    case E_REMOTE_NETWORK_DISCOVER:
        /* do nothing, wait for classic discovery and join to finish */
        u32Time = APP_TIME_MS(1000);
        DBG_vPrintf(TRACE_REMOTE_NODE|TRACE_REJOIN, "Poll and Sleep: Network Discovery\n");
        break;
    case E_REMOTE_RUNNING:
     DBG_vPrintf(TRACE_REMOTE_NODE|TRACE_REJOIN, "Poll and Sleep: Running\n");
     if (bFailedToJoin)
     {
      /* Manage rejoin attempts,then short wait, then deep sleep */
      u32Time = APP_TIME_MS(1000);
      if(u8RejoinAttemptsRemaining == 0)
      {
       if (u8DeepSleepTime) 
       {
        vStopAllTimers();
        PWRM_eScheduleActivity(&sWake,(SLEEP_DURATION_MS * SLEEP_TIMER_TICKS_PER_MS), vWakeCallBack);
        if (PWRM_u16GetActivityCount())
        {
         OS_eContinueSWTimer(APP_PollTimer, APP_TIME_MS(1000), NULL);
         u8DeepSleepTime--;
        }
        else
        {
         PWRM_vInit(E_AHI_SLEEP_OSCOFF_RAMON);
        }
       }
       else
       {
        vStopAllTimers();
        DBG_vPrintf(TRACE_REJOIN, "join failed: go deep... %d\n", PWRM_u16GetActivityCount());
        PWRM_vInit(E_AHI_SLEEP_DEEP);
        bDeepSleep = TRUE;
        return;
       }
      }
      else
      {
       if(!App_CheckButtonStatus())
       {
        u8RejoinAttemptsRemaining--;
        DBG_vPrintf(TRACE_REJOIN, "join failed: try a rejoin\n");
        vSetRejoinFilter();
        ZPS_eAplZdoRejoinNetwork(TRUE);
       }
      }
                   }
     else
     {
      /* Manage polling, then warm sleep, then deep sleep */
      if(u8KeepAliveTime == 0)
      {
       vStopAllTimers();
       if (u8DeepSleepTime)
       {
        PWRM_eScheduleActivity(&sWake, (SLEEP_DURATION_MS * SLEEP_TIMER_TICKS_PER_MS) , vWakeCallBack);
        PWRM_vInit(E_AHI_SLEEP_OSCOFF_RAMON);
        DBG_vPrintf(TRACE_SLEEP, "poll task: schedule sleep\n");
       }
       else 
       {
        PWRM_vInit(E_AHI_SLEEP_DEEP);
        bDeepSleep = TRUE;
        DBG_vPrintf(TRACE_SLEEP, "poll task: go deep\n");
       }
       DBG_vPrintf(TRACE_SLEEP,"Activity %d\n",PWRM_u16GetActivityCount());
       return;
      }
      else
      {
       uint8 u8PStatus;
       u8PStatus = ZPS_eAplZdoPoll();
       if ( 1 /*u8PStatus*/)
       {
        DBG_vPrintf(TRACE_REMOTE_NODE|TRACE_REJOIN, "\nPOLL status %d\n", u8PStatus);
       }
       if (u16FastPoll)
       {
        u16FastPoll--;
        u32Time = POLL_TIME_FAST, NULL;
        if (u16FastPoll == 0)
        {
         DBG_vPrintf(TRACE_REMOTE_NODE, "\nStop fast poll");
        }
       }
       else
       {
        /* Decrement the keep alive in the normal operation mode
        * Not in active scann mode or while fast polling
        */
        if(0 < u8KeepAliveTime)
        {
         if(!App_CheckButtonStatus())
         {
          u8KeepAliveTime--;
         }
        }
        /*Start Poll Timer to continue normal polling */
        u32Time = APP_TIME_MS(1000);
       }
      }
                   }
                   break;
   default:
    /* shouldb't happen, but... */
    u32Time = APP_TIME_MS(1000);
    break;
  }
 }
 else
 {
  DBG_vPrintf(TRACE_REMOTE_NODE|TRACE_REJOIN, "Sleep and Poll: Touch lnk in progress\n");
 }
 OS_eContinueSWTimer(APP_PollTimer, APP_TIME_MS(1000), NULL);
}
#endif

build the project Controller_ColorController, and  program to device, open UART COM of the device , you can see:
















2018年1月12日 星期五

JN516x Start (1): how to start JenOS development environment

JN5169 Start (1): how to start JenOS development environment

Before starting to program, we need to prepare our development environment, but there is no a document for developers to step-by-step install IDE, SDK, and plugins to start there, and that  this article written about.

for "How to install JenOS configuration Dialog Editor", please jump to STEP 6

JN5169 Start (2) is about how to program your  .bin into your JN516x chip.


STEP 0. download from NXP website.

we need 4 files download from NXP
1. JN-SW- 4141 BeyondStudio for NXP  (not LOWER then v13.08)
2. JN-SW- 4168 JN516x SDK
3. JN-SW- 4107 JN51xx Production Flash Programmer
4. JN-SW- 1171 An example code for JN5169

STEP 1.  install BeyondStudio for NXP
download  from NXP website and unzip



































press right button and (A) (excution as system administrator) and  "agree"


















then press "next" until "choose install location".
I choose default location in
C: \NXP\bstudio_nxp\

and press "install"
















start installing.....
















installation complete
















in C:\ we can see file of BeyondStudio for  NXP















STEP 2.   install JN-SW-4168 SDK for JN516X
download from the same webpage and unzip it.













press right button and (A)  (excution as system administrator) and  "agree"

















then press "next" until "choose install location".
I choose default location in
C: \NXP\bstudio_nxp\

and press "install"




















installation complete


and now we can see in
C:\NXP\bstudio_nxp\sdk
It will be like this




STEP 2.install JN51xx Production Flash Programmer

download from here and unzip


press right button and (A)  (excution as system administrator) and  "agree"


















then press "next" until "choose install location".
I choose default location in
C: \NXP\ProductionFlashProgrammer


After installation completed, in C:\NXP\ProductionFlashProgrammer
we can see:




STEP 3. download JN-SW- 3098 (An example code for JN5169)
download from here and unzip it




STEP 4. import  example code
(1) copy "JN-AN-1171-ZigBee-LightLink-Demo" folder
C:\..\..\..\JN-AN-1171\JN-AN-1171-ZigBee-LightLink-Demo

to C:\NXP\bstudio_nxp\workspace


(2) doudle press "bstudio_nxp.exe" to start beyond studio


select workspace  at
C:\NXP\bstudio_nxp\workspace and press "OK"



(3) check BeyondStudio edition
press "help" ->  "about BeyondStudio for NXP"
then we will see: Build  1308



(4) import project

press "file" -> "import"
select "General"->"Existing projects into Workspace"


press "select root directory"->"browse"
and select JN-AN-1171 in workspace


select "JN-AN-1171-ZigBee-LightLink-Demo" folder and press "finish"


now we successfully import in project




STEP 5.compile example code
press the hammer button and select a project


start building


finish



STEP 6. install Jennic configuration Editor tool
JN51XX use a kind of RTOS called "JenOS", and "JenOS" use a graphical interface
configuration Dialog 
to register hardware interrupts, timers...etc.

before we install it, if we press any of ".oscfgdiag" , we will see:


and we have to install a eclipse plugin to let it be a graphical interface
this installer is already in JN-SW-4168
what we need to do is installing it into BeyondStudio

open BeyondStudio, and press "Help"->"install new software"


press "Add..."->"Local..."


select C:\NXP\bstudio_nxp\sdk\JN-SW-4168\Tools\Eclipse_plugins\com.nxp.sdk.update_site


and you will see "Jennic ZBPro SDK" ->"Jennic configuration Editor"
select all and press "next"


accept the agreement and press "finish"



start installing...


After installation completed, you have to restart BeyondStudio


After restart, select any ".oscfgdiag" we will see:





Now we successfully compile the example code and make sure that our Development Environment is completed prepared.



reference:

1.NXP website
https://www.nxp.com/products/wireless-connectivity/proprietary-ieee-802.15.4-based/zigbee/zigbee-light-link:ZIGBEE-LIGHT-LINK

2. BeyondStudio for NXP Installation and User Guide

3. ZigBee Cluster Library User Guide (for ZLL/HA)

4. JN-UG-3099

5.JN-SW- 3098 Document