add BME280, try to work with SPI TFT display (no reaction yet)

This commit is contained in:
Edward Emelianov 2023-05-08 01:30:34 +03:00
parent e0352dde3f
commit 16f3b31f4f
14 changed files with 187 additions and 30 deletions

View File

@ -4,6 +4,7 @@ MCU := F302xc
# change this linking script depending on particular MCU model,
LDSCRIPT := stm32f302xB.ld
DEFINES := -DUSB1_16
LDADD := -lm
include ../makefile.f3
include ../../makefile.stm32

View File

@ -59,7 +59,7 @@ Automated liquid nitrogen flooding machine
| 48 | PB11 | SCRN RST | slow out | Screen reset |
| 49 | (VSS) | | | |
| 50 | (VDD) | | | |
| 51 | PB12 | SCRN NSS | slow out | Screen activate |
| 51 | PB12 | SCRN LED | slow out | Screen LEDs on |
| 52 | PB13 | SCRN SCK | AF5 | SPI for screen |
| 53 | PB14 | SCRN MISO | AF5 | |
| 54 | PB15 | SCRN MOSI | AF5 | |
@ -143,7 +143,7 @@ Automated liquid nitrogen flooding machine
| 96 | PB9 | - | - | |
| 47 | PB10 | SCRN DCRS | slow out | Screen data/cmd |
| 48 | PB11 | SCRN RST | slow out | Screen reset |
| 51 | PB12 | SCRN NSS | slow out | Screen activate |
| 51 | PB12 | SCRN LED | slow out | Screen LEDs on |
| 52 | PB13 | SCRN SCK | AF5 | SPI for screen |
| 53 | PB14 | SCRN MISO | AF5 | |
| 54 | PB15 | SCRN MOSI | AF5 | |
@ -208,6 +208,8 @@ Automated liquid nitrogen flooding machine
### DMA1
- Channel 1 - ADC1
- Channel 4 - SPI2 Rx
- Channel 5 - SPI2 Tx
- Channel 6 - I2C1 Tx
- Channel 7 - I2C1 Rx

View File

