/*
 *  Copyright (C) 2008-2015, Marvell International Ltd.
 *  All Rights Reserved.
 */
#include <wm_os.h>
#include <wmstdio.h>
#include <wmtime.h>
#include <wmsdk.h>
#include <led_indicator.h>
#include <board.h>
#include <mdev_gpio.h>
#include <push_button.h>
#include <aws_iot_mqtt_interface.h>
#include <aws_iot_shadow_interface.h>
#include <aws_utils.h>
#include <lowlevel_drivers.h>
#include <mdev_pinmux.h>
#include <mdev_adc.h>
/* configuration parameters */
#include <aws_iot_config.h>
#include "aws_starter_root_ca_cert.h"
/* ADC definitions */
#define SAMPLES	1
#define ADC_GAIN	ADC_GAIN_2
#define BIT_RESOLUTION_FACTOR 32768	/* For 16 bit resolution (2^15-1) */
#define VMAX_IN_mV	3300	/* Max input voltage in milliVolts */
/*-----------------------Global declarations----------------------*/
uint16_t buffer[SAMPLES];
mdev_t *adc_dev;
/* These hold each pushbutton's count, updated in the callback ISR */
static volatile uint32_t pushbutton_a_count;
static volatile uint32_t pushbutton_a_count_prev = -1;
static volatile uint32_t pushbutton_b_count;
static volatile uint32_t pushbutton_b_count_prev = -1;
static volatile uint32_t led_1_state;
static volatile uint32_t led_1_state_prev = -1;
static output_gpio_cfg_t led_1;
static MQTTClient_t mqtt_client;
static int is_demo_started;
/* Thread handle */
static os_thread_t aws_starter_thread;
/* Buffer to be used as stack */
static os_thread_stack_define(aws_starter_stack, 8 * 1024);
/* aws iot url */
static char url[128];
#define UAP_SSID                "aws_starter"
#define UAP_PASSPHRASE          "marvellwm"
#define AMAZON_ACTION_BUF_SIZE  100
#define VAR_LED_1_PROPERTY      "led"
#define VAR_BUTTON_A_PROPERTY   "pb"
#define VAR_LPG_VALUE           "lpg"
#define VAR_BUTTON_B_PROPERTY   "pb_lambda"
#define RESET_TO_FACTORY_TIMEOUT 10000
#define BUFSIZE                  128
/* callback function invoked on reset to factory */
static void device_reset_to_factory_cb()
{
	invoke_reset_to_factory();
}
/* board_button_2() is configured to perform reset to factory,
 * when pressed for more than 10 seconds.
 */
