/*
* 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