@ -18,6 +18,7 @@
#include "hardware.h"
#include "i2c.h"
#include "spi.h"
int LEDsON = 1;
@ -47,10 +48,10 @@ TRUE_INLINE void gpio_setup(){
GPIOB->AFR[0] = AFRf(4, 6) | AFRf(4, 7);
GPIOB->AFR[1] = AFRf(5, 13) | AFRf(5, 14) | AFRf(5, 15);
GPIOB->MODER = MODER_O(0) | MODER_AF(6) | MODER_AF(7) | MODER_O(10) | MODER_O(11) | MODER_O(12) | MODER_AF(13)
| MODER_AF(14) | MODER_AF(15);
GPIOB->OSPEEDR = OSPEED_HI(6) | OSPEED_HI(7) | OSPEED_MED(13) | OSPEED_MED(14) | OSPEED_MED(15);
| MODER_AF(14) | MODER_AF(15); // 10-DC, 11-RST, 12-LED, 13-SCK, 14-MISO, 15-MOSI
GPIOB->OSPEEDR = OSPEED_HI(6) | OSPEED_HI(7) | OSPEED_HI(13) | OSPEED_HI(14) | OSPEED_HI(15);
GPIOB->OTYPER = 0;
GPIOB->PUPDR = 0;
GPIOB->PUPDR = PUPD_PU(14); // PU MISO
// PORT C
//GPIOC->ODR = 0;
@ -134,7 +135,8 @@ TRUE_INLINE void iwdg_setup(){
void hw_setup(){
RCC->AHBENR |= RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN;
gpio_setup();
i2c_setup(HIGH_SPEED);
i2c_setup(LOW_SPEED);
spi_setup();
pwm_setup();
#ifndef EBUG
iwdg_setup();

View File

@ -49,6 +49,21 @@
#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)
// 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_DCX_pin (1<<10)
#define SCRN_DCX_port (GPIOB)
#define SCRN_DCX_get() (SCRN_DCX_port->IDR & SCRN_DCX_pin ? 1: 0)
#define SCRN_Data() do{pin_set(SCRN_DCX_port, SCRN_DCX_pin);}while(0)
#define SCRN_Command() do{pin_clear(SCRN_DCX_port, SCRN_DCX_pin);}while(0)
// Buttons amount
#define BTNSNO (7)
#define BTNs_port GPIOD

View File

@ -42,7 +42,7 @@ static uint8_t I2Cbuf[256], i2cbuflen = 0; // buffer for DMA tx/rx and its len
static inline int isI2Cbusy(){
cntr = Tms;
do{
if(Tms - cntr > I2C_TIMEOUT){ USND("Timeout, DMA transfer in progress?\n"); return 1;}
if(Tms - cntr > I2C_TIMEOUT){ USND("Timeout, DMA transfer in progress?"); return 1;}
}while(I2Cbusy);
return 0;
}
@ -103,7 +103,7 @@ static uint8_t i2c_start(uint8_t busychk){
while(I2C1->ISR & I2C_ISR_BUSY){
IWDG->KR = IWDG_REFRESH;
if(Tms - cntr > I2C_TIMEOUT){
USND("Line busy\n");
USND("Line busy");
return 0; // check busy
}}
}
@ -111,7 +111,7 @@ static uint8_t i2c_start(uint8_t busychk){
while(I2C1->CR2 & I2C_CR2_START){
IWDG->KR = IWDG_REFRESH;
if(Tms - cntr > I2C_TIMEOUT){
USND("No start\n");
USND("No start");
return 0; // check start
}}
return 1;
@ -143,11 +143,11 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t s
IWDG->KR = IWDG_REFRESH;
if(I2C1->ISR & I2C_ISR_NACKF){
I2C1->ICR |= I2C_ICR_NACKCF;
//USND("NAK\n");
DBG("NAK");
return 0;
}
if(Tms - cntr > I2C_TIMEOUT){
//USND("Timeout\n");
DBG("Timeout");
return 0;
}
}
@ -163,7 +163,10 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t s
}
uint8_t write_i2c(uint8_t addr, uint8_t *data, uint8_t nbytes){
if(isI2Cbusy()) return 0;
if(isI2Cbusy()){
DBG("I2C busy");
return 0;
}
return write_i2cs(addr, data, nbytes, 1);
}
@ -203,11 +206,11 @@ static uint8_t read_i2cb(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t bu
IWDG->KR = IWDG_REFRESH;
if(I2C1->ISR & I2C_ISR_NACKF){
I2C1->ICR |= I2C_ICR_NACKCF;
//USND("NAK\n");
//DBG("NAK");
return 0;
}
if(Tms - cntr > I2C_TIMEOUT){
//USND("Timeout\n");
//DBG("Timeout");
return 0;
}
}
@ -250,22 +253,22 @@ uint8_t read_i2c_reg16(uint8_t addr, uint16_t reg16, uint8_t *data, uint8_t nbyt
void i2c_init_scan_mode(){
i2caddr = 1; // start from 1 as 0 is a broadcast address
I2C_scan_mode = 1;
DBG("init scan");
}
// return 1 if next addr is active & return in as `addr`
// if addresses are over, return 1 and set addr to I2C_NOADDR
// if scan mode inactive, return 0 and set addr to I2C_NOADDR
int i2c_scan_next_addr(uint8_t *addr){
if(isI2Cbusy()) return 0;
if(isI2Cbusy()){
DBG("scan: busy");
return 0;
}
*addr = i2caddr;
if(i2caddr == I2C_ADDREND){
*addr = I2C_ADDREND;
I2C_scan_mode = 0;
return 0;
}
/*while(!u3txrdy);
USND("Addr: "); USND(uhex2str(i2caddr)); USND("\n");
usart3_sendbuf();*/
uint8_t byte;
if(!read_i2c((i2caddr++)<<1, &byte, 1)) return 0;
return 1;
@ -274,10 +277,10 @@ int i2c_scan_next_addr(uint8_t *addr){
// dump I2Cbuf
void i2c_bufdudump(){
if(goterr){
USND("Last transfer ends with error!\n");
USND("Last transfer ends with error!");
goterr = 0;
}
USND("I2C buffer:\n");
USND("I2C buffer:");
hexdump(USB_sendstr, I2Cbuf, i2cbuflen);
}

View File

@ -17,12 +17,14 @@
*/
#include "adc.h"
#include "BMP280.h"
//#include "buttons.h"
//#include "can.h"
//#include "flash.h"
#include "hardware.h"
#include "i2c.h"
#include "proto.h"
#include "strfunc.h"
#include "usb.h"
#define MAXSTRLEN RBINSZ
@ -47,6 +49,7 @@ int main(void){
USB_setup();
//CAN_setup(the_conf.CANspeed);
adc_setup();
BMP280_setup(0);
USBPU_ON();
uint32_t ctr = 0;
// CAN_message *can_mesg;
@ -86,7 +89,23 @@ int main(void){
USB_sendstr(") - found device\n");
}
}
i2c_have_DMA_Rx(); // check if there's DMA Rx complete
//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){

View File

@ -1,3 +1,5 @@
BMP280.c
BMP280.h
adc.c
adc.h
buttons.c
@ -16,6 +18,8 @@ hashgen/hdr.h
hashgen/test.c
i2c.c
i2c.h
ili9341.c
ili9341.h
main.c
pdnuart.c
pdnuart.h
@ -23,6 +27,8 @@ proto.c
proto.h
ringbuffer.c
ringbuffer.h
spi.c
spi.h
steppers.c
steppers.h
strfunc.c

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 402 B

View File

@ -17,9 +17,11 @@
*/
#include "adc.h"
#include "BMP280.h"
#include "hardware.h"
#include "i2c.h"
#include "proto.h"
#include "ili9341.h"
#include "strfunc.h"
#include "version.inc"
@ -37,21 +39,30 @@ static int goodstub(const char *cmd, int parno, const char *carg, int32_t iarg){
return RET_GOOD;
}
// send over USB cmd[parno][=i]
static void sendkey(const char *cmd, int parno, int32_t i){
USB_sendstr(cmd);
if(parno > -1) USB_sendstr(u2str((uint32_t)parno));
USB_putbyte('='); USB_sendstr(i2str(i)); newline();
}
// `sendkey` for floating parameter
static void sendkeyf(const char *cmd, int parno, float f){
USB_sendstr(cmd);
if(parno > -1) USB_sendstr(u2str((uint32_t)parno));
USB_putbyte('='); USB_sendstr(float2str(f, 2)); newline();
}
// `sendkey` for uint32_t
static void sendkeyu(const char *cmd, int parno, uint32_t u){
USB_sendstr(cmd);
if(parno > -1) USB_sendstr(u2str((uint32_t)parno));
USB_putbyte('='); USB_sendstr(u2str(u)); newline();
}
// `sendkey` for uint32_t out in hex
static void sendkeyuhex(const char *cmd, int parno, uint32_t u){
USB_sendstr(cmd);
if(parno > -1) USB_sendstr(u2str((uint32_t)parno));
USB_putbyte('='); USB_sendstr(uhex2str(u)); newline();
}
static int leds(const char *cmd, int parno, const char *c, int32_t i){
if(parno < 0){ // enable/disable all
@ -72,6 +83,30 @@ static int leds(const char *cmd, int parno, const char *c, int32_t i){
return RET_GOOD;
}
static int bme(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t _U_ i){
if(BMP280_get_status() == BMP280_NOTINIT){
DBG("Need 2 init");
if(!BMP280_init()){
USND("Can't init");
return RET_BAD;
}
}
if(!BMP280_start()) return RET_BAD;
return RET_GOOD;
}
static int bmefilter(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t _U_ i){
BMP280_Filter f = BMP280_FILTER_OFF;
if(c){
if(i < 0 || i >= BMP280_FILTERMAX) return RET_WRONGARG;
f = (BMP280_Filter) i;
BMP280_setfilter(f);
if(!BMP280_init()) return RET_BAD;
}
sendkey(cmd, -1, BMP280_getfilter());
return RET_GOOD;
}
static int buzzer(const char *cmd, int _U_ parno, const char _U_ *c, int32_t i){
if(c){
if(i > 0) BUZZER_ON();
@ -88,9 +123,29 @@ static int i2scan(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t
static int i2addr(const char *cmd, int _U_ parno, const char *c, int32_t i){
if(c){
if(i < 0 || i>= I2C_ADDREND) return RET_WRONGARG;
I2Caddress = (uint8_t) i;
I2Caddress = ((uint8_t) i)<<1;
}
sendkey(cmd, -1, I2Caddress);
sendkey(cmd, -1, I2Caddress>>1);
return RET_GOOD;
}
static int i2reg(const char *cmd, int parno, const char _U_ *c, int32_t i){
if(parno < 0 || parno > 127) return RET_WRONGPARNO;
uint8_t d[2];
if(c){
if(i < 0 || i > 255) return RET_WRONGARG;
d[0] = parno; d[1] = (uint8_t)i;
if(!write_i2c(I2Caddress, d, 2)) return RET_BAD;
}
if(!read_i2c_reg(I2Caddress, (uint8_t)parno, d, 1)) return RET_BAD;
sendkey(cmd, parno, d[0]);
return RET_GOOD;
}
static int i2read(const char _U_ *cmd, int parno, const char _U_ *c, int32_t _U_ i){
uint8_t buf[128];
if(parno < 0 || parno > 128) return RET_WRONGPARNO;
if(!read_i2c(I2Caddress, buf, (uint8_t)parno)) return RET_BAD;
USB_sendstr("I2C got data:\n");
hexdump(USB_sendstr, buf, parno);
return RET_GOOD;
}
@ -142,6 +197,45 @@ static int pwm(const char *cmd, int parno, const char *c, int32_t i){
return RET_GOOD;
}
static int scrnled(const char *cmd, int _U_ parno, const char *c, int32_t i){
if(c) SCRN_LED_set(i);
sendkeyu(cmd, -1, SCRN_LED_get());
return RET_GOOD;
}
static int scrndcr(const char *cmd, int _U_ parno, const char *c, int32_t i){
if(c){
if(i) SCRN_Data();
else SCRN_Command();
}
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());
return RET_GOOD;
}
static int scrnrdwr(const char *cmd, int parno, const char *c, int32_t i){
if(parno < 0) return RET_WRONGPARNO;
if(c){
if(i < 0 || i > 255) return RET_WRONGARG;
if(!ili9341_writereg(parno, (uint8_t*)&i, 1)) return RET_BAD;
}
i = 0;
if(!ili9341_readreg(parno, (uint8_t*)&i, 1)) return RET_BAD;
sendkeyu(cmd, parno, i);
return RET_GOOD;
}
static int scrnrdwr4(const char *cmd, int parno, const char *c, int32_t i){
if(parno < 0) return RET_WRONGPARNO;
if(c){
if(!ili9341_writereg(parno, (uint8_t*)&i, 4)) return RET_BAD;
}
if(!ili9341_readreg(parno, (uint8_t*)&i, 4)) return RET_BAD;
sendkeyuhex(cmd, parno, i);
return RET_GOOD;
}
typedef struct{
int (*fn)(const char*, int, const char*, int32_t);
const char *cmd;
@ -151,6 +245,8 @@ typedef struct{
commands cmdlist[] = {
{goodstub, "stub", "simple stub"},
{NULL, "Different commands", NULL},
{bme, "BME", "get pressure, temperature and humidity"},
{bmefilter, "BMEf", "set filter (0..4)"},
{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)"},
{pwm, "pwm", "set/get x channel (0..3) pwm value (0..100)"},
@ -158,7 +254,15 @@ commands cmdlist[] = {
{tms, "tms", "print Tms"},
{NULL, "I2C commands", NULL},
{i2addr, "iicaddr", "set/get I2C address"},
{i2read, "iicread", "read X (0..128) bytes"},
{i2reg, "iicreg", "read/write I2C register"},
{i2scan, "iicscan", "scan I2C bus"},
{NULL, "Screen commands", NULL},
{scrnled, "Sled", "turn on/off screen lights"},
{scrndcr, "Sdcr", "set data(1)/command(0)"},
{scrnrst, "Srst", "reset (1/0)"},
{scrnrdwr, "Sreg", "read/write 8-bit register"},
{scrnrdwr4, "Sregx", "read/write 32-bit register"},
{NULL, "ADC commands", NULL},
{adcval, "ADC", "get ADCx value (without x - for all)"},
{adcvoltage, "ADCv", "get ADCx voltage (without x - for all)"},

View File

@ -272,7 +272,7 @@ const char *getint(const char *txt, int32_t *I){
static const float pwr10[] = {1.f, 10.f, 100.f, 1000.f, 10000.f};
static const float rounds[] = {0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f};
#define P10L (sizeof(pwr10)/sizeof(uint32_t) - 1)
const char *float2str(float x, uint8_t prec){
char *float2str(float x, uint8_t prec){
static char str[16] = {0}; // -117.5494E-36\0 - 14 symbols max!
if(prec > P10L) prec = P10L;
if(isnan(x)){ memcpy(str, "NAN", 4); return str;}

View File

@ -25,8 +25,8 @@ void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len);
char *u2str(uint32_t val);
char *i2str(int32_t i);
char *uhex2str(uint32_t val);
char *float2str(float x, uint8_t prec);
const char *getnum(const char *txt, uint32_t *N);
const char *omit_spaces(const char *buf);
const char *getint(const char *txt, int32_t *I);
const char *float2str(float x, uint8_t prec);
//void mymemcpy(char *dest, const char *src, int len);

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "56"
#define BUILD_DATE "2023-05-03"
#define BUILD_NUMBER "110"
#define BUILD_DATE "2023-05-08"

View File

@ -40,6 +40,10 @@
#define NULL (0)
#endif
#ifndef _U_
#define _U_ __attribute__((__unused__))
#endif
// some good things from CMSIS
#define nop() __NOP()

View File

@ -96,7 +96,7 @@ release: LDFLAGS += -flto
release: $(TARGFILE) bin list size
#debug: add debug flags
debug: CFLAGS += -DEBUG -Werror -g3 -gdwarf-2
debug: CFLAGS += -DEBUG -Werror -g3 -gdwarf-2
debug: TARGET := DEBUG
debug: $(TARGFILE) bin list size
@ -145,7 +145,7 @@ $(LIST): $(ELF)
$(ELF): $(OBJDIR) $(OBJS)
@echo " LD $(ELF)"
$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF) $(LDADD)
size: $(ELF)
$(SIZE) $(ELF)
@ -158,6 +158,7 @@ clean:
flash: $(BIN)
@echo " FLASH $(BIN)"
$(STFLASH) write $(BIN) 0x8000000
$(STFLASH) reset
boot: $(BIN)
@echo " LOAD $(BIN) through bootloader"