static void configure_reset_to_factory()
{
	input_gpio_cfg_t pushbutton_reset_to_factory = {
		.gpio = board_button_2(),
		.type = GPIO_ACTIVE_LOW
	};
	push_button_set_cb(pushbutton_reset_to_factory,
			   device_reset_to_factory_cb,
			   RESET_TO_FACTORY_TIMEOUT, 0, NULL);
}
/* callback function invoked when pushbutton_a is pressed */
static void pushbutton_cb_a()
{
	if (pushbutton_a_count_prev == pushbutton_a_count) {
		pushbutton_a_count++;
	}
}
/* callback function invoked when pushbutton_b is pressed */
static void pushbutton_cb_b()
{
	if (pushbutton_b_count_prev == pushbutton_b_count) {
		pushbutton_b_count++;
	}
}
static void configure_led_and_button()
{
	input_gpio_cfg_t pushbutton_a = {
		.gpio = board_button_1(),
		.type = GPIO_ACTIVE_LOW
	};
	input_gpio_cfg_t pushbutton_b = {
		.gpio = board_button_2(),
		.type = GPIO_ACTIVE_LOW
	};
	led_1 = board_led_1();
	push_button_set_cb(pushbutton_a,
			   pushbutton_cb_a,
			   100, 0, NULL);
	push_button_set_cb(pushbutton_b,
			   pushbutton_cb_b,
			   100, 0, NULL);
}
static char client_cert_buffer[AWS_PUB_CERT_SIZE];
static char private_key_buffer[AWS_PRIV_KEY_SIZE];
static char thing_name[126];
/* populate aws shadow configuration details */
static int aws_starter_load_configuration(ShadowParameters_t *sp)
{
	int ret = WM_SUCCESS;
	char region[16];
	memset(region, 0, sizeof(region));
	/* read configured thing name from psm */
	ret = read_aws_thing(thing_name);
	if (ret == WM_SUCCESS) {
		sp->pMyThingName = thing_name;
	} else {
		/* if not found in psm, take the default thing name */
		sp->pMyThingName = AWS_IOT_MY_THING_NAME;
	}
	sp->pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
	/* read configured region name from psm */
	ret = read_aws_region(region);
	if (ret == WM_SUCCESS) {
		snprintf(url, sizeof(url), "data.iot.%s.amazonaws.com",
			 region);
	} else {
		snprintf(url, sizeof(url), "data.iot.%s.amazonaws.com",
			 AWS_IOT_MY_REGION_NAME);
	}
	sp->pHost = url;
	sp->port = AWS_IOT_MQTT_PORT;
	sp->pRootCA = rootCA;
	/* read configured certificate from psm */
	ret = read_aws_certificate(client_cert_buffer);
	if (ret != WM_SUCCESS) {
		wmprintf("Failed to configure certificate. Returning!\r\n");
		return -WM_FAIL;
	}
	sp->pClientCRT = client_cert_buffer;
	/* read configured private key from psm */
	ret = read_aws_key(private_key_buffer);
	if (ret != WM_SUCCESS) {
		wmprintf("Failed to configure key. Returning!\r\n");
		return -WM_FAIL;
	}
	sp->pClientKey = private_key_buffer;
	return ret;
}
static void make_str(char *property, int val, char buff_out[], int buff_len)
{
	if (!buff_out)
		return;
	snprintf(buff_out, buff_len, "{\"state\": {\"reported\":{\"%s\":%d}}}",
		 property, val);
}
void shadow_update_status_cb(const char *pThingName, ShadowActions_t action,
			     Shadow_Ack_Status_t status,
			     const char *pReceivedJsonDocument,
			     void *pContextData) {
	if (status == SHADOW_ACK_TIMEOUT) {
		wmprintf("shadow publish state change timeout occured\r\n");
	} else if (status == SHADOW_ACK_REJECTED) {
		wmprintf("shadow publish state change rejected\r\n");
	} else if (status == SHADOW_ACK_ACCEPTED) {
		wmprintf("shadow publish state change accepted\r\n");
	}
}
void led_indicator_callback(const char *p_json_string,
			    uint32_t json_string_datalen,
			    jsonStruct_t *p_context) {
	int state;
	if (p_context != NULL) {
		state = *(int *)(p_context->pData);
		if (state) {
			led_on(led_1);
			led_1_state = 1;
		} else {
			led_off(led_1);
			led_1_state = 0;
		}
	}
}
static void aws_starter_demo(os_thread_arg_t data)
{
	char buf_out[BUFSIZE];
	char *property = NULL;
	ShadowParameters_t sp;
	int led_state = 0;
	jsonStruct_t led_indicator;
	int i, samples = SAMPLES;
	float result;
	ADC_CFG_Type config;
	uint16_t lpgValue_prev = 0 ;
	uint16_t lpgValue_curr = 0 ;
/* get default ADC gain value */
	adc_get_config(&config);
	wmprintf("Default ADC gain value = %d\r\n", config.adcGainSel);
	/* Modify ADC gain to 2 */
	adc_modify_default_config(adcGainSel, ADC_GAIN);
	adc_get_config(&config);
	wmprintf("Modified ADC gain value to %d\r\n", config.adcGainSel);
	adc_dev = adc_drv_open(ADC0_ID, ADC_CH0);
	led_indicator.cb = led_indicator_callback;
	led_indicator.pData = &led_state;
	led_indicator.pKey = "led";
	led_indicator.type = SHADOW_JSON_INT8;
	aws_iot_mqtt_init(&mqtt_client);
	int ret = aws_starter_load_configuration(&sp);
	if (ret != WM_SUCCESS) {
		wmprintf("aws shadow configuration failed : %d\r\n", ret);
		goto out;
	}
	ret = aws_iot_shadow_init(&mqtt_client);
	if (ret != WM_SUCCESS) {
		wmprintf("aws shadow init failed : %d\r\n", ret);
		goto out;
	}
	ret = aws_iot_shadow_connect(&mqtt_client, &sp);
	if (ret != WM_SUCCESS) {
		wmprintf("aws shadow connect failed : %d\r\n", ret);
		goto out;
	}
	/* indication that device is connected and cloud is started */
	led_on(board_led_2());
	wmprintf("Cloud Started\r\n");
	/* subscribe to delta topic of the configured thing */
	ret = aws_iot_shadow_register_delta(&mqtt_client, &led_indicator);
	if (ret != WM_SUCCESS) {
		wmprintf("return value is %d\r\n", ret);
	}
	while (1) {
		/* periodically check if any data is received on socket */
		aws_iot_shadow_yield(&mqtt_client, 1000);
		/* check if pushbutton a is pressed
		if (pushbutton_a_count_prev != pushbutton_a_count) {
			property = VAR_BUTTON_A_PROPERTY;
			make_str(property, pushbutton_a_count, buf_out,
				 sizeof(buf_out));
			wmprintf("Publishing '%s %s' to AWS\r\n", property,
				 buf_out);
*/
			/* publish incremented value on pushbutton press on
			 * configured thing
			ret = aws_iot_shadow_update(&mqtt_client,
						    sp.pMyThingName,
						    buf_out,
						    shadow_update_status_cb,
						    NULL,
						    10, true);
			if (ret != WM_SUCCESS) {
				wmprintf("Sending property failed\r\n");
			} else {
				pushbutton_a_count_prev = pushbutton_a_count;
			}
		}*/
		/* check if pushbutton b is pressed
		if (pushbutton_b_count_prev != pushbutton_b_count) {
			property = VAR_BUTTON_B_PROPERTY;
			make_str(property, pushbutton_b_count, buf_out,
				 sizeof(buf_out));
			wmprintf("Publishing '%s %s' to AWS\r\n",
				 property, buf_out);
 */
			/* publish incremented value on pushbutton press on
			 * configured thing
			ret = aws_iot_shadow_update(&mqtt_client,
						    sp.pMyThingName,
						    buf_out,
						    shadow_update_status_cb,
						    NULL, 10, true);
			if (ret != WM_SUCCESS) {
				wmprintf("Sending property failed\r\n");
			} else {
				pushbutton_b_count_prev = pushbutton_b_count;
			}
		}*/
#ifdef ADC_DMA
	adc_drv_get_samples(adc_dev, buffer, samples);
	for (i = 0; i < samples; i++) {
		result = ((float)buffer[i] / BIT_RESOLUTION_FACTOR) *
		VMAX_IN_mV * ((float)1/(float)(config.adcGainSel != 0 ?
		config.adcGainSel : 0.5));
		wmprintf("Iteration %d: count %d - %d.%d mV\r\n",
					i, buffer[i],
					wm_int_part_of(result),
					wm_frac_part_of(result, 2));
	}
#else
	for (i = 0; i < samples; i++) {
		buffer[0] = adc_drv_result(adc_dev);
		result = ((float)buffer[0] / BIT_RESOLUTION_FACTOR) *
		VMAX_IN_mV * ((float)1/(float)(config.adcGainSel != 0 ?
		config.adcGainSel : 0.5));
/*		 wmprintf("Iteration %d: count %d - %d.%d mV\r\n",
					i, buffer[0],
					wm_int_part_of(result),
					wm_frac_part_of(result, 2));*/
		os_thread_sleep(os_msec_to_ticks(50));
	}
#endif
	lpgValue_curr = wm_int_part_of(result);
	if ( lpgValue_prev - lpgValue_curr >= 10 || lpgValue_curr-lpgValue_prev >= 10){
		wmprintf("ADC Application Over %d\r\n",lpgValue_prev);
			property = VAR_LPG_VALUE;
			make_str(property, lpgValue_curr, buf_out,
				 sizeof(buf_out));
			wmprintf("Publishing '%s %d' to AWS\r\n",
				 property, lpgValue_curr);
			ret = aws_iot_shadow_update(&mqtt_client,
						    sp.pMyThingName,
						    buf_out,
						    shadow_update_status_cb,
						    NULL, 10, true);
			if (ret != WM_SUCCESS) {
				wmprintf("Sending property failed\r\n");
			} else {
				pushbutton_b_count_prev = pushbutton_b_count;
			}
	}
	lpgValue_prev = lpgValue_curr;
		/* On receiving led state change notification, change the state
		 * of the led in callback function and publish updated state on
		 * configured topic.
		 */
		if (led_1_state_prev != led_1_state) {
			property = VAR_LED_1_PROPERTY;
			make_str(property, led_1_state, buf_out,
				 sizeof(buf_out));
			wmprintf("Publishing '%s %s' to AWS\r\n", property,
				 buf_out);
			ret = aws_iot_shadow_update(&mqtt_client,
						    sp.pMyThingName,
						    buf_out,
						    shadow_update_status_cb,
						    NULL, 10, true);
			if (ret == WM_SUCCESS) {
				led_1_state_prev = led_1_state;
			}
		}
	}
	ret = aws_iot_shadow_disconnect(&mqtt_client);
	if (NONE_ERROR != ret) {
		wmprintf("aws iot shadow error %d\r\n", ret);
	}
out:
	os_thread_self_complete(NULL);
	return;
}
/* Event: AF_EVT_NORMAL_CONNECTED
 *
 * Station interface connected to home AP.
 *
 * Network dependent services can be started here. Note that these
 * services need to be stopped on disconnection and
 * reset-to-provisioning event.
 */
