fix code for new PCB

This commit is contained in:
Edward Emelianov 2025-06-02 17:03:42 +03:00
parent 9c4d8c4ba9
commit 7f44a60965
13 changed files with 357 additions and 23 deletions

View File

@ -1,8 +1,8 @@
BINARY := encoders BINARY := encoders
# MCU code # MCU code
MCU ?= F103x8 MCU ?= F103xB
# change this linking script depending on particular MCU model, # change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32f103x8.ld LDSCRIPT ?= stm32f103xB.ld
DEFINES := -DSTM32F10X_MD DEFINES := -DSTM32F10X_MD
include ../makefile.f1 include ../makefile.f1

Binary file not shown.

View File

@ -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 15.0.1, 2025-04-02T18:29:56. --> <!-- Written by QtCreator 16.0.2, 2025-06-02T17:02:57. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -13,8 +13,8 @@
<data> <data>
<variable>ProjectExplorer.Project.EditorSettings</variable> <variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value> <value type="QString" key="language">Cpp</value>

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 15.0.0, 2025-01-08T17:55:30. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{7bd84e39-ca37-46d3-be9d-99ebea85bc0d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">8</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{65a14f9e-e008-4c1b-89df-4eaa4774b6e3}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="QList&lt;int&gt;" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -13,6 +13,8 @@ spi.c
spi.h spi.h
strfunc.c strfunc.c
strfunc.h strfunc.h
usart.c
usart.h
usb_descr.c usb_descr.c
usb_descr.h usb_descr.h
usb_lib.c usb_lib.c

View File

@ -45,6 +45,7 @@ typedef struct{
*/ */
typedef struct __attribute__((packed, aligned(4))){ typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number" uint16_t userconf_sz; // "magick number"
uint16_t send232_interval; // interval (ms) of sending data to SSII over RS-232 (or 0 - not to send)
uint16_t iInterface[bTotNumEndpoints][MAX_IINTERFACE_SZ]; // hryunikod! uint16_t iInterface[bTotNumEndpoints][MAX_IINTERFACE_SZ]; // hryunikod!
uint8_t iIlengths[bTotNumEndpoints]; uint8_t iIlengths[bTotNumEndpoints];
uint8_t encbits; // encoder bits: 26 or 32 uint8_t encbits; // encoder bits: 26 or 32

View File

@ -26,11 +26,11 @@ static inline void gpio_setup(){
// AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; // AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE;
AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15 AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15
// Set led as opendrain output // Set led as opendrain output
GPIOC->CRH |= CRH(13, CNF_ODOUTPUT|MODE_SLOW); //GPIOC->CRH |= CRH(13, CNF_ODOUTPUT|MODE_SLOW);
// SPI1 pins // SPI1 pins
//GPIOA->CRL = CRL(5, CNF_AFPP|MODE_FAST) | CRL(6, CNF_FLINPUT); //GPIOA->CRL = CRL(5, CNF_AFPP|MODE_FAST) | CRL(6, CNF_FLINPUT);
// USB pullup (PA15) - pushpull output // USB pullup (PA10) - pushpull output
GPIOA->CRH = CRH(15, CNF_PPOUTPUT|MODE_SLOW); GPIOA->CRH = CRH(10, CNF_PPOUTPUT|MODE_SLOW);
// SPI2 pins // SPI2 pins
//GPIOB->CRH = CRH(13, CNF_AFPP|MODE_FAST) | CRH(14, CNF_FLINPUT); //GPIOB->CRH = CRH(13, CNF_AFPP|MODE_FAST) | CRH(14, CNF_FLINPUT);
} }

View File

@ -25,9 +25,9 @@
// USB pullup (not present in bluepill, should be soldered) - PA15 // USB pullup (not present in bluepill, should be soldered) - PA15
#define USBPU_port GPIOA #define USBPU_port GPIOA
#define USBPU_pin (1<<15) #define USBPU_pin (1<<10)
#define USBPU_ON() pin_set(USBPU_port, USBPU_pin) #define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) #define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
#define LED_blink(x) pin_toggle(x ## _port, x ## _pin) #define LED_blink(x) pin_toggle(x ## _port, x ## _pin)
#define LED_on(x) pin_clear(x ## _port, x ## _pin) #define LED_on(x) pin_clear(x ## _port, x ## _pin)

View File

@ -22,7 +22,7 @@
#include "proto.h" #include "proto.h"
#include "spi.h" #include "spi.h"
#include "strfunc.h" #include "strfunc.h"
//#include "usart.h" #include "usart.h"
#include "usb_dev.h" #include "usb_dev.h"
volatile uint32_t Tms = 0; volatile uint32_t Tms = 0;
@ -49,6 +49,7 @@ static void printResult(BiSS_Frame *result){
static void proc_enc(uint8_t idx){ static void proc_enc(uint8_t idx){
static uint32_t lastMSG[2], gotgood[2], gotwrong[2]; static uint32_t lastMSG[2], gotgood[2], gotwrong[2];
static uint32_t lastXval = 0, usartT = 0;
int iface = idx ? I_Y : I_X; int iface = idx ? I_Y : I_X;
char ifacechr = idx ? 'Y' : 'X'; char ifacechr = idx ? 'Y' : 'X';
if(CDCready[iface]){ if(CDCready[iface]){
@ -71,6 +72,13 @@ static void proc_enc(uint8_t idx){
if(!encbuf) return; if(!encbuf) return;
BiSS_Frame result = parse_biss_frame(encbuf, the_conf.encbufsz); BiSS_Frame result = parse_biss_frame(encbuf, the_conf.encbufsz);
char *str = result.crc_valid ? u2str(result.data) : NULL; char *str = result.crc_valid ? u2str(result.data) : NULL;
if(result.crc_valid){
if(idx == 0) lastXval = result.data;
else if(the_conf.send232_interval && Tms - usartT >= the_conf.send232_interval){
usart_send_enc(lastXval, result.data);
usartT = Tms;
}
}
uint8_t testflag = (idx) ? user_pars.testy : user_pars.testx; uint8_t testflag = (idx) ? user_pars.testy : user_pars.testx;
if(CDCready[I_CMD]){ if(CDCready[I_CMD]){
if(testflag){ if(testflag){
@ -109,7 +117,7 @@ static void proc_enc(uint8_t idx){
} }
int main(){ int main(){
uint32_t lastT = 0; uint32_t lastT = 0, usartT = 0;
StartHSE(); StartHSE();
flashstorage_init(); flashstorage_init();
hw_setup(); hw_setup();
@ -119,11 +127,12 @@ int main(){
#ifndef EBUG #ifndef EBUG
iwdg_setup(); iwdg_setup();
#endif #endif
usart_setup();
USBPU_ON(); USBPU_ON();
while (1){ while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(Tms - lastT > 499){ if(Tms - lastT > 499){
LED_blink(LED0); //LED_blink(LED0);
lastT = Tms; lastT = Tms;
} }
if(CDCready[I_CMD]){ if(CDCready[I_CMD]){
@ -133,11 +142,19 @@ int main(){
} }
proc_enc(0); proc_enc(0);
proc_enc(1); proc_enc(1);
int started[2] = {0, 0};
if(the_conf.flags.monit){ if(the_conf.flags.monit){
for(int i = 0; i < 2; ++i){ for(int i = 0; i < 2; ++i){
if(Tms - monitT[i] >= the_conf.monittime) spi_start_enc(i); if(Tms - monitT[i] >= the_conf.monittime){
spi_start_enc(i);
started[i] = 1;
} }
} }
} }
if(the_conf.send232_interval && Tms - usartT >= the_conf.send232_interval){
for(int i = 0; i < 2; ++i) if(!started[i]) spi_start_enc(i);
usartT = Tms;
}
}
return 0; return 0;
} }

View File

@ -22,6 +22,7 @@
#include "proto.h" #include "proto.h"
#include "spi.h" #include "spi.h"
#include "strfunc.h" #include "strfunc.h"
#include "usart.h"
#include "usb_dev.h" #include "usb_dev.h"
#include "version.inc" #include "version.inc"
@ -77,6 +78,8 @@ typedef enum{
C_maxzeros, C_maxzeros,
C_autom, C_autom,
C_amperiod, C_amperiod,
C_usart,
C_ssii,
C_AMOUNT C_AMOUNT
} cmd_e; } cmd_e;
@ -257,6 +260,10 @@ static errcode_e setuintpar(cmd_e idx, char *par){
if(val > 255 || val == 0) return ERR_BADPAR; if(val > 255 || val == 0) return ERR_BADPAR;
the_conf.monittime = val; the_conf.monittime = val;
break; break;
case C_ssii:
if(val > UINT16_MAX) return ERR_BADPAR;
the_conf.send232_interval = val;
break;
default: default:
return ERR_BADCMD; return ERR_BADCMD;
} }
@ -282,6 +289,9 @@ static errcode_e setuintpar(cmd_e idx, char *par){
case C_amperiod: case C_amperiod:
val = the_conf.monittime; val = the_conf.monittime;
break; break;
case C_ssii:
val = the_conf.send232_interval;
break;
default: default:
return ERR_BADCMD; return ERR_BADCMD;
} }
@ -358,9 +368,15 @@ static errcode_e dumpconf(cmd_e _U_ idx, char _U_ *par){
setuintpar(C_encbufsz, NULL); setuintpar(C_encbufsz, NULL);
setuintpar(C_maxzeros, NULL); setuintpar(C_maxzeros, NULL);
setuintpar(C_minzeros, NULL); setuintpar(C_minzeros, NULL);
setuintpar(C_ssii, NULL);
return ERR_SILENCE; return ERR_SILENCE;
} }
static errcode_e usart(cmd_e _U_ idx, char _U_ *par){
usart_send_enc(0xdeadbeef, 0xbeefdead);
return ERR_OK;
}
// text commands // text commands
static const funcdescr_t commands[C_AMOUNT] = { static const funcdescr_t commands[C_AMOUNT] = {
[C_dummy] = {"dummy", dummy}, [C_dummy] = {"dummy", dummy},
@ -392,6 +408,8 @@ static const funcdescr_t commands[C_AMOUNT] = {
[C_maxzeros] = {"maxzeros", setuintpar}, [C_maxzeros] = {"maxzeros", setuintpar},
[C_autom] = {"autom", setboolpar}, [C_autom] = {"autom", setboolpar},
[C_amperiod] = {"amperiod", setuintpar}, [C_amperiod] = {"amperiod", setuintpar},
[C_usart] = {"usart", usart},
[C_ssii] = {"ssii", setuintpar},
}; };
typedef struct{ typedef struct{
@ -425,6 +443,7 @@ static const help_t helpmessages[] = {
{C_setiface1, "set name of first (command) interface"}, {C_setiface1, "set name of first (command) interface"},
{C_setiface2, "set name of second (axis X) interface"}, {C_setiface2, "set name of second (axis X) interface"},
{C_setiface3, "set name of third (axis Y) interface"}, {C_setiface3, "set name of third (axis Y) interface"},
{C_ssii, "change interval (ms) of sending enc data to SSII (0 - don't send)"},
{C_storeconf, "store configuration in flash memory"}, {C_storeconf, "store configuration in flash memory"},
{-1, "Debug commands"}, {-1, "Debug commands"},
{C_dummy, "dummy integer setter/getter"}, {C_dummy, "dummy integer setter/getter"},
@ -433,11 +452,18 @@ static const help_t helpmessages[] = {
{C_sendY, "send text string to Y encoder's terminal"}, {C_sendY, "send text string to Y encoder's terminal"},
{C_testX, "test X-axis throughput"}, {C_testX, "test X-axis throughput"},
{C_testY, "test Y-axis throughput"}, {C_testY, "test Y-axis throughput"},
{C_usart, "send test encoders data over usart"},
{-1, NULL}, {-1, NULL},
}; };
static errcode_e help(_U_ cmd_e idx, _U_ char* par){ static errcode_e help(_U_ cmd_e idx, _U_ char* par){
CMDWRn("https://github.com/eddyem/stm32samples/tree/master/F1:F103/BISS_C_encoders build #" BUILD_NUMBER " @ " BUILD_DATE); CMDWRn("https://github.com/eddyem/stm32samples/tree/master/F1:F103/BISS_C_encoders "
#ifdef EBUG
"debug "
#else
"release "
#endif
"build #" BUILD_NUMBER " @ " BUILD_DATE);
CMDWRn("\ncommands format: 'command[=setter]\\n'"); CMDWRn("\ncommands format: 'command[=setter]\\n'");
const help_t *c = helpmessages; const help_t *c = helpmessages;
while(c->help){ while(c->help){

View File

@ -0,0 +1,107 @@
/*
* usart.c
*
* Copyright 2018 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <string.h>
#include "stm32f1.h"
#include "usart.h"
// magick starting sequence
#define ENC_MAGICK (204)
// buffers for out ringbuffer and DMA send
static uint8_t txbuf[UARTBUFSZ];
static volatile int usart_txrdy = 1; // transmission done
void usart_send(const uint8_t *buf, int buflen){
while(!usart_txrdy);
if(buflen > UARTBUFSZ) buflen = UARTBUFSZ;
memcpy(txbuf, buf, buflen);
DMA1_Channel7->CCR &= ~DMA_CCR_EN;
DMA1_Channel7->CMAR = (uint32_t) txbuf; // mem
DMA1_Channel7->CNDTR = buflen;
usart_txrdy = 0;
DMA1_Channel7->CCR |= DMA_CCR_EN;
}
// encoders raw data
typedef struct __attribute__((packed)){
uint8_t magick;
uint32_t encY;
uint32_t encX;
uint8_t crc[4];
} enc_t;
void usart_send_enc(uint32_t encX, uint32_t encY){
enc_t edata;
uint8_t *databuf = (uint8_t*) &edata;
uint32_t POS_SUM = 0;
for(int i = 1; i < 9; ++i) POS_SUM += databuf[i];
edata.crc[0] = POS_SUM >> 8;
edata.crc[1] = ((0xFFFF - POS_SUM) & 0xFF) - edata.crc[0];
edata.crc[2] = (0xFFFF - POS_SUM) >> 8;
edata.crc[3] = 0;
edata.magick = ENC_MAGICK;
edata.encX = encX;
edata.encY = encY;
usart_send(databuf, sizeof(enc_t));
}
/*
* USART2 speed: baudrate = Fck/(USARTDIV)
* USARTDIV stored in USART->BRR
*
* for 36MHz USARTDIV=36000/f(kboud)
*/
void usart_setup(){
uint32_t tmout = 16000000;
// PA9 - Tx, PA10 - Rx
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
GPIOA->CRL = (GPIOA->CRL & ~(GPIO_CRL_CNF2 | GPIO_CRL_CNF3)) |
CRL(2, CNF_AFPP|MODE_NORMAL) | CRL(3, CNF_FLINPUT|MODE_INPUT);
// USART1 Tx DMA - Channel4 (Rx - channel 5)
DMA1_Channel7->CPAR = (uint32_t) &USART2->DR; // periph
DMA1_Channel7->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
// Tx CNDTR set @ each transmission due to data size
NVIC_SetPriority(DMA1_Channel7_IRQn, 3);
NVIC_EnableIRQ(DMA1_Channel7_IRQn);
//NVIC_SetPriority(USART1_IRQn, 0);
// setup usart1
USART2->BRR = 36000000 / 153000;
USART2->CR1 = USART_CR1_TE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USART1->SR & USART_SR_TC)){
IWDG->KR = IWDG_REFRESH;
if(--tmout == 0) break;
} // polling idle frame Transmission
USART2->SR = 0; // clear flags
USART2->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ
USART2->CR3 = USART_CR3_DMAT; // enable DMA Tx
}
void dma1_channel7_isr(){
if(DMA1->ISR & DMA_ISR_TCIF7){ // Tx
DMA1->IFCR = DMA_IFCR_CTCIF7; // clear TC flag
usart_txrdy = 1;
}
}

View File

@ -21,12 +21,10 @@
#pragma once #pragma once
#include "stdint.h"
#define UARTBUFSZ (128) #define UARTBUFSZ (128)
// macro for static strings void usart_send(const uint8_t *buf, int buflen);
#define USEND(str) usart_send(str)
void usart_transmit();
void usart_setup(); void usart_setup();
void usart_send(const char *str); void usart_send_enc(uint32_t encX, uint32_t encY);
void usart_putchar(const char ch);

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "96" #define BUILD_NUMBER "107"
#define BUILD_DATE "2025-04-04" #define BUILD_DATE "2025-06-02"