Statistics
| Branch: | Tag: | Revision:

mongoose / examples / CC3200 / main.c @ eaef5bd1

History | View | Annotate | Download (8.78 KB)

1
/*
2
 * Copyright (c) 2014-2016 Cesanta Software Limited
3
 * All rights reserved
4
 */
5

    
6
#include <stdbool.h>
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <string.h>
10

    
11
#include <inc/hw_types.h>
12
#include <inc/hw_ints.h>
13
#include <inc/hw_memmap.h>
14

    
15
#include <driverlib/gpio.h>
16
#include <driverlib/interrupt.h>
17
#include <driverlib/pin.h>
18
#include <driverlib/prcm.h>
19
#include <driverlib/rom.h>
20
#include <driverlib/rom_map.h>
21
#include <driverlib/uart.h>
22
#include <driverlib/utils.h>
23

    
24
#include <example/common/gpio_if.h>
25
#include <example/common/i2c_if.h>
26

    
27
/* Mongoose.h brings in SimpleLink support. Do not include simplelink.h. */
28
#include <mongoose.h>
29
#include "cs_dbg.h"
30
#include <simplelink/include/device.h>
31

    
32
#include "data.h"
33
#include "wifi.h"
34

    
35
/* Set up an AP or connect to existing WiFi network. */
36
#define WIFI_AP_SSID "Mongoose"
37
#define WIFI_AP_PASS ""
38
#define WIFI_AP_CHAN 6
39
// #define WIFI_STA_SSID "YourWiFi"
40
// #define WIFI_STA_PASS "YourPass"
41

    
42
#define DATA_COLLECTION_INTERVAL_MS 20
43

    
44
#define CONSOLE_BAUD_RATE 115200
45
#define CONSOLE_UART UARTA0_BASE
46
#define CONSOLE_UART_PERIPH PRCM_UARTA0
47
#define MGOS_TASK_PRIORITY 3
48
#define MG_TASK_STACK_SIZE 8192
49

    
50
#define BM222_ADDR 0x18
51
#define TMP006_ADDR 0x41
52

    
53
void fs_slfs_set_new_file_size(const char *name, size_t size);
54

    
55
static const char *upload_form =
56
    "\
57
<h1>Upload file</h1> \
58
<form action='/upload' method='POST' enctype='multipart/form-data'> \
59
  <input type='file' name='file'> \
60
  <input type='submit' value='Upload'> \
61
</form>";
62

    
63
static struct mg_str upload_fname(struct mg_connection *nc,
64
                                  struct mg_str fname) {
65
  struct mg_str lfn;
66
  char *fn = malloc(fname.len + 4);
67
  memcpy(fn, "SL:", 3);
68
  memcpy(fn + 3, fname.p, fname.len);
69
  fn[3 + fname.len] = '\0';
70
  if (nc->user_data != NULL) {
71
    intptr_t cl = (intptr_t) nc->user_data;
72
    if (cl >= 0) {
73
      fs_slfs_set_new_file_size(fn + 3, cl);
74
    }
75
  }
76
  lfn.len = fname.len + 4;
77
  lfn.p = fn;
78
  return lfn;
79
}
80

    
81
static void mg_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
82
  switch (ev) {
83
    case MG_EV_ACCEPT: {
84
      char addr[32];
85
      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
86
                                                      MG_SOCK_STRINGIFY_IP |
87
                                                      MG_SOCK_STRINGIFY_PORT);
88
      LOG(LL_INFO, ("%p conn from %s", nc, addr));
89
      break;
90
    }
91
    case MG_EV_HTTP_REQUEST: {
92
      char addr[32];
93
      struct http_message *hm = (struct http_message *) ev_data;
94
      cs_stat_t st;
95
      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
96
                                                      MG_SOCK_STRINGIFY_IP |
97
                                                      MG_SOCK_STRINGIFY_PORT);
98
      LOG(LL_INFO,
99
          ("HTTP request from %s: %.*s %.*s", addr, (int) hm->method.len,
100
           hm->method.p, (int) hm->uri.len, hm->uri.p));
101
      if (mg_vcmp(&hm->uri, "/upload") == 0 ||
102
          (mg_vcmp(&hm->uri, "/") == 0 && mg_stat("SL:index.html", &st) != 0)) {
103
        mg_send(nc, upload_form, strlen(upload_form));
104
        nc->flags |= MG_F_SEND_AND_CLOSE;
105
        break;
106
      }
