diff --git a/F3:F303/NitrogenFlooding/BMP280.c b/F3:F303/NitrogenFlooding/BMP280.c index 4770a2b..7cf963d 100644 --- a/F3:F303/NitrogenFlooding/BMP280.c +++ b/F3:F303/NitrogenFlooding/BMP280.c @@ -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); } diff --git a/F3:F303/NitrogenFlooding/buttons.c b/F3:F303/NitrogenFlooding/buttons.c new file mode 100644 index 0000000..a1a0231 --- /dev/null +++ b/F3:F303/NitrogenFlooding/buttons.c @@ -0,0 +1,90 @@ +/* + * This file is part of the nitrogen project. + * Copyright 2023 Edward V. Emelianov . + * + * 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 . + */ + +#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; +} diff --git a/F3:F303/NitrogenFlooding/buttons.h b/F3:F303/NitrogenFlooding/buttons.h new file mode 100644 index 0000000..f981e30 --- /dev/null +++ b/F3:F303/NitrogenFlooding/buttons.h @@ -0,0 +1,40 @@ +/* + * This file is part of the nitrogen project. + * Copyright 2023 Edward V. Emelianov . + * + * 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 . + */ + +#pragma once + +#include + +// 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); + diff --git a/F3:F303/NitrogenFlooding/hardware.c b/F3:F303/NitrogenFlooding/hardware.c index e31aefa..1ba7ef6 100644 --- a/F3:F303/NitrogenFlooding/hardware.c +++ b/F3:F303/NitrogenFlooding/hardware.c @@ -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; diff --git a/F3:F303/NitrogenFlooding/hardware.h b/F3:F303/NitrogenFlooding/hardware.h index bfbbaa2..fe872fc 100644 --- a/F3:F303/NitrogenFlooding/hardware.h +++ b/F3:F303/NitrogenFlooding/hardware.h @@ -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); diff --git a/F3:F303/NitrogenFlooding/ili9341.c b/F3:F303/NitrogenFlooding/ili9341.c index beaac7a..8e92f4d 100644 --- a/F3:F303/NitrogenFlooding/ili9341.c +++ b/F3:F303/NitrogenFlooding/ili9341.c @@ -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; diff --git a/F3:F303/NitrogenFlooding/ili9341.h b/F3:F303/NitrogenFlooding/ili9341.h index ae5627e..853001d 100644 --- a/F3:F303/NitrogenFlooding/ili9341.h +++ b/F3:F303/NitrogenFlooding/ili9341.h @@ -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); diff --git a/F3:F303/NitrogenFlooding/incication.h b/F3:F303/NitrogenFlooding/incication.h new file mode 100644 index 0000000..afbf7a2 --- /dev/null +++ b/F3:F303/NitrogenFlooding/incication.h @@ -0,0 +1,32 @@ +/* + * This file is part of the nitrogen project. + * Copyright 2023 Edward V. Emelianov . + * + * 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 . + */ + +#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(); diff --git a/F3:F303/NitrogenFlooding/indication.c b/F3:F303/NitrogenFlooding/indication.c new file mode 100644 index 0000000..e6bacf0 --- /dev/null +++ b/F3:F303/NitrogenFlooding/indication.c @@ -0,0 +1,188 @@ +/* + * This file is part of the nitrogen project. + * Copyright 2023 Edward V. Emelianov . + * + * 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 . + */ + +#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< SENSORS_DATA_TIMEOUT){ + refresh_mainwin(); + lastTmeas = Tms; + } + break; + case DISP_MENU: // do nothing + ; + break; + } +} diff --git a/F3:F303/NitrogenFlooding/main.c b/F3:F303/NitrogenFlooding/main.c index 39b5504..0dd74f7 100644 --- a/F3:F303/NitrogenFlooding/main.c +++ b/F3:F303/NitrogenFlooding/main.c @@ -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(); + } + } } } diff --git a/F3:F303/NitrogenFlooding/nitrogen.bin b/F3:F303/NitrogenFlooding/nitrogen.bin index 805c2d5..61c4c13 100755 Binary files a/F3:F303/NitrogenFlooding/nitrogen.bin and b/F3:F303/NitrogenFlooding/nitrogen.bin differ diff --git a/F3:F303/NitrogenFlooding/nitrogen.files b/F3:F303/NitrogenFlooding/nitrogen.files index ed85dc1..5b5717e 100644 --- a/F3:F303/NitrogenFlooding/nitrogen.files +++ b/F3:F303/NitrogenFlooding/nitrogen.files @@ -24,6 +24,8 @@ i2c.c i2c.h ili9341.c ili9341.h +incication.h +indication.c main.c pdnuart.c pdnuart.h diff --git a/F3:F303/NitrogenFlooding/proto.c b/F3:F303/NitrogenFlooding/proto.c index 9bb7975..542a505 100644 --- a/F3:F303/NitrogenFlooding/proto.c +++ b/F3:F303/NitrogenFlooding/proto.c @@ -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"}, diff --git a/F3:F303/NitrogenFlooding/screen.c b/F3:F303/NitrogenFlooding/screen.c index c1ff253..63dcb40 100644 --- a/F3:F303/NitrogenFlooding/screen.c +++ b/F3:F303/NitrogenFlooding/screen.c @@ -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) diff --git a/F3:F303/NitrogenFlooding/screen.h b/F3:F303/NitrogenFlooding/screen.h index a912f7f..fd2e567 100644 --- a/F3:F303/NitrogenFlooding/screen.h +++ b/F3:F303/NitrogenFlooding/screen.h @@ -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); diff --git a/F3:F303/NitrogenFlooding/version.inc b/F3:F303/NitrogenFlooding/version.inc index 3a1d7b1..f64e00a 100644 --- a/F3:F303/NitrogenFlooding/version.inc +++ b/F3:F303/NitrogenFlooding/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "242" -#define BUILD_DATE "2023-05-11" +#define BUILD_NUMBER "253" +#define BUILD_DATE "2023-05-12" diff --git a/makefile.stm32 b/makefile.stm32 index 6e51ee4..6fb8ab5 100644 --- a/makefile.stm32 +++ b/makefile.stm32 @@ -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)