diff --git a/LICENSE b/LICENSE index 2acc94fa820a741742e4b3966dd9b294edf7ac4a..0b37b2bc7ea68f12210e292d92ba947747f16c6b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Sergey Lyubka +Copyright (c) 2021 Cesanta Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/examples/http/Makefile b/examples/http/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5b0a0692e4f15332429d1faadc8abab13349b62b --- /dev/null +++ b/examples/http/Makefile @@ -0,0 +1,3 @@ +SOURCES = main.c + +include ../../make/project.mk diff --git a/examples/http/README.md b/examples/http/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4325a1eb730bc29c97d3da3c6d5c7d9b1e71f539 --- /dev/null +++ b/examples/http/README.md @@ -0,0 +1,16 @@ +# BME280 sensor example + +Pinout is according to the C source: MOSI - 23, MISO - 19, CLK - 18, CS = 5: + +```c + struct spi bme280 = {.mosi = 23, .miso = 19, .clk = 18, .cs = {5, -1, -1}}; +``` + +Build, flash and monitor: + +``` +Chip ID: 96, expecting 96 +Temp: 23.69 +Chip ID: 96, expecting 96 +Temp: 25.5 +``` diff --git a/examples/http/main.c b/examples/http/main.c new file mode 100644 index 0000000000000000000000000000000000000000..25e11cba0f3ddddeb4ed1c4d54be354cd7c9f919 --- /dev/null +++ b/examples/http/main.c @@ -0,0 +1,63 @@ +#include <sdk.h> + +static unsigned readn(struct spi *spi, uint8_t reg, int n) { + unsigned rx = 0; + spi_begin(spi, 0); + spi_txn(spi, reg | 0x80); + for (int i = 0; i < n; i++) rx <<= 8, rx |= spi_txn(spi, 0); + spi_end(spi, 0); + return rx; +} + +static void write8(struct spi *spi, uint8_t reg, uint8_t val) { + spi_begin(spi, 0); + spi_txn(spi, (uint8_t)(reg & ~0x80)); + spi_txn(spi, val); + spi_end(spi, 0); +} + +uint16_t swap16(uint16_t val) { + uint8_t data[2] = {0, 0}; + memcpy(&data, &val, sizeof(data)); + return (uint16_t)((uint16_t) data[1] | (((uint16_t) data[0]) << 8)); +} + +// Taken from the BME280 datasheet, 4.2.3 +int32_t read_temp(struct spi *spi) { + int32_t t = (int32_t)(readn(spi, 0xfa, 3) >> 4); // Read temperature reg + + uint16_t c1 = (uint16_t) readn(spi, 0x88, 2); // dig_T1 + uint16_t c2 = (uint16_t) readn(spi, 0x8a, 2); // dig_T2 + uint16_t c3 = (uint16_t) readn(spi, 0x8c, 2); // dig_T3 + + int32_t t1 = (int32_t) swap16(c1); + int32_t t2 = (int32_t)(int16_t) swap16(c2); + int32_t t3 = (int32_t)(int16_t) swap16(c3); + + int32_t var1 = ((((t >> 3) - (t1 << 1))) * t2) >> 11; + int32_t var2 = (((((t >> 4) - t1) * ((t >> 4) - t1)) >> 12) * t3) >> 14; + + return ((var1 + var2) * 5 + 128) >> 8; +} + +int main(void) { + wdt_disable(); + + struct spi bme280 = {.mosi = 23, .miso = 19, .clk = 18, .cs = {5, -1, -1}}; + spi_init(&bme280); + + write8(&bme280, 0xe0, 0xb6); // Soft reset + spin(999999); // Wait until reset + write8(&bme280, 0xf4, 0); // REG_CONTROL, MODE_SLEEP + write8(&bme280, 0xf5, (3 << 5)); // REG_CONFIG, filter = off, 20ms + write8(&bme280, 0xf4, (1 << 5) | 3); // REG_CONFIG, MODE_NORMAL + + for (;;) { + sdk_log("Chip ID: %d, expecting 96\n", readn(&bme280, 0xd0, 1)); + int temp = read_temp(&bme280); + sdk_log("Temp: %d.%d\n", temp / 100, temp % 100); + spin(9999999); + } + + return 0; +} diff --git a/include/cnip.h b/include/cnip.h new file mode 100644 index 0000000000000000000000000000000000000000..eefeb647b3cfe5455a6f5bc7a7040798d721726b --- /dev/null +++ b/include/cnip.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012-2021 Charles Lohr, MIT license +// All rights reserved + +#pragma once + +#include <stddef.h> + +// Low level (hardware) API +void cn_mac_in(void *buf, size_t len); // Implemented by CNIP +void cn_mac_out(void *buf, size_t len); // Must be implemented by user +void cn_poll(unsigned long now_ms); // Called periodically or on event + +// High level (user) API +// This is a user-defined callback function that gets called on various events +struct cn_conn; // A connection - opaque +typedef void (*cn_fn_t)(struct cn_conn *, int ev); // User function +enum { + CN_EV_ERROR, // Error! Use cn_get_error() to get the reason + CN_EV_CONNECT, // Client connection established + CN_EV_ACCEPT, // New server connection accepted + CN_EV_READ, // More data arrived, use cn_rx() to access data + CN_EV_WRITE, // Data has been sent to the network + CN_EV_CLOSE, // Connection is about to vanish +}; +// API for creating new connections +struct cn_conn *cn_tcp_listen(const char *url, cn_fn_t handler_fn); +struct cn_conn *cn_tcp_connect(const char *url, cn_fn_t handler_fn); +// API for use from inside a user callback function +void cn_rx(struct cn_conn *, void **buf, size_t *len); // Get recv data +void cn_tx(struct cn_conn *, void **buf, size_t *len); // Get sent data +void cn_send(struct cn_conn *, void *buf, size_t len); // Send more data +void cn_free(struct cn_conn *, size_t off, size_t len); // Discard recv data diff --git a/src/cnip.c b/src/cnip.c new file mode 100644 index 0000000000000000000000000000000000000000..3c13cde0ce2757c6fd4da84cbcd9dc632e3bedd8 --- /dev/null +++ b/src/cnip.c @@ -0,0 +1,13 @@ +// Copyright (c) 2012-2021 Charles Lohr, MIT license +// All rights reserved + +#include <cnip.h> + +void cn_mac_in(void *buf, size_t len) { + (void) buf; + (void) len; +} + +void cn_poll(unsigned long now_ms) { + (void) now_ms; +}