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
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:
沒有留言:
張貼留言