8 Code Examples

Magnetometer readings
 /*
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    (C)2013 Semtech

Description: Generic lora driver implementation

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene
*/
/******************************************************************************
  * @file    main.c
  * @author  MCD Application Team
  * @version V1.1.2
  * @date    08-September-2017
  * @brief   this is the main!
  ******************************************************************************
  * @attention
  *
  * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V. 
  * All rights reserved.</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without 
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice, 
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other 
  *    contributors to this software may be used to endorse or promote products 
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this 
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under 
  *    this license is void and will automatically terminate your rights under 
  *    this license. 
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "hw.h"
#include "low_power.h"
#include "lora.h"
#include "bsp.h"
#include "timeServer.h"
#include "vcom.h"
#include "version.h"



/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define LPP_APP_PORT 99

/*!
 * Defines the application data transmission duty cycle. 1*60s, value in [ms].
 */
#define APP_TX_DUTYCYCLE                            1*60000				//3*1000
/*!
 * LoRaWAN Adaptive Data Rate
 * @note Please note that when ADR is enabled the end-device should be static
 */
#define LORAWAN_ADR_ON                              1
/*!
 * LoRaWAN confirmed messages
 */
#define LORAWAN_CONFIRMED_MSG                    DISABLE
/*!
 * LoRaWAN application port
 * @note do not use 224. It is reserved for certification
 */
#define LORAWAN_APP_PORT                            2
/*!
 * Number of trials for the join request.
 */
#define JOINREQ_NBTRIALS                            3

/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/

/* call back when LoRa will transmit a frame*/
static void LoraTxData( lora_AppData_t *AppData, FunctionalState* IsTxConfirmed);

/* call back when LoRa has received a frame*/
static void LoraRxData( lora_AppData_t *AppData);

/* Private variables ---------------------------------------------------------*/
/* load call backs*/
static LoRaMainCallback_t LoRaMainCallbacks ={ HW_GetBatteryLevel,
                                               HW_GetUniqueId,
                                               HW_GetRandomSeed,
                                               LoraTxData,
                                               LoraRxData};

/*!
 * Specifies the state of the application LED
 */
static uint8_t AppLedStateOn = RESET;


#ifdef USE_B_L072Z_LRWAN1
/*!
 * Timer to handle the application Tx Led to toggle
 */
static TimerEvent_t TxLedTimer;
static void OnTimerLedEvent( void );
#endif
/* !
 *Initialises the Lora Parameters
 */
static  LoRaParam_t LoRaParamInit= {TX_ON_TIMER,
                                    APP_TX_DUTYCYCLE,
                                    CLASS_A,
                                    LORAWAN_ADR_ON,
                                    DR_0,
                                    LORAWAN_PUBLIC_NETWORK,
                                    JOINREQ_NBTRIALS};

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
//#define N_PN_BETA2													  // [ MANUEL ] Uncomment if n-PN BETA2 is used.
#define MAGNETOMETER_VALUES									// [ BRIAN ] Uncomment if sends the acceleromter instead of zeros									
																																	
																		
ADC_HandleTypeDef hadc;
I2C_HandleTypeDef hi2c1;											// [ MANUEL ] I2C handler
uint8_t		myTXData[]		=	 { 0, 0, 0, 0 };		// [ MANUEL ] Acc. ID	| RFID MSB | RFID Manufacturer code | SI7006: SNB_3				

