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 655429d..57d1ae8 100755 Binary files a/F1:F103/FX3U/fx3u.bin and b/F1:F103/FX3U/fx3u.bin differ diff --git a/F1:F103/FX3U/fx3u.creator.user b/F1:F103/FX3U/fx3u.creator.user index b9fc616..147f593 100644 --- a/F1:F103/FX3U/fx3u.creator.user +++ b/F1:F103/FX3U/fx3u.creator.user @@ -1,10 +1,10 @@ - + 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"