Skip to content

Commit

Permalink
rework for new setup
Browse files Browse the repository at this point in the history
  • Loading branch information
catphish committed Apr 12, 2018
1 parent 5672737 commit f1e64f7
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 89 deletions.
135 changes: 66 additions & 69 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void uart_write_string(char* str);
void uart_write_int(int32_t i);
void uart_write_nl();


// Phase should rotate from 0 - (2^24)*6-1
// Voltage should be 0 - 2^12-1
void update_svm(uint32_t phase, uint32_t voltage)
Expand Down Expand Up @@ -79,78 +80,74 @@ void update_svm(uint32_t phase, uint32_t voltage)
}
}

void TIM1_UP_TIM16_IRQHandler(void) {
// Start ADC conversions.
// TODO: Try to cause these 2 conversions to run for a
// significant portion of the PWM cycle.
ADC1->SQR1 = (1<<6);
ADC2->SQR1 = (2<<6);
uint16_t adc_data[4];
void DMA1_Channel1_IRQHandler(void) {
// Debug output
uart_write_int(adc_data[0]);
uart_write_string(",");
uart_write_int(adc_data[1]);
uart_write_string(",");
uart_write_int(adc_data[2]);
uart_write_string(",");
uart_write_int(adc_data[3]);
uart_write_nl();
ADC1->CR |= ADC_CR_ADSTART;
ADC2->CR |= ADC_CR_ADSTART;
TIM1->SR = ~TIM_SR_UIF;
}

void ADC1_2_IRQHandler(void) {
// Fetch current values
// TODO: Instead of waiting for 2 ADCs, use combined mode and trust the interrupt.
while(ADC1->CR & ADC_CR_ADSTART);
while(ADC2->CR & ADC_CR_ADSTART);
i1 = ((float)ADC1->DR - 31715);
i2 = ((float)ADC2->DR - 31800) * 1.04f;
i3 = 0 - i1 - i2;

// Fetch the voltages.
v1 = TIM1->CCR1 + TIM1->CCR1 - TIM1->CCR2 - TIM1->CCR3;
v2 = TIM1->CCR2 + TIM1->CCR2 - TIM1->CCR1 - TIM1->CCR3;
v3 = TIM1->CCR3 + TIM1->CCR3 - TIM1->CCR1 - TIM1->CCR2;

// Calculate the instantaneous current and power.
// TODO optimize compiler, especially here.
current = sqrt(i1 * i1 + i2 * i2 + i3 * i3);
power = (v1 * i1 + v2 * i2 + v3 * i3) >> 14;

// Adjust voltage to fit calculates power to target power.
if (power > target_power) voltage -= 10;
if (power < target_power) voltage += 10;
if (voltage < 0) voltage = 0;
if (voltage > 4080) voltage = 4080;

// TODO: We can do better V/Hz control if we measure the
// bus voltage too.
// Work out V/Hz by multiplying the voltage by a Hz constant.
// Subtract some voltage based on current to account for resistive losses.

// A multiple is 25 here is theoretically correct for my motor at 23V DC supply.
int increment = voltage * 25 - 1000 * 25;
if(increment < 0) increment = 0;

// Increment the output phase.
sine_angle += increment;
if(sine_angle > 100663295) sine_angle -= 100663296;
if(sine_angle < 0) sine_angle += 100663296;
// Output SVM using PWM.
update_svm(sine_angle, voltage);
}
// void TIM1_UP_TIM16_IRQHandler(void) {
// // Start ADC conversions.
// // TODO: Try to cause these 2 conversions to run for a
// // significant portion of the PWM cycle.
// ADC1->SQR1 = (1<<6);
// ADC2->SQR1 = (2<<6);
// ADC1->CR |= ADC_CR_ADSTART;
// ADC2->CR |= ADC_CR_ADSTART;
// TIM1->SR = ~TIM_SR_UIF;
// }

// void ADC1_2_IRQHandler(void) {
// // Fetch current values
// // TODO: Instead of waiting for 2 ADCs, use combined mode and trust the interrupt.
// while(ADC1->CR & ADC_CR_ADSTART);
// while(ADC2->CR & ADC_CR_ADSTART);
// i1 = ((float)ADC1->DR - 31715);
// i2 = ((float)ADC2->DR - 31800) * 1.04f;
// i3 = 0 - i1 - i2;

// // Fetch the voltages.
// v1 = TIM1->CCR1 + TIM1->CCR1 - TIM1->CCR2 - TIM1->CCR3;
// v2 = TIM1->CCR2 + TIM1->CCR2 - TIM1->CCR1 - TIM1->CCR3;
// v3 = TIM1->CCR3 + TIM1->CCR3 - TIM1->CCR1 - TIM1->CCR2;

// // Calculate the instantaneous current and power.
// // TODO optimize compiler, especially here.
// current = sqrt(i1 * i1 + i2 * i2 + i3 * i3);
// power = (v1 * i1 + v2 * i2 + v3 * i3) >> 14;

// // Adjust voltage to fit calculates power to target power.
// if (power > target_power) voltage -= 10;
// if (power < target_power) voltage += 10;
// if (voltage < 0) voltage = 0;
// if (voltage > 4080) voltage = 4080;

// // TODO: We can do better V/Hz control if we measure the
// // bus voltage too.
// // Work out V/Hz by multiplying the voltage by a Hz constant.
// // Subtract some voltage based on current to account for resistive losses.

// // A multiple is 25 here is theoretically correct for my motor at 23V DC supply.
// int increment = voltage * 25 - 1000 * 25;
// if(increment < 0) increment = 0;

// // Increment the output phase.
// sine_angle += increment;
// if(sine_angle > 100663295) sine_angle -= 100663296;
// if(sine_angle < 0) sine_angle += 100663296;
// // Output SVM using PWM.
// update_svm(sine_angle, voltage);
// }

int main() {
ADC3->SQR1 = (4<<6);
while (1) {
// Fetch throttle input.
ADC3->CR |= ADC_CR_ADSTART;
while(ADC3->CR & ADC_CR_ADSTART);
throttle = ADC3->DR;
target_power = throttle;

// Debug output.
int n; for(n=0;n<20000;n++) nop();
uart_write_int(target_power);
uart_write_string(",");
uart_write_int(power);
uart_write_string(",");
uart_write_int(voltage);
uart_write_string(",");
uart_write_int(current);
uart_write_nl();
}
return(0);
ADC1->CR |= ADC_CR_ADSTART;
while(1);
}
53 changes: 33 additions & 20 deletions system.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ void SystemInitError(uint8_t error_source) {
while(1);
}

extern uint32_t adc_data[];

void SystemInit() {

// Enable FPU
Expand Down Expand Up @@ -56,16 +58,14 @@ void SystemInit() {
// B13,B14,B15 -> TIM1
GPIOB->AFR[1] &= ~(GPIO_AFRH_AFSEL13_Msk|GPIO_AFRH_AFSEL14_Msk|GPIO_AFRH_AFSEL15_Msk);
GPIOB->AFR[1] |= GPIO_AFRH_AFSEL13_0 | GPIO_AFRH_AFSEL14_0 | GPIO_AFRH_AFSEL15_0;
// C0,C1,C2,C3 -> ADC1
GPIOC->AFR[0] &= ~(GPIO_AFRL_AFSEL0_Msk|GPIO_AFRL_AFSEL1_Msk|GPIO_AFRL_AFSEL2_Msk|GPIO_AFRL_AFSEL3_Msk);
GPIOC->AFR[0] |= GPIO_AFRH_AFSEL13_0 | GPIO_AFRH_AFSEL14_0 | GPIO_AFRH_AFSEL15_0;
// PORTA Modes
GPIOA->MODER = 0xABEAFFEF;
GPIOA->ASCR = 0x3; // ADC
// PORTB Modes
GPIOB->MODER = 0xABFFFFFF;
// PORTC Modes
GPIOC->MODER = 0xFFFFFFFF;
GPIOC->ASCR = 0xF;
GPIOC->ASCR = 0xF; // ADC

// Enable USART2 clock
RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
Expand All @@ -79,28 +79,44 @@ void SystemInit() {
// Enable transmit
USART2->CR1 |= USART_CR1_TE;

// DMA for ADC1
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; // DMA1
// Wait a bit
nop(); nop(); nop(); nop(); nop(); nop();
DMA1_Channel1->CPAR = (uint32_t)&(ADC123_COMMON->CDR);
DMA1_Channel1->CMAR = (uint32_t)&adc_data;
DMA1_Channel1->CNDTR = 2;
DMA1_Channel1->CCR = DMA_CCR_MSIZE_1 | DMA_CCR_PSIZE_1 | DMA_CCR_MINC |
DMA_CCR_CIRC | DMA_CCR_TCIE | DMA_CCR_EN;

// ADC123
RCC->AHB2ENR |= RCC_AHB2ENR_ADCEN;
// Connect to system clock
RCC->CCIPR |= RCC_CCIPR_ADCSEL_0 | RCC_CCIPR_ADCSEL_1;
// Divide clock (/8)
ADC123_COMMON->CCR |= (4<<18);
ADC123_COMMON->CCR |= ADC_CCR_PRESC_2;
// Dual mode
ADC123_COMMON->CCR |= ADC_CCR_DUAL_1 | ADC_CCR_DUAL_2;
// MDMA
ADC123_COMMON->CCR |= ADC_CCR_MDMA_1;

// ADC1+2+3
// ADC1+2
// Disable DEEPPWD, enable ADVREGEN
ADC1->CR = ADC_CR_ADVREGEN;
ADC2->CR = ADC_CR_ADVREGEN;
ADC3->CR = ADC_CR_ADVREGEN;

// Wait a bit
int n; for(n=0;n<100000;n++) nop();

// Configure ADC1/2 IN5 for differential input
ADC1->DIFSEL |= (1<<5);
ADC2->DIFSEL |= (1<<5);

// Calibrate
// ADC1->CR |= ADC_CR_ADCAL;
// ADC2->CR |= ADC_CR_ADCAL;
// ADC3->CR |= ADC_CR_ADCAL;
// while(ADC1->CR & ADC_CR_ADCAL);
// while(ADC2->CR & ADC_CR_ADCAL);
// while(ADC3->CR & ADC_CR_ADCAL);
// // Wait a bit
// for(n=0;n<100000;n++) nop();

Expand All @@ -109,20 +125,16 @@ void SystemInit() {
ADC1->CR |= ADC_CR_ADEN;
ADC2->ISR |= ADC_ISR_ADRDY;
ADC2->CR |= ADC_CR_ADEN;
ADC3->ISR |= ADC_ISR_ADRDY;
ADC3->CR |= ADC_CR_ADEN;
while(!(ADC1->ISR & ADC_ISR_ADRDY));
while(!(ADC2->ISR & ADC_ISR_ADRDY));
while(!(ADC3->ISR & ADC_ISR_ADRDY));
// Interrupts
ADC1->IER = ADC_IER_EOCIE;

// Sequence
ADC1->SQR1 = (1<<6) | (5<<12) | 1;
ADC2->SQR1 = (2<<6) | (4<<12) | 1;

// Oversampling (16x)
ADC1->CFGR2 = (3<<2) | 1;
ADC2->CFGR2 = (3<<2) | 1;
// ADC1->CFGR2 = (4<<5) | (3<<2) | 1;
// ADC2->CFGR2 = (4<<5) | (3<<2) | 1;
// ADC3->CFGR2 = (4<<5) | (3<<2) | 1;
// ADC1->CFGR2 = (3<<2) | 1;
// ADC2->CFGR2 = (3<<2) | 1;

// TIM1
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
Expand All @@ -143,6 +155,7 @@ void SystemInit() {
TIM1->CR1 |= 1;

// Global interrupt config
NVIC->ISER[0] = (1 << TIM1_UP_TIM16_IRQn) | (1 << ADC1_2_IRQn);
//NVIC->ISER[0] = (1 << TIM1_UP_TIM16_IRQn);
NVIC->ISER[0] = (1 << DMA1_Channel1_IRQn);
}

0 comments on commit f1e64f7

Please sign in to comment.