void main(void) { rccInit(); timerInit(); configInit(); adcInit(); fetInit(); serialInit(); runInit(); cliInit(); owInit(); runDisarm(REASON_STARTUP); inputMode = ESC_INPUT_PWM; fetSetDutyCycle(0); fetBeep(200, 100); fetBeep(300, 100); fetBeep(400, 100); fetBeep(500, 100); fetBeep(400, 100); fetBeep(300, 100); fetBeep(200, 100); pwmInit(); statusLed = digitalInit(GPIO_STATUS_LED_PORT, GPIO_STATUS_LED_PIN); digitalHi(statusLed); errorLed = digitalInit(GPIO_ERROR_LED_PORT, GPIO_ERROR_LED_PIN); digitalHi(errorLed); #ifdef ESC_DEBUG tp = digitalInit(GPIO_TP_PORT, GPIO_TP_PIN); digitalLo(tp); #endif // self calibrating idle timer loop { volatile unsigned long cycles; volatile unsigned int *DWT_CYCCNT = (int *)0xE0001004; volatile unsigned int *DWT_CONTROL = (int *)0xE0001000; volatile unsigned int *SCB_DEMCR = (int *)0xE000EDFC; *SCB_DEMCR = *SCB_DEMCR | 0x01000000; *DWT_CONTROL = *DWT_CONTROL | 1; // enable the counter minCycles = 0xffff; while (1) { idleCounter++; NOPS_4; cycles = *DWT_CYCCNT; *DWT_CYCCNT = 0; // reset the counter // record shortest number of instructions for loop totalCycles += cycles; if (cycles < minCycles) minCycles = cycles; } } }
void rccConfiguration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH, ENABLE); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_Init(GPIOE, &GPIO_InitStructure); // exclude PA13 & PA14 for SWD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All & ~(GPIO_Pin_13 | GPIO_Pin_14); GPIO_Init(GPIOA, &GPIO_InitStructure); #ifdef RCC_EN1_PORT en1 = digitalInit(RCC_EN1_PORT, RCC_EN1_PIN, 1); #endif #ifdef RCC_EN2_PORT en2 = digitalInit(RCC_EN2_PORT, RCC_EN2_PIN, 0); #endif #ifdef RCC_SYSOFF_PORT sysoff = digitalInit(RCC_SYSOFF_PORT, RCC_SYSOFF_PIN, 0); #endif #ifdef RCC_STEPUP_EN_PORT stepupEn = digitalInit(RCC_STEPUP_EN_PORT, RCC_STEPUP_EN_PIN, 1); #endif #ifdef RCC_SYNC_PORT sync = digitalInit(RCC_SYNC_PORT, RCC_SYNC_PIN, 1); #endif RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_DMA2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // enable timer clocks RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_TIM7, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8 | RCC_APB2Periph_TIM9 | RCC_APB2Periph_TIM10 | RCC_APB2Periph_TIM11, ENABLE); SYSCFG_CompensationCellCmd(ENABLE); // Clear reset flags RCC_ClearFlag(); RCC_GetClocksFreq(&rccClocks); pwmZeroTimers(); }
static void radioRCSelect(uint8_t rcPort, uint8_t level) { #ifdef RADIO_RC1_SELECT_PORT if (rcPort == 0) radioData.select[0] = digitalInit(RADIO_RC1_SELECT_PORT, RADIO_RC1_SELECT_PIN, level); #endif #ifdef RADIO_RC2_SELECT_PORT if (rcPort == 1) radioData.select[1] = digitalInit(RADIO_RC2_SELECT_PORT, RADIO_RC2_SELECT_PIN, level); #endif }
void supervisorInit(void) { memset((void *)&supervisorData, 0, sizeof(supervisorData)); supervisorData.readyLed = digitalInit(SUPERVISOR_READY_PORT, SUPERVISOR_READY_PIN, 0); #ifdef SUPERVISOR_DEBUG_PORT supervisorData.debugLed = digitalInit(SUPERVISOR_DEBUG_PORT, SUPERVISOR_DEBUG_PIN, 0); #endif supervisorData.gpsLed = digitalInit(GPS_LED_PORT, GPS_LED_PIN, 0); supervisorData.state = STATE_INITIALIZING; supervisorTaskStack = aqStackInit(SUPERVISOR_STACK_SIZE, "SUPERVISOR"); supervisorData.supervisorTask = CoCreateTask(supervisorTaskCode, (void *)0, SUPERVISOR_PRIORITY, &supervisorTaskStack[SUPERVISOR_STACK_SIZE-1], SUPERVISOR_STACK_SIZE); }
spiClient_t *spiClientInit(SPI_TypeDef *spi, uint16_t baud, GPIO_TypeDef *csPort, uint16_t csPin, volatile uint32_t *flag, spiCallback_t *callback) { spiClient_t *client; client = (spiClient_t *)aqCalloc(1, sizeof(spiClient_t)); #ifdef SPI_SPI1_CLOCK if (spi == SPI1) { client->interface = 0; spi1Init(); } #endif #ifdef SPI_SPI2_CLOCK if (spi == SPI2) { client->interface = 1; spi2Init(); } #endif #ifdef SPI_SPI3_CLOCK if (spi == SPI3) { client->interface = 2; spi3Init(); } #endif client->cs = digitalInit(csPort, csPin, 1); spiDeselect(client); spiChangeBaud(client, baud); client->flag = flag; client->callback = callback; return client; }
void rccBootLoader(void) { // check for magic cookie if (rccReadBkpDr() == 0xDECEA5ED) { digitalPin *statusLed, *errorLed; rccWriteBkpDr(0); // reset flag RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); statusLed = digitalInit(GPIO_STATUS_LED_PORT, GPIO_STATUS_LED_PIN); digitalLo(statusLed); errorLed = digitalInit(GPIO_ERROR_LED_PORT, GPIO_ERROR_LED_PIN); digitalLo(errorLed); // jump to boot loader ROM __asm volatile ("LDR R0, =0x1FFFF000\n" "LDR SP,[R0, #0]\n" "LDR R0,[R0, #4]\n" "BX R0\n"); }
void adcInit(void) { GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; AQ_NOTICE("ADC init\n"); memset((void *)&adcData, 0, sizeof(adcData)); // energize mag's set/reset circuit adcData.magSetReset = digitalInit(GPIOE, GPIO_Pin_10, 1); // use auto-zero function of gyros adcData.rateAutoZero = digitalInit(GPIOE, GPIO_Pin_8, 0); // bring ACC's SELF TEST line low adcData.accST = digitalInit(GPIOE, GPIO_Pin_12, 0); // bring ACC's SCALE line low (ADXL3X5 requires this line be tied to GND or left floating) adcData.accScale = digitalInit(GPIOC, GPIO_Pin_15, 0); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOC, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE); adcData.sample = ADC_SAMPLES - 1; // Use STM32F4's Triple Regular Simultaneous Mode capable of ~ 6M samples per second DMA_DeInit(ADC_DMA_STREAM); DMA_InitStructure.DMA_Channel = ADC_DMA_CHANNEL; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adcDMAData.adc123Raw1; DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)0x40012308); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = ADC_CHANNELS * 3 * 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(ADC_DMA_STREAM, &DMA_InitStructure); DMA_ITConfig(ADC_DMA_STREAM, DMA_IT_HT | DMA_IT_TC, ENABLE); DMA_ClearITPendingBit(ADC_DMA_STREAM, ADC_DMA_FLAGS); DMA_Cmd(ADC_DMA_STREAM, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = ADC_DMA_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // ADC Common Init ADC_CommonStructInit(&ADC_CommonInitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInit(&ADC_CommonInitStructure); // ADC1 configuration ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 16; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 1, ADC_SAMPLE_TIME); // magX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 2, ADC_SAMPLE_TIME); // magX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 3, ADC_SAMPLE_TIME); // magX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 4, ADC_SAMPLE_TIME); // magX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 5, ADC_SAMPLE_TIME); // magY ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 6, ADC_SAMPLE_TIME); // magY ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 7, ADC_SAMPLE_TIME); // magY ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 8, ADC_SAMPLE_TIME); // magY ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 9, ADC_SAMPLE_TIME); // magZ ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 10, ADC_SAMPLE_TIME); // magZ ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 11, ADC_SAMPLE_TIME); // magZ ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 12, ADC_SAMPLE_TIME); // magZ ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 13, ADC_SAMPLE_TIME); // rateX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 14, ADC_SAMPLE_TIME); // rateX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 15, ADC_SAMPLE_TIME); // rateX ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 16, ADC_SAMPLE_TIME); // rateX // Enable ADC1 DMA since ADC1 is the Master ADC_DMACmd(ADC1, ENABLE); // ADC2 configuration ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 16; ADC_Init(ADC2, &ADC_InitStructure); ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 1, ADC_SAMPLE_TIME); // rateY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 2, ADC_SAMPLE_TIME); // rateY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 3, ADC_SAMPLE_TIME); // rateY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 4, ADC_SAMPLE_TIME); // rateY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 5, ADC_SAMPLE_TIME); // accX ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 6, ADC_SAMPLE_TIME); // accX ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 7, ADC_SAMPLE_TIME); // accX ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 8, ADC_SAMPLE_TIME); // accX ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 9, ADC_SAMPLE_TIME); // accY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 10, ADC_SAMPLE_TIME); // accY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 11, ADC_SAMPLE_TIME); // accY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 12, ADC_SAMPLE_TIME); // accY ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 13, ADC_SAMPLE_TIME); // accZ ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 14, ADC_SAMPLE_TIME); // accZ ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 15, ADC_SAMPLE_TIME); // accZ ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 16, ADC_SAMPLE_TIME); // accZ // ADC3 configuration ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 16; ADC_Init(ADC3, &ADC_InitStructure); ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 1, ADC_SAMPLE_TIME); // rateZ ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 2, ADC_SAMPLE_TIME); // rateZ ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 3, ADC_SAMPLE_TIME); // rateZ ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 4, ADC_SAMPLE_TIME); // rateZ ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP1, 5, ADC_SAMPLE_TIME); // temp1 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP2, 6, ADC_SAMPLE_TIME); // temp2 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 7, ADC_SAMPLE_TIME); // pressure1 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 8, ADC_SAMPLE_TIME); // pressure1 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 9, ADC_SAMPLE_TIME); // pressure1 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 10, ADC_SAMPLE_TIME); // pressure1 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_VIN, 11, ADC_SAMPLE_TIME); // Vin ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP3, 12, ADC_SAMPLE_TIME); // temp3 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 13, ADC_SAMPLE_TIME); // pressure2 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 14, ADC_SAMPLE_TIME); // pressure2 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 15, ADC_SAMPLE_TIME); // pressure2 ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 16, ADC_SAMPLE_TIME); // pressure2 // Enable DMA request after last transfer (Multi-ADC mode) ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); // Enable ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_Cmd(ADC3, ENABLE); adcData.adcFlag = CoCreateFlag(1, 0); adcTaskStack = aqStackInit(ADC_STACK_SIZE, "ADC"); adcData.adcTask = CoCreateTask(adcTaskCode, (void *)0, ADC_PRIORITY, &adcTaskStack[ADC_STACK_SIZE-1], ADC_STACK_SIZE); // Start ADC1 Software Conversion ADC_SoftwareStartConv(ADC1); yield(100); // set initial temperatures adcData.temp1 = adcIDGVoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP1]); adcData.temp2 = adcIDGVoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP2]); adcData.temp3 = adcT1VoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP3]); analogData.vIn = adcVsenseToVin(adcData.voltages[ADC_VOLTS_VIN]); adcCalibOffsets(); }
void main(void) { rccInit(); statusLed = digitalInit(GPIO_STATUS_LED_PORT, GPIO_STATUS_LED_PIN); errorLed = digitalInit(GPIO_ERROR_LED_PORT, GPIO_ERROR_LED_PIN); #ifdef ESC_DEBUG tp = digitalInit(GPIO_TP_PORT, GPIO_TP_PIN); digitalLo(tp); #endif timerInit(); configInit(); adcInit(); fetInit(); serialInit(); canInit(); runInit(); cliInit(); owInit(); runDisarm(REASON_STARTUP); inputMode = ESC_INPUT_PWM; fetSetDutyCycle(0); fetBeep(200, 100); fetBeep(300, 100); fetBeep(400, 100); fetBeep(500, 100); fetBeep(400, 100); fetBeep(300, 100); fetBeep(200, 100); pwmInit(); digitalHi(statusLed); digitalHi(errorLed); // self calibrating idle timer loop { uint32_t lastRunCount; uint32_t thisCycles, lastCycles; volatile uint32_t cycles; volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xE0001004; volatile uint32_t *DWT_CONTROL = (uint32_t *)0xE0001000; volatile uint32_t *SCB_DEMCR = (uint32_t *)0xE000EDFC; *SCB_DEMCR = *SCB_DEMCR | 0x01000000; *DWT_CONTROL = *DWT_CONTROL | 1; // enable the counter minCycles = 0xffff; while (1) { idleCounter++; if (runCount != lastRunCount && !(runCount % (RUN_FREQ / 1000))) { if (commandMode == CLI_MODE) cliCheck(); else binaryCheck(); lastRunCount = runCount; } thisCycles = *DWT_CYCCNT; cycles = thisCycles - lastCycles; lastCycles = thisCycles; // record shortest number of instructions for loop totalCycles += cycles; if (cycles < minCycles) minCycles = cycles; } } }