int main( void )
{
  /* STM32 HAL library initialization*/
  HAL_Init( );
  
  /* Configure the system clock*/
  SystemClock_Config( );
  
  /* Configure the debug mode*/
  DBG_Init( );
  
  /* Configure the hardware*/
  HW_Init( );
  
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  
  	
	/* USER CODE BEGIN 1 */
	// 		Tasks to be completed:
	//		1. It configures the I2C1 module.
	//		2. It checks if the Accelerometer works.
	
	RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
	
	hi2c1.Instance 							= 	I2C1;			//PB9:I2C1_SDA && PB8:I2C1_SCL	
  hi2c1.Init.Timing          	= 	100000;
  hi2c1.Init.OwnAddress1     	= 	0x1D;
  hi2c1.Init.AddressingMode  	= 	I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode 	= 	I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2Masks = 	I2C_OA2_NOMASK;
  hi2c1.Init.OwnAddress2     	= 	0xFF;
  hi2c1.Init.GeneralCallMode 	= 	I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode   	= 	I2C_NOSTRETCH_DISABLE; 
	
	
	GPIO_InitTypeDef initStruct;
	
	initStruct.Pin 							= 	GPIO_PIN_9;
	initStruct.Mode 						= 	GPIO_MODE_AF_OD;
	initStruct.Pull 						= 	GPIO_NOPULL;					// GPIO_PULLUP;	
	initStruct.Speed 						= 	GPIO_SPEED_FREQ_LOW;	// GPIO_SPEED_FREQ_HIGH;
	initStruct.Alternate 				= 	GPIO_AF4_I2C1;	
	
  __HAL_RCC_GPIOB_CLK_ENABLE();
	/* I2C1_SDA */
	HAL_GPIO_Init(GPIOB, &initStruct);
	/* I2C1_SCL */
	initStruct.Pin = GPIO_PIN_8;
  HAL_GPIO_Init( GPIOB, &initStruct);
	
	
	/*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
  RCC_PeriphCLKInitStruct.PeriphClockSelection 	= 	RCC_PERIPHCLK_I2C1;
  RCC_PeriphCLKInitStruct.I2c1ClockSelection 		= 	RCC_I2C1CLKSOURCE_SYSCLK;
  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);

	__HAL_RCC_I2C1_CLK_ENABLE();
	
	if(HAL_I2C_Init(&hi2c1)!= HAL_OK){
		Error_Handler();
	}
	
  uint8_t myCMD[]	=	{ 0, 0 };																									
	uint8_t myGetBuffer[ 8 ]  = { 0 };
	
// [ ACCELEROMETER TEST ] Read Acc. ID
	PRINTF("ACCELEROMETER TEST\n\r");
  myCMD[0]	=	0x0F;																																// Acc. WHO_AM_I_A register
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1D << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1D << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[0]	 =	myGetBuffer[0];
	PRINTF("Acc. ID is: %X ( it should be 0x43 )\n\r", myTXData[0]);
	
	// [ MAGNETOMETER TEST ]
	PRINTF("MAGNETOMETER TEST\n\r");
	myCMD[0] = 0x4f;
	
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);

	myTXData[0]	 =	myGetBuffer[0];
	PRINTF("Mag. ID is: %X ( it should be 0x40 )\n\r", myTXData[0]);

	myCMD[0] = 0x68;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[0]	 =	myGetBuffer[0];
	
	myCMD[0] = 0x69;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);

	myTXData[1]	 =	myGetBuffer[0];
	
	PRINTF("Mag. X1 reg ID is: %X \n\r", myTXData[0]);	
	PRINTF("Mag. X2 reg ID is: %X \n\r", myTXData[1]);	
	
	//Trigger measurement
	
	myCMD[0] = 0x60;
	myCMD[1] = 0x81;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 2, 500);
	
	
	PRINTF("CONFIGURE LORA STACK\n\r");
	/* Configure the Lora Stack*/
  lora_Init( &LoRaMainCallbacks, &LoRaParamInit);
	PRINTF("SETUP COMPLETE\n\r");
	PRINTF("##############\n\r");
	
	while (1)
	{
		/* run the LoRa class A state machine*/
    lora_fsm( );
    
    DISABLE_IRQ( );
    /* if an interrupt has occurred after DISABLE_IRQ, it is kept pending 
     * and cortex will not enter low power anyway  */
    if ( lora_getDeviceState( ) == DEVICE_STATE_SLEEP )
    {
#ifndef LOW_POWER_DISABLE
      LowPower_Handler( );
#endif
    }
    ENABLE_IRQ();
    
    /* USER CODE BEGIN 2 */
		
    /* USER CODE END 2 */
  }	
}