void wlan_event_normal_connected(void *data)
{
	int ret;
	/* Default time set to 1 October 2015 */
	time_t time = 1443657600;
	wmprintf("Connected successfully to the home network\r\n");
	if (!is_demo_started) {
		wmtime_time_set_posix(time);
		ret = os_thread_create(
			/* thread handle */
			&aws_starter_thread,
			/* thread name */
			"awsStarterDemo",
			/* entry function */
			aws_starter_demo,
			/* argument */
			0,
			/* stack */
			&aws_starter_stack,
			/* priority */
			OS_PRIO_3);
		if (ret != WM_SUCCESS) {
			wmprintf("Failed to start cloud_thread: %d\r\n", ret);
			return;
		}
		is_demo_started = true;
	}
}
void wlan_event_normal_link_lost(void *data)
{
	/* led indication to indicate link loss */
}
void wlan_event_normal_connect_failed(void *data)
{
	/* led indication to indicate link loss */
}
int main()
{
	if (wmstdio_init(UART0_ID, 0) != WM_SUCCESS) {
		return -WM_FAIL;
	}
	/*if (gpio_drv_init() != WM_SUCCESS) {
		wmprintf("gpio_drv_init failed\r\n");
		return -WM_FAIL;
		}*/
	/*adc initialization */
	if (adc_drv_init(ADC0_ID != WM_SUCCESS)){
			wmprintf("Cannot init ADC \n\r");
			return -1;
		}
	wmprintf("Build Time: " __DATE__ " " __TIME__ "\r\n");
	wmprintf("\r\n#### AWS ADC STARTER DEMO ####\r\n\r\n");
	configure_reset_to_factory();
	configure_led_and_button();
	/* This api adds aws iot configuration support in
	 * provisioning web application.
	 */
	enable_aws_config_support();
	wm_wlan_provision(UAP_SSID, UAP_PASSPHRASE);
		return 0;
}
Comments