mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
add template for main screen and buttons, need menu etc
This commit is contained in:
parent
e63b29435c
commit
e6dc55764b
@ -359,6 +359,6 @@ int BMP280_getdata(float *T, float *P, float *H){
|
||||
|
||||
// dewpoint calculation (T in degrC, H in percents)
|
||||
float Tdew(float T, float H){
|
||||
float gamma = 17.27f * T / (237.7f + T) + log(H/100.f);
|
||||
float gamma = 17.27f * T / (237.7f + T) + logf(H/100.f);
|
||||
return (237.7f * gamma)/(17.27 - gamma);
|
||||
}
|
||||
|
||||
90
F3:F303/NitrogenFlooding/buttons.c
Normal file
90
F3:F303/NitrogenFlooding/buttons.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the nitrogen project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "buttons.h"
|
||||
#include "hardware.h"
|
||||
|
||||
typedef struct{
|
||||
keyevent event; // current key event
|
||||
int16_t counter; // press/release counter
|
||||
uint32_t lastTms; // time of last event change
|
||||
} keybase;
|
||||
|
||||
static keybase allkeys[BTNSNO] = {0}; // array for buttons' states
|
||||
|
||||
uint32_t lastUnsleep = 0; // last keys activity time
|
||||
|
||||
void process_keys(){
|
||||
static uint32_t lastT = 0;
|
||||
if(Tms == lastT) return;
|
||||
uint16_t d = (uint16_t)(Tms - lastT);
|
||||
lastT = Tms;
|
||||
for(int i = 0; i < BTNSNO; ++i){
|
||||
keybase *k = &allkeys[i];
|
||||
keyevent e = k->event;
|
||||
if(BTN_state(i)){ // key is in pressed state
|
||||
switch(e){
|
||||
case EVT_NONE: // just pressed
|
||||
case EVT_RELEASE:
|
||||
if((k->counter += d) > PRESSTHRESHOLD){
|
||||
k->event = EVT_PRESS;
|
||||
}
|
||||
break;
|
||||
case EVT_PRESS: // hold
|
||||
if((k->counter += d)> HOLDTHRESHOLD){
|
||||
k->event = EVT_HOLD;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else{ // released
|
||||
if(e == EVT_PRESS || e == EVT_HOLD){ // released
|
||||
if(k->counter > PRESSTHRESHOLD) k->counter = PRESSTHRESHOLD;
|
||||
else if((k->counter -= d) < 0){
|
||||
k->event = EVT_RELEASE; // button released
|
||||
}
|
||||
}
|
||||
}
|
||||
if(e != k->event){
|
||||
k->lastTms = Tms;
|
||||
lastUnsleep = Tms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief keystate - curent key state
|
||||
* @param k - key number
|
||||
* @param T - last event changing time
|
||||
* @return key event
|
||||
*/
|
||||
keyevent keystate(uint8_t k, uint32_t *T){
|
||||
if(k >= BTNSNO) return EVT_NONE;
|
||||
keyevent evt = allkeys[k].event;
|
||||
// change state `release` to `none` after 1st check
|
||||
if(evt == EVT_RELEASE) allkeys[k].event = EVT_NONE;
|
||||
if(T) *T = allkeys[k].lastTms;
|
||||
return evt;
|
||||
}
|
||||
|
||||
// getter of keyevent for allkeys[]
|
||||
keyevent keyevt(uint8_t k){
|
||||
if(k >= BTNSNO) return EVT_NONE;
|
||||
return allkeys[k].event;
|
||||
}
|
||||
40
F3:F303/NitrogenFlooding/buttons.h
Normal file
40
F3:F303/NitrogenFlooding/buttons.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the nitrogen project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stm32f3.h>
|
||||
|
||||
// threshold in ms for press/hold
|
||||
#define PRESSTHRESHOLD (9)
|
||||
#define HOLDTHRESHOLD (199)
|
||||
|
||||
// events
|
||||
typedef enum{
|
||||
EVT_NONE, // no events with given key
|
||||
EVT_PRESS, // pressed (hold more than PRESSTHRESHOLD ms)
|
||||
EVT_HOLD, // hold more than HOLDTHRESHOLD ms
|
||||
EVT_RELEASE // released after press or hold state
|
||||
} keyevent;
|
||||
|
||||
extern uint32_t lastUnsleep; // last keys activity time
|
||||
|
||||
void process_keys();
|
||||
keyevent keystate(uint8_t k, uint32_t *T);
|
||||
keyevent keyevt(uint8_t k);
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
|
||||
int LEDsON = 1;
|
||||
int LEDsON = 0;
|
||||
|
||||
// setup here ALL GPIO pins (due to table in Readme.md)
|
||||
// leave SWD as default AF; high speed for CLK and some other AF; med speed for some another AF
|
||||
@ -161,7 +161,7 @@ void setPWM(int nch, uint16_t val){
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getPWM(int nch){
|
||||
uint16_t getPWM(int nch){
|
||||
switch(nch){
|
||||
case 0:
|
||||
return TIM3->CCR1;
|
||||
|
||||
@ -48,16 +48,18 @@
|
||||
#define LED_off(x) do{pin_set(LEDs_port, 1<<(8+x));}while(0)
|
||||
#define LED_on(x) do{if(LEDsON) pin_clear(LEDs_port, 1<<(8+x));}while(0)
|
||||
#define LED_get(x) (LEDs_port->IDR & 1<<(8+x) ? 0 : 1)
|
||||
#define LEDS_OFF() do{LEDsON = 0; for(int _ = 0; _ < 4; ++_) LED_off(_);}while(0)
|
||||
#define LEDS_ON() do{LEDsON = 1;}while(0)
|
||||
|
||||
// screen LEDon/off - PB12; reset - PB11; data/command - PB10
|
||||
#define SCRN_LED_pin (1<<12)
|
||||
#define SCRN_LED_port (GPIOB)
|
||||
#define SCRN_LED_set(a) do{if(a) pin_set(SCRN_LED_port, SCRN_LED_pin); else pin_clear(SCRN_LED_port, SCRN_LED_pin);}while(0)
|
||||
#define SCRN_LED_get() (SCRN_LED_port->IDR & SCRN_LED_pin ? 1: 0)
|
||||
#define SCRN_RST_pin (1<<11)
|
||||
#define SCRN_RST_port (GPIOB)
|
||||
#define SCRN_RST_set(a) do{if(a) pin_set(SCRN_RST_port, SCRN_RST_pin); else pin_clear(SCRN_RST_port, SCRN_RST_pin);}while(0)
|
||||
#define SCRN_RST_get() (SCRN_RST_port->IDR & SCRN_RST_pin ? 1: 0)
|
||||
#define SCRN_CS_pin (1<<11)
|
||||
#define SCRN_CS_port (GPIOB)
|
||||
#define SCRN_CS_set(a) do{if(a) pin_set(SCRN_CS_port, SCRN_CS_pin); else pin_clear(SCRN_CS_port, SCRN_CS_pin);}while(0)
|
||||
#define SCRN_CS_get() (SCRN_CS_port->IDR & SCRN_CS_pin ? 1: 0)
|
||||
#define SCRN_DCX_pin (1<<10)
|
||||
#define SCRN_DCX_port (GPIOB)
|
||||
#define SCRN_DCX_get() (SCRN_DCX_port->IDR & SCRN_DCX_pin ? 1: 0)
|
||||
@ -77,6 +79,10 @@
|
||||
#define BTN6_pin (1<<15)
|
||||
// state 0 - pressed, 1 - released
|
||||
#define BTN_state(x) (BTNs_port->IDR & 1<<(9+x) ? 0 : 1)
|
||||
// timeout to turn off screen and LEDs after no keys activity - 300 seconds
|
||||
#define BTN_ACTIVITY_TIMEOUT (300000)
|
||||
// refresh interval for BME280 and other data - 2.5s
|
||||
#define SENSORS_DATA_TIMEOUT (2500)
|
||||
|
||||
// buzzer, ADC voltage
|
||||
#define BUZZER_port GPIOB
|
||||
@ -96,4 +102,4 @@ uint8_t MSB(uint16_t val);
|
||||
void hw_setup();
|
||||
|
||||
void setPWM(int nch, uint16_t val);
|
||||
uint8_t getPWM(int nch);
|
||||
uint16_t getPWM(int nch);
|
||||
|
||||
@ -79,6 +79,22 @@ int ili9341_init(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// turn screen ON of OFF
|
||||
int ili9341_on(){
|
||||
SCRN_LED_set(1);
|
||||
if(!ili9341_writecmd(ILI9341_SLPOUT)) return 0;
|
||||
if(!ili9341_writecmd(ILI9341_NORON)) return 0;
|
||||
if(!ili9341_writecmd(ILI9341_DISPON)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ili9341_off(){
|
||||
SCRN_LED_set(0);
|
||||
if(!ili9341_writecmd(ILI9341_SLPIN)) return 0;
|
||||
if(!ili9341_writecmd(ILI9341_DISPOFF)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief il9341_readreg - read data from register
|
||||
* @param reg - register
|
||||
@ -88,7 +104,7 @@ int ili9341_init(){
|
||||
*/
|
||||
int ili9341_readreg(uint8_t reg, uint8_t *data, uint32_t N){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(®, 1)) break;
|
||||
@ -99,7 +115,7 @@ int ili9341_readreg(uint8_t reg, uint8_t *data, uint32_t N){
|
||||
r = 1;
|
||||
}while(0);
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -112,7 +128,7 @@ int ili9341_readreg(uint8_t reg, uint8_t *data, uint32_t N){
|
||||
*/
|
||||
int ili9341_writereg(uint8_t reg, const uint8_t *data, uint32_t N){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(®, 1)) break;
|
||||
@ -123,14 +139,14 @@ int ili9341_writereg(uint8_t reg, const uint8_t *data, uint32_t N){
|
||||
r = 1;
|
||||
}while(0);
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
// write register with uint16_t data (swap bytes)
|
||||
int ili9341_writereg16(uint8_t reg, const uint16_t data){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(®, 1)) break;
|
||||
@ -142,13 +158,13 @@ int ili9341_writereg16(uint8_t reg, const uint16_t data){
|
||||
r = 1;
|
||||
}while(0);
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
int ili9341_writereg32(uint8_t reg, uint16_t data1, uint16_t data2){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(®, 1)) break;
|
||||
@ -162,21 +178,21 @@ int ili9341_writereg32(uint8_t reg, uint16_t data1, uint16_t data2){
|
||||
r = 1;
|
||||
}while(0);
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
// write simple command
|
||||
int ili9341_writecmd(uint8_t cmd){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(&cmd, 1)) break;
|
||||
if(!spi_waitbsy()) break;
|
||||
r = 1;
|
||||
}while(0);
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -185,7 +201,7 @@ static int dmardwr(uint8_t *out, uint8_t *in, uint32_t N){
|
||||
if(!out || !N) return 0;
|
||||
if(in) bzero(out, N);
|
||||
SCRN_Data();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
uint32_t r = 0;
|
||||
do{
|
||||
if(!spi_write_dma((const uint8_t*)out, in, N)) break;
|
||||
@ -197,7 +213,7 @@ static int dmardwr(uint8_t *out, uint8_t *in, uint32_t N){
|
||||
else r = 1;
|
||||
}while(0);
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(1);
|
||||
SCRN_CS_set(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -214,7 +230,7 @@ int ili9341_readdata(uint8_t *data, uint32_t N){
|
||||
|
||||
int ili9341_readregdma(uint8_t reg, uint8_t *data, uint32_t N){
|
||||
SCRN_Command();
|
||||
SCRN_RST_set(0);
|
||||
SCRN_CS_set(0);
|
||||
int r = 0;
|
||||
do{
|
||||
if(!spi_write(®, 1)) break;
|
||||
|
||||
@ -173,6 +173,8 @@
|
||||
extern uint16_t colorbuf[];
|
||||
|
||||
int ili9341_init();
|
||||
int ili9341_on();
|
||||
int ili9341_off();
|
||||
int ili9341_readreg(uint8_t reg, uint8_t *data, uint32_t N);
|
||||
int ili9341_writereg(uint8_t reg, const uint8_t *data, uint32_t N);
|
||||
int ili9341_writereg16(uint8_t reg, uint16_t data);
|
||||
|
||||
32
F3:F303/NitrogenFlooding/incication.h
Normal file
32
F3:F303/NitrogenFlooding/incication.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the nitrogen project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// temporary defines - should be stored in settings
|
||||
// temperature (degC) limits
|
||||
#define T_MIN (-20.f)
|
||||
#define T_MAX (40.f)
|
||||
// pressure (Pa) limit
|
||||
#define P_MAX (120e3f)
|
||||
// humidity limit
|
||||
#define H_MAX (90.f)
|
||||
// minimal difference above dew point
|
||||
#define DEW_MIN (3.f)
|
||||
|
||||
void indication_process();
|
||||
188
F3:F303/NitrogenFlooding/indication.c
Normal file
188
F3:F303/NitrogenFlooding/indication.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* This file is part of the nitrogen project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BMP280.h"
|
||||
#include "buttons.h"
|
||||
#include "hardware.h"
|
||||
#include "ili9341.h"
|
||||
#include "incication.h"
|
||||
#include "screen.h"
|
||||
#include "strfunc.h"
|
||||
#include "usb.h"
|
||||
|
||||
/*
|
||||
* LEDs:
|
||||
* 0 - blinks all the time
|
||||
* 1 - PWM2 state (blinks as longer as PWM larger)
|
||||
* 2 - PWM3 state (-//-)
|
||||
* 3 - ?
|
||||
*/
|
||||
// next state change time
|
||||
static uint32_t ledT[LEDS_AMOUNT] = {0};
|
||||
// arrays of high and low states' length
|
||||
static uint32_t ledH[LEDS_AMOUNT] = {199, 0, 0, 0};
|
||||
static uint32_t ledL[LEDS_AMOUNT] = {799, 1, 1, 1};
|
||||
|
||||
// led blinking
|
||||
TRUE_INLINE void leds_proc(){
|
||||
uint32_t v = getPWM(2);
|
||||
ledH[1] = v*5; ledL[1] = (PWM_CCR_MAX - v) * 5;
|
||||
v = getPWM(3);
|
||||
ledH[2] = v*5; ledL[2] = (PWM_CCR_MAX - v) * 5;
|
||||
for(int i = 0; i < LEDS_AMOUNT; ++i){
|
||||
int state = LED_get(i);
|
||||
if(state){ // shining
|
||||
if(ledH[i] == 0) LED_off(i); // don't turn it on
|
||||
else if(ledL[i] && Tms > ledT[i]){
|
||||
LED_off(i);
|
||||
ledT[i] = Tms + ledL[i];
|
||||
}
|
||||
}else{
|
||||
if(ledL[i] == 0) LED_on(i); // don't turn it off
|
||||
else if(ledH[i] && Tms > ledT[i]){
|
||||
LED_on(i);
|
||||
ledT[i] = Tms + ledH[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display state: main window or menu
|
||||
typedef enum{
|
||||
DISP_MAINWIN,
|
||||
DISP_MENU
|
||||
} display_state;
|
||||
|
||||
static display_state dispstate = DISP_MAINWIN;
|
||||
static uint32_t lastTmeas = 0; // last measurement time
|
||||
|
||||
static void cls(){ // set default colors (bg=0, fg=0xffff) and clear screen
|
||||
setBGcolor(0);
|
||||
setFGcolor(0xffff);
|
||||
ClearScreen();
|
||||
}
|
||||
|
||||
static void refresh_mainwin(){ // ask all parameters and refresh main window with new values
|
||||
DBG("REFRESH main window");
|
||||
cls();
|
||||
float T, P, H;
|
||||
BMP280_status s = BMP280_get_status();
|
||||
if(s == BMP280_NOTINIT || s == BMP280_ERR) BMP280_init();
|
||||
SetFontScale(1); // small menu items labels
|
||||
setBGcolor(COLOR_BLACK); setFGcolor(COLOR_LIGHTGREEN);
|
||||
PutStringAt(4, 16, "Temperature Pressure Humidity Dew point");
|
||||
int y = 37;
|
||||
uint16_t fgcolor;
|
||||
if(s == BMP280_RDY && BMP280_getdata(&T, &P, &H)){ // show data
|
||||
if(T < T_MIN || T > T_MAX) fgcolor = COLOR_RED;
|
||||
else if(T < 0) fgcolor = COLOR_BLUE;
|
||||
else fgcolor = COLOR_GREEN;
|
||||
setFGcolor(fgcolor); PutStringAt(32, y, float2str(T, 2));
|
||||
if(P > P_MAX) fgcolor = COLOR_RED;
|
||||
else fgcolor = COLOR_YELLOW;
|
||||
setFGcolor(fgcolor); PutStringAt(112, y, float2str(P, 1));
|
||||
if(H > H_MAX) fgcolor = COLOR_RED;
|
||||
else fgcolor = COLOR_CHOCOLATE;
|
||||
setFGcolor(fgcolor); PutStringAt(192, y, float2str(H, 1));
|
||||
float dew = Tdew(T, H);
|
||||
if(T - dew < DEW_MIN) fgcolor = COLOR_RED;
|
||||
else fgcolor = COLOR_LIGHTBLUE;
|
||||
setFGcolor(fgcolor); PutStringAt(248, y, float2str(dew, 1));
|
||||
#ifdef EBUG
|
||||
USB_sendstr("T="); USB_sendstr(float2str(T, 2)); USB_sendstr("\nP=");
|
||||
USB_sendstr(float2str(P, 1));
|
||||
P *= 0.00750062f; USB_sendstr("\nPmm="); USB_sendstr(float2str(P, 1));
|
||||
USB_sendstr("\nH="); USB_sendstr(float2str(H, 1));
|
||||
USB_sendstr("\nTdew="); USB_sendstr(float2str(dew, 1));
|
||||
newline();
|
||||
#endif
|
||||
}else{ // show "errr"
|
||||
setBGcolor(COLOR_RED); setFGcolor(COLOR_CYAN);
|
||||
CenterStringAt(y, "No signal");
|
||||
}
|
||||
// display all other data
|
||||
SetFontScale(3);
|
||||
// TODO: show current level
|
||||
setFGcolor(COLOR_RED); CenterStringAt(130, "Level: NULL");
|
||||
if(getPWM(2) || getPWM(3)){
|
||||
setFGcolor(COLOR_GREEN);
|
||||
CenterStringAt(220, "Processing");
|
||||
}
|
||||
UpdateScreen(0, SCRNH-1);
|
||||
if(!BMP280_start()) BMP280_init(); // start new measurement
|
||||
}
|
||||
|
||||
static void refresh_menu(){ // refresh menu with changed selection
|
||||
DBG("REFRESH menu");
|
||||
cls();
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom keys:
|
||||
* 0 - main screen
|
||||
* 1 - up
|
||||
* 2 - down
|
||||
* 3 - select/menu
|
||||
*/
|
||||
TRUE_INLINE void btns_proc(){
|
||||
uint8_t evtmask = 0; // bitmask for active buttons (==1)
|
||||
for(int i = 0; i < BTNSNO; ++i){
|
||||
keyevent evt = keystate(i, NULL); // T may be used for doubleclick detection
|
||||
if(evt == EVT_PRESS || evt == EVT_HOLD) evtmask |= 1<<i;
|
||||
}
|
||||
// now check all buttons
|
||||
if(evtmask & 1<<0){ // escape to main window or force refresh
|
||||
if(dispstate == DISP_MENU){
|
||||
dispstate = DISP_MAINWIN;
|
||||
}
|
||||
lastTmeas = Tms - SENSORS_DATA_TIMEOUT*2; // force refresh
|
||||
}
|
||||
if(dispstate == DISP_MENU){ // buttons 'up'/'down' works only in menu mode
|
||||
if(evtmask & 1<<1){ // up
|
||||
;
|
||||
}
|
||||
if(evtmask & 1<<2){ // down
|
||||
;
|
||||
}
|
||||
}
|
||||
if(evtmask & 1<<3){ // select/menu
|
||||
if(dispstate == DISP_MAINWIN){ // switch to menu mode
|
||||
dispstate = DISP_MENU;
|
||||
refresh_menu();
|
||||
}else{ // select
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void indication_process(){
|
||||
if(!LEDsON) return;
|
||||
leds_proc();
|
||||
btns_proc();
|
||||
switch(dispstate){
|
||||
case DISP_MAINWIN:
|
||||
if(Tms - lastTmeas > SENSORS_DATA_TIMEOUT){
|
||||
refresh_mainwin();
|
||||
lastTmeas = Tms;
|
||||
}
|
||||
break;
|
||||
case DISP_MENU: // do nothing
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -18,11 +18,13 @@
|
||||
|
||||
#include "adc.h"
|
||||
#include "BMP280.h"
|
||||
//#include "buttons.h"
|
||||
#include "buttons.h"
|
||||
//#include "can.h"
|
||||
//#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "i2c.h"
|
||||
#include "ili9341.h"
|
||||
#include "incication.h"
|
||||
#include "proto.h"
|
||||
#include "screen.h"
|
||||
#include "strfunc.h"
|
||||
@ -54,14 +56,9 @@ int main(void){
|
||||
adc_setup();
|
||||
BMP280_setup(0);
|
||||
USBPU_ON();
|
||||
uint32_t ctr = 0;
|
||||
// CAN_message *can_mesg;
|
||||
while(1){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(Tms - ctr > 499){
|
||||
ctr = Tms;
|
||||
LED_blink(0);
|
||||
}
|
||||
/*CAN_proc();
|
||||
if(CAN_get_status() == CAN_FIFO_OVERRUN){
|
||||
USB_sendstr("CAN bus fifo overrun occured!\n");
|
||||
@ -94,21 +91,6 @@ int main(void){
|
||||
}
|
||||
//i2c_have_DMA_Rx(); // check if there's DMA Rx complete
|
||||
BMP280_process();
|
||||
BMP280_status s = BMP280_get_status();
|
||||
if(s == BMP280_RDY){ // data ready - get it
|
||||
float T, P, H;
|
||||
if(BMP280_getdata(&T, &P, &H)){
|
||||
USB_sendstr("T="); USB_sendstr(float2str(T, 2)); USB_sendstr("\nP=");
|
||||
USB_sendstr(float2str(P, 1));
|
||||
P *= 0.00750062f; USB_sendstr("\nPmm="); USB_sendstr(float2str(P, 1));
|
||||
USB_sendstr("\nH="); USB_sendstr(float2str(H, 1));
|
||||
USB_sendstr("\nTdew="); USB_sendstr(float2str(Tdew(T, H), 1));
|
||||
newline();
|
||||
}else USB_sendstr("Can't read data\n");
|
||||
}else if(s == BMP280_ERR){
|
||||
USB_sendstr("BME280 error\n");
|
||||
BMP280_init();
|
||||
}
|
||||
int l = USB_receivestr(inbuff, MAXSTRLEN);
|
||||
if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n");
|
||||
else if(l){
|
||||
@ -116,6 +98,20 @@ int main(void){
|
||||
if(ans) USB_sendstr(ans);
|
||||
}
|
||||
process_screen();
|
||||
//process_keys();
|
||||
process_keys();
|
||||
// turn off screen and LEDs if no keys was pressed last X ms
|
||||
if(LEDsON){
|
||||
if(Tms - lastUnsleep > BTN_ACTIVITY_TIMEOUT){ // timeout - turn off LEDs and screen
|
||||
LEDS_OFF();
|
||||
ili9341_off();
|
||||
}else{ // check operation buttons for menu etc
|
||||
indication_process();
|
||||
}
|
||||
}else{
|
||||
if(Tms - lastUnsleep < BTN_ACTIVITY_TIMEOUT/2){ // recent activity - turn on indication
|
||||
LEDS_ON();
|
||||
ili9341_on();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -24,6 +24,8 @@ i2c.c
|
||||
i2c.h
|
||||
ili9341.c
|
||||
ili9341.h
|
||||
incication.h
|
||||
indication.c
|
||||
main.c
|
||||
pdnuart.c
|
||||
pdnuart.h
|
||||
|
||||
|
Before Width: | Height: | Size: 457 B After Width: | Height: | Size: 483 B |
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "adc.h"
|
||||
#include "buttons.h"
|
||||
#include "BMP280.h"
|
||||
#include "hardware.h"
|
||||
#include "i2c.h"
|
||||
@ -70,8 +71,8 @@ static void sendkeyuhex(const char *cmd, int parno, uint32_t u){
|
||||
static int leds(const char *cmd, int parno, const char *c, int32_t i){
|
||||
if(parno < 0){ // enable/disable all
|
||||
if(c){
|
||||
LEDsON = (i ? 1 : 0);
|
||||
if(!LEDsON) for(int _ = 0; _ < 4; ++_) LED_off(_);
|
||||
if(i) LEDS_ON();
|
||||
else LEDS_OFF();
|
||||
}
|
||||
sendkey("LEDon", -1, LEDsON);
|
||||
}else{
|
||||
@ -212,12 +213,12 @@ static int scrndcr(const char *cmd, int _U_ parno, const char *c, int32_t i){
|
||||
}
|
||||
sendkeyu(cmd, -1, SCRN_DCX_get());
|
||||
return RET_GOOD;
|
||||
}
|
||||
}/*
|
||||
static int scrnrst(const char *cmd, int _U_ parno, const char *c, int32_t i){
|
||||
if(c) SCRN_RST_set(i);
|
||||
sendkeyu(cmd, -1, SCRN_RST_get());
|
||||
if(c) SCRN_CS_set(i);
|
||||
sendkeyu(cmd, -1, SCRN_CS_get());
|
||||
return RET_GOOD;
|
||||
}
|
||||
}*/
|
||||
static int scrnrdwr(const char *cmd, int parno, const char *c, int32_t i){
|
||||
if(parno < 0 || parno > 255) return RET_WRONGPARNO;
|
||||
if(c){
|
||||
@ -271,7 +272,13 @@ static int scrninit(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32
|
||||
USB_sendstr(OK);
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
static int scrnonoff(const char _U_ *cmd, int _U_ parno, const char *c, int32_t i){
|
||||
if(!c) return RET_WRONGARG;
|
||||
int r = (i) ? ili9341_on() : ili9341_off();
|
||||
if(!r) return RET_BAD;
|
||||
sendkeyu(cmd, -1, i);
|
||||
return RET_GOOD;
|
||||
}
|
||||
static int scrnfill(const char *cmd, int parno, const char *c, int32_t i){
|
||||
if(parno < 0) parno = RGB(0xf, 0x1f, 0xf);
|
||||
if(parno > 0xffff) return RET_WRONGPARNO;
|
||||
@ -332,6 +339,12 @@ static int scls(const char *cmd, int parno, const char *c, int32_t i){
|
||||
sendkeyuhex(cmd, parno, i);
|
||||
return RET_GOOD;
|
||||
}
|
||||
static int srefr(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t _U_ i){
|
||||
UpdateScreen(0, SCRNH-1);
|
||||
USB_sendstr(OK);
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
static int scolor(const char *cmd, int parno, const char *c, int32_t i){
|
||||
// fg=bg, default: fg=0xffff, bg=0
|
||||
if(parno < 0 || parno > 0xffff) parno = 0xffff;
|
||||
@ -381,6 +394,16 @@ static int sfscale(const char *cmd, int _U_ parno, const char _U_ *c, int32_t i)
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
static int buttons(const char *cmd, int parno, const char _U_ *c, int32_t _U_ i){
|
||||
if(parno < 0 || parno >= BTNSNO) return RET_WRONGPARNO;
|
||||
uint32_t T;
|
||||
keyevent evt = keystate((uint8_t)parno, &T);
|
||||
sendkeyu(cmd, parno, evt);
|
||||
if(evt != EVT_NONE){
|
||||
USB_sendstr("Tevent="); USB_sendstr(u2str(T)); newline();
|
||||
}
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
int (*fn)(const char*, int, const char*, int32_t);
|
||||
@ -393,8 +416,9 @@ commands cmdlist[] = {
|
||||
{NULL, "Different commands", NULL},
|
||||
{bme, "BME", "get pressure, temperature and humidity"},
|
||||
{bmefilter, "BMEf", "set filter (0..4)"},
|
||||
{buttons, "button", "get buttonx state"},
|
||||
{buzzer, "buzzer", "get/set (0 - off, 1 - on) buzzer"},
|
||||
{leds, "LED", "LEDx=y; where x=0..3 to work with single LED (then y=1-set, 0-reset, 2-toggle), absent to work with all (y=0 - disable, 1-enable)"},
|
||||
{leds, "LED", "LEDx=y; where x=0..3 to work with single LED (then y=1-set, 0-reset, 2-toggle), absent to set LEDsON (y=0 - disable, 1-enable)"},
|
||||
{pwm, "pwm", "set/get x channel (0..3) pwm value (0..100)"},
|
||||
{reset, "reset", "reset MCU"},
|
||||
{tms, "tms", "print Tms"},
|
||||
@ -406,7 +430,7 @@ commands cmdlist[] = {
|
||||
{NULL, "Screen commands", NULL},
|
||||
{scrnled, "Sled", "turn on/off screen lights"},
|
||||
{scrndcr, "Sdcr", "set data(1)/command(0)"},
|
||||
{scrnrst, "Srst", "reset (1/0)"},
|
||||
// {scrnrst, "Srst", "reset (1/0)"},
|
||||
{scrnrdwr, "Sreg", "read/write 8-bit register"},
|
||||
{scrnrdwr4, "Sregx", "read/write 32-bit register"},
|
||||
{scrnrdn, "Sregn", "read from register x =n bytes"},
|
||||
@ -415,12 +439,14 @@ commands cmdlist[] = {
|
||||
{scrndata4, "Sdatn", "write x bytes of =data"},
|
||||
{sread, "Sread", "read "},
|
||||
{scrninit, "Sini", "init screen"},
|
||||
{scrnonoff, "Spower", "=0 - off, =1 - on"},
|
||||
{scrnfill, "Sfill", "fill screen with color (=npix)"},
|
||||
{scrnfilln, "Sfilln", "fill screen (next) with color (=npix)"},
|
||||
{smadctl, "Smad", "change MADCTL"},
|
||||
{scol, "Scol", "set column limits (low=high)"},
|
||||
{srow, "Srow", "set row limits (low=high)"},
|
||||
{scls, "Scls", "clear screen fg=bg"},
|
||||
{srefr, "Srefresh", "refresh full screen"},
|
||||
{scolor, "Scolor", "seg color fg=bg"},
|
||||
{sputstr, "Sstr", "put string y=string"},
|
||||
{sstate, "Sstate", "current screen state"},
|
||||
|
||||
@ -90,7 +90,6 @@ void ClearScreen(){
|
||||
foreground[i] = fgColor;
|
||||
background[i] = bgColor;
|
||||
}
|
||||
for(int i = SPRITE_SZ-40; i < SPRITE_SZ; ++i) foreground[i] = i;
|
||||
UpdateScreen(0, SCRNH-1);
|
||||
}
|
||||
|
||||
@ -199,7 +198,7 @@ int strpixlen(const char *str){
|
||||
const uint8_t *c = font_char(*str++);
|
||||
if(c) l += *c;
|
||||
}
|
||||
return l;
|
||||
return l * fontscale;
|
||||
}
|
||||
|
||||
// convert buffer to update (return 0 if all sent)
|
||||
|
||||
@ -42,6 +42,52 @@ typedef enum{ // screen states
|
||||
// maximal font scale
|
||||
#define FONTSCALEMAX (10)
|
||||
|
||||
// some base colors
|
||||
#define COLOR_BLACK 0x0000
|
||||
#define COLOR_BLUE 0x001F
|
||||
#define COLOR_BROWN 0xA145
|
||||
#define COLOR_CHOCOLATE 0xD343
|
||||
#define COLOR_CYAN 0x07FF
|
||||
#define COLOR_DARKBLUE 0x0011
|
||||
#define COLOR_DARKCYAN 0x03EF
|
||||
#define COLOR_DARKGRAY 0x8410
|
||||
#define COLOR_DARKGREEN 0x03E0
|
||||
#define COLOR_DARKMAGENTA 0x8811
|
||||
#define COLOR_DARKORANGE 0xFC60
|
||||
#define COLOR_DARKRED 0x8800
|
||||
#define COLOR_DARKVIOLET 0x901A
|
||||
#define COLOR_DEEPPINK 0xF8B2
|
||||
#define COLOR_GOLD 0xFEA0
|
||||
#define COLOR_GRAY 0xAD55
|
||||
#define COLOR_GREEN 0x07E0
|
||||
#define COLOR_GREENYELLOW 0xAFE5
|
||||
#define COLOR_INDIGO 0x4810
|
||||
#define COLOR_KHAKI 0xF731
|
||||
#define COLOR_LIGHTBLUE 0xAEDC
|
||||
#define COLOR_LIGHTCYAN 0xE7FF
|
||||
#define COLOR_LIGHTGREEN 0x9772
|
||||
#define COLOR_LIGHTGRAY 0xC618
|
||||
#define COLOR_LIGHTYELLOW 0xFFFC
|
||||
#define COLOR_MAGENTA 0xF81F
|
||||
#define COLOR_MEDIUMBLUE 0x0019
|
||||
#define COLOR_NAVY 0x000F
|
||||
#define COLOR_OLIVE 0x7BE0
|
||||
#define COLOR_ORANGE 0xFD20
|
||||
#define COLOR_ORANGERED 0xFA20
|
||||
#define COLOR_PALEGREEN 0x9FD3
|
||||
#define COLOR_PINK 0xF81F
|
||||
#define COLOR_PURPLE 0x780F
|
||||
#define COLOR_RED 0xf800
|
||||
#define COLOR_SEAGREEN 0x2C4A
|
||||
#define COLOR_SKYBLUE 0x867D
|
||||
#define COLOR_SPRINGGREEN 0x07EF
|
||||
#define COLOR_STEELBLUE 0x4416
|
||||
#define COLOR_TOMATO 0xFB08
|
||||
#define COLOR_WHITE 0xFFFF
|
||||
#define COLOR_YELLOW 0xFFE0
|
||||
#define COLOR_YELLOWGREEN 0x9E66
|
||||
|
||||
|
||||
screen_state getScreenState();
|
||||
void ClearScreen();
|
||||
void UpdateScreen(int y0, int y1);
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
#define BUILD_NUMBER "242"
|
||||
#define BUILD_DATE "2023-05-11"
|
||||
#define BUILD_NUMBER "253"
|
||||
#define BUILD_DATE "2023-05-12"
|
||||
|
||||
@ -48,7 +48,7 @@ LIB_DIR := $(INC_DIR)/ld
|
||||
###############################################################################
|
||||
# C flags
|
||||
CFLAGS += -O2 -D__thumb2__=1 -MD
|
||||
CFLAGS += -Wall -Wextra -Wshadow
|
||||
CFLAGS += -Wall -Wextra -Wshadow -Wdouble-promotion
|
||||
CFLAGS += -fshort-enums -ffunction-sections -fdata-sections
|
||||
#CFLAGS += -fno-common -fno-stack-protector
|
||||
CFLAGS += $(ARCH_FLAGS)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user