mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
Always working, but some of schematics was wrong
This commit is contained in:
parent
f127a3ce1a
commit
6cb98bb7ed
@ -1,8 +1,8 @@
|
|||||||
BINARY := fx3u
|
BINARY := fx3u
|
||||||
# MCU code
|
# MCU code
|
||||||
MCU ?= F103xC
|
MCU ?= F103xE
|
||||||
# change this linking script depending on particular MCU model,
|
# change this linking script depending on particular MCU model,
|
||||||
LDSCRIPT ?= stm32f103xC.ld
|
LDSCRIPT ?= stm32f103xE.ld
|
||||||
DEFINES := -DSTM32F10X_HD
|
DEFINES := -DSTM32F10X_HD
|
||||||
INC_DIR := ../inc
|
INC_DIR := ../inc
|
||||||
|
|
||||||
|
|||||||
0
F1:F103/FX3U/Readme.md
Normal file
0
F1:F103/FX3U/Readme.md
Normal file
@ -36,8 +36,9 @@ void adc_setup(){
|
|||||||
// sampling time - 239.5 cycles for channels 0, 16 and 17
|
// sampling time - 239.5 cycles for channels 0, 16 and 17
|
||||||
ADC1->SMPR2 = ADC_SMPR2_SMP0;
|
ADC1->SMPR2 = ADC_SMPR2_SMP0;
|
||||||
ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
|
ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
|
||||||
// sequence order: 0 -> 16 -> 17
|
// sequence order: 1[0]->3[1]->14[2]->15[3]->10[4]->11[5] -> 16[tsen] -> 17[vdd]
|
||||||
ADC1->SQR3 = (0 << 0) | (16<<5) | (17 << 10);
|
ADC1->SQR3 = (1 << 0) | (3<<5) | (14 << 10) | (15 << 15) | (10 << 20) | (11 < 25);
|
||||||
|
ADC1->SQR2 = (16 << 0) | (17 << 5);
|
||||||
ADC1->SQR1 = (ADC_CHANNELS - 1) << 20; // amount of conversions
|
ADC1->SQR1 = (ADC_CHANNELS - 1) << 20; // amount of conversions
|
||||||
ADC1->CR1 = ADC_CR1_SCAN; // scan mode
|
ADC1->CR1 = ADC_CR1_SCAN; // scan mode
|
||||||
// DMA, continuous mode; enable vref & Tsens; enable SWSTART as trigger
|
// DMA, continuous mode; enable vref & Tsens; enable SWSTART as trigger
|
||||||
|
|||||||
@ -22,7 +22,12 @@
|
|||||||
|
|
||||||
// ADC channels in array
|
// ADC channels in array
|
||||||
enum{
|
enum{
|
||||||
ADC_CH_VSEN = 0, // ADC_ch0
|
ADC_CH_0 = 0, // ADC input channels
|
||||||
|
ADC_CH_1,
|
||||||
|
ADC_CH_2,
|
||||||
|
ADC_CH_3,
|
||||||
|
ADC_CH_4,
|
||||||
|
ADC_CH_5,
|
||||||
ADC_CH_TSEN, // T sensor
|
ADC_CH_TSEN, // T sensor
|
||||||
ADC_CH_VDD, // Vdd sensor
|
ADC_CH_VDD, // Vdd sensor
|
||||||
ADC_CHANNELS
|
ADC_CHANNELS
|
||||||
|
|||||||
@ -158,7 +158,7 @@ void CAN_setup(uint32_t speed){
|
|||||||
CAN1->FA1R = CAN_FA1R_FACT0; /* (8) */
|
CAN1->FA1R = CAN_FA1R_FACT0; /* (8) */
|
||||||
CAN1->FM1R = CAN_FM1R_FBM0;
|
CAN1->FM1R = CAN_FM1R_FBM0;
|
||||||
// filter 0 for FIFO0
|
// filter 0 for FIFO0
|
||||||
CAN1->sFilterRegister[0].FR1 = the_conf.CANID << 5; // (10) CANID and 0
|
CAN1->sFilterRegister[0].FR1 = the_conf.CANIDin << 5; // (10) CANIDin and 0
|
||||||
if(flags.can_monitor){ /* (11) */
|
if(flags.can_monitor){ /* (11) */
|
||||||
CAN1->FA1R |= CAN_FA1R_FACT1; // activate filter1
|
CAN1->FA1R |= CAN_FA1R_FACT1; // activate filter1
|
||||||
CAN1->sFilterRegister[1].FR1 = 0; // all packets
|
CAN1->sFilterRegister[1].FR1 = 0; // all packets
|
||||||
@ -299,7 +299,7 @@ CAN_status CAN_send(CAN_message *message){
|
|||||||
* incoming data may have variable length
|
* incoming data may have variable length
|
||||||
*/
|
*/
|
||||||
TRUE_INLINE void parseCANcommand(CAN_message *msg){
|
TRUE_INLINE void parseCANcommand(CAN_message *msg){
|
||||||
msg->ID = the_conf.CANID; // set own ID for broadcast messages
|
msg->ID = the_conf.CANIDout; // set output ID for all output messages
|
||||||
// check PING
|
// check PING
|
||||||
if(msg->length != 0) run_can_cmd(msg);
|
if(msg->length != 0) run_can_cmd(msg);
|
||||||
uint32_t Tstart = Tms;
|
uint32_t Tstart = Tms;
|
||||||
@ -354,7 +354,7 @@ static void can_process_fifo(uint8_t fifo_num){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// run command for my or broadcast ID
|
// run command for my or broadcast ID
|
||||||
if(msg.ID == the_conf.CANID || msg.ID == 0) parseCANcommand(&msg);
|
if(msg.ID == the_conf.CANIDin || msg.ID == 0) parseCANcommand(&msg);
|
||||||
if(flags.can_monitor && CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later
|
if(flags.can_monitor && CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later
|
||||||
*RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message
|
*RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,36 +57,33 @@ static errcodes adcraw(CAN_message *msg){
|
|||||||
*(uint32_t*)&msg->data[4] = getADCval(no);
|
*(uint32_t*)&msg->data[4] = getADCval(no);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
// get ADC voltage
|
// set common CAN ID / get CAN IN in
|
||||||
static errcodes adcv(CAN_message *msg){
|
|
||||||
FIXDL(msg);
|
|
||||||
uint8_t no = msg->data[2] & ~SETTER_FLAG;
|
|
||||||
if(no >= ADC_CH_TSEN) return ERR_BADPAR;
|
|
||||||
float v = getADCvoltage(no) /** the_conf.adcmul[no] * 100.f*/;
|
|
||||||
*(uint32_t*)&msg->data[4] = (uint32_t) v;
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
// get/set CAN ID
|
|
||||||
static errcodes canid(CAN_message *msg){
|
static errcodes canid(CAN_message *msg){
|
||||||
if(ISSETTER(msg->data)){
|
if(ISSETTER(msg->data)){
|
||||||
the_conf.CANID = *(uint32_t*)&msg->data[4];
|
the_conf.CANIDin = the_conf.CANIDout = *(uint32_t*)&msg->data[4];
|
||||||
CAN_reinit(0); // setup with new ID
|
CAN_reinit(0); // setup with new ID
|
||||||
}else FIXDL(msg);
|
}else FIXDL(msg);
|
||||||
*(uint32_t*)&msg->data[4] = the_conf.CANID;
|
*(uint32_t*)&msg->data[4] = the_conf.CANIDin;
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
/*
|
// get/set input CAN ID
|
||||||
// get/set ADC multiplier
|
static errcodes canidin(CAN_message *msg){
|
||||||
static errcodes adcmul(CAN_message *msg){
|
|
||||||
uint8_t no = msg->data[2] & ~SETTER_FLAG;
|
|
||||||
if(no >= ADC_TSENS) return ERR_BADPAR;
|
|
||||||
if(ISSETTER(msg->data)){
|
if(ISSETTER(msg->data)){
|
||||||
the_conf.adcmul[no] = ((float)*(uint32_t*)&msg->data[4])/1000.f;
|
the_conf.CANIDin = *(uint32_t*)&msg->data[4];
|
||||||
|
CAN_reinit(0); // setup with new ID
|
||||||
}else FIXDL(msg);
|
}else FIXDL(msg);
|
||||||
*(uint32_t*)&msg->data[4] = (uint32_t)(1000.f * the_conf.adcmul[no]);
|
*(uint32_t*)&msg->data[4] = the_conf.CANIDin;
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
*/
|
// get/set output CAN ID
|
||||||
|
static errcodes canidout(CAN_message *msg){
|
||||||
|
if(ISSETTER(msg->data)){
|
||||||
|
the_conf.CANIDout = *(uint32_t*)&msg->data[4];
|
||||||
|
}else FIXDL(msg);
|
||||||
|
*(uint32_t*)&msg->data[4] = the_conf.CANIDout;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// save config
|
// save config
|
||||||
static errcodes saveconf(CAN_message _U_ *msg){
|
static errcodes saveconf(CAN_message _U_ *msg){
|
||||||
if(0 == store_userconf()) return ERR_OK;
|
if(0 == store_userconf()) return ERR_OK;
|
||||||
@ -97,33 +94,39 @@ static errcodes erasestor(CAN_message _U_ *msg){
|
|||||||
if(0 == erase_storage(-1)) return ERR_OK;
|
if(0 == erase_storage(-1)) return ERR_OK;
|
||||||
return ERR_CANTRUN;
|
return ERR_CANTRUN;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// relay management
|
// relay management
|
||||||
static errcodes relay(CAN_message *msg){
|
static errcodes relay(CAN_message *msg){
|
||||||
|
uint8_t no = OUTMAX+1;
|
||||||
|
if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG;
|
||||||
if(ISSETTER(msg->data)){
|
if(ISSETTER(msg->data)){
|
||||||
if(msg->data[4] == 1) RELAY_ON();
|
if(set_relay(no, *(uint32_t*)&msg->data[4]) < 0) return ERR_BADPAR;
|
||||||
else RELAY_OFF();
|
|
||||||
}else FIXDL(msg);
|
}else FIXDL(msg);
|
||||||
*(uint32_t*)&msg->data[4] = RELAY_GET();
|
int rval = get_relay(no);
|
||||||
|
if(rval < 0) return ERR_BADPAR;
|
||||||
|
*(uint32_t*)&msg->data[4] = (uint32_t)rval;
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
// blocking ESW get status
|
// get current ESW status
|
||||||
static errcodes eswblk(CAN_message *msg){
|
static errcodes esw(CAN_message *msg){
|
||||||
uint8_t no = msg->data[2] & ~SETTER_FLAG;
|
uint8_t no = INMAX+1;
|
||||||
if(no > 1) return ERR_BADPAR;
|
if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG;
|
||||||
|
int val = get_esw(no);
|
||||||
|
if(val < 0) return ERR_BADPAR;
|
||||||
|
*(uint32_t*)&msg->data[4] = (uint32_t) val;
|
||||||
FIXDL(msg);
|
FIXDL(msg);
|
||||||
*(uint32_t*)&msg->data[4] = getSwitches(no);
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
// bounce-free ESW get status
|
// bounce-free ESW get status
|
||||||
static errcodes esw(CAN_message *msg){
|
static errcodes eswg(CAN_message *msg){
|
||||||
uint8_t no = msg->data[2] & ~SETTER_FLAG;
|
uint8_t no = INMAX+1;
|
||||||
if(no > 1) return ERR_BADPAR;
|
if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG;
|
||||||
|
uint32_t curval = get_ab_esw();
|
||||||
|
if(no > INMAX) *(uint32_t*)&msg->data[4] = curval;
|
||||||
|
else *(uint32_t*)&msg->data[4] = (curval & (1<<no)) ? 0 : 1;
|
||||||
FIXDL(msg);
|
FIXDL(msg);
|
||||||
*(uint32_t*)&msg->data[4] = getESW(no);
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// common uint32_t setter/getter
|
// common uint32_t setter/getter
|
||||||
static errcodes u32setget(CAN_message *msg){
|
static errcodes u32setget(CAN_message *msg){
|
||||||
@ -131,7 +134,7 @@ static errcodes u32setget(CAN_message *msg){
|
|||||||
uint32_t *ptr = NULL;
|
uint32_t *ptr = NULL;
|
||||||
switch(idx){
|
switch(idx){
|
||||||
case CMD_CANSPEED: ptr = &the_conf.CANspeed; CAN_reinit(*(uint32_t*)&msg->data[4]); break;
|
case CMD_CANSPEED: ptr = &the_conf.CANspeed; CAN_reinit(*(uint32_t*)&msg->data[4]); break;
|
||||||
//case CMD_BOUNCE: ptr = &the_conf.bounce_ms; break;
|
case CMD_BOUNCE: ptr = &the_conf.bouncetime; break;
|
||||||
case CMD_USARTSPEED: ptr = &the_conf.usartspeed; break;
|
case CMD_USARTSPEED: ptr = &the_conf.usartspeed; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -177,16 +180,16 @@ static const commonfunction funclist[CMD_AMOUNT] = {
|
|||||||
[CMD_TIME] = {time_getset, 0, 0, 0},
|
[CMD_TIME] = {time_getset, 0, 0, 0},
|
||||||
[CMD_MCUTEMP] = {mcut, 0, 0, 0},
|
[CMD_MCUTEMP] = {mcut, 0, 0, 0},
|
||||||
[CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..4
|
[CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..4
|
||||||
[CMD_ADCV] = {adcv, 0, 0, 3}, // need parno: 0..3
|
|
||||||
[CMD_CANSPEED] = {u32setget, CAN_MIN_SPEED, CAN_MAX_SPEED, 0},
|
[CMD_CANSPEED] = {u32setget, CAN_MIN_SPEED, CAN_MAX_SPEED, 0},
|
||||||
[CMD_CANID] = {canid, 1, 0x7ff, 0},
|
[CMD_CANID] = {canid, 1, 0x7ff, 0},
|
||||||
// [CMD_ADCMUL] = {adcmul, 0, 0, 3}, // at least parno
|
[CMD_CANIDin] = {canidin, 1, 0x7ff, 0},
|
||||||
|
[CMD_CANIDout] = {canidout, 1, 0x7ff, 0},
|
||||||
[CMD_SAVECONF] = {saveconf, 0, 0, 0},
|
[CMD_SAVECONF] = {saveconf, 0, 0, 0},
|
||||||
[CMD_ERASESTOR] = {erasestor, 0, 0, 0},
|
[CMD_ERASESTOR] = {erasestor, 0, 0, 0},
|
||||||
// [CMD_RELAY] = {relay, 0, 1, 0},
|
[CMD_RELAY] = {relay, 0, INT32_MAX, 0},
|
||||||
// [CMD_GETESW_BLK] = {eswblk, 0, 0, 3},
|
[CMD_GETESW] = {eswg, 0, INT32_MAX, 0},
|
||||||
// [CMD_GETESW] = {esw, 0, 0, 3},
|
[CMD_GETESWNOW] = {esw, 0, INT32_MAX, 0},
|
||||||
// [CMD_BOUNCE] = {u32setget, 0, 300, 0},
|
[CMD_BOUNCE] = {u32setget, 0, 1000, 0},
|
||||||
[CMD_USARTSPEED] = {u32setget, 1200, 3000000, 0},
|
[CMD_USARTSPEED] = {u32setget, 1200, 3000000, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -45,29 +45,21 @@ typedef enum{
|
|||||||
|
|
||||||
// CAN commands indexes
|
// CAN commands indexes
|
||||||
enum{
|
enum{
|
||||||
CMD_RESET, // 0 - reset MCU
|
CMD_RESET, // reset MCU
|
||||||
CMD_TIME, // 1 - get/set Tms
|
CMD_TIME, // get/set Tms
|
||||||
CMD_MCUTEMP, // 2 - get MCU temperature (*10)
|
CMD_MCUTEMP, // get MCU temperature (*10)
|
||||||
CMD_ADCRAW, // 3 - get ADC raw values
|
CMD_ADCRAW, // get ADC raw values
|
||||||
CMD_ADCV, // 4 - get ADC voltage (*100)
|
CMD_CANSPEED, // get/set CAN speed (kbps)
|
||||||
CMD_CANSPEED, // 5 - get/set CAN speed (kbps)
|
CMD_CANID, // get/set common CAN ID (both in and out)
|
||||||
CMD_CANID, // 6 - get/set CAN ID
|
CMD_CANIDin, // input CAN ID
|
||||||
CMD_ADCMUL, // 7 - get/set ADC multipliers 0..4
|
CMD_CANIDout, // output CAN ID
|
||||||
CMD_SAVECONF, // 8 - save configuration
|
CMD_SAVECONF, // save configuration
|
||||||
CMD_ERASESTOR, // 9 - erase all flash storage
|
CMD_ERASESTOR, // erase all flash storage
|
||||||
CMD_RELAY, // 10 - switch relay ON/OFF
|
CMD_RELAY, // switch relay ON/OFF
|
||||||
CMD_GETESW_BLK, // 11 - blocking read of ESW
|
CMD_GETESW, // current ESW state, bounce-free
|
||||||
CMD_GETESW, // 12 - current ESW state, bounce-free
|
CMD_GETESWNOW, // current ESW state, absolute
|
||||||
CMD_BOUNCE, // 13 - get/set bounce constant (ms)
|
CMD_BOUNCE, // get/set bounce constant (ms)
|
||||||
CMD_USARTSPEED, // 14 - get/set USART1 speed (if encoder on RS-422)
|
CMD_USARTSPEED, // get/set USART1 speed (if encoder on RS-422)
|
||||||
CMD_ENCISSSI, // 15 - encoder is SSI (1) or RS-422 (0)
|
|
||||||
CMD_SPIINIT, // 16 - init SPI2
|
|
||||||
CMD_SPISEND, // 17 - send 1..4 bytes over SPI
|
|
||||||
CMD_ENCGET, // 18 - get encoder value
|
|
||||||
CMD_EMULPEP, // 19 - emulate (1) / not (0) PEP
|
|
||||||
CMD_ENCREINIT, // 20 - reinit encoder
|
|
||||||
CMD_TIMESTAMP, // 21 - 2mks 24-bit timestamp
|
|
||||||
CMD_SPIDEINIT, // 22 - turn off SPI2
|
|
||||||
// should be the last:
|
// should be the last:
|
||||||
CMD_AMOUNT // amount of CAN commands
|
CMD_AMOUNT // amount of CAN commands
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,8 +30,10 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
|
|||||||
#define USERCONF_INITIALIZER { \
|
#define USERCONF_INITIALIZER { \
|
||||||
.userconf_sz = sizeof(user_conf) \
|
.userconf_sz = sizeof(user_conf) \
|
||||||
,.CANspeed = 250000 \
|
,.CANspeed = 250000 \
|
||||||
,.CANID = 1 \
|
,.CANIDin = 1 \
|
||||||
|
,.CANIDout = 2 \
|
||||||
,.usartspeed = 115200 \
|
,.usartspeed = 115200 \
|
||||||
|
,.bouncetime = 50 \
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write2flash(const void*, const void*, uint32_t);
|
static int write2flash(const void*, const void*, uint32_t);
|
||||||
|
|||||||
@ -28,7 +28,10 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct __attribute__((aligned(4))){
|
typedef struct __attribute__((aligned(4))){
|
||||||
uint16_t userconf_sz; // "magick number"
|
uint16_t userconf_sz; // "magick number"
|
||||||
uint16_t CANID; // CAN bus device ID
|
uint16_t CANIDin; // CAN bus device ID for input commands
|
||||||
|
uint16_t CANIDout; // -//- for output signals
|
||||||
|
uint16_t reserved;
|
||||||
|
uint32_t bouncetime; // anti-bounce timeout (ms)
|
||||||
uint32_t usartspeed; // RS-232 speed
|
uint32_t usartspeed; // RS-232 speed
|
||||||
uint32_t CANspeed; // CAN bus speed
|
uint32_t CANspeed; // CAN bus speed
|
||||||
} user_conf;
|
} user_conf;
|
||||||
|
|||||||
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 13.0.1, 2024-05-31T21:22:50. -->
|
<!-- Written by QtCreator 13.0.1, 2024-06-03T20:25:16. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@ -16,7 +16,13 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "can.h"
|
||||||
|
#include "canproto.h"
|
||||||
|
#include "flash.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#ifdef EBUG
|
||||||
|
#include "strfunc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* pinout:
|
/* pinout:
|
||||||
|
|
||||||
@ -103,3 +109,145 @@ void iwdg_setup(){
|
|||||||
while(IWDG->SR){if(--tmout == 0) break;}
|
while(IWDG->SR){if(--tmout == 0) break;}
|
||||||
IWDG->KR = IWDG_REFRESH;
|
IWDG->KR = IWDG_REFRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
GPIO_TypeDef* port; // GPIOx or NULL if no such pin
|
||||||
|
uint16_t pin; // (1 << pin)
|
||||||
|
} pin_t;
|
||||||
|
|
||||||
|
// input pins (X0..X15)
|
||||||
|
static const pin_t IN[INMAX+1] = { // youbannye uskoglazye pidarasy! Ready to fuck their own mother to save kopeyka
|
||||||
|
{GPIOB, 1<<13}, // X0 - PB13
|
||||||
|
{GPIOB, 1<<14}, // X1 - PB14
|
||||||
|
{GPIOB, 1<<11}, // X2 - PB11
|
||||||
|
{GPIOB, 1<<12}, // X3 - PB12
|
||||||
|
{GPIOE, 1<<15}, // X4 - PE15
|
||||||
|
{GPIOB, 1<<10}, // X5 - PB10
|
||||||
|
{GPIOE, 1<<13}, // X6 - PE13
|
||||||
|
{GPIOE, 1<<14}, // X7 - PE14
|
||||||
|
{NULL, 0}, // X8 - absent
|
||||||
|
{NULL, 0}, // X9 - absent
|
||||||
|
{GPIOE, 1<11}, // X10 - PE11
|
||||||
|
{GPIOE, 1<<12}, // X11 - PE12
|
||||||
|
{GPIOE, 1<<9}, // X12 - PE9
|
||||||
|
{GPIOE, 1<<10}, // X13 - PE10
|
||||||
|
{GPIOE, 1<<7}, // X14 - PE7
|
||||||
|
{GPIOE, 1<<8}, // X15 - PE8
|
||||||
|
};
|
||||||
|
|
||||||
|
// output (relay) pins (Y0..Y15)
|
||||||
|
static const pin_t OUT[OUTMAX+1] = {
|
||||||
|
{GPIOC, 1<<9}, // Y0 - PC9
|
||||||
|
{GPIOC, 1<<8}, // Y1 - PC8
|
||||||
|
{GPIOA, 1<<8}, // Y2 - PA8
|
||||||
|
{GPIOA, 1<<0}, // Y3 - PA0
|
||||||
|
{GPIOB, 1<<3}, // Y4 - PB3
|
||||||
|
{GPIOD, 1<<12}, // Y5 - PD12
|
||||||
|
{GPIOB, 1<<15}, // Y6 - PB15
|
||||||
|
{GPIOA, 1<<7}, // Y7 - PA7
|
||||||
|
{NULL, 0}, // Y8 - absent
|
||||||
|
{NULL, 0}, // Y9 - absent
|
||||||
|
{GPIOA, 1<<6}, // Y10 - PA6
|
||||||
|
{GPIOA, 1<<2}, // Y11 - PA2
|
||||||
|
};
|
||||||
|
|
||||||
|
// bit 1 - input channel is working, 0 - no
|
||||||
|
uint32_t inchannels(){
|
||||||
|
return 0b1111110011111111;
|
||||||
|
}
|
||||||
|
// bit 1 - input channel is working, 0 - no
|
||||||
|
uint32_t outchannels(){
|
||||||
|
return 0b110011111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief set_relay - turn on/off relay `Nch` (if Nch > OUTMAX - all)
|
||||||
|
* @param Nch - single relay channel No or >Ymax to set/reset all relays
|
||||||
|
* @param val - value to set/reset/change
|
||||||
|
* @return TRUE if OK, -1 if `Nch` is wrong
|
||||||
|
*/
|
||||||
|
int set_relay(uint8_t Nch, uint32_t val){
|
||||||
|
int chpin(uint8_t N, uint32_t v){
|
||||||
|
const pin_t *cur = &OUT[N];
|
||||||
|
if(NULL == cur->port) return -1;
|
||||||
|
if(v) pin_set(cur->port, cur->pin);
|
||||||
|
else pin_clear(cur->port, cur->pin);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if(Nch > OUTMAX){ // all
|
||||||
|
uint32_t mask = 1;
|
||||||
|
for(uint8_t i = 0; i <= OUTMAX; ++i, mask <<= 1){
|
||||||
|
chpin(i, val & mask);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return chpin(Nch, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readpins(uint8_t Nch, const pin_t *pins, uint8_t max){
|
||||||
|
int gpin(uint8_t N){
|
||||||
|
const pin_t *cur = &pins[N];
|
||||||
|
if(NULL == cur->port) return -1;
|
||||||
|
return pin_read(cur->port, cur->pin);
|
||||||
|
}
|
||||||
|
if(Nch > max){ // all
|
||||||
|
int val = 0;
|
||||||
|
for(int i = max; i > -1; --i){
|
||||||
|
val <<= 1;
|
||||||
|
int p = gpin(i);
|
||||||
|
if(p > -1) val |= gpin(i);
|
||||||
|
}
|
||||||
|
usart_send("readpins, val="); usart_send(i2str(val)); newline();
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return gpin(Nch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get_relay - get `Nch` relay state (if Nch > OUTMAX - all)
|
||||||
|
* @param Nch - single relay channel No or <0 for all
|
||||||
|
* @return current state or -1 if `Nch` is wrong
|
||||||
|
*/
|
||||||
|
int get_relay(uint8_t Nch){
|
||||||
|
return readpins(Nch, OUT, OUTMAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get_esw - get input `Nch` state (or all if Nch > INMAX)
|
||||||
|
* @param Nch - channel number or -1 for all
|
||||||
|
* @return ESW state or -1 if `Nch` is wrong
|
||||||
|
*/
|
||||||
|
int get_esw(uint8_t Nch){
|
||||||
|
return readpins(Nch, IN, INMAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ESW_ab_values = 0; // current anti-bounce values of ESW
|
||||||
|
static uint32_t lastET[INMAX+1] = {0}; // last changing time
|
||||||
|
|
||||||
|
// anti-bouce process esw
|
||||||
|
void proc_esw(){
|
||||||
|
uint32_t mask = 1, oldesw = ESW_ab_values;
|
||||||
|
for(uint8_t i = 0; i <= OUTMAX; ++i, mask <<= 1){
|
||||||
|
if(Tms - lastET[i] < the_conf.bouncetime) continue;
|
||||||
|
if(NULL == IN[i].port) continue;
|
||||||
|
uint32_t now = pin_read(IN[i].port, IN[i].pin);
|
||||||
|
if(now) ESW_ab_values |= mask;
|
||||||
|
else ESW_ab_values &= ~mask;
|
||||||
|
lastET[i] = Tms;
|
||||||
|
}
|
||||||
|
if(oldesw != ESW_ab_values){
|
||||||
|
usart_send("esw="); usart_send(u2str(ESW_ab_values)); newline();
|
||||||
|
CAN_message msg = {.ID = the_conf.CANIDout, .length = 8};
|
||||||
|
msg.data[0] = CMD_GETESW;
|
||||||
|
*((uint32_t*)(&msg.data[4])) = ESW_ab_values;
|
||||||
|
uint32_t Tstart = Tms;
|
||||||
|
while(Tms - Tstart < SEND_TIMEOUT_MS){
|
||||||
|
if(CAN_OK == CAN_send(&msg)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all anti-bounce ESW values
|
||||||
|
uint32_t get_ab_esw(){
|
||||||
|
return ESW_ab_values;
|
||||||
|
}
|
||||||
|
|||||||
@ -20,14 +20,32 @@
|
|||||||
|
|
||||||
#include <stm32f1.h>
|
#include <stm32f1.h>
|
||||||
|
|
||||||
|
|
||||||
#define CONCAT(a,b) a ## b
|
#define CONCAT(a,b) a ## b
|
||||||
#define STR_HELPER(s) #s
|
#define STR_HELPER(s) #s
|
||||||
#define STR(s) STR_HELPER(s)
|
#define STR(s) STR_HELPER(s)
|
||||||
|
|
||||||
|
/* this stuff may be usefull later
|
||||||
#define FORMUSART(X) CONCAT(USART, X)
|
#define FORMUSART(X) CONCAT(USART, X)
|
||||||
#define USARTX FORMUSART(USARTNUM)
|
#define USARTX FORMUSART(USARTNUM)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// max number of in/out pins
|
||||||
|
#define INMAX (15)
|
||||||
|
#define OUTMAX (11)
|
||||||
|
|
||||||
extern volatile uint32_t Tms;
|
extern volatile uint32_t Tms;
|
||||||
|
|
||||||
void gpio_setup(void);
|
void gpio_setup(void);
|
||||||
void iwdg_setup();
|
void iwdg_setup();
|
||||||
|
int set_relay(uint8_t Nch, uint32_t val);
|
||||||
|
int get_relay(uint8_t Nch);
|
||||||
|
int get_esw(uint8_t Nch);
|
||||||
|
void proc_esw();
|
||||||
|
uint32_t get_ab_esw();
|
||||||
|
|
||||||
|
uint32_t inchannels();
|
||||||
|
uint32_t outchannels();
|
||||||
|
int set_relay(uint8_t Nch, uint32_t val);
|
||||||
|
int get_relay(uint8_t Nch);
|
||||||
|
int get_esw(uint8_t Nch);
|
||||||
|
|||||||
@ -51,6 +51,7 @@ int main(void){
|
|||||||
usart_transmit();
|
usart_transmit();
|
||||||
lastT = Tms;
|
lastT = Tms;
|
||||||
}
|
}
|
||||||
|
proc_esw();
|
||||||
CAN_proc();
|
CAN_proc();
|
||||||
CAN_status st = CAN_get_status();
|
CAN_status st = CAN_get_status();
|
||||||
if(st == CAN_FIFO_OVERRUN){
|
if(st == CAN_FIFO_OVERRUN){
|
||||||
|
|||||||
@ -53,20 +53,28 @@ static const funcdescr funclist[] = {
|
|||||||
// {"adcraw", CMD_ADCRAW, "get raw ADC values of channel 0..4"},
|
// {"adcraw", CMD_ADCRAW, "get raw ADC values of channel 0..4"},
|
||||||
// {"adcv", CMD_ADCV, "get ADC voltage of channel 0..3 (*100V)"},
|
// {"adcv", CMD_ADCV, "get ADC voltage of channel 0..3 (*100V)"},
|
||||||
// {"bounce", CMD_BOUNCE, "get/set bounce constant (ms)"},
|
// {"bounce", CMD_BOUNCE, "get/set bounce constant (ms)"},
|
||||||
|
{NULL, 0, "CAN bus commands"},
|
||||||
{"canbuserr", -TCMD_CANBUSERRPRNT, "print all CAN bus errors (a lot of if not connected)"},
|
{"canbuserr", -TCMD_CANBUSERRPRNT, "print all CAN bus errors (a lot of if not connected)"},
|
||||||
{"canid", CMD_CANID, "get/set CAN ID"},
|
|
||||||
{"cansniff", -TCMD_CANSNIFFER, "switch CAN sniffer mode"},
|
{"cansniff", -TCMD_CANSNIFFER, "switch CAN sniffer mode"},
|
||||||
|
{NULL, 0, "Configuration"},
|
||||||
|
{"bounce", CMD_BOUNCE, "set/get anti-bounce timeout (ms, max: 1000)"},
|
||||||
|
{"canid", CMD_CANID, "set both (in/out) CAN ID / get in CAN ID"},
|
||||||
|
{"canidin", CMD_CANIDin, "get/set input CAN ID"},
|
||||||
|
{"canidout", CMD_CANIDout, "get/set output CAN ID"},
|
||||||
{"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"},
|
{"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"},
|
||||||
{"dumpconf", -TCMD_DUMPCONF, "dump current configuration"},
|
{"dumpconf", -TCMD_DUMPCONF, "dump current configuration"},
|
||||||
{"esw", CMD_GETESW, "anti-bounce read ESW of channel 0 or 1"},
|
|
||||||
{"eraseflash", CMD_ERASESTOR, "erase all flash storage"},
|
{"eraseflash", CMD_ERASESTOR, "erase all flash storage"},
|
||||||
{"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"},
|
{"saveconf", CMD_SAVECONF, "save configuration"},
|
||||||
|
{"usartspeed", CMD_USARTSPEED, "get/set USART1 speed"},
|
||||||
|
{NULL, 0, "IN/OUT"},
|
||||||
|
{"esw", CMD_GETESW, "anti-bounce read inputs"},
|
||||||
|
{"eswnow", CMD_GETESWNOW, "read current inputs' state"},
|
||||||
{"relay", CMD_RELAY, "get/set relay state (0 - off, 1 - on)"},
|
{"relay", CMD_RELAY, "get/set relay state (0 - off, 1 - on)"},
|
||||||
|
{NULL, 0, "Other commands"},
|
||||||
|
{"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"},
|
||||||
{"reset", CMD_RESET, "reset MCU"},
|
{"reset", CMD_RESET, "reset MCU"},
|
||||||
{"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"},
|
{"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"},
|
||||||
{"saveconf", CMD_SAVECONF, "save configuration"},
|
|
||||||
{"time", CMD_TIME, "get/set time (1ms, 32bit)"},
|
{"time", CMD_TIME, "get/set time (1ms, 32bit)"},
|
||||||
{"usartspeed", CMD_USARTSPEED, "get/set USART1 speed"},
|
|
||||||
{"wdtest", -TCMD_WDTEST, "test watchdog"},
|
{"wdtest", -TCMD_WDTEST, "test watchdog"},
|
||||||
{NULL, 0, NULL} // last record
|
{NULL, 0, NULL} // last record
|
||||||
};
|
};
|
||||||
@ -150,12 +158,14 @@ static errcodes dumpconf(const char _U_ *str){
|
|||||||
usart_send("\nuserconf_idx="); printi(currentconfidx);
|
usart_send("\nuserconf_idx="); printi(currentconfidx);
|
||||||
usart_send("\nuserconf_sz="); printu(the_conf.userconf_sz);
|
usart_send("\nuserconf_sz="); printu(the_conf.userconf_sz);
|
||||||
usart_send("\ncanspeed="); printu(the_conf.CANspeed);
|
usart_send("\ncanspeed="); printu(the_conf.CANspeed);
|
||||||
usart_send("\ncanid="); printu(the_conf.CANID);
|
usart_send("\ncanid_in="); printu(the_conf.CANIDin);
|
||||||
|
usart_send("\ncanid_out="); printu(the_conf.CANIDout);
|
||||||
/*for(int i = 0; i < ADC_TSENS; ++i){
|
/*for(int i = 0; i < ADC_TSENS; ++i){
|
||||||
usart_send("\nadcmul"); usart_putchar('0'+i); usart_putchar('=');
|
usart_send("\nadcmul"); usart_putchar('0'+i); usart_putchar('=');
|
||||||
usart_send(float2str(the_conf.adcmul[i], 3));
|
usart_send(float2str(the_conf.adcmul[i], 3));
|
||||||
}*/
|
}*/
|
||||||
usart_send("\nusartspeed="); printu(the_conf.usartspeed);
|
usart_send("\nusartspeed="); printu(the_conf.usartspeed);
|
||||||
|
usart_send("\nbouncetime="); printu(the_conf.bouncetime);
|
||||||
/*
|
/*
|
||||||
const char * const *p = bitfields;
|
const char * const *p = bitfields;
|
||||||
int bit = 0;
|
int bit = 0;
|
||||||
@ -254,8 +264,7 @@ void cmd_parser(const char *str){
|
|||||||
if(l == 0) goto ret;
|
if(l == 0) goto ret;
|
||||||
cmd[l] = 0;
|
cmd[l] = 0;
|
||||||
while(c->help){
|
while(c->help){
|
||||||
if(!c->cmd) continue;
|
if(c->cmd && 0 == strcmp(c->cmd, cmd)){
|
||||||
if(0 == strcmp(c->cmd, cmd)){
|
|
||||||
idx = c->idx;
|
idx = c->idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hardware.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
#ifndef _U_
|
#ifndef _U_
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "36"
|
#define BUILD_NUMBER "50"
|
||||||
#define BUILD_DATE "2024-06-01"
|
#define BUILD_DATE "2024-06-03"
|
||||||
|
|||||||
@ -26,7 +26,7 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_BLOCKSIZE = 1024);
|
PROVIDE(_BLOCKSIZE = 2048);
|
||||||
|
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE stm32f01234.ld
|
INCLUDE stm32f01234.ld
|
||||||
|
|||||||
@ -26,7 +26,7 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_BLOCKSIZE = 1024);
|
PROVIDE(_BLOCKSIZE = 2048);
|
||||||
|
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE stm32f01234.ld
|
INCLUDE stm32f01234.ld
|
||||||
|
|||||||
@ -26,7 +26,7 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_BLOCKSIZE = 1024);
|
PROVIDE(_BLOCKSIZE = 2048);
|
||||||
|
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE stm32f01234.ld
|
INCLUDE stm32f01234.ld
|
||||||
|
|||||||
@ -26,7 +26,7 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_BLOCKSIZE = 1024);
|
PROVIDE(_BLOCKSIZE = 2048);
|
||||||
|
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE stm32f01234.ld
|
INCLUDE stm32f01234.ld
|
||||||
|
|||||||
@ -26,7 +26,7 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_BLOCKSIZE = 1024);
|
PROVIDE(_BLOCKSIZE = 2048);
|
||||||
|
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE stm32f01234.ld
|
INCLUDE stm32f01234.ld
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user