107
      struct mg_serve_http_opts opts;
108
      memset(&opts, 0, sizeof(opts));
109
      opts.document_root = "SL:";
110
      mg_serve_http(nc, hm, opts);
111
      break;
112
    }
113
    case MG_EV_CLOSE: {
114
      LOG(LL_INFO, ("%p closed", nc));
115
      break;
116
    }
117
    case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
118
      LOG(LL_INFO, ("%p switching to data mode", nc));
119
      nc->handler = data_conn_handler;
120
      nc->ev_timer_time = mg_time(); /* Immediately */
121
      break;
122
    }
123
    case MG_EV_TIMER: {
124
      data_collect();
125
      nc->ev_timer_time = mg_time() + (DATA_COLLECTION_INTERVAL_MS * 0.001);
126
      break;
127
    }
128
    /* SimpleLink FS requires pre-declaring max file size. We use Content-Length
129
     * for that purpose - it will not exactly match file size, but is guaranteed
130
     * to exceed it and should be close enough. */
131
    case MG_EV_HTTP_MULTIPART_REQUEST: {
132
      struct http_message *hm = (struct http_message *) ev_data;
133
      struct mg_str *cl_header = mg_get_http_header(hm, "Content-Length");
134
      intptr_t cl = -1;
135
      if (cl_header != NULL && cl_header->len < 20) {
136
        char buf[20];
137
        memcpy(buf, cl_header->p, cl_header->len);
138
        buf[cl_header->len] = '\0';
139
        cl = atoi(buf);
140
        if (cl < 0) cl = -1;
141
      }
142
      nc->user_data = (void *) cl;
143
      break;
144
    }
145
    case MG_EV_HTTP_PART_BEGIN:
146
    case MG_EV_HTTP_PART_DATA:
147
    case MG_EV_HTTP_PART_END: {
148
      struct mg_http_multipart_part *mp =
149
          (struct mg_http_multipart_part *) ev_data;
150
      if (ev == MG_EV_HTTP_PART_BEGIN) {
151
        LOG(LL_INFO, ("Begin file upload: %s", mp->file_name));
152
      } else if (ev == MG_EV_HTTP_PART_END) {
153
        LOG(LL_INFO, ("End file upload: %s", mp->file_name));
154
      }
155
      mg_file_upload_handler(nc, ev, ev_data, upload_fname);
156
    }
157
  }
158
}
159

    
160
static void mg_init(struct mg_mgr *mgr) {
161
  LOG(LL_INFO, ("MG task running"));
162

    
163
  stop_nwp(); /* See function description in wifi.c */
164
  LOG(LL_INFO, ("Starting NWP..."));
165
  int role = sl_Start(0, 0, 0);
166
  if (role < 0) {
167
    LOG(LL_ERROR, ("Failed to start NWP"));
168
    return;
169
  }
170

    
171
  {
172
    SlVersionFull ver;
173
    unsigned char opt = SL_DEVICE_GENERAL_VERSION;
174
    unsigned char len = sizeof(ver);
175

    
176
    memset(&ver, 0, sizeof(ver));
177
    sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &opt, &len,
178
              (unsigned char *) (&ver));
179
    LOG(LL_INFO, ("NWP v%d.%d.%d.%d started, host v%d.%d.%d.%d",
180
                  ver.NwpVersion[0], ver.NwpVersion[1], ver.NwpVersion[2],
181
                  ver.NwpVersion[3], SL_MAJOR_VERSION_NUM, SL_MINOR_VERSION_NUM,
182
                  SL_VERSION_NUM, SL_SUB_VERSION_NUM));
183
  }
184

    
185
  GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
186

    
187
  data_init_sensors(TMP006_ADDR, BM222_ADDR);
188

    
189
  sl_fs_init();
190

    
191
#if defined(WIFI_STA_SSID)
192
  if (!wifi_setup_sta(WIFI_STA_SSID, WIFI_STA_PASS)) {
193
    LOG(LL_ERROR, ("Error setting up WiFi station"));
194
  }
195
#elif defined(WIFI_AP_SSID)
196
  if (!wifi_setup_ap(WIFI_AP_SSID, WIFI_AP_PASS, WIFI_AP_CHAN)) {
197
    LOG(LL_ERROR, ("Error setting up WiFi AP"));
198
  }
