Compare commits
2 Commits
main
...
wifi-modul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17563c2a15 | ||
|
|
01784b6a80 |
28
read_logs.py
28
read_logs.py
@ -1,28 +0,0 @@
|
||||
import serial
|
||||
from datetime import datetime
|
||||
|
||||
# Configure serial port settings
|
||||
port = '/dev/cu.usbmodemNRAQBQER2' # Replace with your specific serial port
|
||||
baud_rate = 115200 # Replace with the appropriate baud rate
|
||||
timeout = 1 # Specify the timeout for reading from the serial port
|
||||
|
||||
# Open the serial port
|
||||
ser = serial.Serial(port, baud_rate, timeout=timeout)
|
||||
|
||||
# Generate the filename based on current date and time
|
||||
now = datetime.now()
|
||||
date_time = now.strftime("%Y-%m-%d_%H-%M")
|
||||
filename = f"{date_time}_SHOH.txt"
|
||||
|
||||
# Open a file to write the logs
|
||||
with open(filename, 'w') as file:
|
||||
# Read and write the logs from the serial port
|
||||
while True:
|
||||
line = ser.readline().decode().strip()
|
||||
if line:
|
||||
file.write(line + '\n')
|
||||
print(line) # Optional: Print the logs to the console as well
|
||||
|
||||
# Close the serial port when done
|
||||
ser.close()
|
||||
|
||||
@ -43,20 +43,22 @@
|
||||
<option id="com.crt.advproject.cpp.fpu.1211390952" name="Floating point" superClass="com.crt.advproject.cpp.fpu" useByScannerDiscovery="true"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.417443680" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.cpp.misc.dialect.4036734" name="Language standard" superClass="com.crt.advproject.cpp.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.cpp17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.cpp.input.2005422649" superClass="com.crt.advproject.compiler.cpp.input"/>
|
||||
@ -84,13 +86,19 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.82852045" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.input.765511076" superClass="com.crt.advproject.compiler.input"/>
|
||||
@ -106,13 +114,19 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/master}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1836378919" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="com.crt.advproject.assembler.input.339410672" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
|
||||
@ -212,6 +226,13 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
</option>
|
||||
<inputType id="com.crt.advproject.compiler.cpp.input.903614193" superClass="com.crt.advproject.compiler.cpp.input"/>
|
||||
</tool>
|
||||
@ -243,6 +264,13 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.1008527937" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.input.246185412" superClass="com.crt.advproject.compiler.input"/>
|
||||
@ -266,6 +294,12 @@
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/user_interface}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/logging}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/temperature}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/peripherals/networking}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/manager}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/rotary}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/relay}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/src/threads/networking}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1117166373" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="com.crt.advproject.assembler.input.2071009798" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
|
||||
|
||||
@ -94,6 +94,7 @@
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
#define configUSE_TICKLESS_IDLE 1
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configRUN_TIME_COUNTER_TYPE uint64_t
|
||||
|
||||
|
||||
|
||||
@ -57,12 +57,8 @@ I2C::I2C (const I2C_config &cfg) : device (nullptr)
|
||||
*/
|
||||
//Manual: Table 83 & 90
|
||||
Chip_SYSCTL_PeriphReset(RESET_I2C0);
|
||||
Chip_IOCON_PinMuxSet(LPC_IOCON, ThreadCommon::PORT_I2C_SCL,
|
||||
ThreadCommon::PIN_I2C_SCL, IOCON_FUNC1 |
|
||||
IOCON_DIGMODE_EN | cfg.i2c_mode);
|
||||
Chip_IOCON_PinMuxSet(LPC_IOCON, ThreadCommon::PORT_I2C_SDA,
|
||||
ThreadCommon::PIN_I2C_SDA, IOCON_FUNC1 |
|
||||
IOCON_DIGMODE_EN | cfg.i2c_mode);
|
||||
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 4, IOCON_FUNC1 | IOCON_DIGMODE_EN | cfg.i2c_mode);
|
||||
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5, IOCON_FUNC1 | IOCON_DIGMODE_EN | cfg.i2c_mode);
|
||||
//}
|
||||
// else {
|
||||
// currently we support only I2C number 0
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
|
||||
#include "chip.h"
|
||||
#include "board.h"
|
||||
#include "pinportmap.h"
|
||||
|
||||
struct I2C_config {
|
||||
unsigned int device_number;
|
||||
|
||||
@ -116,14 +116,14 @@ void LpcDebugUart::set_on_receive(void(*cb)(void))
|
||||
|
||||
int LpcDebugUart::free()
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(write_mutex);
|
||||
std::lock_guard<Fmutex> lock(write_debug_mutex);
|
||||
|
||||
return UART_RB_SIZE - RingBuffer_GetCount(&txring);
|
||||
}
|
||||
|
||||
int LpcDebugUart::peek()
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(read_mutex);
|
||||
std::lock_guard<Fmutex> lock(read_debug_mutex);
|
||||
|
||||
return RingBuffer_GetCount(&rxring);
|
||||
}
|
||||
@ -135,7 +135,7 @@ int LpcDebugUart::read(char &c)
|
||||
|
||||
int LpcDebugUart::read(char *buffer, int len)
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(read_mutex);
|
||||
std::lock_guard<Fmutex> lock(read_debug_mutex);
|
||||
|
||||
if(RingBuffer_GetCount(&rxring) <= 0) {
|
||||
notify_rx = xTaskGetCurrentTaskHandle();
|
||||
@ -151,7 +151,7 @@ int LpcDebugUart::read(char *buffer, int len)
|
||||
|
||||
int LpcDebugUart::read(char *buffer, int len, TickType_t total_timeout, TickType_t ic_timeout)
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(read_mutex);
|
||||
std::lock_guard<Fmutex> lock(read_debug_mutex);
|
||||
|
||||
// we can't read more than ring buffer size at a time
|
||||
if(len > UART_RB_SIZE) len = UART_RB_SIZE;
|
||||
@ -181,7 +181,7 @@ int LpcDebugUart::write(const char *s)
|
||||
|
||||
int LpcDebugUart::write(const char *buffer, int len)
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(write_mutex);
|
||||
std::lock_guard<Fmutex> lock(write_debug_mutex);
|
||||
|
||||
int pos = 0;
|
||||
notify_tx = xTaskGetCurrentTaskHandle();
|
||||
@ -214,15 +214,15 @@ bool LpcDebugUart::rxbreak()
|
||||
|
||||
void LpcDebugUart::speed(int bps)
|
||||
{
|
||||
std::lock_guard<Fmutex> lockw(write_mutex);
|
||||
std::lock_guard<Fmutex> lockr(read_mutex);
|
||||
std::lock_guard<Fmutex> lockw(write_debug_mutex);
|
||||
std::lock_guard<Fmutex> lockr(read_debug_mutex);
|
||||
|
||||
Chip_UART0_SetBaud(uart, bps);
|
||||
}
|
||||
|
||||
bool LpcDebugUart::txempty()
|
||||
{
|
||||
std::lock_guard<Fmutex> lock(write_mutex);
|
||||
std::lock_guard<Fmutex> lock(write_debug_mutex);
|
||||
|
||||
return (RingBuffer_GetCount(&txring) == 0);
|
||||
}
|
||||
|
||||
@ -56,8 +56,8 @@ private:
|
||||
TaskHandle_t notify_rx;
|
||||
TaskHandle_t notify_tx;
|
||||
void (*on_receive)(void); // callback for received data notifications
|
||||
Fmutex read_mutex;
|
||||
Fmutex write_mutex;
|
||||
Fmutex read_debug_mutex;
|
||||
Fmutex write_debug_mutex;
|
||||
};
|
||||
|
||||
#endif /* LPCUART_H_ */
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include "LpcUart.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* shoh: Important differences
|
||||
* We don't have movable pins -> not needed.
|
||||
@ -126,6 +128,8 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) {
|
||||
uart = cfg.pUART; // set the actual value after validity checking
|
||||
|
||||
|
||||
//Not that straightforward.
|
||||
//But will work for uart1, kind of...
|
||||
if(cfg.tx.port >= 0) {
|
||||
Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.tx.port, cfg.tx.pin, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN));
|
||||
}
|
||||
|
||||
787
source/shoh/src/peripherals/networking/esp8266_socket.c
Normal file
787
source/shoh/src/peripherals/networking/esp8266_socket.c
Normal file
@ -0,0 +1,787 @@
|
||||
/* ========================================
|
||||
*
|
||||
* Copyright YOUR COMPANY, THE YEAR
|
||||
* All Rights Reserved
|
||||
* UNPUBLISHED, LICENSED SOFTWARE.
|
||||
*
|
||||
* CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* WHICH IS THE PROPERTY OF your company.
|
||||
*
|
||||
* ========================================
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ring_buffer.h"
|
||||
|
||||
#include "esp8266_socket.h"
|
||||
|
||||
#include "serial_port.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
typedef int EspSocket_t;
|
||||
|
||||
static inline uint32_t get_ticks(void) {
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
#define I_DONT_USE(x) (void) x
|
||||
#define DEBUGP( ... ) printf( __VA_ARGS__ )
|
||||
|
||||
// macro for changing state. Correct operation requires that ctx is a pointer to state machine instance (see state template)
|
||||
#define TRAN(st) ctx->next_state = st
|
||||
|
||||
typedef enum eventTypes { eEnter, eExit, eTick, eReceive, eConnect, eDisconnect, eSend } EventType;
|
||||
|
||||
typedef struct event_ {
|
||||
EventType ev; // event type (= what happened)
|
||||
// we could add additional data
|
||||
} event;
|
||||
|
||||
static const event evEnter = { eEnter };
|
||||
static const event evExit = { eExit };
|
||||
|
||||
|
||||
typedef struct smi_ smi;
|
||||
|
||||
typedef void (*smf)(smi *, const event *); // prototype of state handler function pointer
|
||||
|
||||
#define EVQ_SIZE 32
|
||||
|
||||
#define SMI_BUFSIZE 80
|
||||
#define RC_NOT_AVAILABLE -1
|
||||
#define RC_OK 0
|
||||
#define RC_ERROR 1
|
||||
|
||||
struct smi_ {
|
||||
smf state; // current state (function pointer)
|
||||
smf next_state; // next state (function pointer)
|
||||
RINGBUFF_T EspEventQ;
|
||||
event evq_buf[EVQ_SIZE];
|
||||
int timer;
|
||||
int count;
|
||||
int pos;
|
||||
char buffer[SMI_BUFSIZE];
|
||||
char ssid[32]; // SSID
|
||||
char pwd[32]; // password
|
||||
char sa_data[32]; // ip address
|
||||
char sa_port[14]; // port number (string)
|
||||
};
|
||||
|
||||
static void stInit(smi *ctx, const event *e);
|
||||
static void stEchoOff(smi *ctx, const event *e);
|
||||
static void stStationModeCheck(smi *ctx, const event *e);
|
||||
static void stStationModeSet(smi *ctx, const event *e);
|
||||
static void stConnectAP(smi *ctx, const event *e);
|
||||
static void stReady(smi *ctx, const event *e);
|
||||
static void stConnectTCP(smi *ctx, const event *e);
|
||||
static void stConnected(smi *ctx, const event *e);
|
||||
static void stCloseTCP(smi *ctx, const event *e);
|
||||
static void stPassthrough(smi *ctx, const event *e);
|
||||
static void stPassthroughOK(smi *ctx, const event *e);
|
||||
static void stAT(smi *ctx, const event *e);
|
||||
static void stCommandMode(smi *ctx, const event *e);
|
||||
|
||||
static void EspSocketRun(smi *ctx);
|
||||
|
||||
|
||||
|
||||
smi EspSocketInstance;
|
||||
|
||||
static void port2str(int i, char *str)
|
||||
{
|
||||
int m = 100000;
|
||||
i %= m; // limit integer size to max 5 digits.
|
||||
while(i / m == 0) m/=10;
|
||||
while(m > 0) {
|
||||
*str++ = '0' + i / m;
|
||||
i %= m;
|
||||
m /= 10;
|
||||
}
|
||||
*str='\0';
|
||||
}
|
||||
|
||||
void smi_init(smi *ctx)
|
||||
{
|
||||
serial_init(ctx);
|
||||
memset(ctx, 0, sizeof(smi));
|
||||
ctx->state = stInit;
|
||||
ctx->next_state = stInit;
|
||||
RingBuffer_Init(&ctx->EspEventQ, ctx->evq_buf, sizeof(event), EVQ_SIZE);
|
||||
|
||||
ctx->state(ctx, &evEnter); // enter initial state
|
||||
}
|
||||
|
||||
//Needs a mechanism to return error code after the timeout.
|
||||
//Timeout is done by the ctx->timer in states.
|
||||
//Tick event should be dispatched every ms, which seems not to be the case. (It's more rare.)
|
||||
//Look at the stInit for reference
|
||||
int esp_socket(const char *ssid, const char *password)
|
||||
{
|
||||
smi_init(&EspSocketInstance);
|
||||
|
||||
|
||||
strncpy(EspSocketInstance.ssid, ssid, 32);
|
||||
strncpy(EspSocketInstance.pwd, password, 32);
|
||||
|
||||
|
||||
while(EspSocketInstance.state != stReady) {
|
||||
// run esp task and run ticks
|
||||
EspSocketRun(&EspSocketInstance);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Needs a mechanism to return error code after the timeout.
|
||||
int esp_connect(int sockfd, const char *addr, int port)
|
||||
{
|
||||
I_DONT_USE(sockfd);
|
||||
|
||||
strncpy(EspSocketInstance.sa_data,addr,sizeof(EspSocketInstance.sa_data)-1);
|
||||
EspSocketInstance.sa_data[sizeof(EspSocketInstance.sa_data)-1] = '\0';
|
||||
port2str(port, EspSocketInstance.sa_port);
|
||||
|
||||
const event e = { eConnect };
|
||||
|
||||
RingBuffer_Insert(&EspSocketInstance.EspEventQ,&e);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
while(EspSocketInstance.state != stConnected) {
|
||||
// run esp task and run ticks
|
||||
EspSocketRun(&EspSocketInstance);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int esp_read(int sockfd, void *data, int length)
|
||||
{
|
||||
I_DONT_USE(sockfd);
|
||||
int count = 0;
|
||||
|
||||
if(EspSocketInstance.state == stConnected) {
|
||||
#if 0
|
||||
DEBUGP("[rd=%d]\r\n", length);
|
||||
// read data
|
||||
while(count < length && serial_get_char(&EspSocketInstance, data)) {
|
||||
//char c = *((unsigned char *)data);
|
||||
//DEBUGP("[%02X %c]\r\n", c , isprint(c) ? c : '.');
|
||||
++count;
|
||||
++data;
|
||||
}
|
||||
#else
|
||||
count = serial_read_buf(&EspSocketInstance, data, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int esp_write(int sockfd, const void *data, int length)
|
||||
{
|
||||
I_DONT_USE(sockfd);
|
||||
|
||||
if(EspSocketInstance.state == stConnected) {
|
||||
// write data
|
||||
serial_write_buf(&EspSocketInstance, data, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int esp_close(int sockfd)
|
||||
{
|
||||
return esp_shutdown(sockfd, -1);
|
||||
}
|
||||
|
||||
int esp_shutdown(int sockfd, int how)
|
||||
{
|
||||
I_DONT_USE(sockfd);
|
||||
I_DONT_USE(how);
|
||||
const event e = { eDisconnect };
|
||||
|
||||
RingBuffer_Insert(&EspSocketInstance.EspEventQ,&e);
|
||||
while(EspSocketInstance.state != stReady) {
|
||||
// run esp task and run ticks
|
||||
EspSocketRun(&EspSocketInstance);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_peek(int sockfd)
|
||||
{
|
||||
int cnt = 0;
|
||||
if(EspSocketInstance.state == stConnected) {
|
||||
cnt = serial_peek(&EspSocketInstance);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* this is state template */
|
||||
void stStateTemplate(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_counters(smi *ctx) {
|
||||
ctx->count = 0;
|
||||
ctx->pos = 0;
|
||||
ctx->timer = 0;
|
||||
}
|
||||
|
||||
/* Read and store characters upto specified length.
|
||||
* Returns true when specified amount of characters have been accumulated. */
|
||||
void sm_flush(smi *ctx)
|
||||
{
|
||||
//DEBUGP("flush: %d\n", (int)xSerialRxWaiting(ctx->ComPort));
|
||||
while(serial_get_char(ctx, ctx->buffer));
|
||||
}
|
||||
|
||||
|
||||
/* Read and store characters upto specified length.
|
||||
* Returns true when specified amount of characters have been accumulated. */
|
||||
bool sm_read_buffer(smi *ctx, int count)
|
||||
{
|
||||
while(ctx->pos < (SMI_BUFSIZE - 1) && ctx->pos < count && serial_get_char(ctx, ctx->buffer + ctx->pos)) {
|
||||
//putchar(ctx->buffer[ctx->pos]); // debugging
|
||||
++ctx->pos;
|
||||
}
|
||||
return (ctx->pos >= count);
|
||||
}
|
||||
|
||||
|
||||
/* Read an integer.
|
||||
* Consumes characters until a non-nondigit is received. The nondigit is also consumed. */
|
||||
bool sm_read_int(smi *ctx, int *value)
|
||||
{
|
||||
bool result = false;
|
||||
while(ctx->pos < (SMI_BUFSIZE - 1) && serial_get_char(ctx, ctx->buffer + ctx->pos)) {
|
||||
if(!isdigit((int)ctx->buffer[ctx->pos])) {
|
||||
ctx->buffer[ctx->pos] = '\0';
|
||||
*value = atoi(ctx->buffer);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
++ctx->pos;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Read and store data until one of the specified strings is received.
|
||||
* The matched string is also included in the data .*/
|
||||
int sm_read_until(smi *ctx, const char **p)
|
||||
{
|
||||
int result = RC_NOT_AVAILABLE;
|
||||
while(result < 0 && ctx->pos < (SMI_BUFSIZE - 1) && serial_get_char(ctx, ctx->buffer + ctx->pos)) {
|
||||
++ctx->pos;
|
||||
ctx->buffer[ctx->pos] = '\0';
|
||||
for(int i = 0; result < 0 && p[i] != NULL; ++i) {
|
||||
if(strstr(ctx->buffer, p[i]) != NULL) {
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/* read and store data until result is received */
|
||||
int sm_read_result(smi *ctx)
|
||||
{
|
||||
static const char *result_list[] = { "OK\r\n", "ERROR\r\n", NULL };
|
||||
return sm_read_until(ctx, result_list);
|
||||
}
|
||||
|
||||
/* read and consume characters until specified string occurs */
|
||||
bool sm_wait_for(smi *ctx, const char *p)
|
||||
{
|
||||
bool result = false;
|
||||
int len = strlen(p);
|
||||
|
||||
while(sm_read_buffer(ctx, len)) {
|
||||
ctx->buffer[ctx->pos] = '\0';
|
||||
if(strstr(ctx->buffer, p) != NULL) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
memmove(ctx->buffer, ctx->buffer + 1, ctx->pos);
|
||||
--ctx->pos;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void stInit(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stInit\r\n");
|
||||
sm_flush(ctx);
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer; //increases timer value with every tick
|
||||
|
||||
//if(ctx->timer == 2) DEBUGP("[%s]\r\n", ctx->buffer);
|
||||
|
||||
//When it hits five - tries to reach the esp, incresing count of attempts.
|
||||
if(ctx->timer >= 5) {
|
||||
ctx->timer = 0;
|
||||
++ctx->count;
|
||||
|
||||
if(ctx->count < 2) {
|
||||
serial_write_str(ctx, "AT\r\n");
|
||||
}
|
||||
//If done more attempts than expected - give up.
|
||||
else {
|
||||
DEBUGP("Error: Module not responding\r\n");
|
||||
TRAN(stAT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eReceive:
|
||||
if(sm_wait_for(ctx, "OK\r\n")) {
|
||||
TRAN(stEchoOff);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stAT(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stAT\r\n");
|
||||
init_counters(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer;
|
||||
if(ctx->timer == 5) serial_write_str(ctx, "+++");
|
||||
if(ctx->timer == 15) TRAN(stInit);
|
||||
break;
|
||||
case eReceive:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stEchoOff(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stEchoOff\r\n");
|
||||
sm_flush(ctx);
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "ATE0\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer;
|
||||
if(ctx->timer >= 10) {
|
||||
++ctx->count;
|
||||
if(ctx->count < 3) {
|
||||
serial_write_str(ctx, "ATE0\r\n");
|
||||
}
|
||||
else {
|
||||
DEBUGP("Error: setting local echo off failed\r\n");
|
||||
TRAN(stInit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eReceive:
|
||||
if(sm_wait_for(ctx, "OK\r\n")) {
|
||||
TRAN(stStationModeCheck);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stStationModeCheck(smi *ctx, const event *e)
|
||||
{
|
||||
int rc = -1;
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stStationModeCheck\r\n");
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CWMODE_CUR?\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
rc = sm_read_result(ctx);
|
||||
if(rc == RC_OK) {
|
||||
//DEBUGP("%d: %s", rc, ctx->buffer);
|
||||
if(strstr(ctx->buffer, "+CWMODE_CUR:1\r\n") != NULL) {
|
||||
TRAN(stConnectAP);
|
||||
}
|
||||
else {
|
||||
TRAN(stStationModeSet);
|
||||
}
|
||||
}
|
||||
else if(rc == RC_ERROR) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stStationModeSet(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stStationModeSet\r\n");
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CWMODE_CUR=1\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
if(sm_wait_for(ctx, "OK\r\n")) {
|
||||
TRAN(stStationModeCheck);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void connect_ssid(smi *ctx)
|
||||
{
|
||||
serial_write_str(ctx, "AT+CWJAP_CUR=\"");
|
||||
serial_write_str(ctx, ctx->ssid);
|
||||
serial_write_str(ctx, "\",\"");
|
||||
serial_write_str(ctx, ctx->pwd);
|
||||
serial_write_str(ctx, "\"\r\n");
|
||||
}
|
||||
|
||||
static void stConnectAP(smi *ctx, const event *e)
|
||||
{
|
||||
int rc;
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stConnectAP\r\n");
|
||||
init_counters(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
// may take upto 7 seconds. do we need a timeout?
|
||||
++ctx->timer;
|
||||
if(ctx->timer == 1) {
|
||||
connect_ssid(ctx);
|
||||
}
|
||||
if(ctx->timer >= 70) {
|
||||
ctx->timer = 0;
|
||||
}
|
||||
break;
|
||||
case eReceive:
|
||||
rc = sm_read_result(ctx);
|
||||
if(rc == RC_OK) {
|
||||
//DEBUGP("%d: %s", rc, ctx->buffer);
|
||||
TRAN(stReady);
|
||||
}
|
||||
else if(rc == RC_ERROR) {
|
||||
// failed: what to do now?
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stReady(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stReady\r\n");
|
||||
init_counters(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
break;
|
||||
case eConnect:
|
||||
TRAN(stConnectTCP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void connect_tcp(smi *ctx)
|
||||
{
|
||||
serial_write_str(ctx, "AT+CIPSTART=\"TCP\",\"");
|
||||
serial_write_str(ctx, ctx->sa_data);
|
||||
serial_write_str(ctx, "\",");
|
||||
serial_write_str(ctx, ctx->sa_port);
|
||||
serial_write_str(ctx, "\r\n");
|
||||
}
|
||||
|
||||
static void stConnectTCP(smi *ctx, const event *e)
|
||||
{
|
||||
int rc;
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stConnectTCP\r\n");
|
||||
init_counters(ctx);
|
||||
connect_tcp(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer;
|
||||
if(ctx->timer >= 70) {
|
||||
ctx->timer = 0;
|
||||
}
|
||||
break;
|
||||
case eReceive:
|
||||
rc = sm_read_result(ctx);
|
||||
if(rc == RC_OK) {
|
||||
//DEBUGP("%d: %s", rc, ctx->buffer);
|
||||
if(strstr(ctx->buffer, "CONNECT\r\n") != NULL) {
|
||||
TRAN(stPassthrough);
|
||||
}
|
||||
else {
|
||||
// what else can we get with OK??
|
||||
}
|
||||
}
|
||||
else if(rc == RC_ERROR) {
|
||||
// failed: what to do now?
|
||||
DEBUGP("Connect failed\r\n");
|
||||
connect_tcp(ctx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stPassthrough(smi *ctx, const event *e)
|
||||
{
|
||||
int rc;
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stPassthrough\r\n");
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CIPMODE=1\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
rc = sm_read_result(ctx);
|
||||
if(rc == RC_OK) {
|
||||
TRAN(stPassthroughOK);
|
||||
}
|
||||
else if(rc == RC_ERROR) {
|
||||
// failed: what to do now?
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void stPassthroughOK(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stPassthroughOK\r\n");
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CIPSEND\r\n");
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
if(sm_wait_for(ctx, ">")) {
|
||||
TRAN(stConnected);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void stConnected(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stConnected\r\n");
|
||||
init_counters(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
break;
|
||||
case eReceive:
|
||||
break;
|
||||
case eDisconnect:
|
||||
TRAN(stCommandMode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void stCommandMode(smi *ctx, const event *e)
|
||||
{
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stCommandMode\r\n");
|
||||
init_counters(ctx);
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer;
|
||||
if(ctx->timer == 10) serial_write_str(ctx, "+++");
|
||||
if(ctx->timer == 25) TRAN(stCloseTCP);
|
||||
break;
|
||||
case eReceive:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void stCloseTCP(smi *ctx, const event *e)
|
||||
{
|
||||
int rc = -1;
|
||||
switch(e->ev) {
|
||||
case eEnter:
|
||||
DEBUGP("stCloseTCP\r\n");
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CIPMODE=0\r\n");;
|
||||
break;
|
||||
case eReceive:
|
||||
rc = sm_read_result(ctx);
|
||||
if(rc == RC_OK) {
|
||||
if(strstr(ctx->buffer, "CLOSED") != NULL) {
|
||||
TRAN(stReady);
|
||||
}
|
||||
else {
|
||||
init_counters(ctx);
|
||||
serial_write_str(ctx, "AT+CIPCLOSE\r\n");;
|
||||
}
|
||||
}
|
||||
else if(rc == RC_ERROR) {
|
||||
}
|
||||
break;
|
||||
case eExit:
|
||||
break;
|
||||
case eTick:
|
||||
++ctx->timer;
|
||||
if(ctx->timer == 25) TRAN(stCommandMode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void dispatch_event(smi *ctx, const event *e)
|
||||
{
|
||||
ctx->state(ctx, e); // dispatch event to current state
|
||||
if(ctx->state != ctx->next_state) { // check if state was changed
|
||||
ctx->state(ctx, &evExit); // exit old state (cleanup)
|
||||
ctx->state = ctx->next_state; // change state
|
||||
ctx->state(ctx, &evEnter); // enter new state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Receive events from queue and dispatch them to state machine
|
||||
*/
|
||||
static void EspSocketRun(smi *ctx)
|
||||
{
|
||||
event e;
|
||||
|
||||
static uint32_t old = 0 ;
|
||||
uint32_t now = 0 ;
|
||||
|
||||
now = get_ticks()/100;
|
||||
if(now != old) {
|
||||
const event tick = { eTick };
|
||||
old = now;
|
||||
// send ESP tick
|
||||
RingBuffer_Insert(&ctx->EspEventQ, &tick);
|
||||
}
|
||||
|
||||
if(serial_peek(ctx)) {
|
||||
const event rcv = { eReceive };
|
||||
RingBuffer_Insert(&ctx->EspEventQ, &rcv);
|
||||
}
|
||||
|
||||
// read queue
|
||||
while (RingBuffer_Pop(&ctx->EspEventQ,&e)) {
|
||||
dispatch_event(ctx, &e); // dispatch event to current state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* [] END OF FILE */
|
||||
21
source/shoh/src/peripherals/networking/esp8266_socket.h
Normal file
21
source/shoh/src/peripherals/networking/esp8266_socket.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef ESP8266_H_
|
||||
#define ESP8266_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int esp_socket(const char *ssid, const char *password) ;
|
||||
int esp_connect(int sockfd, const char *addr, int port);
|
||||
int esp_read(int sockfd, void *data, int length);
|
||||
int esp_write(int sockfd, const void *data, int length);
|
||||
int esp_close(int sockfd);
|
||||
int esp_shutdown(int sockfd, int how);
|
||||
int esp_peek(int sockfd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
source/shoh/src/peripherals/networking/serial_port.cpp
Normal file
56
source/shoh/src/peripherals/networking/serial_port.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* serial_port.cpp
|
||||
*
|
||||
* Created on: 25.8.2021
|
||||
* Author: keijo
|
||||
*/
|
||||
#include "LpcUart.h"
|
||||
#include "serial_port.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static LpcUart *EspUart;
|
||||
|
||||
void serial_init(void *ctx)
|
||||
{
|
||||
if(EspUart == nullptr) {
|
||||
LpcPinMap none = {-1, -1}; // unused pin has negative values in it
|
||||
LpcPinMap txpin_esp = { 0, 14 }; // transmit pin
|
||||
LpcPinMap rxpin_esp = { 0, 13 }; // receive pin
|
||||
LpcUartConfig cfg = { LPC_USART1, 115200, UARTN_CFG_DATALEN_8 | UARTN_CFG_PARITY_NONE | UARTN_CFG_STOPLEN_1, false, txpin_esp, rxpin_esp, none, none };
|
||||
|
||||
EspUart = new LpcUart(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_write_buf(void *ctx, const char *buf, int len)
|
||||
{
|
||||
EspUart->write(buf, len);
|
||||
}
|
||||
|
||||
void serial_write_str(void *ctx, const char *s)
|
||||
{
|
||||
EspUart->write(s);
|
||||
}
|
||||
|
||||
int serial_read_buf(void *ctx, char *buf, int len)
|
||||
{
|
||||
return EspUart->read(buf, len, 20 * len);
|
||||
}
|
||||
|
||||
int serial_get_char(void *ctx, char *p)
|
||||
{
|
||||
return EspUart->read(p, 1, 20);//EspUart->read(p, 1, 20);
|
||||
}
|
||||
|
||||
int serial_peek(void *ctx)
|
||||
{
|
||||
return EspUart->peek();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
30
source/shoh/src/peripherals/networking/serial_port.h
Normal file
30
source/shoh/src/peripherals/networking/serial_port.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* serial_port.h
|
||||
*
|
||||
* Created on: 25.8.2021
|
||||
* Author: keijo
|
||||
*/
|
||||
|
||||
#ifndef SERIAL_PORT_H_
|
||||
#define SERIAL_PORT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void serial_init(void *ctx);
|
||||
void serial_write_buf(void *ctx, const char *buf, int len);
|
||||
void serial_write_str(void *ctx, const char *s);
|
||||
int serial_read_buf(void *ctx, char *buf, int len);
|
||||
int serial_get_char(void *ctx, char *p);
|
||||
int serial_peek(void *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* SERIAL_PORT_H_ */
|
||||
@ -13,12 +13,12 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "queue.h"
|
||||
#include "pinportmap.h"
|
||||
#include "task.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace ThreadCommon
|
||||
{
|
||||
|
||||
enum RotaryAction
|
||||
{
|
||||
Right,
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* pinportmap.h
|
||||
*
|
||||
* Created on: 17 Jun 2023
|
||||
* Author: dave
|
||||
*/
|
||||
|
||||
#ifndef THREADS_COMMON_PINPORTMAP_H_
|
||||
#define THREADS_COMMON_PINPORTMAP_H_
|
||||
|
||||
namespace ThreadCommon
|
||||
{
|
||||
|
||||
enum PINMAP
|
||||
{
|
||||
PIN_LCD_RS = 24,
|
||||
PIN_LCD_EN = 26,
|
||||
PIN_LCD_D4 = 27,
|
||||
PIN_LCD_D5 = 25,
|
||||
PIN_LCD_D6 = 28,
|
||||
PIN_LCD_D7 = 3,
|
||||
PIN_I2C_SCL = 4,
|
||||
PIN_I2C_SDA = 5,
|
||||
PIN_ROTARY_SIG_A = 18,
|
||||
PIN_ROTARY_SIG_B = 12,
|
||||
PIN_ROTARY_PRESS = 2,
|
||||
PIN_BOARD_SW1 = 1
|
||||
};
|
||||
|
||||
enum PORTMAP
|
||||
{
|
||||
PORT_LCD_RS = 1,
|
||||
PORT_LCD_EN = 1,
|
||||
PORT_LCD_D4 = 1,
|
||||
PORT_LCD_D5 = 1,
|
||||
PORT_LCD_D6 = 1,
|
||||
PORT_LCD_D7 = 2,
|
||||
PORT_I2C_SCL = 0,
|
||||
PORT_I2C_SDA = 0,
|
||||
PORT_ROTARY_SIG_A = 1,
|
||||
PORT_ROTARY_SIG_B = 2,
|
||||
PORT_ROTARY_PRESS = 0,
|
||||
PORT_BOARD_SW1 = 0
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* THREADS_COMMON_PINPORTMAP_H_ */
|
||||
@ -16,7 +16,7 @@ extern QueueHandle_t logging_queue;
|
||||
/* ================= Settings ================== */
|
||||
#define LOG_COLORED_OUTPUT
|
||||
#define HIGH_PRIORITY_DEBUG
|
||||
#define LOG_DEBUG_MESSAGES 0
|
||||
#define LOG_DEBUG_MESSAGES 1
|
||||
/* ================= Settings ================== */
|
||||
|
||||
// internal debug defines
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "Logging.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Temperature.h"
|
||||
#include "Network.h"
|
||||
#include "queue.h"
|
||||
|
||||
static const char* rotary_direction[] =
|
||||
@ -50,7 +51,7 @@ void Master::HandleEventType(Event* e)
|
||||
//Comes from rotary, goes to manager
|
||||
send = _qm->send<Event>(ThreadCommon::QueueManager::manager_event_master, e, 0);
|
||||
//LOG_WARNING("Timestamp: %zus, Clock: %zu, Chip freq: %zu", LPC_SCT1->COUNT_U / Chip_Clock_GetMainClockRate(), LPC_SCT1->COUNT_U, Chip_Clock_GetMainClockRate());
|
||||
if (send) LOG_INFO("Rotary: %s has been forwarded to manager", rotary_direction[rd]);
|
||||
if (send) LOG_DEBUG("Rotary: %s has been forwarded to manager", rotary_direction[rd]);
|
||||
break;
|
||||
case Event::InternalTemp:
|
||||
// TODO remove (deprecated)
|
||||
@ -136,6 +137,9 @@ void thread_master(void* pvParams) {
|
||||
manager->tm->createTask(thread_temperature, "temperature",
|
||||
configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(manager));
|
||||
manager->tm->createTask(thread_network, "network",
|
||||
configMINIMAL_STACK_SIZE * 8,tskIDLE_PRIORITY + 1UL,
|
||||
static_cast<void*>(manager));
|
||||
LOG_INFO("Master created tasks");
|
||||
m.taskFunction();
|
||||
}
|
||||
|
||||
54
source/shoh/src/threads/networking/Network.cpp
Normal file
54
source/shoh/src/threads/networking/Network.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Network.cpp
|
||||
*
|
||||
* Created on: 31 May 2023
|
||||
*/
|
||||
|
||||
#include "Network.h"
|
||||
#include "esp8266_socket.h"
|
||||
#include "Log.h"
|
||||
|
||||
#define NETWORK_DEMO 0
|
||||
|
||||
Network::Network(ThreadCommon::QueueManager* qm) : _qm(qm)
|
||||
{
|
||||
this->ssid = "SSID";
|
||||
this->password = "PASSWORD";
|
||||
this->ip = "127.0.0.1";
|
||||
}
|
||||
|
||||
Network::~Network() {}
|
||||
|
||||
void Network::taskFunction()
|
||||
{
|
||||
#if NETWORK_DEMO
|
||||
|
||||
int soc = esp_socket(this->ssid.c_str(), this->password.c_str());
|
||||
LOG_INFO("Connected to network");
|
||||
int stat = esp_connect(soc, this->ip.c_str(), 5000);
|
||||
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#if NETWORK_DEMO
|
||||
|
||||
LOG_DEBUG("ESP socket status: %d", stat);
|
||||
if(stat == 0)
|
||||
stat = esp_connect(soc, this->ip.c_str(), 5000);
|
||||
|
||||
#else
|
||||
|
||||
vTaskDelay(portMAX_DELAY);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void thread_network(void* pvParams)
|
||||
{
|
||||
ThreadCommon::CommonManagers * manager = static_cast<ThreadCommon::CommonManagers*>(pvParams);
|
||||
Network n(manager->qm);
|
||||
n.taskFunction();
|
||||
}
|
||||
29
source/shoh/src/threads/networking/Network.h
Normal file
29
source/shoh/src/threads/networking/Network.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Network.h
|
||||
*
|
||||
* Created on: 31 May 2023
|
||||
*/
|
||||
|
||||
#ifndef THREADS_NETWORKING_NETWORK_H_
|
||||
#define THREADS_NETWORKING_NETWORK_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Event.h"
|
||||
#include "ThreadCommon.h"
|
||||
|
||||
class Network {
|
||||
public:
|
||||
Network(ThreadCommon::QueueManager* qm);
|
||||
virtual ~Network();
|
||||
void taskFunction();
|
||||
private:
|
||||
ThreadCommon::QueueManager* _qm;
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
std::string ip;
|
||||
};
|
||||
|
||||
void thread_network(void* pvParams);
|
||||
|
||||
#endif /* THREADS_NETWORKING_NETWORK_H_ */
|
||||
@ -12,8 +12,6 @@
|
||||
|
||||
static QueueHandle_t * p_rotary_isr_q;
|
||||
|
||||
static DigitalIoPin * p_sigB;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void
|
||||
@ -21,17 +19,11 @@ extern "C"
|
||||
{
|
||||
Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT0_IRQn));
|
||||
portBASE_TYPE xHigherPriorityWoken = pdFALSE;
|
||||
uint8_t data;
|
||||
|
||||
if (p_sigB->read())
|
||||
data = ThreadCommon::RotaryAction::Left;
|
||||
else
|
||||
data = ThreadCommon::RotaryAction::Right;
|
||||
|
||||
uint8_t data = ThreadCommon::RotaryAction::Right;
|
||||
xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
|
||||
portEND_SWITCHING_ISR(xHigherPriorityWoken);
|
||||
}
|
||||
/*
|
||||
|
||||
void
|
||||
PIN_INT1_IRQHandler (void)
|
||||
{
|
||||
@ -41,11 +33,11 @@ extern "C"
|
||||
xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
|
||||
portEND_SWITCHING_ISR(xHigherPriorityWoken);
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
PIN_INT1_IRQHandler (void)
|
||||
PIN_INT2_IRQHandler (void)
|
||||
{
|
||||
Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT1_IRQn));
|
||||
Chip_PININT_ClearIntStatus (LPC_PININT, PININTCH (PIN_INT2_IRQn));
|
||||
portBASE_TYPE xHigherPriorityWoken = pdFALSE;
|
||||
uint8_t data = ThreadCommon::RotaryAction::Press;
|
||||
xQueueSendFromISR (*p_rotary_isr_q, &data, &xHigherPriorityWoken);
|
||||
@ -56,7 +48,6 @@ extern "C"
|
||||
Rotary::Rotary(ThreadCommon::QueueManager* qm) : _qm(qm)
|
||||
{
|
||||
LOG_DEBUG("Creating Rotary");
|
||||
p_sigB = &(this->signal[1]);
|
||||
}
|
||||
|
||||
Rotary::~Rotary()
|
||||
|
||||
@ -20,15 +20,9 @@ public:
|
||||
private:
|
||||
Event* message;
|
||||
ThreadCommon::QueueManager* _qm;
|
||||
DigitalIoPin signal[3] = { { ThreadCommon::PORT_ROTARY_SIG_A,
|
||||
ThreadCommon::PIN_ROTARY_SIG_A,
|
||||
true, true, false, true, PIN_INT0_IRQn},
|
||||
{ ThreadCommon::PORT_ROTARY_SIG_B,
|
||||
ThreadCommon::PIN_ROTARY_SIG_B,
|
||||
true, true, false},
|
||||
{ ThreadCommon::PORT_ROTARY_PRESS,
|
||||
ThreadCommon::PIN_ROTARY_PRESS,
|
||||
true, true, false, true, PIN_INT1_IRQn} };
|
||||
DigitalIoPin signal[3] = { { 1, 18, true, true, false, true, PIN_INT0_IRQn}, //SW1 //Right //0 1
|
||||
{ 2, 12, true, true, false, true, PIN_INT1_IRQn}, //SW2 //Left //0 16
|
||||
{ 2, 11, true, false, false, true, PIN_INT2_IRQn} }; //Press //1 8
|
||||
};
|
||||
|
||||
void thread_rotary(void* pvParams);
|
||||
|
||||
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* SensorTempSHT20.cpp
|
||||
*
|
||||
* Created on: 16 May 2023
|
||||
*/
|
||||
|
||||
#include "SensorTempSHT20.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "Log.h"
|
||||
|
||||
//D6U9H:
|
||||
//D - Digital (i2c)
|
||||
//6 - 2016 year of production
|
||||
//U9H - Sensirion undecodable crap
|
||||
//Address: 0x40
|
||||
|
||||
//Trigger T measurement | hold master | 1110 0011 - 0xe3 (implemented)
|
||||
//Trigger T measurement | no hold master | 1111 0011 - 0xf3
|
||||
//Write user register | | 1110 0110 - 0xe6
|
||||
//Read user register | | 1110 0111 - 0xe7
|
||||
//Soft reset | | 1111 1110 - 0xfe
|
||||
|
||||
|
||||
SensorTempSHT20::SensorTempSHT20(I2C* pi2c)
|
||||
: _pi2c(pi2c), _dev_addr(0x40), _up_flag(false),
|
||||
_com_read_hold(0xe3), _com_read_nohold(0xf3),
|
||||
_com_write_ur(0xe6), _com_read_ur(0xe7),
|
||||
_com_soft_reset(0xfe), _polynominal(0x131)
|
||||
{
|
||||
//Read sensor during the initialisation to get the "UP" state earlier.
|
||||
this->read();
|
||||
}
|
||||
|
||||
SensorTempSHT20::~SensorTempSHT20()
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Gets temperature from SHT20 sensor.
|
||||
*
|
||||
* @return int8_t temperature value trimmed from -128 to 127.
|
||||
*/
|
||||
int8_t SensorTempSHT20::getTemperature()
|
||||
{
|
||||
uint16_t raw_temp = this->read();
|
||||
bool err_bit = raw_temp & 0x1;
|
||||
int temp = 0;
|
||||
if (err_bit)
|
||||
return -128;
|
||||
|
||||
//Formula: (St / 2 ^ 16) * 175.72 - 46.85
|
||||
temp = ((double)raw_temp / 65536) * 175.72 - 46.85;
|
||||
|
||||
if(temp > 127)
|
||||
temp = 127;
|
||||
if (temp < -128)
|
||||
temp = -128;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Makes sure that the sensor is up.
|
||||
*
|
||||
* @return true It is.
|
||||
* @return false It is not.
|
||||
*/
|
||||
bool SensorTempSHT20::is_up()
|
||||
{
|
||||
this->read();
|
||||
return this->_up_flag;
|
||||
}
|
||||
|
||||
//Use hold master - read(com = 0xe3)
|
||||
//Reading is done via 3 bytes.
|
||||
//WRITE: I2C address + write | read command
|
||||
//READ: Data (MSB) | Data (LSB) + Stat. | Checksum
|
||||
/**
|
||||
* @brief Gets raw temperature measurement data from sensor
|
||||
* using hold master mode.
|
||||
*
|
||||
* @return uint16_t Raw temperature measurement data.
|
||||
*/
|
||||
uint16_t SensorTempSHT20::read()
|
||||
{
|
||||
uint8_t tbuf = this->_com_read_hold;
|
||||
uint8_t rbuf[3] = {0x0, 0x2, 0x0};
|
||||
uint8_t crc = 0x0;
|
||||
uint16_t raw_temp = 0;
|
||||
this->_up_flag = this->_pi2c->transaction(this->_dev_addr, &tbuf, 1, rbuf, 3);
|
||||
|
||||
//Sensor changes this bit to 0 on temp measurement.
|
||||
if (rbuf[1] & 0x2)
|
||||
return 0x1;
|
||||
|
||||
raw_temp |= (rbuf[0] << 8);
|
||||
raw_temp |= (rbuf[1] & 0xfc);
|
||||
crc = rbuf[2];
|
||||
|
||||
if (this->crc_check(rbuf, 2, crc))
|
||||
LOG_WARNING("Temperature sensor reported crc mismatch. Raw data: %04x; CRC: %x", raw_temp, crc);
|
||||
|
||||
return raw_temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if checksum is correct.
|
||||
*
|
||||
* @param data array of raw data to check.
|
||||
* @param nbrOfBytes size of an array.
|
||||
* @param checksum received checksum to compare calculated crc to.
|
||||
* @return true - checksum is incorrect.
|
||||
* @return false - checksum is the same as calculated.
|
||||
*/
|
||||
bool SensorTempSHT20::crc_check(uint8_t * data, uint8_t nbrOfBytes, uint8_t checksum)
|
||||
{
|
||||
uint8_t crc = 0;
|
||||
uint8_t bit;
|
||||
uint8_t byteCtr;
|
||||
//Calculates 8-Bit checksum with given _polynomial
|
||||
for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
|
||||
{
|
||||
crc ^= (data[byteCtr]);
|
||||
for ( bit = 8; bit > 0; --bit)
|
||||
crc = (crc & 0x80) ? ((crc << 1) ^ this->_polynominal) : (crc << 1);
|
||||
}
|
||||
return crc != checksum;
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* SensorTempSHT20.h
|
||||
*
|
||||
* Created on: 16 May 2023
|
||||
*/
|
||||
|
||||
#ifndef THREADS_TEMPERATURE_SENSORTEMPTC74_H_
|
||||
#define THREADS_TEMPERATURE_SENSORTEMPTC74_H_
|
||||
|
||||
#include "I2C.h"
|
||||
#include "chip.h"
|
||||
|
||||
class SensorTempSHT20 {
|
||||
public:
|
||||
SensorTempSHT20(I2C* pi2c);
|
||||
virtual ~SensorTempSHT20();
|
||||
int8_t getTemperature();
|
||||
bool is_up();
|
||||
private:
|
||||
uint16_t read();
|
||||
bool crc_check(uint8_t * data, uint8_t nbrOfBytes, uint8_t checksum);
|
||||
|
||||
I2C* _pi2c;
|
||||
const uint8_t _dev_addr;
|
||||
bool _up_flag;
|
||||
const uint8_t _com_read_hold;
|
||||
const uint8_t _com_read_nohold;
|
||||
const uint8_t _com_write_ur; //user register
|
||||
const uint8_t _com_read_ur; //user register
|
||||
const uint8_t _com_soft_reset;
|
||||
const uint16_t _polynominal;
|
||||
};
|
||||
|
||||
#endif /* THREADS_TEMPERATURE_SENSORTEMPSHT20_H_ */
|
||||
@ -5,8 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Temperature.h"
|
||||
//#include "SensorTempTC74.h"
|
||||
#include "SensorTempSHT20.h"
|
||||
#include "SensorTempTC74.h"
|
||||
#include "Event.h"
|
||||
#include "Log.h"
|
||||
|
||||
@ -16,11 +15,10 @@ Temperature::~Temperature() {}
|
||||
|
||||
void Temperature::taskFunction()
|
||||
{
|
||||
//SensorTempTC74 ext_temp_sensor(this->_pi2c, 0x4a);
|
||||
SensorTempSHT20 ext_temp_sensor(this->_pi2c);
|
||||
SensorTempTC74 ext_temp_sensor(this->_pi2c, 0x4a);
|
||||
Event t (Event::ExternalTemp, -128);
|
||||
int8_t temp_value = -128;
|
||||
while(ext_temp_sensor.is_up() != true);
|
||||
_qm->send<Event>(ThreadCommon::QueueManager::master_event_all, &t, 0);
|
||||
for (;;)
|
||||
{
|
||||
if (ext_temp_sensor.is_up())
|
||||
@ -29,7 +27,6 @@ void Temperature::taskFunction()
|
||||
if(temp_value == -128)
|
||||
{
|
||||
LOG_ERROR("Failed to get temperature.");
|
||||
vTaskDelay(10000);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -43,7 +40,7 @@ void Temperature::taskFunction()
|
||||
void thread_temperature(void* pvParams)
|
||||
{
|
||||
ThreadCommon::CommonManagers * manager = static_cast<ThreadCommon::CommonManagers*>(pvParams);
|
||||
I2C_config conf{0, 100000};
|
||||
I2C_config conf{0x4a, 100000};
|
||||
I2C i2c(conf);
|
||||
Temperature t(manager->qm, &i2c);
|
||||
t.taskFunction();
|
||||
|
||||
@ -75,18 +75,12 @@ void UserInterface::handleLCD(LiquidCrystal *lcd, const char *str)
|
||||
|
||||
void UserInterface::initLCD1()
|
||||
{
|
||||
this->lcd1_rs = new DigitalIoPin(ThreadCommon::PORT_LCD_RS,
|
||||
ThreadCommon::PIN_LCD_RS, false);//(1, 18, false);
|
||||
this->lcd1_en = new DigitalIoPin(ThreadCommon::PORT_LCD_EN,
|
||||
ThreadCommon::PIN_LCD_EN, false);//(1, 24, false);
|
||||
this->lcd1_d4 = new DigitalIoPin(ThreadCommon::PORT_LCD_D4,
|
||||
ThreadCommon::PIN_LCD_D4, false);//(1, 19, false);
|
||||
this->lcd1_d5 = new DigitalIoPin(ThreadCommon::PORT_LCD_D5,
|
||||
ThreadCommon::PIN_LCD_D5, false);//(1, 26, false);
|
||||
this->lcd1_d6 = new DigitalIoPin(ThreadCommon::PORT_LCD_D6,
|
||||
ThreadCommon::PIN_LCD_D6, false);//(1, 27, false);
|
||||
this->lcd1_d7 = new DigitalIoPin(ThreadCommon::PORT_LCD_D7,
|
||||
ThreadCommon::PIN_LCD_D7, false);//(1, 25, false);
|
||||
this->lcd1_rs = new DigitalIoPin(1, 24, false);//(1, 18, false);
|
||||
this->lcd1_en = new DigitalIoPin(1, 26, false);//(1, 24, false);
|
||||
this->lcd1_d4 = new DigitalIoPin(1, 27, false);//(1, 19, false);
|
||||
this->lcd1_d5 = new DigitalIoPin(1, 25, false);//(1, 26, false);
|
||||
this->lcd1_d6 = new DigitalIoPin(1, 28, false);//(1, 27, false);
|
||||
this->lcd1_d7 = new DigitalIoPin(2, 3, false);//(1, 25, false);
|
||||
|
||||
this->lcd1_rs->write(false);
|
||||
this->lcd1_en->write(false);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user