/**
* 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