199
#else
200
#error WiFi not configured
201
#endif
202

    
203
  /* We don't need SimpleLink's web server. */
204
  sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
205

    
206
  const char *err = "";
207
  struct mg_bind_opts opts;
208
  memset(&opts, 0, sizeof(opts));
209
  opts.error_string = &err;
210

    
211
  struct mg_connection *nc = mg_bind_opt(mgr, "80", mg_ev_handler, opts);
212
  if (nc != NULL) {
213
    mg_set_protocol_http_websocket(nc);
214
    nc->ev_timer_time = mg_time(); /* Start data collection */
215
  } else {
216
    LOG(LL_ERROR, ("Failed to create listener: %s", err));
217
  }
218
}
219

    
220
#ifndef USE_TIRTOS
221
/* Int vector table, defined in startup_gcc.c */
222
extern void (*const g_pfnVectors[])(void);
223
#endif
224

    
225
int main(void) {
226
#ifndef USE_TIRTOS
227
  MAP_IntVTableBaseSet((unsigned long) &g_pfnVectors[0]);
228
#endif
229
  MAP_IntEnable(FAULT_SYSTICK);
230
  MAP_IntMasterEnable();
231
  PRCMCC3200MCUInit();
232

    
233
  /* Console UART init. */
234
  MAP_PRCMPeripheralClkEnable(CONSOLE_UART_PERIPH, PRCM_RUN_MODE_CLK);
235
  MAP_PinTypeUART(PIN_55, PIN_MODE_3); /* PIN_55 -> UART0_TX */
236
  MAP_PinTypeUART(PIN_57, PIN_MODE_3); /* PIN_57 -> UART0_RX */
237
  MAP_UARTConfigSetExpClk(
238
      CONSOLE_UART, MAP_PRCMPeripheralClockGet(CONSOLE_UART_PERIPH),
239
      CONSOLE_BAUD_RATE,
240
      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
241
  MAP_UARTFIFOLevelSet(CONSOLE_UART, UART_FIFO_TX1_8, UART_FIFO_RX4_8);
242
  MAP_UARTFIFOEnable(CONSOLE_UART);
243

    
244
  setvbuf(stdout, NULL, _IOLBF, 0);
245
  setvbuf(stderr, NULL, _IOLBF, 0);
246
  cs_log_set_level(LL_INFO);
247
  cs_log_set_file(stdout);
248

    
249
  LOG(LL_INFO, ("Hello, world!"));
250

    
251
  MAP_PinTypeI2C(PIN_01, PIN_MODE_1); /* SDA */
252
  MAP_PinTypeI2C(PIN_02, PIN_MODE_1); /* SCL */
253
  I2C_IF_Open(I2C_MASTER_MODE_FST);
254

    
255
  /* Set up the red LED. Note that amber and green cannot be used as they share
256
   * pins with I2C. */
257
  MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK);
258
  MAP_PinTypeGPIO(PIN_64, PIN_MODE_0, false);
259
  MAP_GPIODirModeSet(GPIOA1_BASE, 0x2, GPIO_DIR_MODE_OUT);
260
  GPIO_IF_LedConfigure(LED1);
261
  GPIO_IF_LedOn(MCU_RED_LED_GPIO);
262

    
263
  if (VStartSimpleLinkSpawnTask(8) != 0) {
264
    LOG(LL_ERROR, ("Failed to create SL task"));
265
  }
266

    
267
  if (!mg_start_task(MGOS_TASK_PRIORITY, MG_TASK_STACK_SIZE, mg_init)) {
268
    LOG(LL_ERROR, ("Failed to create MG task"));
269
  }
270

    
271
  osi_start();
272

    
273
  return 0;
274
}
275

    
276
/* These are FreeRTOS hooks for various life situations. */
277
void vApplicationMallocFailedHook(void) {
278
}
279

    
280
void vApplicationIdleHook(void) {
281
}
282

    
283
void vApplicationStackOverflowHook(OsiTaskHandle *th, signed char *tn) {
284
}
285

    
286
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *e,
287
                                  SlHttpServerResponse_t *resp) {
288
}
289

    
290
void SimpleLinkSockEventHandler(SlSockEvent_t *e) {
291
}
292

    
293
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *e) {
294
  LOG(LL_ERROR, ("status %d sender %d", e->EventData.deviceEvent.status,
295
                 e->EventData.deviceEvent.sender));
296
}