diff --git a/src/main.c b/src/main.c index 817254fc..d00d0f75 100644 --- a/src/main.c +++ b/src/main.c @@ -1,438 +1,438 @@ -#include -#include -#include "printf.h" -#include "scanf.h" -#include "param.h" -#include "setup.h" -#include - -#ifdef USBTERM -#include "stm32_ub_usb_cdc.h" -#endif - -int __errno; -void Wait(unsigned int ms); - -//bosch grau, gelb, grün -#define pole_count 4 -#define res_offset DEG(36.6) //minimaler positiver resolver output bei mag_pos = 0 - -//mayr gelb sw, rot -//amp zu gering! -// #define pole_count 2 -// #define res_offset 0.5 //minimaler positiver resolver output bei mag_pos = 0 -// float p = 8.000000 -// float i = 400.000000 -// float d = 0.050000 -// float p = 3.000000 -// float i = 100.000000 -// float d = 0.004999 - -#define pwm_scale 0.9//max/min PWM duty cycle - -#define NO 0 -#define YES 1 - -#define offseta 0.0 * 2.0 * M_PI / 3.0 -#define offsetb 1.0 * 2.0 * M_PI / 3.0 -#define offsetc 2.0 * 2.0 * M_PI / 3.0 - -volatile float mag_pos = 0; -volatile float soll_pos = 0; -volatile float soll_pos_old = 0; -volatile float ist = 0; -volatile float ist_old = 0; -volatile float voltage_scale = 0;// -1 bis 1 - -volatile int t1, t2;//rohdaten sin/cos -volatile int t1_last = 0, t2_last = 0;//rohdaten sin/cos letzter aufruf -volatile int t1_mid = 0,t2_mid = 0;//mittelpunkt sin/cos -volatile int amp1,amp2;//betrag -volatile int erreger = 0;//resolver erreger pin an/aus -volatile int erreger_enable = NO;//erreger aktiv -volatile float w = -1; -volatile int k = 0,l = 0; -volatile int data[10][2][2]; -volatile int rescal = 0;//potis einstellen -volatile float calv = 0.5;//potis einstellen -volatile float res_s_var = 0.0; -volatile float res_c_var = 0.0; -volatile float startpos = 0.0; -volatile int count = 0; -volatile int mode = 0; -volatile float amp = 0.0; -volatile float freq = 0.0; - -enum{ - STBY, - RUNNING, - EFOLLOW, - EFEEDBACK -} state; - -void enable(){ - PWM_E = mag_res*0.97; -} - -void disable(){ - PWM_E = 0; -} - -float get_enc_pos(){ - return (TIM_GetCounter(TIM3) * 2 * M_PI / 2048);//nochmal in der setup -} - -float get_res_pos(){ - return ist - res_offset; -} - -void output_ac_pwm(){ - float volt = CLAMP(voltage_scale,-1.0,1.0); - //volt = volt*-1; - - if(rescal){ - mag_pos = 0; - volt = calv; - }else{ - mag_pos = get_res_pos() * pole_count + DEG(90); - } - - mag_pos = mod(mag_pos); - PWM_U = (sinf(mag_pos + offseta) * pwm_scale * volt + 1.0) * mag_res / 2.0; - PWM_V = (sinf(mag_pos + offsetb) * pwm_scale * volt + 1.0) * mag_res / 2.0; - PWM_W = (sinf(mag_pos + offsetc) * pwm_scale * volt + 1.0) * mag_res / 2.0; -} - -void output_dc_pwm(){ - float volt = CLAMP(voltage_scale,-1.0,1.0); - - int foo = volt * mag_res * pwm_scale / 2 + mag_res / 2; - PWM_U = foo;//PD12 PIN1 - PWM_V = mag_res-foo;//PD13 PIN2 - PWM_W = 0;//PD15 PIN3 -} - -void DMA2_Stream2_IRQHandler(void){ - // welches flag? - //DMA_ClearFlag(DMA2_FLAG_IT); - DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2); - printf_("DMA\n"); -} - -void TIM2_IRQHandler(void){ //20KHz - TIM_ClearITPendingBit(TIM2, TIM_IT_Update); - GPIO_SetBits(GPIOC,GPIO_Pin_4);//messpin -} - -void ADC_IRQHandler(void) // 20khz -{ - while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC)); - ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); - GPIO_ResetBits(GPIOC,GPIO_Pin_4);//messpin - - t1 = ADC_GetConversionValue(ADC1); - t2 = ADC_GetConversionValue(ADC2); - t1_mid = t1_mid * 0.95 + (t1+t1_last)/2 * 0.05; - t2_mid = t2_mid * 0.95 + (t2+t2_last)/2 * 0.05; - if(erreger_enable){//erreger signal aktiv - if(erreger){//eine halbwelle - GPIO_SetBits(GPIOC,GPIO_Pin_2);//erreger - amp1 = (t1-t1_mid)*(t1-t1_mid)+(t2-t2_mid)*(t2-t2_mid); - if(w >= 0){ - data[k][0][0] = t1 - t1_mid; - data[k][0][1] = t2 - t2_mid; - k++; - } - }else{//andere halbwelle - GPIO_ResetBits(GPIOC,GPIO_Pin_2);//erreger - amp2 = (t1_mid-t1)*(t1_mid-t1)+(t2_mid-t2)*(t2_mid-t2); - if(w >= 0){ - data[l][1][0] = t1_mid - t1; - data[l][1][1] = t2_mid - t2; - l++; - } - } - if(l == 10 && k == 10){ - w = -1; - l = 0; - k = 0; - } - }else{//mittelpunkt messen - if(t1_mid == 0 && t2_mid == 0){//erster durchlauf - t1_mid = t1; - t2_mid = t2; - }else{//restliche durchläufe - t1_mid = t1_mid * 0.95 + t1 * 0.05; - t2_mid = t2_mid * 0.95 + t2 * 0.05; - } - - } - t1_last = t1; - t2_last = t2; - erreger = !erreger; // 10khz -} - -float get_cmd(float periode){ - static float time = 0.0; - static float pos = 0.0; - - time += periode; - - switch(mode){ - case 0: // hold - return(0.0); - case 1: // enc - return(get_enc_pos()); - case 2: // vel - pos += amp * periode; - pos = mod(pos); - return(pos); - case 3: // square - if(sinf(freq * 2 * M_PI * time) > 0){ - return(amp); - } - else{ - return(-amp); - } - case 4: // sine - return(amp * sinf(freq * 2 * M_PI * time)); - } - return(0.0); -} - -void TIM5_IRQHandler(void){ //1KHz - TIM_ClearITPendingBit(TIM5, TIM_IT_Update); - float s = 0,c = 0; - int freq = 1000; - float periode = 1.0 / freq; - kal.periode = periode; - for(int i = 0;i<10;i++){ - s += data[i][0][0] * 0.05; - c += data[i][0][1] * 0.05; - } - for(int i = 0;i<10;i++){ - s += data[i][1][0] * 0.05; - c += data[i][1][1] * 0.05; - } - //revs = (int)(ist/(2*M_PI)); - //ist = revs*2*M_PI+atan2f(s,c); - ist = atan2f(s,c); - - if(count > 1000){ - if(count < 2000){ - res_s_var += s * s / 1000; - res_c_var += c * c / 1000; - } - } - - count++; - - soll_pos = startpos + get_cmd(periode) + res_offset;//MIN(res_pos1, res_pos2) + MIN(ABS(minus(res_pos1,res_pos2)), ABS(minus(res_pos2,res_pos1))) / 2; - soll_pos = mod(soll_pos); - - pid.feedbacka = (minus(ist, ist_old) * freq - pid.feedbackv) * freq * 0.5 + pid.feedbacka * 0.5; - pid.feedbackv = minus(ist, ist_old) * freq * 0.5 + pid.feedbackv * 0.5; - pid.commanda = (minus(soll_pos, soll_pos_old) * freq - pid.commandv) * freq * 0.5 + pid.commanda * 0.5; - pid.commandv = minus(soll_pos, soll_pos_old) * freq * 0.5 + pid.commandv * 0.5; - pid.error = minus(soll_pos, ist); - - soll_pos_old = soll_pos; - ist_old = ist; - - /*if(ABS(pid.error) > DEG(90)){ - disable(); - state = EFOLLOW; - pid.enable = 0; - }*/ - - kal.res = ist; - update(&kal); - - calc_pid(&pid, periode * 1000.0); - kal.volt = pid.output; - predict(&kal); - voltage_scale = pid.output; - - if(amp1 < 1000000 || amp2 < 1000000){ - //voltage_scale = 0.0; - state = EFEEDBACK; - } - output_ac_pwm(); - w=0;//request data -} - -int main(void) -{ - #define MAX_WAVE 4 - unsigned char buf[MAX_WAVE * 2 + 2]; - int wave[MAX_WAVE]; - int bufpos = 0; - char name[] = "wave "; - int e = 0; - - setup(); - param_init(); - - for(bufpos = 0; bufpos < MAX_WAVE; bufpos++){ - name[4] = bufpos + '1'; - register_int(name,&wave[bufpos]); - wave[bufpos] = 0; - } - - register_int("e",&pid.enable); - register_float("p",&pid.pgain); - register_float("i",&pid.igain); - register_float("d",&pid.dgain); - register_float("b",&pid.bgain); - // register_float("ff0",&pid.ff0gain); - register_float("ff1",&pid.ff1gain); - register_float("ff2",&pid.ff2gain); - register_float("w",&w); - register_int("rescal",&rescal); - register_float("ist",&ist); - register_float("calv",&calv); - register_float("s_var",&res_s_var); - register_float("c_var",&res_c_var); - register_float("amp",&); - register_float("freq",&freq); - register_int("mode",&mode); - register_float("startpos",&startpos); - - state = STBY; - - GPIO_ResetBits(GPIOC,GPIO_Pin_2);//reset erreger - Wait(10); - TIM_Cmd(TIM2, ENABLE);//int - Wait(50); - erreger_enable = YES; - Wait(50); - TIM_Cmd(TIM4, ENABLE);//PWM - TIM_Cmd(TIM5, ENABLE);//PID - Wait(50); - startpos = get_res_pos(); - pid.enable = 1; - enable(); - - - - while(1) // Do not exit - { - //printf_("%f %f diff: %f\r",RAD(res_pos1),RAD(res_pos2),RAD(res_pos1-res_pos2)); - //printf_("%i %i",t1_mid,t2_mid); - //printf_("%i %i diff: %i\r",amp1,amp2,amp1-amp2); - for(bufpos = 0; bufpos < MAX_WAVE; bufpos++){ - switch(wave[bufpos]){ - case 1: - e = (int)RAD(pid.error); - break; - case 2: - e = (int)RAD(pid.error_d); - break; - case 3: - e = (int)RAD(pid.error_dd); - break; - case 4: - e = (int)RAD(soll_pos); - break; - case 5: - e = (int)RAD(pid.cmd_d); - break; - case 6: - e = (int)RAD(pid.cmd_dd); - break; - case 7: - e = (int)RAD(ist); - break; - case 8: - e = (int)RAD(pid.feedbackv); - break; - case 9: - e = (int)(voltage_scale * 10); - break; - case 10: - e = (int)(pid.saturated_count / 10); - break; - case 12: - e = (int)RAD(mag_pos); - break; - case 13: - e = (int)RAD(startpos); - break; - case 14: - e = (int)RAD(res_offset); - break; - default: - e = 0; - } - e = CLAMP(e + 128,1,255); - - buf[bufpos * 2] = bufpos + 128; - buf[bufpos * 2 + 1] = e; - } - buf[MAX_WAVE * 2] = 255; - buf[MAX_WAVE * 2 + 1] = 0; - - - //printf_("e: %f\n", pid.error); - //printf_("soll: %f\n", soll_pos); - -#ifdef USBTERM - if(UB_USB_CDC_GetStatus()==USB_CDC_CONNECTED){ - UB_USB_CDC_SendString(buf, NONE);//schleppfehler senden - /* - if(w == -1){ - w = -2; - printf_("pos:\n"); - for(int i = 0;i<10;i++){ - printf_("%i %i\n",data[i][0][0], data[i][0][1]); - } - printf_("neg:\n"); - for(int i = 0;i<10;i++){ - printf_("%i %i\n",data[i][1][0], data[i][1][1]); - } - } - */ - char name[APP_TX_BUF_SIZE]; - float value = 0; - int i = scanf_("%s = %f",name,&value); - switch(i){ - case 2: - if(is_param(name)) - printf_("%s = %f\n",name,get_param(name)); - else{ - printf_("not found\n"); - } - break; - case 5: - if(is_param(name)){ - if(set_param(name,value)) - printf_("OK, %s = %f\n",name,get_param(name)); - else - printf_("error!\n"); - } - break; - case -1: - break; - default: - //if(name[0] == '?') - list_param(); - //else - // printf_("unknown command\n"); - //break; - } - //if(UB_USB_CDC_ReceiveString(rx_buf)==RX_READY) { - // UB_USB_CDC_SendString(rx_buf,LF); - // - //} - } -#endif - - Wait(20); - } -} - -void Wait(unsigned int ms){ - volatile unsigned int t = time + ms; - while(t >= time){ - } -} +#include +#include +#include "printf.h" +#include "scanf.h" +#include "param.h" +#include "setup.h" +#include + +#ifdef USBTERM +#include "stm32_ub_usb_cdc.h" +#endif + +int __errno; +void Wait(unsigned int ms); + +//bosch grau, gelb, grün +#define pole_count 4 +#define res_offset DEG(36.6) //minimaler positiver resolver output bei mag_pos = 0 + +//mayr gelb sw, rot +//amp zu gering! +// #define pole_count 2 +// #define res_offset 0.5 //minimaler positiver resolver output bei mag_pos = 0 +// float p = 8.000000 +// float i = 400.000000 +// float d = 0.050000 +// float p = 3.000000 +// float i = 100.000000 +// float d = 0.004999 + +#define pwm_scale 0.9//max/min PWM duty cycle + +#define NO 0 +#define YES 1 + +#define offseta 0.0 * 2.0 * M_PI / 3.0 +#define offsetb 1.0 * 2.0 * M_PI / 3.0 +#define offsetc 2.0 * 2.0 * M_PI / 3.0 + +volatile float mag_pos = 0; +volatile float soll_pos = 0; +volatile float soll_pos_old = 0; +volatile float ist = 0; +volatile float ist_old = 0; +volatile float voltage_scale = 0;// -1 bis 1 + +volatile int t1, t2;//rohdaten sin/cos +volatile int t1_last = 0, t2_last = 0;//rohdaten sin/cos letzter aufruf +volatile int t1_mid = 0,t2_mid = 0;//mittelpunkt sin/cos +volatile int amp1,amp2;//betrag +volatile int erreger = 0;//resolver erreger pin an/aus +volatile int erreger_enable = NO;//erreger aktiv +volatile float w = -1; +volatile int k = 0,l = 0; +volatile int data[10][2][2]; +volatile int rescal = 0;//potis einstellen +volatile float calv = 0.5;//potis einstellen +volatile float res_s_var = 0.0; +volatile float res_c_var = 0.0; +volatile float startpos = 0.0; +volatile int count = 0; +volatile int mode = 0; +volatile float amp = 0.0; +volatile float freq = 0.0; + +enum{ + STBY, + RUNNING, + EFOLLOW, + EFEEDBACK +} state; + +void enable(){ + PWM_E = mag_res*0.97; +} + +void disable(){ + PWM_E = 0; +} + +float get_enc_pos(){ + return (TIM_GetCounter(TIM3) * 2 * M_PI / 2048);//nochmal in der setup +} + +float get_res_pos(){ + return ist - res_offset; +} + +void output_ac_pwm(){ + float volt = CLAMP(voltage_scale,-1.0,1.0); + //volt = volt*-1; + + if(rescal){ + mag_pos = 0; + volt = calv; + }else{ + mag_pos = get_res_pos() * pole_count + DEG(90); + } + + mag_pos = mod(mag_pos); + PWM_U = (sinf(mag_pos + offseta) * pwm_scale * volt + 1.0) * mag_res / 2.0; + PWM_V = (sinf(mag_pos + offsetb) * pwm_scale * volt + 1.0) * mag_res / 2.0; + PWM_W = (sinf(mag_pos + offsetc) * pwm_scale * volt + 1.0) * mag_res / 2.0; +} + +void output_dc_pwm(){ + float volt = CLAMP(voltage_scale,-1.0,1.0); + + int foo = volt * mag_res * pwm_scale / 2 + mag_res / 2; + PWM_U = foo;//PD12 PIN1 + PWM_V = mag_res-foo;//PD13 PIN2 + PWM_W = 0;//PD15 PIN3 +} + +void DMA2_Stream2_IRQHandler(void){ + // welches flag? + //DMA_ClearFlag(DMA2_FLAG_IT); + DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2); + printf_("DMA\n"); +} + +void TIM2_IRQHandler(void){ //20KHz + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + GPIO_SetBits(GPIOC,GPIO_Pin_4);//messpin +} + +void ADC_IRQHandler(void) // 20khz +{ + while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC)); + ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); + GPIO_ResetBits(GPIOC,GPIO_Pin_4);//messpin + + t1 = ADC_GetConversionValue(ADC1); + t2 = ADC_GetConversionValue(ADC2); + t1_mid = t1_mid * 0.95 + (t1+t1_last)/2 * 0.05; + t2_mid = t2_mid * 0.95 + (t2+t2_last)/2 * 0.05; + if(erreger_enable){//erreger signal aktiv + if(erreger){//eine halbwelle + GPIO_SetBits(GPIOC,GPIO_Pin_2);//erreger + amp1 = (t1-t1_mid)*(t1-t1_mid)+(t2-t2_mid)*(t2-t2_mid); + if(w >= 0){ + data[k][0][0] = t1 - t1_mid; + data[k][0][1] = t2 - t2_mid; + k++; + } + }else{//andere halbwelle + GPIO_ResetBits(GPIOC,GPIO_Pin_2);//erreger + amp2 = (t1_mid-t1)*(t1_mid-t1)+(t2_mid-t2)*(t2_mid-t2); + if(w >= 0){ + data[l][1][0] = t1_mid - t1; + data[l][1][1] = t2_mid - t2; + l++; + } + } + if(l == 10 && k == 10){ + w = -1; + l = 0; + k = 0; + } + }else{//mittelpunkt messen + if(t1_mid == 0 && t2_mid == 0){//erster durchlauf + t1_mid = t1; + t2_mid = t2; + }else{//restliche durchläufe + t1_mid = t1_mid * 0.95 + t1 * 0.05; + t2_mid = t2_mid * 0.95 + t2 * 0.05; + } + + } + t1_last = t1; + t2_last = t2; + erreger = !erreger; // 10khz +} + +float get_cmd(float periode){ + static float time = 0.0; + static float pos = 0.0; + + time += periode; + + switch(mode){ + case 0: // hold + return(0.0); + case 1: // enc + return(get_enc_pos()); + case 2: // vel + pos += amp * periode; + pos = mod(pos); + return(pos); + case 3: // square + if(sinf(freq * 2 * M_PI * time) > 0){ + return(amp); + } + else{ + return(-amp); + } + case 4: // sine + return(amp * sinf(freq * 2 * M_PI * time)); + } + return(0.0); +} + +void TIM5_IRQHandler(void){ //1KHz + TIM_ClearITPendingBit(TIM5, TIM_IT_Update); + float s = 0,c = 0; + int freq = 1000; + float periode = 1.0 / freq; + kal.periode = periode; + for(int i = 0;i<10;i++){ + s += data[i][0][0] * 0.05; + c += data[i][0][1] * 0.05; + } + for(int i = 0;i<10;i++){ + s += data[i][1][0] * 0.05; + c += data[i][1][1] * 0.05; + } + //revs = (int)(ist/(2*M_PI)); + //ist = revs*2*M_PI+atan2f(s,c); + ist = atan2f(s,c); + + if(count > 1000){ + if(count < 2000){ + res_s_var += s * s / 1000; + res_c_var += c * c / 1000; + } + } + + count++; + + soll_pos = startpos + get_cmd(periode) + res_offset;//MIN(res_pos1, res_pos2) + MIN(ABS(minus(res_pos1,res_pos2)), ABS(minus(res_pos2,res_pos1))) / 2; + soll_pos = mod(soll_pos); + + pid.feedbacka = (minus(ist, ist_old) * freq - pid.feedbackv) * freq * 0.5 + pid.feedbacka * 0.5; + pid.feedbackv = minus(ist, ist_old) * freq * 0.5 + pid.feedbackv * 0.5; + pid.commanda = (minus(soll_pos, soll_pos_old) * freq - pid.commandv) * freq * 0.5 + pid.commanda * 0.5; + pid.commandv = minus(soll_pos, soll_pos_old) * freq * 0.5 + pid.commandv * 0.5; + pid.error = minus(soll_pos, ist); + + soll_pos_old = soll_pos; + ist_old = ist; + + /*if(ABS(pid.error) > DEG(90)){ + disable(); + state = EFOLLOW; + pid.enable = 0; + }*/ + + kal.res = ist; + update(&kal); + + calc_pid(&pid, periode * 1000.0); + kal.volt = pid.output; + predict(&kal); + voltage_scale = pid.output; + + if(amp1 < 1000000 || amp2 < 1000000){ + //voltage_scale = 0.0; + state = EFEEDBACK; + } + output_ac_pwm(); + w=0;//request data +} + +int main(void) +{ +#define MAX_WAVE 4 + unsigned char buf[MAX_WAVE * 2 + 2]; + int wave[MAX_WAVE]; + int bufpos = 0; + char name[] = "wave "; + int e = 0; + + setup(); + param_init(); + + for(bufpos = 0; bufpos < MAX_WAVE; bufpos++){ + name[4] = bufpos + '1'; + register_int(name,&wave[bufpos]); + wave[bufpos] = 0; + } + + register_int("e",&pid.enable); + register_float("p",&pid.pgain); + register_float("i",&pid.igain); + register_float("d",&pid.dgain); + register_float("b",&pid.bgain); + // register_float("ff0",&pid.ff0gain); + register_float("ff1",&pid.ff1gain); + register_float("ff2",&pid.ff2gain); + register_float("w",&w); + register_int("rescal",&rescal); + register_float("ist",&ist); + register_float("calv",&calv); + register_float("s_var",&res_s_var); + register_float("c_var",&res_c_var); + register_float("amp",&); + register_float("freq",&freq); + register_int("mode",&mode); + register_float("startpos",&startpos); + + state = STBY; + + GPIO_ResetBits(GPIOC,GPIO_Pin_2);//reset erreger + Wait(10); + TIM_Cmd(TIM2, ENABLE);//int + Wait(50); + erreger_enable = YES; + Wait(50); + TIM_Cmd(TIM4, ENABLE);//PWM + TIM_Cmd(TIM5, ENABLE);//PID + Wait(50); + startpos = get_res_pos(); + pid.enable = 1; + enable(); + + + + while(1) // Do not exit + { + //printf_("%f %f diff: %f\r",RAD(res_pos1),RAD(res_pos2),RAD(res_pos1-res_pos2)); + //printf_("%i %i",t1_mid,t2_mid); + //printf_("%i %i diff: %i\r",amp1,amp2,amp1-amp2); + for(bufpos = 0; bufpos < MAX_WAVE; bufpos++){ + switch(wave[bufpos]){ + case 1: + e = (int)RAD(pid.error); + break; + case 2: + e = (int)RAD(pid.error_d); + break; + case 3: + e = (int)RAD(pid.error_dd); + break; + case 4: + e = (int)RAD(soll_pos); + break; + case 5: + e = (int)RAD(pid.cmd_d); + break; + case 6: + e = (int)RAD(pid.cmd_dd); + break; + case 7: + e = (int)RAD(ist); + break; + case 8: + e = (int)RAD(pid.feedbackv); + break; + case 9: + e = (int)(voltage_scale * 10); + break; + case 10: + e = (int)(pid.saturated_count / 10); + break; + case 11: + e = (int)RAD(mag_pos); + break; + case 12: + e = (int)RAD(startpos); + break; + case 13: + e = (int)RAD(res_offset); + break; + default: + e = 0; + } + e = CLAMP(e + 128,1,255); + + buf[bufpos * 2] = bufpos + 128; + buf[bufpos * 2 + 1] = e; + } + buf[MAX_WAVE * 2] = 255; + buf[MAX_WAVE * 2 + 1] = 0; + + + //printf_("e: %f\n", pid.error); + //printf_("soll: %f\n", soll_pos); + +#ifdef USBTERM + if(UB_USB_CDC_GetStatus()==USB_CDC_CONNECTED){ + UB_USB_CDC_SendString(buf, NONE);//schleppfehler senden + /* + if(w == -1){ + w = -2; + printf_("pos:\n"); + for(int i = 0;i<10;i++){ + printf_("%i %i\n",data[i][0][0], data[i][0][1]); + } + printf_("neg:\n"); + for(int i = 0;i<10;i++){ + printf_("%i %i\n",data[i][1][0], data[i][1][1]); + } + } + */ + char name[APP_TX_BUF_SIZE]; + float value = 0; + int i = scanf_("%s = %f",name,&value); + switch(i){ + case 2: + if(is_param(name)) + printf_("%s = %f\n",name,get_param(name)); + else{ + printf_("not found\n"); + } + break; + case 5: + if(is_param(name)){ + if(set_param(name,value)) + printf_("OK, %s = %f\n",name,get_param(name)); + else + printf_("error!\n"); + } + break; + case -1: + break; + default: + //if(name[0] == '?') + list_param(); + //else + // printf_("unknown command\n"); + //break; + } + //if(UB_USB_CDC_ReceiveString(rx_buf)==RX_READY) { + // UB_USB_CDC_SendString(rx_buf,LF); + // + //} + } +#endif + + Wait(20); + } +} + +void Wait(unsigned int ms){ + volatile unsigned int t = time + ms; + while(t >= time){ + } +} diff --git a/src/pid.c b/src/pid.c index b21a9865..273409d6 100644 --- a/src/pid.c +++ b/src/pid.c @@ -49,9 +49,9 @@ void pid_init(hal_pid_t *pid){ pid->cmd_d = 0; /* opt. pin: differentiated command */ pid->cmd_dd = 0; /* opt. pin: 2nd derivative of command */ pid->bias = 0; /* param: steady state offset */ - pid->pgain = 2; /* pin: proportional gain */ - pid->igain = 40; /* pin: integral gain */ - pid->dgain = 0.02; /* pin: derivative gain */ + pid->pgain = 4; /* pin: proportional gain */ + pid->igain = 0.02; /* pin: integral gain */ + pid->dgain = 0.01; /* pin: derivative gain */ pid->bgain = 0.0; /* pin: derivative gain */ // pid->ff0gain = 0; /* pin: feedforward proportional */ pid->ff1gain = 0.006; /* pin: feedforward derivative */ diff --git a/src/printf.c b/src/printf.c index 404d4aa2..4735e740 100755 --- a/src/printf.c +++ b/src/printf.c @@ -1,276 +1,276 @@ - -/* -+=============================================================================+ -| includes -+=============================================================================+ -*/ - -#include // (...) parameter handling -//#include "stlinky.h" -#ifdef USBTERM -#include "stm32_ub_usb_cdc.h" -#endif - -#include "printf.h" -#define PRINTF_BSIZE 128 -#define PRINTF_FLENGTH 6 - - -/* -+=============================================================================+ -| local declarations -+=============================================================================+ -*/ -int vfprintf_(char *, const char *format, va_list arg); //generic print - - -/* -+=============================================================================+ -| global functions -+=============================================================================+ -*/ -int printf_(const char *format, ...) -{ - va_list arg; - char buffer[PRINTF_BSIZE]; - int buffer_pos; - - va_start(arg, format); - buffer_pos = vfprintf_(buffer, format, arg); - va_end(arg); - - buffer[buffer_pos] = '\0'; - - #ifdef USBTERM - if(UB_USB_CDC_GetStatus()==USB_CDC_CONNECTED){ - UB_USB_CDC_SendString(buffer, NONE); - } - #endif - //stlinky_wait_tx(&g_stlinky_term); - //stlinky_tx(&g_stlinky_term, buffer, buffer_pos); - - return 0; -} - - - -/* -+=============================================================================+ -| local functions -+=============================================================================+ -*/ - - -/*--------------------------------------------------------------------------------+ - * vfprintf_() - * Prints a string to buffer. Supports %s, %c, %d, %ld %ul %02d %i %x %lud and %% - * - partly supported: long long, float (%ll %f, %F, %2.2f) - * - not supported: double float and exponent (%e %g %p %o \t) - * returns length of string - * limits string length to PRINTF_BSIZE - *--------------------------------------------------------------------------------+ -*/ -int vfprintf_(char *buffer, const char* str, va_list arp){ - int buffer_pos = 0; // position in output buffer - int input_pos = 0; // position in input buffer - - int state = 0; // 0 = last char = normal char - // 1 = last char = '%' - // 2 = last char = '\' - - int i = 0; // number to print - float f = 0; // float to print - char tmp[20]; // tmp string for numbers - int tmp_pos = 0; // pos in tmp - char *s = 0; // string to print - unsigned char float_length = PRINTF_FLENGTH; - - while(str[input_pos] != '\0' && buffer_pos < PRINTF_BSIZE){ - switch(state){ - case 0: // last = normal - switch(str[input_pos]){ - case '%': - state = 1; - break; - - case '\'': - state = 2; - break; - - default: - buffer[buffer_pos++] = str[input_pos]; - } - input_pos++; - break; - - case 1: // last = '%' - switch(str[input_pos++]){ - case '%': // "%%" - buffer[buffer_pos++] = '%'; - break; - - case 'c': // "%c" - buffer[buffer_pos++] = (char)va_arg(arp, int); - break; - - case 's': // "%s" - s = va_arg(arp, char*); - while(*s){ - buffer[buffer_pos++] = *(s++); - } - break; - - case 'i': // "%i" - tmp_pos = 0; - i = va_arg(arp, int); - - if(i < 0){ - buffer[buffer_pos++] = '-'; - i *= -1; - } - - do{ - tmp[tmp_pos++] = i % 10 + '0'; - i /= 10; - - } - while(i > 0); - - while(tmp_pos--){ - buffer[buffer_pos++] = tmp[tmp_pos]; - } - break; - - case 'b': // "%b" - tmp_pos = 0; - i = va_arg(arp, int); - - if(i < 0){ - buffer[buffer_pos++] = '-'; - i *= -1; - } - - do{ - tmp[tmp_pos++] = i % 2 + '0'; - i /= 2; - - } - while(i > 0); - - buffer[buffer_pos++] = 'b'; - - while(tmp_pos--){ - buffer[buffer_pos++] = tmp[tmp_pos]; - } - break; - - case 'h': // "%h" - tmp_pos = 0; - i = va_arg(arp, int); - - if(i < 0){ - buffer[buffer_pos++] = '-'; - i *= -1; - } - - do{ - if(i % 16 < 10){ - tmp[tmp_pos++] = i % 16 + '0'; - } - else{ - tmp[tmp_pos++] = i % 16 + 'A' - 10; - } - i /= 16; - - } - while(i > 0); - - buffer[buffer_pos++] = '0'; - buffer[buffer_pos++] = 'x'; - - while(tmp_pos--){ - buffer[buffer_pos++] = tmp[tmp_pos]; - } - break; - - case 'f': // "%f" - tmp_pos = 0; - f = va_arg(arp, double); // change to float for stm32 - - if(f < 0){ - buffer[buffer_pos++] = '-'; - f *= -1; - } - - i = f; - - do{ - tmp[tmp_pos++] = i % 10 + '0'; - i /= 10; - } - while(i > 0); - - while(tmp_pos--){ - buffer[buffer_pos++] = tmp[tmp_pos]; - } - - buffer[buffer_pos++] = '.'; - - f -= i; - tmp_pos = float_length - 1; - for(int j = 0; j < float_length; j++){ - f *= 10; - tmp[tmp_pos--] = ((int)f) % 10 + '0'; - } - tmp_pos = float_length; - while(tmp_pos--){ - buffer[buffer_pos++] = tmp[tmp_pos]; - } - break; - - default: - break; - } - state = 0; - break; - - case 2: // last = '\' - switch(str[input_pos++]){ - case 'n': // "\n" - buffer[buffer_pos++] = '\n'; - state = 0; - break; - - case 't': // "\t" - buffer[buffer_pos++] = '\t'; - state = 0; - break; - - case 'r': // "\t" - buffer[buffer_pos++] = '\r'; - state = 0; - break; - - case '\'': // "\'" - buffer[buffer_pos++] = '\''; - state = 0; - break; - - case '"': // "\"" - buffer[buffer_pos++] = '\"'; - state = 0; - break; - - case '\\': // "\\" - buffer[buffer_pos++] = '\\'; - state = 0; - break; - - default: - break; - } - break; - } - } - return(buffer_pos); -} + +/* ++=============================================================================+ +| includes ++=============================================================================+ +*/ + +#include // (...) parameter handling +//#include "stlinky.h" +#ifdef USBTERM +#include "stm32_ub_usb_cdc.h" +#endif + +#include "printf.h" +#define PRINTF_BSIZE 128 +#define PRINTF_FLENGTH 6 + + +/* ++=============================================================================+ +| local declarations ++=============================================================================+ +*/ +int vfprintf_(char *, const char *format, va_list arg); //generic print + + +/* ++=============================================================================+ +| global functions ++=============================================================================+ +*/ +int printf_(const char *format, ...) +{ + va_list arg; + char buffer[PRINTF_BSIZE]; + int buffer_pos; + + va_start(arg, format); + buffer_pos = vfprintf_(buffer, format, arg); + va_end(arg); + + buffer[buffer_pos] = '\0'; + + #ifdef USBTERM + if(UB_USB_CDC_GetStatus()==USB_CDC_CONNECTED){ + UB_USB_CDC_SendString(buffer, NONE); + } + #endif + //stlinky_wait_tx(&g_stlinky_term); + //stlinky_tx(&g_stlinky_term, buffer, buffer_pos); + + return 0; +} + + + +/* ++=============================================================================+ +| local functions ++=============================================================================+ +*/ + + +/*--------------------------------------------------------------------------------+ + * vfprintf_() + * Prints a string to buffer. Supports %s, %c, %d, %ld %ul %02d %i %x %lud and %% + * - partly supported: long long, float (%ll %f, %F, %2.2f) + * - not supported: double float and exponent (%e %g %p %o \t) + * returns length of string + * limits string length to PRINTF_BSIZE + *--------------------------------------------------------------------------------+ +*/ +int vfprintf_(char *buffer, const char* str, va_list arp){ + int buffer_pos = 0; // position in output buffer + int input_pos = 0; // position in input buffer + + int state = 0; // 0 = last char = normal char + // 1 = last char = '%' + // 2 = last char = '\' + + int i = 0; // number to print + float f = 0; // float to print + char tmp[20]; // tmp string for numbers + int tmp_pos = 0; // pos in tmp + char *s = 0; // string to print + unsigned char float_length = PRINTF_FLENGTH; + + while(str[input_pos] != '\0' && buffer_pos < PRINTF_BSIZE){ + switch(state){ + case 0: // last = normal + switch(str[input_pos]){ + case '%': + state = 1; + break; + + case '\'': + state = 2; + break; + + default: + buffer[buffer_pos++] = str[input_pos]; + } + input_pos++; + break; + + case 1: // last = '%' + switch(str[input_pos++]){ + case '%': // "%%" + buffer[buffer_pos++] = '%'; + break; + + case 'c': // "%c" + buffer[buffer_pos++] = (char)va_arg(arp, int); + break; + + case 's': // "%s" + s = va_arg(arp, char*); + while(*s){ + buffer[buffer_pos++] = *(s++); + } + break; + + case 'i': // "%i" + tmp_pos = 0; + i = va_arg(arp, int); + + if(i < 0){ + buffer[buffer_pos++] = '-'; + i *= -1; + } + + do{ + tmp[tmp_pos++] = i % 10 + '0'; + i /= 10; + + } + while(i > 0); + + while(tmp_pos--){ + buffer[buffer_pos++] = tmp[tmp_pos]; + } + break; + + case 'b': // "%b" + tmp_pos = 0; + i = va_arg(arp, int); + + if(i < 0){ + buffer[buffer_pos++] = '-'; + i *= -1; + } + + do{ + tmp[tmp_pos++] = i % 2 + '0'; + i /= 2; + + } + while(i > 0); + + buffer[buffer_pos++] = 'b'; + + while(tmp_pos--){ + buffer[buffer_pos++] = tmp[tmp_pos]; + } + break; + + case 'h': // "%h" + tmp_pos = 0; + i = va_arg(arp, int); + + if(i < 0){ + buffer[buffer_pos++] = '-'; + i *= -1; + } + + do{ + if(i % 16 < 10){ + tmp[tmp_pos++] = i % 16 + '0'; + } + else{ + tmp[tmp_pos++] = i % 16 + 'A' - 10; + } + i /= 16; + + } + while(i > 0); + + buffer[buffer_pos++] = '0'; + buffer[buffer_pos++] = 'x'; + + while(tmp_pos--){ + buffer[buffer_pos++] = tmp[tmp_pos]; + } + break; + + case 'f': // "%f" + tmp_pos = 0; + f = va_arg(arp, double); // change to float for stm32 + + if(f < 0){ + buffer[buffer_pos++] = '-'; + f *= -1; + } + + i = f; + + do{ + tmp[tmp_pos++] = i % 10 + '0'; + i /= 10; + } + while(i > 0); + + while(tmp_pos--){ + buffer[buffer_pos++] = tmp[tmp_pos]; + } + + buffer[buffer_pos++] = '.'; + + f -= i; + tmp_pos = float_length - 1; + for(int j = 0; j < float_length; j++){ + f *= 10; + tmp[tmp_pos--] = ((int)f) % 10 + '0'; + } + tmp_pos = float_length; + while(tmp_pos--){ + buffer[buffer_pos++] = tmp[tmp_pos]; + } + break; + + default: + break; + } + state = 0; + break; + + case 2: // last = '\' + switch(str[input_pos++]){ + case 'n': // "\n" + buffer[buffer_pos++] = '\n'; + state = 0; + break; + + case 't': // "\t" + buffer[buffer_pos++] = '\t'; + state = 0; + break; + + case 'r': // "\t" + buffer[buffer_pos++] = '\r'; + state = 0; + break; + + case '\'': // "\'" + buffer[buffer_pos++] = '\''; + state = 0; + break; + + case '"': // "\"" + buffer[buffer_pos++] = '\"'; + state = 0; + break; + + case '\\': // "\\" + buffer[buffer_pos++] = '\\'; + state = 0; + break; + + default: + break; + } + break; + } + } + return(buffer_pos); +} diff --git a/src/stm32_ub_encoder_tim3.c b/src/stm32_ub_encoder_tim3.c index 1d05bc14..41d0faa3 100755 --- a/src/stm32_ub_encoder_tim3.c +++ b/src/stm32_ub_encoder_tim3.c @@ -1,144 +1,144 @@ -//-------------------------------------------------------------- -// File : stm32_ub_encoder_tim3.c -// Datum : 21.07.2013 -// Version : 1.0 -// Autor : UB -// EMail : mc-4u(@)t-online.de -// Web : www.mikrocontroller-4u.de -// CPU : STM32F4 -// IDE : CooCox CoIDE 1.7.0 -// Module : GPIO, TIM -// Funktion : Drehgeber Messung (Rotary Encoder) per Timer3 -// -// Hinweis : mögliche Pinbelegungen -// CH1 : [PA6, PB4, PC6] -// CH2 : [PA7, PB5, PC7] -// -//-------------------------------------------------------------- - - -//-------------------------------------------------------------- -// Includes -//-------------------------------------------------------------- -#include "stm32_ub_encoder_tim3.h" - - - -//-------------------------------------------------------------- -// interne Funktionen -//-------------------------------------------------------------- -void P_ENCODER_InitIO(void); -void P_ENCODER_InitTIM(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert); - - -//-------------------------------------------------------------- -// Definition der zwei Rotary-Encoder Pins -// -// Channel : [1 und 2] -//-------------------------------------------------------------- -ENC_TIM3_t ENC_TIM3[] = { - // Name ,Channel, PORT , PIN , CLOCK , Source - {ENC_T3_A ,1 ,GPIOB ,GPIO_Pin_4 ,RCC_AHB1Periph_GPIOB ,GPIO_PinSource4}, - {ENC_T3_B ,2 ,GPIOB ,GPIO_Pin_5 ,RCC_AHB1Periph_GPIOB ,GPIO_PinSource5}, -}; - - -//-------------------------------------------------------------- -// init und start vom Encoder (Drehgeber-Messung) mit Timer3 -// -// mode : [ENC_MODE_2A, ENC_MODE_2B, ENC_MODE_4AB] -// typ : [ENC_TYP_NORMAL, ENC_TYP_REVERS] -// maxwert : [0 bis 65535] -//-------------------------------------------------------------- -void UB_ENCODER_TIM3_Init(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert) -{ - // init der Funktionen - P_ENCODER_InitIO(); - P_ENCODER_InitTIM(mode, typ, maxwert); -} - - -//-------------------------------------------------------------- -// auslesen der aktuellen Position vom Drehgeber -// -// Return_Wert : [0 bis eingestelltem Maxwert] -//-------------------------------------------------------------- -uint16_t UB_ENCODER_TIM3_ReadPos(void) -{ - uint16_t ret_wert=0; - - ret_wert=TIM_GetCounter(TIM3); - - return(ret_wert); -} - - - -//-------------------------------------------------------------- -// interne Funktion -// Init aller IO-Pins (mit PullUp) -//-------------------------------------------------------------- -void P_ENCODER_InitIO(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - ENC_TIM3_NAME_t vname; - - for(vname=0;vname<2;vname++) { - // Clock Enable - RCC_AHB1PeriphClockCmd(ENC_TIM3[vname].ENC_CLK, ENABLE); - - // Config des Pins als AF-Input - GPIO_InitStructure.GPIO_Pin = ENC_TIM3[vname].ENC_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(ENC_TIM3[vname].ENC_PORT, &GPIO_InitStructure); - - // Alternative-Funktion mit dem IO-Pin verbinden - GPIO_PinAFConfig(ENC_TIM3[vname].ENC_PORT, ENC_TIM3[vname].ENC_SOURCE, GPIO_AF_TIM3); - } -} - - - -//-------------------------------------------------------------- -// interne Funktion -// Init vom Timer für den Rotary-Encoder -//-------------------------------------------------------------- -void P_ENCODER_InitTIM(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert) -{ - uint16_t enc_mode, enc_edge; - - // Clock enable - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); - - // Encoder Mode - if(mode==ENC_T3_MODE_2A) { - enc_mode=TIM_EncoderMode_TI1; - } - else if(mode==ENC_T3_MODE_2B){ - enc_mode=TIM_EncoderMode_TI2; - } - else { - enc_mode=TIM_EncoderMode_TI12; - } - - // Encoder Typ - if(typ==ENC_T3_TYP_NORMAL) { - enc_edge=TIM_ICPolarity_Rising; - } - else { - enc_edge=TIM_ICPolarity_Falling; - } - - // Modus einstellen - TIM_EncoderInterfaceConfig(TIM3, enc_mode, enc_edge, TIM_ICPolarity_Rising); - - // Maxwert setzen - TIM_SetAutoreload(TIM3, maxwert); - - // Timer enable - TIM_Cmd(TIM3, ENABLE); -} - +//-------------------------------------------------------------- +// File : stm32_ub_encoder_tim3.c +// Datum : 21.07.2013 +// Version : 1.0 +// Autor : UB +// EMail : mc-4u(@)t-online.de +// Web : www.mikrocontroller-4u.de +// CPU : STM32F4 +// IDE : CooCox CoIDE 1.7.0 +// Module : GPIO, TIM +// Funktion : Drehgeber Messung (Rotary Encoder) per Timer3 +// +// Hinweis : mögliche Pinbelegungen +// CH1 : [PA6, PB4, PC6] +// CH2 : [PA7, PB5, PC7] +// +//-------------------------------------------------------------- + + +//-------------------------------------------------------------- +// Includes +//-------------------------------------------------------------- +#include "stm32_ub_encoder_tim3.h" + + + +//-------------------------------------------------------------- +// interne Funktionen +//-------------------------------------------------------------- +void P_ENCODER_InitIO(void); +void P_ENCODER_InitTIM(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert); + + +//-------------------------------------------------------------- +// Definition der zwei Rotary-Encoder Pins +// +// Channel : [1 und 2] +//-------------------------------------------------------------- +ENC_TIM3_t ENC_TIM3[] = { + // Name ,Channel, PORT , PIN , CLOCK , Source + {ENC_T3_A ,1 ,GPIOB ,GPIO_Pin_4 ,RCC_AHB1Periph_GPIOB ,GPIO_PinSource4}, + {ENC_T3_B ,2 ,GPIOB ,GPIO_Pin_5 ,RCC_AHB1Periph_GPIOB ,GPIO_PinSource5}, +}; + + +//-------------------------------------------------------------- +// init und start vom Encoder (Drehgeber-Messung) mit Timer3 +// +// mode : [ENC_MODE_2A, ENC_MODE_2B, ENC_MODE_4AB] +// typ : [ENC_TYP_NORMAL, ENC_TYP_REVERS] +// maxwert : [0 bis 65535] +//-------------------------------------------------------------- +void UB_ENCODER_TIM3_Init(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert) +{ + // init der Funktionen + P_ENCODER_InitIO(); + P_ENCODER_InitTIM(mode, typ, maxwert); +} + + +//-------------------------------------------------------------- +// auslesen der aktuellen Position vom Drehgeber +// +// Return_Wert : [0 bis eingestelltem Maxwert] +//-------------------------------------------------------------- +uint16_t UB_ENCODER_TIM3_ReadPos(void) +{ + uint16_t ret_wert=0; + + ret_wert=TIM_GetCounter(TIM3); + + return(ret_wert); +} + + + +//-------------------------------------------------------------- +// interne Funktion +// Init aller IO-Pins (mit PullUp) +//-------------------------------------------------------------- +void P_ENCODER_InitIO(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + ENC_TIM3_NAME_t vname; + + for(vname=0;vname<2;vname++) { + // Clock Enable + RCC_AHB1PeriphClockCmd(ENC_TIM3[vname].ENC_CLK, ENABLE); + + // Config des Pins als AF-Input + GPIO_InitStructure.GPIO_Pin = ENC_TIM3[vname].ENC_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(ENC_TIM3[vname].ENC_PORT, &GPIO_InitStructure); + + // Alternative-Funktion mit dem IO-Pin verbinden + GPIO_PinAFConfig(ENC_TIM3[vname].ENC_PORT, ENC_TIM3[vname].ENC_SOURCE, GPIO_AF_TIM3); + } +} + + + +//-------------------------------------------------------------- +// interne Funktion +// Init vom Timer für den Rotary-Encoder +//-------------------------------------------------------------- +void P_ENCODER_InitTIM(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert) +{ + uint16_t enc_mode, enc_edge; + + // Clock enable + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); + + // Encoder Mode + if(mode==ENC_T3_MODE_2A) { + enc_mode=TIM_EncoderMode_TI1; + } + else if(mode==ENC_T3_MODE_2B){ + enc_mode=TIM_EncoderMode_TI2; + } + else { + enc_mode=TIM_EncoderMode_TI12; + } + + // Encoder Typ + if(typ==ENC_T3_TYP_NORMAL) { + enc_edge=TIM_ICPolarity_Rising; + } + else { + enc_edge=TIM_ICPolarity_Falling; + } + + // Modus einstellen + TIM_EncoderInterfaceConfig(TIM3, enc_mode, enc_edge, TIM_ICPolarity_Rising); + + // Maxwert setzen + TIM_SetAutoreload(TIM3, maxwert); + + // Timer enable + TIM_Cmd(TIM3, ENABLE); +} + diff --git a/src/stm32_ub_encoder_tim3.h b/src/stm32_ub_encoder_tim3.h index 969112d1..d2e4da17 100755 --- a/src/stm32_ub_encoder_tim3.h +++ b/src/stm32_ub_encoder_tim3.h @@ -1,73 +1,73 @@ -//-------------------------------------------------------------- -// File : stm32_ub_encoder_tim3.h -//-------------------------------------------------------------- - -//-------------------------------------------------------------- -#ifndef __STM32F4_UB_ENCODER_TIM3_H -#define __STM32F4_UB_ENCODER_TIM3_H - - -//-------------------------------------------------------------- -// Includes -//-------------------------------------------------------------- -#include "stm32f4xx.h" -#include "stm32f4xx_gpio.h" -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_tim.h" - - -//-------------------------------------------------------------- -// Zwei Kanäle [0 und 1] werden für den Rotary-Encoder benötigt -//-------------------------------------------------------------- -typedef enum -{ - ENC_T3_A = 0, // Encoder Kanal-A - ENC_T3_B = 1 // Encoder Kanal-B -}ENC_TIM3_NAME_t; - - -//-------------------------------------------------------------- -// Mode vom Encoder -//-------------------------------------------------------------- -typedef enum { - ENC_T3_MODE_2A = 0, // Counter Zählt bei jeder Flanke von Eingang_A - ENC_T3_MODE_2B = 1, // Counter Zählt bei jeder Flanke von Eingang_B - ENC_T3_MODE_4AB = 2 // Counter Zählt bei jeder Flanke von Eingang_A UND Eingang_B -}ENC_TIM3_MODE_t; - - -//-------------------------------------------------------------- -// Richtung vom Encoder -//-------------------------------------------------------------- -typedef enum { - ENC_T3_TYP_NORMAL = 0, // Counter incrementiert bei rechts - ENC_T3_TYP_REVERS = 1 // Counter decrementiert bei rechts -}ENC_TIM3_TYP_t; - - - -//-------------------------------------------------------------- -// Struktur von einem Encoder-Kanal -//-------------------------------------------------------------- -typedef struct { - ENC_TIM3_NAME_t ENC_NAME; // Name - const uint8_t CHANNEL; // Channel [1...2] - GPIO_TypeDef* ENC_PORT; // Port - const uint16_t ENC_PIN; // Pin - const uint32_t ENC_CLK; // Clock - const uint8_t ENC_SOURCE; // Source -}ENC_TIM3_t; - - - -//-------------------------------------------------------------- -// Globale Funktionen -//-------------------------------------------------------------- -void UB_ENCODER_TIM3_Init(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert); -uint16_t UB_ENCODER_TIM3_ReadPos(void); - - - - -//-------------------------------------------------------------- -#endif // __STM32F4_UB_ENCODER_TIM3_H +//-------------------------------------------------------------- +// File : stm32_ub_encoder_tim3.h +//-------------------------------------------------------------- + +//-------------------------------------------------------------- +#ifndef __STM32F4_UB_ENCODER_TIM3_H +#define __STM32F4_UB_ENCODER_TIM3_H + + +//-------------------------------------------------------------- +// Includes +//-------------------------------------------------------------- +#include "stm32f4xx.h" +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_tim.h" + + +//-------------------------------------------------------------- +// Zwei Kanäle [0 und 1] werden für den Rotary-Encoder benötigt +//-------------------------------------------------------------- +typedef enum +{ + ENC_T3_A = 0, // Encoder Kanal-A + ENC_T3_B = 1 // Encoder Kanal-B +}ENC_TIM3_NAME_t; + + +//-------------------------------------------------------------- +// Mode vom Encoder +//-------------------------------------------------------------- +typedef enum { + ENC_T3_MODE_2A = 0, // Counter Zählt bei jeder Flanke von Eingang_A + ENC_T3_MODE_2B = 1, // Counter Zählt bei jeder Flanke von Eingang_B + ENC_T3_MODE_4AB = 2 // Counter Zählt bei jeder Flanke von Eingang_A UND Eingang_B +}ENC_TIM3_MODE_t; + + +//-------------------------------------------------------------- +// Richtung vom Encoder +//-------------------------------------------------------------- +typedef enum { + ENC_T3_TYP_NORMAL = 0, // Counter incrementiert bei rechts + ENC_T3_TYP_REVERS = 1 // Counter decrementiert bei rechts +}ENC_TIM3_TYP_t; + + + +//-------------------------------------------------------------- +// Struktur von einem Encoder-Kanal +//-------------------------------------------------------------- +typedef struct { + ENC_TIM3_NAME_t ENC_NAME; // Name + const uint8_t CHANNEL; // Channel [1...2] + GPIO_TypeDef* ENC_PORT; // Port + const uint16_t ENC_PIN; // Pin + const uint32_t ENC_CLK; // Clock + const uint8_t ENC_SOURCE; // Source +}ENC_TIM3_t; + + + +//-------------------------------------------------------------- +// Globale Funktionen +//-------------------------------------------------------------- +void UB_ENCODER_TIM3_Init(ENC_TIM3_MODE_t mode, ENC_TIM3_TYP_t typ, uint16_t maxwert); +uint16_t UB_ENCODER_TIM3_ReadPos(void); + + + + +//-------------------------------------------------------------- +#endif // __STM32F4_UB_ENCODER_TIM3_H diff --git a/src/stm32f4xx_it.c b/src/stm32f4xx_it.c index 82954c5b..635a70b7 100644 --- a/src/stm32f4xx_it.c +++ b/src/stm32f4xx_it.c @@ -1,167 +1,167 @@ -/** - ****************************************************************************** - * @file IO_Toggle/stm32f4xx_it.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Main Interrupt Service Routines. - * This file provides template for all exceptions handler and - * peripherals interrupt service routine. - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_it.h" - -/** @addtogroup STM32F4_Discovery_Peripheral_Examples - * @{ - */ - -/** @addtogroup IO_Toggle - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************/ -/* Cortex-M4 Processor Exceptions Handlers */ -/******************************************************************************/ - -/** - * @brief This function handles NMI exception. - * @param None - * @retval None - */ -void NMI_Handler(void) -{ -} - -/** - * @brief This function handles Hard Fault exception. - * @param None - * @retval None - */ -void HardFault_Handler(void) -{ - /* Go to infinite loop when Hard Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Memory Manage exception. - * @param None - * @retval None - */ -void MemManage_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -//void SysTick_Handler(void) -//{ -//} - -/******************************************************************************/ -/* STM32F4xx Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32f4xx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles PPP interrupt request. - * @param None - * @retval None - */ -/*void PPP_IRQHandler(void) -{ -}*/ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file IO_Toggle/stm32f4xx_it.c + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and + * peripherals interrupt service routine. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_it.h" + +/** @addtogroup STM32F4_Discovery_Peripheral_Examples + * @{ + */ + +/** @addtogroup IO_Toggle + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +//void SysTick_Handler(void) +//{ +//} + +/******************************************************************************/ +/* STM32F4xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32f4xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/src/system_stm32f4xx.c b/src/system_stm32f4xx.c index e29a7fed..9b2a3e75 100644 --- a/src/system_stm32f4xx.c +++ b/src/system_stm32f4xx.c @@ -1,546 +1,546 @@ -/** - ****************************************************************************** - * @file system_stm32f4xx.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. - * This file contains the system clock configuration for STM32F4xx devices, - * and is generated by the clock configuration tool - * stm32f4xx_Clock_Configuration_V1.0.0.xls - * - * 1. This file provides two functions and one global variable to be called from - * user application: - * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier - * and Divider factors, AHB/APBx prescalers and Flash settings), - * depending on the configuration made in the clock xls tool. - * This function is called at startup just after reset and - * before branch to main program. This call is made inside - * the "startup_stm32f4xx.s" file. - * - * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used - * by the user application to setup the SysTick - * timer or configure other parameters. - * - * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must - * be called whenever the core clock is changed - * during program execution. - * - * 2. After each device reset the HSI (16 MHz) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to - * configure the system clock before to branch to main program. - * - * 3. If the system clock source selected by user fails to startup, the SystemInit() - * function will do nothing and HSI still used as system clock source. User can - * add some code to deal with this issue inside the SetSysClock() function. - * - * 4. The default value of HSE crystal is set to 8 MHz, refer to "HSE_VALUE" define - * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or - * through PLL, and you are using different crystal you have to adapt the HSE - * value to your own configuration. - * - * 5. This file configures the system clock as follows: - *============================================================================= - *============================================================================= - * Supported STM32F4xx device revision | Rev A - *----------------------------------------------------------------------------- - * System Clock source | PLL (HSE) - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 4 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 2 - *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | 8000000 - *----------------------------------------------------------------------------- - * PLL_M | 8 - *----------------------------------------------------------------------------- - * PLL_N | 336 - *----------------------------------------------------------------------------- - * PLL_P | 2 - *----------------------------------------------------------------------------- - * PLL_Q | 7 - *----------------------------------------------------------------------------- - * PLLI2S_N | NA - *----------------------------------------------------------------------------- - * PLLI2S_R | NA - *----------------------------------------------------------------------------- - * I2S input clock | NA - *----------------------------------------------------------------------------- - * VDD(V) | 3.3 - *----------------------------------------------------------------------------- - * High Performance mode | Enabled - *----------------------------------------------------------------------------- - * Flash Latency(WS) | 5 - *----------------------------------------------------------------------------- - * Prefetch Buffer | OFF - *----------------------------------------------------------------------------- - * Instruction cache | ON - *----------------------------------------------------------------------------- - * Data cache | ON - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Enabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= - ****************************************************************************** - * @attention - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2011 STMicroelectronics

- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f4xx_system - * @{ - */ - -/** @addtogroup STM32F4xx_System_Private_Includes - * @{ - */ - -#include "stm32f4xx.h" - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Defines - * @{ - */ - -/*!< Uncomment the following line if you need to use external SRAM mounted - on STM324xG_EVAL board as data memory */ -/* #define DATA_IN_ExtSRAM */ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ - - -/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#define PLL_M 8 -#define PLL_N 336 - -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 7 - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Variables - * @{ - */ - - uint32_t SystemCoreClock = 168000000; - - __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes - * @{ - */ - -static void SetSysClock(void); -#ifdef DATA_IN_ExtSRAM - static void SystemInit_ExtMemCtl(void); -#endif /* DATA_IN_ExtSRAM */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system - * Initialize the Embedded Flash Interface, the PLL and update the - * SystemFrequency variable. - * @param None - * @retval None - */ -void SystemInit(void) -{ - SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* Set CP10 and CP11 to full access */ - - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Disable all interrupts */ - RCC->CIR = 0x00000000; - -#ifdef DATA_IN_ExtSRAM - SystemInit_ExtMemCtl(); -#endif /* DATA_IN_ExtSRAM */ - - /* Configure the System clock source, PLL Multiplier and Divider factors, - AHB/APBx prescalers and Flash settings ----------------------------------*/ - SetSysClock(); - - /* Configure the Vector Table location add offset address ------------------*/ -#ifdef VECT_TAB_SRAM - SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ -#else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ -#endif -} - -/** - * @brief Update SystemCoreClock variable according to Clock Register Values. - * The SystemCoreClock variable contains the core clock (HCLK), it can - * be used by the user application to setup the SysTick timer or configure - * other parameters. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) - * - * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) - * or HSI_VALUE(*) multiplied/divided by the PLL factors. - * - * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value - * 25 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * - * @param None - * @retval None - */ -void SystemCoreClockUpdate(void) -{ - uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00: /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; - case 0x04: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - case 0x08: /* PLL used as system clock source */ - - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N - SYSCLK = PLL_VCO / PLL_P - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - - pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; - SystemCoreClock = pllvco/pllp; - break; - default: - SystemCoreClock = HSI_VALUE; - break; - } - /* Compute HCLK frequency --------------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - /* HCLK frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, - * AHB/APBx prescalers and Flash settings - * @Note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). - * @param None - * @retval None - */ -static void SetSysClock(void) -{ -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable high performance mode, System frequency up to 168 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_PMODE; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } - -} - -/** - * @brief Setup the external memory controller. Called in startup_stm32f4xx.s - * before jump to __main - * @param None - * @retval None - */ -#ifdef DATA_IN_ExtSRAM -/** - * @brief Setup the external memory controller. - * Called in startup_stm32f4xx.s before jump to main. - * This function configures the external SRAM mounted on STM324xG_EVAL board - * This SRAM will be used as program data memory (including heap and stack). - * @param None - * @retval None - */ -void SystemInit_ExtMemCtl(void) -{ -/*-- GPIOs Configuration -----------------------------------------------------*/ -/* - +-------------------+--------------------+------------------+------------------+ - + SRAM pins assignment + - +-------------------+--------------------+------------------+------------------+ - | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | - | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | - | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | - | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | - | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | - | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | - | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | - | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+ - | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | - | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | - | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+ - | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | - | | PE15 <-> FSMC_D12 | - +-------------------+--------------------+ -*/ - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ - RCC->AHB1ENR = 0x00000078; - - /* Connect PDx pins to FSMC Alternate function */ - GPIOD->AFR[0] = 0x00cc00cc; - GPIOD->AFR[1] = 0xcc0ccccc; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xaaaa0a0a; - /* Configure PDx pins speed to 100 MHz */ - GPIOD->OSPEEDR = 0xffff0f0f; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; - - /* Connect PEx pins to FSMC Alternate function */ - GPIOE->AFR[0] = 0xc00cc0cc; - GPIOE->AFR[1] = 0xcccccccc; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xaaaa828a; - /* Configure PEx pins speed to 100 MHz */ - GPIOE->OSPEEDR = 0xffffc3cf; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FSMC Alternate function */ - GPIOF->AFR[0] = 0x00cccccc; - GPIOF->AFR[1] = 0xcccc0000; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xaa000aaa; - /* Configure PFx pins speed to 100 MHz */ - GPIOF->OSPEEDR = 0xff000fff; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FSMC Alternate function */ - GPIOG->AFR[0] = 0x00cccccc; - GPIOG->AFR[1] = 0x000000c0; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0x00080aaa; - /* Configure PGx pins speed to 100 MHz */ - GPIOG->OSPEEDR = 0x000c0fff; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - -/*-- FSMC Configuration ------------------------------------------------------*/ - /* Enable the FSMC interface clock */ - RCC->AHB3ENR = 0x00000001; - - /* Configure and enable Bank1_SRAM2 */ - FSMC_Bank1->BTCR[2] = 0x00001015; - FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400; - FSMC_Bank1E->BWTR[2] = 0x0fffffff; -/* - Bank1_SRAM2 is configured as follow: - - p.FSMC_AddressSetupTime = 3;//0; - p.FSMC_AddressHoldTime = 0; - p.FSMC_DataSetupTime = 6;//4; - p.FSMC_BusTurnAroundDuration = 1; - p.FSMC_CLKDivision = 0; - p.FSMC_DataLatency = 0; - p.FSMC_AccessMode = FSMC_AccessMode_A; - - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; - FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; - FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; - FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; - FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; -*/ - -} -#endif /* DATA_IN_ExtSRAM */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @version V1.0.0 + * @date 19-September-2011 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * This file contains the system clock configuration for STM32F4xx devices, + * and is generated by the clock configuration tool + * stm32f4xx_Clock_Configuration_V1.0.0.xls + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * and Divider factors, AHB/APBx prescalers and Flash settings), + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. If the system clock source selected by user fails to startup, the SystemInit() + * function will do nothing and HSI still used as system clock source. User can + * add some code to deal with this issue inside the SetSysClock() function. + * + * 4. The default value of HSE crystal is set to 8 MHz, refer to "HSE_VALUE" define + * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or + * through PLL, and you are using different crystal you have to adapt the HSE + * value to your own configuration. + * + * 5. This file configures the system clock as follows: + *============================================================================= + *============================================================================= + * Supported STM32F4xx device revision | Rev A + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSE) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 4 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 2 + *----------------------------------------------------------------------------- + * HSE Frequency(Hz) | 8000000 + *----------------------------------------------------------------------------- + * PLL_M | 8 + *----------------------------------------------------------------------------- + * PLL_N | 336 + *----------------------------------------------------------------------------- + * PLL_P | 2 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * High Performance mode | Enabled + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 5 + *----------------------------------------------------------------------------- + * Prefetch Buffer | OFF + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Enabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + +#include "stm32f4xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/*!< Uncomment the following line if you need to use external SRAM mounted + on STM324xG_EVAL board as data memory */ +/* #define DATA_IN_ExtSRAM */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ + + +/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ +#define PLL_M 8 +#define PLL_N 336 + +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 + +/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ +#define PLL_Q 7 + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + + uint32_t SystemCoreClock = 168000000; + + __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); +#ifdef DATA_IN_ExtSRAM + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemFrequency variable. + * @param None + * @retval None + */ +void SystemInit(void) +{ + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* Set CP10 and CP11 to full access */ + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#ifdef DATA_IN_ExtSRAM + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM */ + + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings ----------------------------------*/ + SetSysClock(); + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief Configures the System clock source, PLL Multiplier and Divider factors, + * AHB/APBx prescalers and Flash settings + * @Note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). + * @param None + * @retval None + */ +static void SetSysClock(void) +{ +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable high performance mode, System frequency up to 168 MHz */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_PMODE; + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } + +} + +/** + * @brief Setup the external memory controller. Called in startup_stm32f4xx.s + * before jump to __main + * @param None + * @retval None + */ +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external SRAM mounted on STM324xG_EVAL board + * This SRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+------------------+------------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+------------------+ + | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | + | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | + | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | + | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | + | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | + | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | + | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | + | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+ + | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | + | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | + | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+ + | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | + | | PE15 <-> FSMC_D12 | + +-------------------+--------------------+ +*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR = 0x00000078; + + /* Connect PDx pins to FSMC Alternate function */ + GPIOD->AFR[0] = 0x00cc00cc; + GPIOD->AFR[1] = 0xcc0ccccc; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xaaaa0a0a; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xffff0f0f; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FSMC Alternate function */ + GPIOE->AFR[0] = 0xc00cc0cc; + GPIOE->AFR[1] = 0xcccccccc; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xaaaa828a; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xffffc3cf; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FSMC Alternate function */ + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xcccc0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xaa000aaa; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xff000fff; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FSMC Alternate function */ + GPIOG->AFR[0] = 0x00cccccc; + GPIOG->AFR[1] = 0x000000c0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00080aaa; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000c0fff; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FSMC Configuration ------------------------------------------------------*/ + /* Enable the FSMC interface clock */ + RCC->AHB3ENR = 0x00000001; + + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001015; + FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400; + FSMC_Bank1E->BWTR[2] = 0x0fffffff; +/* + Bank1_SRAM2 is configured as follow: + + p.FSMC_AddressSetupTime = 3;//0; + p.FSMC_AddressHoldTime = 0; + p.FSMC_DataSetupTime = 6;//4; + p.FSMC_BusTurnAroundDuration = 1; + p.FSMC_CLKDivision = 0; + p.FSMC_DataLatency = 0; + p.FSMC_AccessMode = FSMC_AccessMode_A; + + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; +*/ + +} +#endif /* DATA_IN_ExtSRAM */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/term/basicdrawpane.cpp b/term/basicdrawpane.cpp index 62146f6f..1592fc22 100644 --- a/term/basicdrawpane.cpp +++ b/term/basicdrawpane.cpp @@ -1,11 +1,14 @@ #include "basicdrawpane.hpp" +const wxPen BasicDrawPane::pen[] = {*wxRED_PEN, *wxBLUE_PEN, *wxGREEN_PEN, *wxYELLOW_PEN}; + BasicDrawPane::BasicDrawPane(wxFrame* parent, int ch) : wxPanel(parent){ time = 0; diff = 0; Bind(wxEVT_PAINT, &BasicDrawPane::paintEvent, this); xpos = 0; channels = ch; + for (int i = 0; i()); for (int j = 0; j<1024/2; j++) { @@ -14,6 +17,15 @@ BasicDrawPane::BasicDrawPane(wxFrame* parent, int ch) : wxPanel(parent){ } } +void BasicDrawPane::Clear(){ + for (int i = 0; iAdd(drawpanel, 1,wxEXPAND,0); + wxArrayString waves; + waves.push_back("-"); + waves.push_back("error"); + waves.push_back("error_d"); + waves.push_back("error_dd"); + waves.push_back("soll_pos"); + waves.push_back("pid.cmd_d"); + waves.push_back("pid.cmd_dd"); + waves.push_back("ist"); + waves.push_back("feedbackv"); + waves.push_back("voltage_scale"); + waves.push_back("saturated_count"); + waves.push_back("mag_pos"); + waves.push_back("startpos"); + waves.push_back("res_offset"); + + //channels for(int i = 0;ichannels;i++){ channelchoice.push_back(new wxChoice (top, wxID_ANY)); channelchoice.back()->SetClientData(new int(i)); channelchoice.back()->Bind(wxEVT_CHOICE,&MainFrame::OnChannelChange, this, wxID_ANY); channelchoice.back()->Append(wxT("-")); - for(int j = 1; j < 15; j++){ - channelchoice.back()->Append(std::to_string(j)); - } + channelchoice.back()->Set(waves); + + wxPanel *c_panel; + c_panel = new wxPanel(top, wxID_NEW, wxPoint(150, 20), wxSize(20, 20), wxBORDER_NONE); + c_panel->SetBackgroundColour(drawpanel->pen[i].GetColour()); + channelleiste->Add(c_panel, 0,wxALIGN_LEFT|wxALL,3); + channelleiste->Add(channelchoice.back(), 0,wxALIGN_LEFT|wxALL,3); } + topsizer->Add(channelleiste); top->SetSizer(topsizer); @@ -95,21 +117,23 @@ void MainFrame::OnKeyDown(wxKeyEvent& event){ } void MainFrame::OnChannelChange(wxCommandEvent& event){ - std::cout << *(int*)event.GetClientData() << "->" << event.GetSelection() << std::endl; - std::string df = "wave"; - df += std::to_string(*(int*)event.GetClientData() + 1); - df += " = "; - df += std::to_string(event.GetSelection()); - - if((history.size()==0 || history.back() != df) && df != wxEmptyString){ - history.push_back(df); - } - histpos = history.size(); - int ret1 = sp_nonblocking_write(port, df.c_str(), df.length()); - int ret2 = sp_nonblocking_write(port, "\r", 1); - if(ret1 != df.length() || ret2!=1){ - wxMessageBox( wxT("Fehler beim senden"), wxT("Error"), wxICON_EXCLAMATION); - disconnect(); + if(connected){ + std::cout << *(int*)event.GetClientData() << "->" << event.GetSelection() << std::endl; + std::string df = "wave"; + df += std::to_string(*(int*)event.GetClientData() + 1); + df += " = "; + df += std::to_string(event.GetSelection()); + + if((history.size()==0 || history.back() != df) && df != wxEmptyString){ + history.push_back(df); + } + histpos = history.size(); + int ret1 = sp_nonblocking_write(port, df.c_str(), df.length()); + int ret2 = sp_nonblocking_write(port, "\r", 1); + if(ret1 != df.length() || ret2!=1){ + wxMessageBox( wxT("Fehler beim senden"), wxT("Error"), wxICON_EXCLAMATION); + disconnect(); + } } } @@ -175,6 +199,7 @@ void MainFrame::listports(){ void MainFrame::OnClear(wxCommandEvent& WXUNUSED(event)){ text->Clear(); + drawpanel->Clear(); } void MainFrame::OnConnect(wxCommandEvent& WXUNUSED(event)){ @@ -201,6 +226,8 @@ void MainFrame::connect(){ connectbutton->SetLabel(wxT("&Disonnect")); refresh->Disable(); choose_port->Disable(); + uhu->Disable(); + stmbl->Disable(); textinput->SetFocus(); }else{ wxMessageBox( wxT("Fehler beim Öffnen"), wxT("Error"), wxICON_EXCLAMATION); @@ -214,6 +241,8 @@ void MainFrame::disconnect(){ connectbutton->SetLabel(wxT("&Connect")); refresh->Enable(); choose_port->Enable(); + uhu->Enable(); + stmbl->Enable(); } }