diff --git a/F1:F103/BISS_C_encoders/Makefile b/F1:F103/BISS_C_encoders/Makefile index 46fa24e..3aa2506 100644 --- a/F1:F103/BISS_C_encoders/Makefile +++ b/F1:F103/BISS_C_encoders/Makefile @@ -1,8 +1,8 @@ BINARY := encoders # MCU code -MCU ?= F103x8 +MCU ?= F103xB # change this linking script depending on particular MCU model, -LDSCRIPT ?= stm32f103x8.ld +LDSCRIPT ?= stm32f103xB.ld DEFINES := -DSTM32F10X_MD include ../makefile.f1 diff --git a/F1:F103/BISS_C_encoders/encoders.bin b/F1:F103/BISS_C_encoders/encoders.bin index 41a4e13..ad542ce 100755 Binary files a/F1:F103/BISS_C_encoders/encoders.bin and b/F1:F103/BISS_C_encoders/encoders.bin differ diff --git a/F1:F103/BISS_C_encoders/encoders.creator.user b/F1:F103/BISS_C_encoders/encoders.creator.user index f99097b..48b5440 100644 --- a/F1:F103/BISS_C_encoders/encoders.creator.user +++ b/F1:F103/BISS_C_encoders/encoders.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -13,8 +13,8 @@ ProjectExplorer.Project.EditorSettings + true true - false true Cpp diff --git a/F1:F103/BISS_C_encoders/encoders.creator.user.7bd84e3 b/F1:F103/BISS_C_encoders/encoders.creator.user.7bd84e3 new file mode 100644 index 0000000..6d3b983 --- /dev/null +++ b/F1:F103/BISS_C_encoders/encoders.creator.user.7bd84e3 @@ -0,0 +1,183 @@ + + + + + + EnvironmentId + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + false + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + 0 + 0 + 0 + + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + 0 + true + + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/F1:F103/BISS_C_encoders/encoders.files b/F1:F103/BISS_C_encoders/encoders.files index ee57130..f2d5915 100644 --- a/F1:F103/BISS_C_encoders/encoders.files +++ b/F1:F103/BISS_C_encoders/encoders.files @@ -13,6 +13,8 @@ spi.c spi.h strfunc.c strfunc.h +usart.c +usart.h usb_descr.c usb_descr.h usb_lib.c diff --git a/F1:F103/BISS_C_encoders/flash.h b/F1:F103/BISS_C_encoders/flash.h index cf4b5ff..99a164f 100644 --- a/F1:F103/BISS_C_encoders/flash.h +++ b/F1:F103/BISS_C_encoders/flash.h @@ -45,6 +45,7 @@ typedef struct{ */ typedef struct __attribute__((packed, aligned(4))){ 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! uint8_t iIlengths[bTotNumEndpoints]; uint8_t encbits; // encoder bits: 26 or 32 diff --git a/F1:F103/BISS_C_encoders/hardware.c b/F1:F103/BISS_C_encoders/hardware.c index 82725f8..dd803e2 100644 --- a/F1:F103/BISS_C_encoders/hardware.c +++ b/F1:F103/BISS_C_encoders/hardware.c @@ -26,11 +26,11 @@ static inline void gpio_setup(){ // AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15 // Set led as opendrain output - GPIOC->CRH |= CRH(13, CNF_ODOUTPUT|MODE_SLOW); + //GPIOC->CRH |= CRH(13, CNF_ODOUTPUT|MODE_SLOW); // SPI1 pins //GPIOA->CRL = CRL(5, CNF_AFPP|MODE_FAST) | CRL(6, CNF_FLINPUT); - // USB pullup (PA15) - pushpull output - GPIOA->CRH = CRH(15, CNF_PPOUTPUT|MODE_SLOW); + // USB pullup (PA10) - pushpull output + GPIOA->CRH = CRH(10, CNF_PPOUTPUT|MODE_SLOW); // SPI2 pins //GPIOB->CRH = CRH(13, CNF_AFPP|MODE_FAST) | CRH(14, CNF_FLINPUT); } diff --git a/F1:F103/BISS_C_encoders/hardware.h b/F1:F103/BISS_C_encoders/hardware.h index e7bfb32..584e438 100644 --- a/F1:F103/BISS_C_encoders/hardware.h +++ b/F1:F103/BISS_C_encoders/hardware.h @@ -25,9 +25,9 @@ // USB pullup (not present in bluepill, should be soldered) - PA15 #define USBPU_port GPIOA -#define USBPU_pin (1<<15) -#define USBPU_ON() pin_set(USBPU_port, USBPU_pin) -#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) +#define USBPU_pin (1<<10) +#define USBPU_ON() 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_on(x) pin_clear(x ## _port, x ## _pin) diff --git a/F1:F103/BISS_C_encoders/main.c b/F1:F103/BISS_C_encoders/main.c index d3f43bc..c75c52d 100644 --- a/F1:F103/BISS_C_encoders/main.c +++ b/F1:F103/BISS_C_encoders/main.c @@ -22,7 +22,7 @@ #include "proto.h" #include "spi.h" #include "strfunc.h" -//#include "usart.h" +#include "usart.h" #include "usb_dev.h" volatile uint32_t Tms = 0; @@ -49,6 +49,7 @@ static void printResult(BiSS_Frame *result){ static void proc_enc(uint8_t idx){ static uint32_t lastMSG[2], gotgood[2], gotwrong[2]; + static uint32_t lastXval = 0, usartT = 0; int iface = idx ? I_Y : I_X; char ifacechr = idx ? 'Y' : 'X'; if(CDCready[iface]){ @@ -71,6 +72,13 @@ static void proc_enc(uint8_t idx){ if(!encbuf) return; BiSS_Frame result = parse_biss_frame(encbuf, the_conf.encbufsz); 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; if(CDCready[I_CMD]){ if(testflag){ @@ -109,7 +117,7 @@ static void proc_enc(uint8_t idx){ } int main(){ - uint32_t lastT = 0; + uint32_t lastT = 0, usartT = 0; StartHSE(); flashstorage_init(); hw_setup(); @@ -119,11 +127,12 @@ int main(){ #ifndef EBUG iwdg_setup(); #endif + usart_setup(); USBPU_ON(); while (1){ IWDG->KR = IWDG_REFRESH; // refresh watchdog if(Tms - lastT > 499){ - LED_blink(LED0); + //LED_blink(LED0); lastT = Tms; } if(CDCready[I_CMD]){ @@ -133,11 +142,19 @@ int main(){ } proc_enc(0); proc_enc(1); + int started[2] = {0, 0}; if(the_conf.flags.monit){ 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; } diff --git a/F1:F103/BISS_C_encoders/proto.c b/F1:F103/BISS_C_encoders/proto.c index b99ac90..2a7b315 100644 --- a/F1:F103/BISS_C_encoders/proto.c +++ b/F1:F103/BISS_C_encoders/proto.c @@ -22,6 +22,7 @@ #include "proto.h" #include "spi.h" #include "strfunc.h" +#include "usart.h" #include "usb_dev.h" #include "version.inc" @@ -77,6 +78,8 @@ typedef enum{ C_maxzeros, C_autom, C_amperiod, + C_usart, + C_ssii, C_AMOUNT } cmd_e; @@ -257,6 +260,10 @@ static errcode_e setuintpar(cmd_e idx, char *par){ if(val > 255 || val == 0) return ERR_BADPAR; the_conf.monittime = val; break; + case C_ssii: + if(val > UINT16_MAX) return ERR_BADPAR; + the_conf.send232_interval = val; + break; default: return ERR_BADCMD; } @@ -282,6 +289,9 @@ static errcode_e setuintpar(cmd_e idx, char *par){ case C_amperiod: val = the_conf.monittime; break; + case C_ssii: + val = the_conf.send232_interval; + break; default: return ERR_BADCMD; } @@ -358,9 +368,15 @@ static errcode_e dumpconf(cmd_e _U_ idx, char _U_ *par){ setuintpar(C_encbufsz, NULL); setuintpar(C_maxzeros, NULL); setuintpar(C_minzeros, NULL); + setuintpar(C_ssii, NULL); return ERR_SILENCE; } +static errcode_e usart(cmd_e _U_ idx, char _U_ *par){ + usart_send_enc(0xdeadbeef, 0xbeefdead); + return ERR_OK; +} + // text commands static const funcdescr_t commands[C_AMOUNT] = { [C_dummy] = {"dummy", dummy}, @@ -392,6 +408,8 @@ static const funcdescr_t commands[C_AMOUNT] = { [C_maxzeros] = {"maxzeros", setuintpar}, [C_autom] = {"autom", setboolpar}, [C_amperiod] = {"amperiod", setuintpar}, + [C_usart] = {"usart", usart}, + [C_ssii] = {"ssii", setuintpar}, }; typedef struct{ @@ -425,6 +443,7 @@ static const help_t helpmessages[] = { {C_setiface1, "set name of first (command) interface"}, {C_setiface2, "set name of second (axis X) 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"}, {-1, "Debug commands"}, {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_testX, "test X-axis throughput"}, {C_testY, "test Y-axis throughput"}, + {C_usart, "send test encoders data over usart"}, {-1, NULL}, }; 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'"); const help_t *c = helpmessages; while(c->help){ diff --git a/F1:F103/BISS_C_encoders/usart.c b/F1:F103/BISS_C_encoders/usart.c new file mode 100644 index 0000000..e4702e7 --- /dev/null +++ b/F1:F103/BISS_C_encoders/usart.c @@ -0,0 +1,107 @@ +/* + * usart.c + * + * Copyright 2018 Edward V. Emelianoff + * + * 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 + +#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; + } +} diff --git a/F1:F103/BISS_C_encoders/usart.h b/F1:F103/BISS_C_encoders/usart.h index 27e6375..98994dd 100644 --- a/F1:F103/BISS_C_encoders/usart.h +++ b/F1:F103/BISS_C_encoders/usart.h @@ -21,12 +21,10 @@ #pragma once +#include "stdint.h" + #define UARTBUFSZ (128) -// macro for static strings -#define USEND(str) usart_send(str) - -void usart_transmit(); +void usart_send(const uint8_t *buf, int buflen); void usart_setup(); -void usart_send(const char *str); -void usart_putchar(const char ch); +void usart_send_enc(uint32_t encX, uint32_t encY); diff --git a/F1:F103/BISS_C_encoders/version.inc b/F1:F103/BISS_C_encoders/version.inc index aebe739..e4b7dcc 100644 --- a/F1:F103/BISS_C_encoders/version.inc +++ b/F1:F103/BISS_C_encoders/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "96" -#define BUILD_DATE "2025-04-04" +#define BUILD_NUMBER "107" +#define BUILD_DATE "2025-06-02"