From 1b73ebad2c99a4c050728cf0f8d3213bbe221f51 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Fri, 27 Sep 2024 15:46:12 +0300 Subject: [PATCH] FX3U code ready --- F1:F103/FX3U/Readme.md | 310 ++++++++++++++++++++++++++++++++- F1:F103/FX3U/can.c | 30 ++-- F1:F103/FX3U/canproto.c | 6 +- F1:F103/FX3U/fx3u.bin | Bin 15772 -> 15808 bytes F1:F103/FX3U/fx3u.creator.user | 38 ++-- F1:F103/FX3U/hardware.c | 4 +- F1:F103/FX3U/usart.c | 9 +- F1:F103/FX3U/version.inc | 4 +- 8 files changed, 346 insertions(+), 55 deletions(-) diff --git a/F1:F103/FX3U/Readme.md b/F1:F103/FX3U/Readme.md index a9e7217..e35bfb0 100644 --- a/F1:F103/FX3U/Readme.md +++ b/F1:F103/FX3U/Readme.md @@ -1,25 +1,30 @@ A usefull thing made of chineese FX3U clone =========================================== -Works over RS-232 (default: 115200, 8N1) or CAN (default 250000 baud). +Works over RS-232 (default: 115200, 8N1), CAN (default: 250000 baud) +or MODBUS-RTU (default: 9600, 8N1). You can see pinout table in file `hardware.c`. ## Serial protocol (each string ends with '\n'). -(TODO: add new) +Values in parentheses after flags command is its bit number in whole uint32_t. +E.g. to reset flag "f_relay_inverted" you can call `f_relay_inverted=0` or +`flags2=0`. ``` + commands format: parameter[number][=setter] parameter [CAN idx] - help -------------------------- - CAN bus commands: +CAN bus commands: canbuserr - print all CAN bus errors (a lot of if not connected) cansniff - switch CAN sniffer mode +s - send CAN message: ID 0..8 data bytes - Configuration: +Configuration: bounce [14] - set/get anti-bounce timeout (ms, max: 1000) canid [6] - set both (in/out) CAN ID / get in CAN ID canidin [7] - get/set input CAN ID @@ -27,29 +32,45 @@ canidout [8] - get/set output CAN ID canspeed [5] - get/set CAN speed (bps) dumpconf - dump current configuration eraseflash [10] - erase all flash storage +f_relay_inverted (2) - inverted state between relay and inputs +f_send_esw_can (0) - change of IN will send status over CAN with `canidin` +f_send_relay_can (1) - change of IN will send also CAN command to change OUT with `canidout` +f_send_relay_modbus (3) - change of IN will send also MODBUS command to change OUT with `modbusidout` (only for master!) +flags [17] - set/get configuration flags (as one U32 without parameter or Nth bit with) +modbusid [20] - set/get modbus slave ID (1..247) or set it master (0) +modbusidout [21] - set/get modbus slave ID (0..247) to send relay commands +modbusspeed [22] - set/get modbus speed (1200..115200) saveconf [9] - save configuration usartspeed [15] - get/set USART1 speed - IN/OUT: +IN/OUT: adc [4] - get raw ADC values for given channel esw [12] - anti-bounce read inputs eswnow [13] - read current inputs' state led [16] - work with onboard LED relay [11] - get/set relay state (0 - off, 1 - on) - Other commands: +Other commands: +inchannels [18] - get u32 with bits set on supported IN channels mcutemp [3] - get MCU temperature (*10degrC) +modbus - send modbus request with format "slaveID fcode regaddr nregs [N data]", to send zeros you can omit rest of 'data' +modbusraw - send RAW modbus request (will send up to 62 bytes + calculated CRC) +outchannels [19] - get u32 with bits set on supported OUT channels reset [1] - reset MCU -s - send CAN message: ID 0..8 data bytes time [2] - get/set time (1ms, 32bit) wdtest - test watchdog -error=badcmd + + ``` Value in square brackets is CAN bus command code. +The INs are changed compared to original "FX3U" clone: instead of the absent IN8 I use the on-board +button "RUN". + ## CAN bus protocol +Default CAN speed is 250kbaud. Default CAN ID: 1 and 2 for slave. All data in little-endian format! BYTE - MEANING @@ -62,6 +83,13 @@ BYTE - MEANING 4..7 - (int32_t) - data. +When device receives CAN packet with its ID or ID=0 ("broadcast" message) it check this packet, perform some action and sends answer +(usually - getter). If command can't be execute or have wrong data (bad command, bad parameter number etc) the device sends back +the same packet with error code inserted. + +When runnming getter you can send only three bytes: command code and parameter number. Sending "no parameter" instead of parno +means in some commands "all data" (e.g. get/set all relays or get all inputs). + ### CAN bus error codes 0 - `ERR_OK` - all OK, @@ -76,7 +104,271 @@ BYTE - MEANING 5 - `ERR_CANTRUN` - can't run given command due to bad parameters or other reason. +### CAN bus command codes + +Number - enum from canproto.h - text command analog + +0 - CMD_PING - ping + +1- CMD_RESET - reset + +2 - CMD_TIME - time + +3 - CMD_MCUTEMP - mcutemp + +4 - CMD_ADCRAW - adc + +5 - CMD_CANSPEED - canspeed + +6 - CMD_CANID - canid + +7 - CMD_CANIDin - canidin + +8 - CMD_CANIDout - canidout + +9 - CMD_SAVECONF - saveconf + +10 - CMD_ERASESTOR - eraseflash + +11 - CMD_RELAY - relay + +12 - CMD_GETESW - esw + +13 - CMD_GETESWNOW - eswnow + +14 - CMD_BOUNCE - bounce + +15 - CMD_USARTSPEED - usartspeed + +16 - CMD_LED - led + +17 - CMD_FLAGS - flags + +18 - CMD_INCHNLS - inchannels + +19 - CMD_OUTCHNLS - outchannels + +20 - CMD_MODBUSID - modbusid + +21 - CMD_MODBUSIDOUT - modbusidout + +22 - CMD_MODBUSSPEED - modbusspeed + +### Examples of CAN commands (bytes of data transmitted with given ID) + +(all data in HEX) + +Get current time: "02 00 00". Answer something like "02 00 00 00 de ad be ef", where last four bytes +is time value (in milliseconds) from powering on. + +Set relay number 5: "0b 00 85 00 01 00 00 00", answer: "0b 00 05 00 01 00 00 00". + +Set relays 0..3 and reset other: "0b 00 ff 00 07 00 00 00", answer: "0b 00 7f 00 07 00 00 00". + +Changing flags is the same as for text command: with parameter number (0..31) it will only change given +bit value, without ("no par" - 0x7f) will change all bits like whole uint32_t. ## MODBUS-RTU protocol -(TODO) \ No newline at end of file +The device can work as master or slave. Default format is 9600-8N1. BIG ENDIAN (like standard requires). +Default device ID is 1 ans 2 for target of "relay command" (if ID would be changed to 0 and flag `f_send_relay_modbus` set. + +To run in master mode you should set its modbus ID to zero. Command `modbus` lets you to send strict +formal modbus packet in format "slaveID fcode regaddr nregs [N data]" (all are space-delimited numbers in +decimal, hexadecimal (e.g. 0xFF), octal (e.g. 075) or binary (e.g. 0b1100110) format. +Here "slaveID" - one byte; "fcode" - one byte; "regaddr" - two bytes big endian; "nregs" - two bytes big endian; +"N" - one byte; "data" - N bytes. +Optional data bytes allowed only for "multiple" functions. In case of simple setters "nregs" is two bytes data +sent to slave. + +The command `modbusraw` will not check your data, just add CRC and send into bus. + +In master mode you can activate flag `f_send_relay_modbus`. In this case each time the IN state changes +device will send command with ID=`modbusidout` to change corresponding relays. So, like for CAN commands +you can bind several devices to transmit IN states of one to OUT states of another. +If `modbusidout` is zero, master will send broadcasting command. Slaves non answer for broadcast, only making +required action. + +The hardware realisation of modbus based on UART4. Both input and output works over DMA, signal of packet end +is IDLE interrupt. This device doesn't supports full modbus protocol realisation: no 3.5 idle frames as packet +end; no long packets (input buffer is 68 bytes, allowing no more that 67 bytes; output buffer is 64 bytes, allowing +no more that 64 bytes). Maximal modbus slave ID is 247. You can increase in/out buffers size changing value of +macros `MODBUSBUFSZI` and `MODBUSBUFSZO` in `modbusrtu.h`. + +In slave mode device doesn't support whole CAN-bus commands range. Next I describe allowed commands. + +There are five holding registers. "[R]" means read-only, "[W]" - write-only, "[RW]" - read and write. + +0 - MR_RESET [W] - reset MCU. + +1 - MR_TIME [RW] - read or set MCU time (milliseconds, uint32_t). + +2 - MR_LED [RW] - read or change on-board LED state. + +3 - MR_INCHANNELS [R] - get uint32_t value where each N-th bit means availability of N-th IN channel +(e.g. if 9th channel is physically absent 9th bit would be 0). + +### Supported functional codes + +#### 01 - read coil +Read state of all relays. Obligatory regaddr="00 00", nregs="00 N", where "N" is 8-multiple +number (in case of 10-relay module: 8 or 16). You will reseive N/8 bytes of data with relays' status (e.g. most +lest significant bit is state or relay0, next - relay1 and so on). + +Example: "01 01 00 00 00 10" - read state of all relays. If only relay 10 active you will +receive: "01 01 02 04 00". + +Errors: "02" - "regaddr" isn't zero; "03" - N isn't multiple of 8 or too large. + +#### 02 - read discrete input +Read state of all discrete inputs. Input/output parameters are the same like for "read coil". + +Example: "01 02 00 00 00 08" - read 8 first INs. Answer if first 4 inputs active (disconnected): +"01 02 01 0f". + +Errors: like for "read coil". + +#### 03 - read holding register +You can read value of non write-only registers. You can read only one register by time. + +Example: "01 03 00 01 00 01" - read time. Answer: "01 03 04 00 15 53 01", where 0x00155301 is 1397.505 seconds +from device start. + +Errors: "02" - "regaddr" is wrong, "03" - "regno" isn't 1. + +#### 04 - read input register +Read "nregs" ADC channels starting from "regaddr" number. + +Example: "01 04 00 05 00 04" - read channels 5..8. +Answer: "01 04 08 08 6c 00 21 00 33 00 41" - got 0x86c (2156) for 5th channel and so on. + +Errors: "02" - wrong starting number, "03" - wrong amount (zero or N+start > last channel available). + +#### 05 - write coil +Change single relay state. "nregs" is value (0 - off, non-0 - on), "regaddr" is relay number. + +Example: "01 05 00 03 00 01" - turn 3rd relay on. Answer: "01 05 00 03 00 01". + +Errors: "02" - wrong relay number. + +#### 06 - write holding register +Write data to non read-only register (reset MCU, change time value or turn LED on/off). + +Example: "01 06 00 02 00 01" - turn LED on. Answer: "01 06 00 02 00 01". + +Errors: "02" - wrong register. + +#### 0f - write multiple coils +Change state of all relays by once. Here "regaddr" should be "00 00", +"nregs" should be multiple of 8, "N" should be equal ("nregs"+7)/8. Each data bit means nth relay state. + +Example: "01 0f 00 00 00 08 01 ff" - turn on relays 0..7. +Answer: "01 0f 00 00 00 08". + +Errors: "02" - "regaddr" isn't zero, "03" - wrong amount of relays, "07" - can't change relay values. + + +#### 10 - write multiple registers +You can write only four "registers" by once changing appropriate uint32_t value. +The only "register" you can change is 01 - MR_TIME. "nregs" should be equal 1. + +Example: "01 10 00 01 00 01 04 00 00 00 00" - clears Tms counter, starting time from zero. +Answer: "01 10 00 01 00 01". + +Errors: "02" - wrong register. + + +### Error codes +01 - ME_ILLEGAL_FUNCION - The function code received in the request is not an authorized action for the slave. + +02 - ME_ILLEGAL_ADDRESS - The data address received by the slave is not an authorized address for the slave. + +03 - ME_ILLEGAL_VALUE - The value in the request data field is not an authorized value for the slave. + +04 - ME_SLAVE_FAILURE - The slave fails to perform a requested action because of an unrecoverable error. + +05 - ME_ACK - The slave accepts the request but needs a long time to process it. + +06 - ME_SLAVE_BUSY - The slave is busy processing another command. + +07 - ME_NACK - The slave cannot perform the programming request sent by the master. + +08 - ME_PARITY_ERROR - Memory parity error: slave is almost dead. + + + + +# Short programming guide + +## Adding a new value to flash storage + +All storing values described in structure `user_conf` (`flash.h`). You can add there any new value +but be carefull with 32-bit alignment. Bit flags stored as union `confflags_t` combining 32-bit and 1-bit access. +After you add this new value don't forget to add setter/getter and string describing it in function `dumpconf`. + +Text protocol allows you to work with flags by their semantic name. So to add some flag you should also modify +`proto.c`: + +- add text constant with flag name; +- add address of this constant into `bitfields` array (according to bit order in flags); +- add appropriate enum into `text_cmd`; +- add appropriate string into `funclist`: pointer to string constant, enum field and help text; +- modify function `confflags` for setter/getter of new flag. + + +## Adding a new command + +All base commands are processed in files `canproto.c` and `proto.c`. `modbusproto.c` is for modbus-specific commands. + +To add CAN/serial command you should first add a field to anonimous enum in `canproto.h`, which will be number code of +given CANbus command. Codes of serial-only commands are stored in enum `text_cmd` of file `proto.c`. + +### Add both CAN/serial command +- add enum in `canproto.c`; +- add string const with text name of this command in `proto.c`; +- add string to `funclist` with address of string const, enum and help; +- add command handler into `canproto.c` and describer into array `funclist` (index should be equal +to command code, struct consists from pointer to handler, minimal and maximal value and minimal data length +of can packet). If min==max then argument wouldn't be checked. + +The handler returns one of `errcodes` and have as argument only pointer to `CAN_message` structure. +So, serial command parser before call this handler creates CAN packet from user data. +Format of command is next: "cmd[X][=VAL]", where "cmd" is command text, "X" - optional parameter, +"VAL" - value for setter. So the packet would be "C C P 0 VAL0 VAL1 VAL2 VAL3", where +"C" - command code, "P" - parameter number (or 0x7f" if X is omit) OR'ed with 0x80 for setter, +VALx - xth byte (little endian) of user value. + +For setting/getting uint32_t paramegers (especially configuration parameters) you can use handler `u32setget`. +For bit flags - `flagsetget`. + +To work with bit-flags by particular name use `confflags` handler of `proto.c`. + +### Add serial-only command +In this case there's no CAN handler. You work only with `proto.c`. +- add enum in `text_cmd`; +- add string const with text name of this command; +- add string to `funclist` with address of string const, enum and help; +- add command handler; +- add pointer to this handler into `textfunctions` array. + +Handler also returns one of `errcodes`, but have next arguments: +- `const char *txt` - all text (excluding spaces in beginning) after command in user string; +- `text_cmd command` - number of command (useful when you have common handler for several commands). + +## Working with modbus + +All exceptions and functional codes described as enums in `modbusrtu.h`. +To form request or responce use structs `modbus_request` and `modbus_responce`. `data` fields in this +structs is big-endian storing bytes in order like they will be sent via RS-485. +Amount of data bytes should be not less then `datalen` value. For requests that don't need data, +`data` may be NULL regardless `datalen` (for Fcode <= 6). `regno` is amount of registers or +data written to register dependent on `Fcode`. +The responce struct of error codes have NULL in `data` and `datalen` is appropriate exception code. + +All high-level commands are in `modbusproto.c`. To add new `register` you should edit `modbus_regusters` +enum in `modbusproto.h`. + +The main parsing pipeline is `parse_modbus_request` in `modbusproto.c`. +Here you can add parsing of new functional codes. + +To work with new "registers" edit `readreg`, `writereg` or `writeregs`. diff --git a/F1:F103/FX3U/can.c b/F1:F103/FX3U/can.c index 5161d68..7870374 100644 --- a/F1:F103/FX3U/can.c +++ b/F1:F103/FX3U/can.c @@ -119,8 +119,8 @@ void CAN_setup(uint32_t speed){ else if(speed > CAN_MAX_SPEED) speed = CAN_MAX_SPEED; uint32_t tmout = 16000000; // Configure GPIO: PD0 - CAN_Rx, PD1 - CAN_Tx - AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP3; - AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; // I don't know why, but without this string JTAG works (despite on turning it off in hardware.c)! + // I don't know why, but without AFIO_MAPR_SWJ_CFG_DISABLE here JTAG works (despite on turning it off in hardware.c)! + AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP3 | AFIO_MAPR_SWJ_CFG_DISABLE; GPIOD->CRL = (GPIOD->CRL & ~(CRL(0,0xf)|CRL(1,0xf))) | CRL(0, CNF_FLINPUT | MODE_INPUT) | CRL(1, CNF_AFPP | MODE_NORMAL); /* Enable the peripheral clock CAN */ @@ -171,9 +171,9 @@ void CAN_setup(uint32_t speed){ CAN1->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_BOFIE; /* (13) */ /* Configure IT */ - NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0); // RX FIFO0 IRQ - NVIC_SetPriority(CAN1_RX1_IRQn, 0); // RX FIFO1 IRQ - NVIC_SetPriority(CAN1_SCE_IRQn, 0); // RX status changed IRQ + NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 4); // RX FIFO0 IRQ + NVIC_SetPriority(CAN1_RX1_IRQn, 4); // RX FIFO1 IRQ + NVIC_SetPriority(CAN1_SCE_IRQn, 4); // RX status changed IRQ NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_EnableIRQ(CAN1_RX1_IRQn); NVIC_EnableIRQ(CAN1_SCE_IRQn); @@ -192,10 +192,7 @@ void CAN_sniffer(uint8_t issniffer){ void CAN_printerr(){ uint32_t last_err_code = CAN1->ESR; - if(!last_err_code){ - usart_send("No errors\n"); - return; - } + if(!last_err_code) return; usart_send("Receive error counter: "); usart_send(u2str((last_err_code & CAN_ESR_REC)>>24)); usart_send("\nTransmit error counter: "); @@ -226,6 +223,7 @@ void CAN_proc(){ if(flags.can_printoff){ const char *e; switch(can_status){ + case CAN_STOP: e = "STOP"; break; case CAN_ERR: e = "ERRI"; break; case CAN_FIFO_OVERRUN: e = "FIFO_OVERRUN"; break; default: e = "UNKNOWN"; @@ -234,7 +232,8 @@ void CAN_proc(){ usart_send(e); newline(); CAN_printerr(); } - CAN_reinit(0); + if(can_status == CAN_FIFO_OVERRUN) can_status = CAN_READY; + else CAN_reinit(0); } // check for messages in FIFO0 & FIFO1 if(CAN1->RF0R & CAN_RF0R_FMP0){ @@ -345,7 +344,7 @@ static void can_process_fifo(uint8_t fifo_num){ } IWDG->KR = IWDG_REFRESH; if(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 } //if(*RFxR & CAN_RF0R_FULL0) *RFxR &= ~CAN_RF0R_FULL0; *RFxR = 0; // clear FOVR & FULL @@ -353,28 +352,25 @@ static void can_process_fifo(uint8_t fifo_num){ void usb_lp_can_rx0_isr(){ // Rx FIFO0 (overrun) if(CAN1->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun - CAN1->RF0R &= ~CAN_RF0R_FOVR0; + CAN1->RF0R = CAN_RF0R_FOVR0; // clear flag can_status = CAN_FIFO_OVERRUN; - RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN; } } void can_rx1_isr(){ // Rx FIFO1 (overrun) if(CAN1->RF1R & CAN_RF1R_FOVR1){ - CAN1->RF1R &= ~CAN_RF1R_FOVR1; + CAN1->RF1R = CAN_RF1R_FOVR1; // clear flag can_status = CAN_FIFO_OVERRUN; - RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN; } } void can_sce_isr(){ // status changed if(CAN1->MSR & CAN_MSR_ERRI){ // Error - CAN1->MSR &= ~CAN_MSR_ERRI; + CAN1->MSR = CAN_MSR_ERRI; // clear flag // request abort for problem mailbox if(CAN1->TSR & CAN_TSR_TERR0) CAN1->TSR |= CAN_TSR_ABRQ0; if(CAN1->TSR & CAN_TSR_TERR1) CAN1->TSR |= CAN_TSR_ABRQ1; if(CAN1->TSR & CAN_TSR_TERR2) CAN1->TSR |= CAN_TSR_ABRQ2; can_status = CAN_ERR; - RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN; } } diff --git a/F1:F103/FX3U/canproto.c b/F1:F103/FX3U/canproto.c index 466d6f9..c9cdd9f 100644 --- a/F1:F103/FX3U/canproto.c +++ b/F1:F103/FX3U/canproto.c @@ -220,9 +220,9 @@ static const commonfunction funclist[CMD_AMOUNT] = { [CMD_CANIDout] = {canidout, 1, 0x7ff, 0}, [CMD_SAVECONF] = {saveconf, 0, 0, 0}, [CMD_ERASESTOR] = {erasestor, 0, 0, 0}, - [CMD_RELAY] = {relay, 0, INT32_MAX, 0}, - [CMD_GETESW] = {eswg, 0, INT32_MAX, 0}, - [CMD_GETESWNOW] = {esw, 0, INT32_MAX, 0}, + [CMD_RELAY] = {relay, 0, 0, 0}, + [CMD_GETESW] = {eswg, 0, 0, 0}, + [CMD_GETESWNOW] = {esw, 0, 0, 0}, [CMD_BOUNCE] = {u32setget, 0, 1000, 0}, [CMD_USARTSPEED] = {u32setget, 1200, 3000000, 0}, [CMD_LED] = {led, 0, 0, 0}, diff --git a/F1:F103/FX3U/fx3u.bin b/F1:F103/FX3U/fx3u.bin index 655429dfb6286362d465d73456c84762f352c9bd..57d1ae857ece6251630cbc1f590b21bb6367ce9c 100755 GIT binary patch delta 4559 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 delta 4351 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 - + EnvironmentId - {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} + {cf63021e-ef53-49b0-b03b-2f2570cdf3b6} ProjectExplorer.Project.ActiveTarget @@ -39,21 +39,21 @@ 1 0 false - true + false false - 0 + 1 true true 0 8 true false - 1 + 2 true - false + true true *.md, *.MD, Makefile - false + true true true @@ -69,15 +69,17 @@ true true + false + 0 true true true Builtin.DefaultTidyAndClazy - 8 - true + 4 + false @@ -91,12 +93,12 @@ Desktop Desktop Desktop - {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + {91347f2c-5221-46a7-80b1-0a054ca02f79} 0 0 0 - /Big/Data/00__Electronics/STM32/F1-nolib/CAR_CANbus/WindShield + /home/eddy/Docs/SAO/ELECTRONICS/STM32/F1-srcs/usbcan @@ -106,8 +108,8 @@ GenericProjectManager.GenericMakeStep 1 - Build - Build + Сборка + Сборка ProjectExplorer.BuildSteps.Build @@ -119,8 +121,8 @@ GenericProjectManager.GenericMakeStep 1 - Clean - Clean + Очистка + Очистка ProjectExplorer.BuildSteps.Clean 2 @@ -135,8 +137,8 @@ 0 - Deploy - Deploy + Развёртывание + Развёртывание ProjectExplorer.BuildSteps.Deploy 1 @@ -148,9 +150,7 @@ true true - 0 true - 2 diff --git a/F1:F103/FX3U/hardware.c b/F1:F103/FX3U/hardware.c index 395e48c..dde1ae4 100644 --- a/F1:F103/FX3U/hardware.c +++ b/F1:F103/FX3U/hardware.c @@ -85,8 +85,10 @@ void gpio_setup(void){ // PD0 & PD1 (CAN) setup in can.c; PA9 & PA10 (USART) in usart.c RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN; - // Turn off JTAG/SWD to use PA14 + // Turn off JTAG/SWD to use PA14 (I don't know why, but here it doesn't work, need to repeat in can.c) +#ifndef EBUG AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; +#endif // be sure that all OK // __ISB(); // __DSB(); diff --git a/F1:F103/FX3U/usart.c b/F1:F103/FX3U/usart.c index df891ab..18cee3e 100644 --- a/F1:F103/FX3U/usart.c +++ b/F1:F103/FX3U/usart.c @@ -115,15 +115,16 @@ void usart_setup(uint32_t speed){ NVIC_SetPriority(USART1_IRQn, 0); // setup usart1 USART1->BRR = 72000000 / speed; - USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART + USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; // 1start,8data,nstop; enable Rx/Tx uint32_t tmout = 16000000; - while(!(USART1->SR & USART_SR_TC)){ + while(!(USART1->SR & USART_SR_TC)){ // polling idle frame Transmission IWDG->KR = IWDG_REFRESH; if(--tmout == 0) break; - } // polling idle frame Transmission + } + (void) USART1->DR; // clear IDLE etc USART1->SR = 0; // clear flags - USART1->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx + USART1->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ NVIC_EnableIRQ(USART1_IRQn); } diff --git a/F1:F103/FX3U/version.inc b/F1:F103/FX3U/version.inc index 60acc86..37d0e76 100644 --- a/F1:F103/FX3U/version.inc +++ b/F1:F103/FX3U/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "105" -#define BUILD_DATE "2024-09-26" +#define BUILD_NUMBER "116" +#define BUILD_DATE "2024-09-27"