/** * STM32 F4 Mini library for custom board * * Author: Jan Dvořák z Vozerovic * E-mail: dvorkaman@gmail.com * Web: dvorkaman.asp2.cz * Created: 2015 */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // M1 is ON until the program STARTS. #ifndef __dvorkaman_STM32F4Mini_c__ #define __dvorkaman_STM32F4Mini_c__ #include "stm32f4xx.h" #include "libF4Mini.h" #include "libUSART.h" /* Global variables */ volatile uint16_t analogValues[F4MINI_MAX_ANALOGS]; /* PINOUT */ /* Motors: TIM3 PWM {B4 B5 B0 B1}, control A4..A7 Servos: TIM4 PWM {B6..B9} Lights: B10 B11 B14 B15 XBee USART: C10 C11 User pins: A0..A3: ADC, IO, TIM2 A8, B12, B13, C9: IO, except analog C0, C1, C2, C4, C5: ADC, IO */ /* Implementation */ /// /// Initialize the F4 mini library. /// /// The f4 mini. /// The xbee addr64msb. /// The xbee addr64lsb. /// Type of the a0_a3 pins, available IO, TIM2. /// The a0 pin type, available I/O, Analog, not considered (0) if TIM /// The a1 pin type, available I/O, Analog, not considered (0) if TIM /// The a2 pin type, available I/O, Analog, not considered (0) if TIM /// The a3 pin type, available I/O, Analog, not considered (0) if TIM /// The a8 pin type, available I/O, except Analog /// The B12 pin type, available I/O except Analog /// The B13 pin type, available I/O except Analog /// The c0 pin type, available I/O, Analog /// The c1 pin type, available I/O, Analog /// The c2 pin type, available I/O, Analog /// The c4 pin type, available I/O, Analog /// The c5 pin type, available I/O, Analog /// The c9 pin type, available I/O except Analog void F4Mini_initialize( libF4Mini* F4Mini, uint32_t xbeeAddr64msb, // XBEE ADDR as ROUTER type; 0 if not used uint32_t xbeeAddr64lsb, // XBEE ADDR as ROUTER type; 0 if not used libF4MiniA0_A3Pins a0_a3Type, // Type of first 4 pins at GPIOA libPinType a0, // Type of pin, available I/O, Analog, not considered (0) if TIM libPinType a1, // Type of pin, available I/O, Analog, not considered (0) if TIM libPinType a2, // Type of pin, available I/O, Analog, not considered (0) if TIM libPinType a3, // Type of pin, available I/O, Analog, not considered (0) if TIM libPinType a8, // Type of pin, available I/O, except Analog libPinType b12, // Type of pin, available I/O except Analog libPinType b13, // Type of pin, available I/O except Analog libPinType c0, // Type of pin, available I/O, Analog libPinType c1, // Type of pin, available I/O, Analog libPinType c2, // Type of pin, available I/O, Analog libPinType c4, // Type of pin, available I/O, Analog libPinType c5, // Type of pin, available I/O, Analog libPinType c9 // Type of pin, available I/O except Analog ) { // Xbee initialization if (xbeeAddr64msb != 0 || xbeeAddr64lsb != 0) { usart_initializeUsart3AtGPIOC(); xbeeRx_initialize(&F4Mini->xbee, USART3, USART3, xbeeAddr64msb, xbeeAddr64lsb); } // store types F4Mini->a0_a3 = a0_a3Type; F4Mini->a0type = a0; F4Mini->a1type = a1; F4Mini->a2type = a2; F4Mini->a3type = a3; F4Mini->a8type = a8; F4Mini->b12type = b12; F4Mini->b13type = b13; F4Mini->c0type = c0; F4Mini->c1type = c1; F4Mini->c2type = c2; F4Mini->c4type = c4; F4Mini->c5type = c5; F4Mini->c9type = c9; // init and clear F4Mini__initializePerihperals(F4Mini); F4Mini__initializeUserPins(F4Mini); F4Mini__initializeUserAnalogPins(F4Mini, &analogValues[0]); // clear F4Mini_clearPerihperals(F4Mini); } /// /// Initialize perihperals for F4 mini. /// void F4Mini__initializePerihperals(libF4Mini* F4Mini) { // Motors pwm_initializeTimer3atGPIOB(); motor_initializePWMPhase(&F4Mini->motor1, GPIOA, GPIO_Pin_7, TIM3, 1); // B4 motor_initializePWMPhase(&F4Mini->motor2, GPIOA, GPIO_Pin_6, TIM3, 2); // B5 motor_initializePWMPhase(&F4Mini->motor3, GPIOA, GPIO_Pin_5, TIM3, 3); // B0 motor_initializePWMPhase(&F4Mini->motor4, GPIOA, GPIO_Pin_4, TIM3, 4); // B1 // Servos pwm_initializeTimer4atGPIOB(); pwm_initializePin(&F4Mini->s1Pin, TIM4, 1); // B6 pwm_initializePin(&F4Mini->s2Pin, TIM4, 2); // B7 pwm_initializePin(&F4Mini->s3Pin, TIM4, 3); // B8 pwm_initializePin(&F4Mini->s4Pin, TIM4, 4); // B9 pwmServo_inizialize(&F4Mini->servo1, &F4Mini->s1Pin); pwmServo_inizialize(&F4Mini->servo2, &F4Mini->s2Pin); pwmServo_inizialize(&F4Mini->servo3, &F4Mini->s3Pin); pwmServo_inizialize(&F4Mini->servo4, &F4Mini->s4Pin); // Lights gpioPin_initialize(&F4Mini->light1, GPIOB, GPIO_Pin_15, libPin_OUTPUT); gpioPin_initialize(&F4Mini->light2, GPIOB, GPIO_Pin_10, libPin_OUTPUT); gpioPin_initialize(&F4Mini->light3, GPIOB, GPIO_Pin_14, libPin_OUTPUT); gpioPin_initialize(&F4Mini->light4, GPIOB, GPIO_Pin_11, libPin_OUTPUT); // Internal lights gpioPin_initialize(&F4Mini->yellow, GPIOC, GPIO_Pin_12, libPin_OUTPUT); gpioPin_initialize(&F4Mini->red, GPIOC, GPIO_Pin_13, libPin_OUTPUT); } /// /// Initialize user pins. /// /// The f4 mini. void F4Mini__initializeUserPins(libF4Mini* F4Mini) { // a0..3 switch (F4Mini->a0_a3) { case io_adc: gpioPin_initialize(&F4Mini->a0, GPIOA, GPIO_Pin_0, F4Mini->a0type); gpioPin_initialize(&F4Mini->a1, GPIOA, GPIO_Pin_1, F4Mini->a1type); gpioPin_initialize(&F4Mini->a2, GPIOA, GPIO_Pin_2, F4Mini->a2type); gpioPin_initialize(&F4Mini->a3, GPIOA, GPIO_Pin_3, F4Mini->a3type); break; case tim2: pwm_initializeTimer2(); break; } // Remaining gpioPin_initialize(&F4Mini->a8, GPIOA, GPIO_Pin_8, F4Mini->a8type); gpioPin_initialize(&F4Mini->b12, GPIOB, GPIO_Pin_12, F4Mini->b12type); gpioPin_initialize(&F4Mini->b13, GPIOB, GPIO_Pin_13, F4Mini->b13type); gpioPin_initialize(&F4Mini->c0, GPIOC, GPIO_Pin_0, F4Mini->c0type); gpioPin_initialize(&F4Mini->c1, GPIOC, GPIO_Pin_1, F4Mini->c1type); gpioPin_initialize(&F4Mini->c2, GPIOC, GPIO_Pin_2, F4Mini->c2type); gpioPin_initialize(&F4Mini->c4, GPIOC, GPIO_Pin_4, F4Mini->c4type); gpioPin_initialize(&F4Mini->c5, GPIOC, GPIO_Pin_5, F4Mini->c5type); gpioPin_initialize(&F4Mini->c9, GPIOC, GPIO_Pin_9, F4Mini->c9type); } /// /// Initialize user analog pins. /// /// The f4 mini. void F4Mini__initializeUserAnalogPins(libF4Mini* F4Mini, volatile uint16_t* adcAnalogSourceAddress) { uint8_t analogPinsCount = 0, i; uint8_t channels[F4MINI_MAX_ANALOGS]; // determine analog pins if (F4Mini->a0_a3 == io_adc && F4Mini->a0type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_0; gpio_initializeInputAnalogPin(GPIOA, GPIO_Pin_0); } if (F4Mini->a0_a3 == io_adc && F4Mini->a1type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_1; gpio_initializeInputAnalogPin(GPIOA, GPIO_Pin_1); } if (F4Mini->a0_a3 == io_adc && F4Mini->a2type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_2; gpio_initializeInputAnalogPin(GPIOA, GPIO_Pin_2); } if (F4Mini->a0_a3 == io_adc && F4Mini->a3type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_3; gpio_initializeInputAnalogPin(GPIOA, GPIO_Pin_3); } if (F4Mini->c0type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_10; gpio_initializeInputAnalogPin(GPIOC, GPIO_Pin_0); } if (F4Mini->c1type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_11; gpio_initializeInputAnalogPin(GPIOC, GPIO_Pin_1); } if (F4Mini->c2type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_12; gpio_initializeInputAnalogPin(GPIOC, GPIO_Pin_2); } if (F4Mini->c4type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_14; gpio_initializeInputAnalogPin(GPIOC, GPIO_Pin_4); } if (F4Mini->c5type == libPin_ANALOG) { channels[analogPinsCount++] = ADC_Channel_15; gpio_initializeInputAnalogPin(GPIOC, GPIO_Pin_5); } // ADC if (analogPinsCount > 0) { // ADC system_inicializeADC(0xFF, analogPinsCount, (uint32_t)adcAnalogSourceAddress); // Analog filter, analogs analogFilter_initialize(&F4Mini->af, analogPinsCount, adcAnalogSourceAddress); // channel configs for (i = 0; i < analogPinsCount; i++) { ADC_RegularChannelConfig(ADC1, channels[i], i + 1, ADC_SAMPLE_RATE); analog_initialize(&F4Mini->analogs[i], &F4Mini->af, i); analogCollection_addLibAnalog(&F4Mini->analogs[i]); } // Finish // - Enable ADC1 / DMA ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); // - Start ADC1 Software Conversion ADC_SoftwareStartConv(ADC1); } } /// /// Clear all perihperals to default states. /// void F4Mini_clearPerihperals(libF4Mini* F4Mini) { // Motors motor_stop(&F4Mini->motor1); motor_stop(&F4Mini->motor2); motor_stop(&F4Mini->motor3); motor_stop(&F4Mini->motor4); // Servos pwmServo_setPosition(&F4Mini->servo1, 90); pwmServo_setPosition(&F4Mini->servo2, 90); pwmServo_setPosition(&F4Mini->servo3, 90); pwmServo_setPosition(&F4Mini->servo4, 90); // Lights gpioPin_write(&F4Mini->light1, Bit_RESET); gpioPin_write(&F4Mini->light2, Bit_RESET); gpioPin_write(&F4Mini->light3, Bit_RESET); gpioPin_write(&F4Mini->light4, Bit_RESET); gpioPin_write(&F4Mini->yellow, Bit_RESET); gpioPin_write(&F4Mini->red, Bit_RESET); // User pins // a0..3 switch (F4Mini->a0_a3) { case io_adc: if (F4Mini->a0type == libPin_OUTPUT) gpioPin_write(&F4Mini->a0, Bit_RESET); if (F4Mini->a1type == libPin_OUTPUT) gpioPin_write(&F4Mini->a1, Bit_RESET); if (F4Mini->a2type == libPin_OUTPUT) gpioPin_write(&F4Mini->a2, Bit_RESET); if (F4Mini->a3type == libPin_OUTPUT) gpioPin_write(&F4Mini->a3, Bit_RESET); break; case tim2: pwm_write(TIM2, 1, 0); pwm_write(TIM2, 2, 0); pwm_write(TIM2, 3, 0); pwm_write(TIM2, 4, 0); break; } if (F4Mini->a8type == libPin_OUTPUT) gpioPin_write(&F4Mini->a8, Bit_RESET); if (F4Mini->b12type == libPin_OUTPUT) gpioPin_write(&F4Mini->b12, Bit_RESET); if (F4Mini->b13type == libPin_OUTPUT) gpioPin_write(&F4Mini->b13, Bit_RESET); if (F4Mini->c0type == libPin_OUTPUT) gpioPin_write(&F4Mini->c0, Bit_RESET); if (F4Mini->c1type == libPin_OUTPUT) gpioPin_write(&F4Mini->c1, Bit_RESET); if (F4Mini->c2type == libPin_OUTPUT) gpioPin_write(&F4Mini->c2, Bit_RESET); if (F4Mini->c4type == libPin_OUTPUT) gpioPin_write(&F4Mini->c4, Bit_RESET); if (F4Mini->c5type == libPin_OUTPUT) gpioPin_write(&F4Mini->c5, Bit_RESET); if (F4Mini->c9type == libPin_OUTPUT) gpioPin_write(&F4Mini->c9, Bit_RESET); } #endif