mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
servo through DMA
This commit is contained in:
parent
3d59c76f65
commit
ff4f2131a2
@ -20,8 +20,10 @@
|
|||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "usart.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)
|
#define SPD_STP (25)
|
||||||
|
|
||||||
static void eff_madwipe(int n){
|
static void eff_madwipe(int n){
|
||||||
@ -35,14 +37,13 @@ static void eff_madwipe(int n){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void eff_wipe(int n){
|
static void eff_wipe(int n){
|
||||||
static uint8_t cntr = 0;
|
|
||||||
if(onposition(n)){ // move back
|
if(onposition(n)){ // move back
|
||||||
int val = 0;
|
int val = 0;
|
||||||
if(getPWM(n) < SG90_MIDPULSE) val = 1;
|
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);
|
setPWM(n, getPWM(n), SG90_STEP/2);
|
||||||
}else{
|
}else{
|
||||||
cntr = 0;
|
cntr[n] = 0;
|
||||||
setPWM(n, val, SG90_STEP/2);
|
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,
|
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,
|
490, 552, 621, 697, 766, 828, 884, 935, 981, 1023, 1060, 1094, 1125, 1153, 1178,
|
||||||
1201, 1221, 1239, 1256, 1271, 1285, 1297, 1308};
|
1201, 1221, 1239, 1256, 1271, 1285, 1297, 1308};
|
||||||
static int8_t cntr = 0, dir = 1;
|
|
||||||
if(onposition(n)){
|
if(onposition(n)){
|
||||||
setPWM(n, SG90_MINPULSE + steps[cntr], SG90_STEP);
|
setPWM(n, SG90_MINPULSE + steps[cntr[n]], SG90_STEP);
|
||||||
cntr += dir;
|
cntr[n] += dir[n];
|
||||||
if(cntr == -1){ // min position
|
if(cntr[n] == -1){ // min position
|
||||||
dir = 1;
|
dir[n] = 1;
|
||||||
cntr = 0; // repeat zero position one time
|
cntr[n] = 0; // repeat zero position one time
|
||||||
}else if(cntr == 41){ // max position
|
}else if(cntr[n] == 41){ // max position
|
||||||
dir = -1;
|
dir[n] = -1;
|
||||||
cntr = 40; // and this position needs to repeat too
|
cntr[n] = 40; // and this position needs to repeat too
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eff_pendsm(int n){
|
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};
|
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)){
|
if(onposition(n)){
|
||||||
setPWM(n, SG90_MINPULSE + steps[cntr], SG90_STEP);
|
setPWM(n, SG90_MINPULSE + steps[cntr[n]], SG90_STEP);
|
||||||
cntr += dir;
|
cntr[n] += dir[n];
|
||||||
if(cntr == -1){ // min position
|
if(cntr[n] == -1){ // min position
|
||||||
dir = 1;
|
dir[n] = 1;
|
||||||
cntr = 1;
|
cntr[n] = 1;
|
||||||
}else if(cntr == 19){ // max position
|
}else if(cntr[n] == 19){ // max position
|
||||||
dir = -1;
|
dir[n] = -1;
|
||||||
cntr = 18;
|
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(){
|
void proc_effect(){
|
||||||
for(int i = 0; i < 3; ++i){
|
for(int i = 0; i < 3; ++i){
|
||||||
switch(current_ef[i]){
|
switch(current_ef[i]){
|
||||||
@ -105,7 +138,42 @@ void proc_effect(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
effect_t set_effect(int n, effect_t eff){
|
effect_t set_effect(int n, effect_t eff){
|
||||||
if(n < 0 || n > 3) return EFF_NONE;
|
if(n < 0 || n > 2) return EFF_NONE;
|
||||||
current_ef[n] = eff;
|
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;
|
return eff;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,9 +27,15 @@ typedef enum{
|
|||||||
EFF_WIPE,
|
EFF_WIPE,
|
||||||
EFF_MADWIPE,
|
EFF_MADWIPE,
|
||||||
EFF_PENDULUM,
|
EFF_PENDULUM,
|
||||||
EFF_SMPENDULUM
|
EFF_SMPENDULUM,
|
||||||
|
EFF_DMASMALL,
|
||||||
|
EFF_DMAMED,
|
||||||
|
EFF_DMABIG,
|
||||||
|
EFF_DMATEST,
|
||||||
|
EFF_DMASTAR
|
||||||
} effect_t;
|
} effect_t;
|
||||||
|
|
||||||
|
extern uint8_t dma_eff;
|
||||||
void proc_effect();
|
void proc_effect();
|
||||||
effect_t set_effect(int n, effect_t eff);
|
effect_t set_effect(int n, effect_t eff);
|
||||||
|
|
||||||
|
|||||||
@ -168,6 +168,14 @@ static inline void timers_setup(){
|
|||||||
TIM3->DIER = TIM_DIER_UIE; //TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC4IE;
|
TIM3->DIER = TIM_DIER_UIE; //TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC4IE;
|
||||||
// enable timer & ARR buffering
|
// enable timer & ARR buffering
|
||||||
TIM3->CR1 |= TIM_CR1_CEN | TIM_CR1_ARPE;
|
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);
|
NVIC_EnableIRQ(TIM3_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,10 +249,12 @@ void tim3_isr(){
|
|||||||
chkPWM(2);
|
chkPWM(2);
|
||||||
}*/
|
}*/
|
||||||
if(TIM3->SR & TIM_SR_UIF){
|
if(TIM3->SR & TIM_SR_UIF){
|
||||||
|
if(!dma_eff){
|
||||||
chkPWM(0);
|
chkPWM(0);
|
||||||
chkPWM(1);
|
chkPWM(1);
|
||||||
chkPWM(2);
|
chkPWM(2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TIM3->SR = 0;
|
TIM3->SR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,8 @@ static void chPWM(const char *command){
|
|||||||
if(*command++ == ','){
|
if(*command++ == ','){
|
||||||
getnum(command, &speed);
|
getnum(command, &speed);
|
||||||
}
|
}
|
||||||
CCR = setPWM(n, CCR, speed);
|
//CCR =
|
||||||
|
setPWM(n, CCR, speed);
|
||||||
}
|
}
|
||||||
put_string("pulse");
|
put_string("pulse");
|
||||||
put_char('1' + n);
|
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");
|
}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
|
* @brief process_command - command parser
|
||||||
* @param command - command text (all inside [] without spaces)
|
* @param command - command text (all inside [] without spaces)
|
||||||
@ -127,7 +158,8 @@ char *process_command(const char *command){
|
|||||||
case '?': // help
|
case '?': // help
|
||||||
SEND_BLK(
|
SEND_BLK(
|
||||||
"1-3[pos[,speed]]- set/get xth pulse length (us) (0,1,2 - min, max, mid)\n"
|
"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"
|
"Mn - set Mad Wipe effect\n"
|
||||||
"Pn - set Pendulum effect\n"
|
"Pn - set Pendulum effect\n"
|
||||||
"R - reset\n"
|
"R - reset\n"
|
||||||
@ -151,6 +183,9 @@ char *process_command(const char *command){
|
|||||||
case 'f':
|
case 'f':
|
||||||
set_servoT(++command);
|
set_servoT(++command);
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
DMA_effect(++command);
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
chk_effect(command, EFF_MADWIPE, "mad wipe");
|
chk_effect(command, EFF_MADWIPE, "mad wipe");
|
||||||
break;
|
break;
|
||||||
|
|||||||
Binary file not shown.
@ -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) - ÷
|
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) - ø
|
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) - ù
|
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) - û
|
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) - ü
|
60 (0x3c) - < 92 (0x5c) - \ 124 (0x7c) - | 156 (0x9c) - œ 188 (0xbc) - ¼ 220 (0xdc) - Ü 252 (0xfc) - ü
|
||||||
61 (0x3d) - = 93 (0x5d) - ] 125 (0x7d) - } 157 (0x9d) - <EFBFBD> 189 (0xbd) - ½ 221 (0xdd) - Ý 253 (0xfd) - ý
|
61 (0x3d) - = 93 (0x5d) - ] 125 (0x7d) - } 157 (0x9d) - <EFBFBD> 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) - ÿ
|
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
|
// 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, 53, // ! -*-*--
|
||||||
6, 18, // " *-**-*
|
6, 18, // " *-**-*
|
||||||
5, 29, // # [no] -*---
|
5, 29, // # [no] -*---
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user