static void LoraTxData( lora_AppData_t *AppData, FunctionalState* IsTxConfirmed)
{
  /* USER CODE BEGIN 3 */
  uint8_t batteryLevel;

#ifdef MAGNETOMETER_VALUES	
	uint8_t myCMD[]	=	{ 0, 0 };																									
	uint8_t myGetBuffer[ 8 ]  = { 0 };
	
	//Trigger next measurement
	myCMD[0] = 0x60;
	myCMD[1] = 0x81;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 2, 500);
	
	
	myCMD[0] = 0x68;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[0]	 =	myGetBuffer[0];
		
	myCMD[0] = 0x69;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[1]	 =	myGetBuffer[0];

	uint16_t magx = myTXData[0] + (myTXData[1] << 8);		

	myCMD[0] = 0x6A;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[0]	 =	myGetBuffer[0];
	
	myCMD[0] = 0x6B;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[1]	 =	myGetBuffer[0];
	
	uint16_t magy = myTXData[0] + (myTXData[1] << 8);		
		

	myCMD[0] = 0x6C;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[0]	 =	myGetBuffer[0];
	
	myCMD[0] = 0x6D;
	HAL_I2C_Master_Transmit	(&hi2c1, ( 0x1E << 1 ), &myCMD[0], 1, 500);
	HAL_I2C_Master_Receive	(&hi2c1, ( 0x1E << 1 ), &myGetBuffer[0], 1, 500);
	myTXData[1]	 =	myGetBuffer[0];

	uint16_t magz = myTXData[0] + (myTXData[1] << 8);
	
	PRINTF("MagXYZ %X %X %X\r\n", magx, magy, magz);
	
#endif	
	
#ifdef USE_B_L072Z_LRWAN1
  TimerInit( &TxLedTimer, OnTimerLedEvent );
  
  TimerSetValue(  &TxLedTimer, 200);
  
  LED_On( LED_GREEN ) ; 	
  
  TimerStart( &TxLedTimer );  
#endif
  uint32_t i = 0;

  batteryLevel = HW_GetBatteryLevel( );                     /* 1 (very low) to 254 (fully charged) */

  AppData->Port = LPP_APP_PORT;
  
  *IsTxConfirmed =  LORAWAN_CONFIRMED_MSG;
	
	AppData->Buff[i++] = 0x01;
	AppData->Buff[i++] = batteryLevel*100/254;


#ifdef N_PN_BETA2	
	//AppData->Buff[i++] = myTXData[3];
#endif

	
#ifdef MAGNETOMETER_VALUES	
	AppData->Buff[i++] = ( magx >> 8 );
	AppData->Buff[i++] = magx;
	AppData->Buff[i++] = ( magy >> 8 );
	AppData->Buff[i++] = magy;
	AppData->Buff[i++] = ( magz >> 8 );
	AppData->Buff[i++] = magz;
#else	
	AppData->Buff[i++] = 	0x0;
	AppData->Buff[i++] = 	0x0;
	AppData->Buff[i++] = 	0x0;
	AppData->Buff[i++] = 	0x0;
	AppData->Buff[i++] = 	0x0;
	AppData->Buff[i++] = 	0x0;
#endif

	
	AppData->BuffSize = i;
  
  /* USER CODE END 3 */
}
    
static void LoraRxData( lora_AppData_t *AppData )
{
  /* USER CODE BEGIN 4 */
  switch (AppData->Port)
  {
  case LORAWAN_APP_PORT:
    if( AppData->BuffSize == 1 )
    {
      AppLedStateOn = AppData->Buff[0] & 0x01;
      if ( AppLedStateOn == RESET )
      {
        //PRINTF("LED OFF\n\r");
        //LED_Off( LED_RED1 ) ;	//LED_Off( LED_BLUE ) ;LED_RED1 
        
      }
      else
      {
        //PRINTF("LED ON\n\r");
        //LED_On( LED_RED1 ) ;	//LED_On( LED_BLUE ) ; 
      }
      //GpioWrite( &Led3, ( ( AppLedStateOn & 0x01 ) != 0 ) ? 0 : 1 );
    }
    break;
  case LPP_APP_PORT:
  {
    AppLedStateOn= (AppData->Buff[2] == 100) ?  0x01 : 0x00;
      if ( AppLedStateOn == RESET )
      {
        //PRINTF("LED OFF\n\r");
        //LED_Off( LED_RED1 ) ;	//LED_Off( LED_BLUE ) ; 
        
      }
      else
      {
        //PRINTF("LED ON\n\r");
        //LED_On( LED_RED1 ) ;	//LED_On( LED_BLUE ) ; 
      }
    break;
  }
  default:
    break;
  }
  /* USER CODE END 4 */
}

#ifdef USE_B_L072Z_LRWAN1
static void OnTimerLedEvent( void )
{
  LED_Off( LED_GREEN ) ;				//LED_Off( LED_RED1 ) ; 		
}
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/