diff --git a/F0-nolib/Servo/effects.c b/F0-nolib/Servo/effects.c index 254edd0..31f5f41 100644 --- a/F0-nolib/Servo/effects.c +++ b/F0-nolib/Servo/effects.c @@ -20,8 +20,10 @@ #include "hardware.h" #include "usart.h" -static effect_t current_ef[3] = {EFF_NONE, EFF_NONE, EFF_NONE}; +uint8_t dma_eff = 0; +static effect_t current_ef[3] = {EFF_NONE, EFF_NONE, EFF_NONE}; +static int8_t cntr[3] = {0,0,0}, dir[3] = {1,1,1}; #define SPD_STP (25) static void eff_madwipe(int n){ @@ -35,14 +37,13 @@ static void eff_madwipe(int n){ } static void eff_wipe(int n){ - static uint8_t cntr = 0; if(onposition(n)){ // move back int val = 0; if(getPWM(n) < SG90_MIDPULSE) val = 1; - if(++cntr < 4){ // stay a little in outermost positions + if(++cntr[n] < 4){ // stay a little in outermost positions setPWM(n, getPWM(n), SG90_STEP/2); }else{ - cntr = 0; + cntr[n] = 0; setPWM(n, val, SG90_STEP/2); } } @@ -52,36 +53,68 @@ static void eff_pendulum(int n){ const uint16_t steps[41] = {0, 10, 21, 33, 47, 62, 79, 97, 117, 140, 165, 193, 224, 258, 295, 337, 383, 434, 490, 552, 621, 697, 766, 828, 884, 935, 981, 1023, 1060, 1094, 1125, 1153, 1178, 1201, 1221, 1239, 1256, 1271, 1285, 1297, 1308}; - static int8_t cntr = 0, dir = 1; if(onposition(n)){ - setPWM(n, SG90_MINPULSE + steps[cntr], SG90_STEP); - cntr += dir; - if(cntr == -1){ // min position - dir = 1; - cntr = 0; // repeat zero position one time - }else if(cntr == 41){ // max position - dir = -1; - cntr = 40; // and this position needs to repeat too + setPWM(n, SG90_MINPULSE + steps[cntr[n]], SG90_STEP); + cntr[n] += dir[n]; + if(cntr[n] == -1){ // min position + dir[n] = 1; + cntr[n] = 0; // repeat zero position one time + }else if(cntr[n] == 41){ // max position + dir[n] = -1; + cntr[n] = 40; // and this position needs to repeat too } } } static void eff_pendsm(int n){ const uint16_t steps[19] = {0, 6, 10, 15, 22, 30, 40, 52, 66, 82, 101, 123, 148, 177, 210, 247, 289, 336, 389}; - static int8_t cntr = 0, dir = 1; if(onposition(n)){ - setPWM(n, SG90_MINPULSE + steps[cntr], SG90_STEP); - cntr += dir; - if(cntr == -1){ // min position - dir = 1; - cntr = 1; - }else if(cntr == 19){ // max position - dir = -1; - cntr = 18; + setPWM(n, SG90_MINPULSE + steps[cntr[n]], SG90_STEP); + cntr[n] += dir[n]; + if(cntr[n] == -1){ // min position + dir[n] = 1; + cntr[n] = 1; + }else if(cntr[n] == 19){ // max position + dir[n] = -1; + cntr[n] = 18; } } } +// buffers for different DMA effects, by pairs: 1st number is CCR1, 2nd is CCR2 +static const uint16_t dmabufsmall[] = { 1400,800,1400,800, + 1400,1000,1400,1000, + 1600,1000,1600,1000, + 1600,800,1600,800,}; + +static const uint16_t dmabufmed[] = { 1400,800,1400,800,1400,800,1400,800, + 1400,1000,1400,1000,1400,1000,1400,1000, + 1600,1000,1600,1000,1600,1000,1600,1000, + 1600,800,1600,800,1600,800,1600,800}; + +static const uint16_t dmabufbig[] = { 1400,800,1400,800,1400,800,1400,800,1400,800,1400,800, + 1400,1000,1400,1000,1400,1000,1400,1000,1400,1000,1400,1000, + 1600,1000,1600,1000,1600,1000,1600,1000,1600,1000,1600,1000, + 1600,800,1600,800,1600,800,1600,800,1600,800,1600,800}; + +static const uint16_t dmabuftest[] = { 1400,800,1400,840,1400,880,1400,920,1400,960,1400,1000, + 1400,1000,1440,1000,1480,1000,1520,1000,1560,1000,1600,1000, + 1600,1000,1600,960,1600,920,1600,880,1600,840,1600,800, + 1600,800,1560,800,1520,800,1480,800,1440,800,1400,800}; + +static const uint16_t dmabufstar[] = { 1300,930,1300,930,1300,930,1300,930,1300,930,1300,930, + 1500,930,1500,930,1500,930,1500,930,1500,930,1500,930, + 1330,800,1330,800,1330,800,1330,800,1330,800,1330,800, + 1400,1000,1400,1000,1400,1000,1400,1000,1400,1000,1400,1000, + 1470,800,1470,800,1470,800,1470,800,1470,800,1470,800}; + +static void DMA_eff(const void* buff, uint8_t len){ + DMA1_Channel3->CMAR = (uint32_t)(buff); + DMA1_Channel3->CNDTR = len; + DMA1_Channel3->CCR |= DMA_CCR_EN; + TIM3->DIER |= TIM_DIER_UDE; +} + void proc_effect(){ for(int i = 0; i < 3; ++i){ switch(current_ef[i]){ @@ -105,7 +138,42 @@ void proc_effect(){ } effect_t set_effect(int n, effect_t eff){ - if(n < 0 || n > 3) return EFF_NONE; - current_ef[n] = eff; + if(n < 0 || n > 2) return EFF_NONE; + cntr[n] = 0; + dir[n] = 1; + if(dma_eff){ + TIM3->DIER &= ~TIM_DIER_UDE; // turn off DMA requests from UE + DMA1_Channel3->CCR &= ~DMA_CCR_EN; // turn off DMA if current was with it + dma_eff = 0; + TIM3->CCR1 = SG90_MIDPULSE; + TIM3->CCR2 = SG90_MIDPULSE; + } + switch(eff){ + case EFF_DMASMALL: + DMA_eff(dmabufsmall, sizeof(dmabufsmall)/sizeof(uint16_t)); + dma_eff = 1; + break; + case EFF_DMAMED: + DMA_eff(dmabufmed, sizeof(dmabufmed)/sizeof(uint16_t)); + dma_eff = 1; + break; + case EFF_DMABIG: + DMA_eff(dmabufbig, sizeof(dmabufbig)/sizeof(uint16_t)); + dma_eff = 1; + break; + case EFF_DMATEST: + DMA_eff(dmabuftest, sizeof(dmabuftest)/sizeof(uint16_t)); + dma_eff = 1; + break; + case EFF_DMASTAR: + DMA_eff(dmabufstar, sizeof(dmabufstar)/sizeof(uint16_t)); + dma_eff = 1; + break; + default: + break; + } + if(dma_eff){ + current_ef[0] = current_ef[1] = eff; + }else current_ef[n] = eff; return eff; } diff --git a/F0-nolib/Servo/effects.h b/F0-nolib/Servo/effects.h index f72d94b..430f621 100644 --- a/F0-nolib/Servo/effects.h +++ b/F0-nolib/Servo/effects.h @@ -27,9 +27,15 @@ typedef enum{ EFF_WIPE, EFF_MADWIPE, EFF_PENDULUM, - EFF_SMPENDULUM + EFF_SMPENDULUM, + EFF_DMASMALL, + EFF_DMAMED, + EFF_DMABIG, + EFF_DMATEST, + EFF_DMASTAR } effect_t; +extern uint8_t dma_eff; void proc_effect(); effect_t set_effect(int n, effect_t eff); diff --git a/F0-nolib/Servo/hardware.c b/F0-nolib/Servo/hardware.c index d4cd5cc..85ff4bb 100644 --- a/F0-nolib/Servo/hardware.c +++ b/F0-nolib/Servo/hardware.c @@ -168,6 +168,14 @@ static inline void timers_setup(){ TIM3->DIER = TIM_DIER_UIE; //TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC4IE; // enable timer & ARR buffering TIM3->CR1 |= TIM_CR1_CEN | TIM_CR1_ARPE; + RCC->AHBENR |= RCC_AHBENR_DMA1EN; + // DMA for more effects (channel 3 -> TIM3_UP) + DMA1_Channel3->CPAR = (uint32_t)(&(TIM3->DMAR)); // each writing to DMAR will change next register + // memsiz 16bit, psiz 32bit, memincrement, from memory, circulate + DMA1_Channel3->CCR |= DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_1 + | DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_CIRC; + TIM3->DCR = (1 << 8) | // DBL=1 -- two transfers + (((uint32_t)&TIM3->CCR1 - (uint32_t)&TIM3->CR1) >> 2); // reg = (DBA + TIM3->CR1)/4 NVIC_EnableIRQ(TIM3_IRQn); } @@ -241,9 +249,11 @@ void tim3_isr(){ chkPWM(2); }*/ if(TIM3->SR & TIM_SR_UIF){ - chkPWM(0); - chkPWM(1); - chkPWM(2); + if(!dma_eff){ + chkPWM(0); + chkPWM(1); + chkPWM(2); + } } TIM3->SR = 0; } diff --git a/F0-nolib/Servo/protocol.c b/F0-nolib/Servo/protocol.c index 335518f..1ae47c1 100644 --- a/F0-nolib/Servo/protocol.c +++ b/F0-nolib/Servo/protocol.c @@ -84,7 +84,8 @@ static void chPWM(const char *command){ if(*command++ == ','){ getnum(command, &speed); } - CCR = setPWM(n, CCR, speed); + //CCR = + setPWM(n, CCR, speed); } put_string("pulse"); put_char('1' + n); @@ -115,6 +116,36 @@ static void chk_effect(const char *cmd, effect_t eff, const char *name){ }else put_string("err\n"); } +static void DMA_effect(const char *cmd){ + int n = *cmd - '1'; + if(n < 0 || n > 4){ + put_string("Wrong DMA eff. number\n"); + return; + } + put_string("DMA effect "); + put_char(*cmd); + put_string(" enabled\n"); + switch(n){ + case 0: + set_effect(0, EFF_DMASMALL); + break; + case 1: + set_effect(0, EFF_DMAMED); + break; + case 2: + set_effect(0, EFF_DMABIG); + break; + case 3: + set_effect(0, EFF_DMATEST); + break; + case 4: + set_effect(0, EFF_DMASTAR); + break; + default: + break; + } +} + /** * @brief process_command - command parser * @param command - command text (all inside [] without spaces) @@ -127,7 +158,8 @@ char *process_command(const char *command){ case '?': // help SEND_BLK( "1-3[pos[,speed]]- set/get xth pulse length (us) (0,1,2 - min, max, mid)\n" - "fx - servo period (us)" + "fx - servo period (us)\n" + "Dx - DMA effect x\n" "Mn - set Mad Wipe effect\n" "Pn - set Pendulum effect\n" "R - reset\n" @@ -151,6 +183,9 @@ char *process_command(const char *command){ case 'f': set_servoT(++command); break; + case 'D': + DMA_effect(++command); + break; case 'M': chk_effect(command, EFF_MADWIPE, "mad wipe"); break; diff --git a/F0-nolib/Servo/servo.bin b/F0-nolib/Servo/servo.bin index 1c373a4..bfc4599 100755 Binary files a/F0-nolib/Servo/servo.bin and b/F0-nolib/Servo/servo.bin differ diff --git a/F0-nolib/morze/morse.c b/F0-nolib/morze/morse.c index 5b49764..7bd1a14 100644 --- a/F0-nolib/morze/morse.c +++ b/F0-nolib/morze/morse.c @@ -53,7 +53,7 @@ uint16_t mbuff[3*MAXPINGS]; 55 (0x37) - 7 87 (0x57) - W 119 (0x77) - w 151 (0x97) - — 183 (0xb7) - · 215 (0xd7) - × 247 (0xf7) - ÷ 56 (0x38) - 8 88 (0x58) - X 120 (0x78) - x 152 (0x98) - ˜ 184 (0xb8) - ¸ 216 (0xd8) - Ø 248 (0xf8) - ø 57 (0x39) - 9 89 (0x59) - Y 121 (0x79) - y 153 (0x99) - ™ 185 (0xb9) - ¹ 217 (0xd9) - Ù 249 (0xf9) - ù - 58 (0x3a) - : 90 (0x5a) - Z 122 (0x7a) - z 154 (0x9a) - š 186 (0xba) - º 218 (0xda) - Ú 250 (0xfa) - ú + 58 (0x3a) - : 90 (0x5a) - Z 122 (0x7a) - z 154 (0x9a) - 186 (0xba) - º 218 (0xda) - Ú 250 (0xfa) - ú 59 (0x3b) - ; 91 (0x5b) - [ 123 (0x7b) - { 155 (0x9b) - › 187 (0xbb) - » 219 (0xdb) - Û 251 (0xfb) - û 60 (0x3c) - < 92 (0x5c) - \ 124 (0x7c) - | 156 (0x9c) - œ 188 (0xbc) - ¼ 220 (0xdc) - Ü 252 (0xfc) - ü 61 (0x3d) - = 93 (0x5d) - ] 125 (0x7d) - } 157 (0x9d) - 189 (0xbd) - ½ 221 (0xdd) - Ý 253 (0xfd) - ý @@ -61,7 +61,7 @@ uint16_t mbuff[3*MAXPINGS]; 63 (0x3f) - ? 95 (0x5f) - _ 127 (0x7f) - 159 (0x9f) - Ÿ 191 (0xbf) - ¿ 223 (0xdf) - ß 255 (0xff) - ÿ */ // 1 - len in pings, 2 - pings (0 - dot, 1 - dash), reverse order -static const uint8_t ascii[] = { // sarting from space+1 +static const uint8_t ascii[] = { // starting from space+1 6, 53, // ! -*-*-- 6, 18, // " *-**-* 5, 29, // # [no] -*---