Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • authierj/dfall-system
1 result
Show changes
Showing
with 0 additions and 2194 deletions
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* piezo.c - Piezo/Buzzer driver
*
* This code mainly interfacing the PWM peripheral lib of ST.
*/
#include <stdbool.h>
/* ST includes */
#include "stm32fxxx.h"
#include "piezo.h"
//FreeRTOS includes
#include "FreeRTOS.h"
#include "task.h"
// HW defines
#define PIEZO_TIM_PERIF RCC_APB1Periph_TIM5
#define PIEZO_TIM TIM5
#define PIEZO_TIM_DBG DBGMCU_TIM2_STOP
#define PIEZO_TIM_SETCOMPARE TIM_SetCompare2
#define PIEZO_TIM_GETCAPTURE TIM_GetCapture2
#define PIEZO_GPIO_POS_PERIF RCC_AHB1Periph_GPIOA
#define PIEZO_GPIO_POS_PORT GPIOA
#define PIEZO_GPIO_POS_PIN GPIO_Pin_2 // TIM5_CH3
#define PIEZO_GPIO_AF_POS_PIN GPIO_PinSource2
#define PIEZO_GPIO_AF_POS GPIO_AF_TIM5
#define PIEZO_GPIO_NEG_PERIF RCC_AHB1Periph_GPIOA
#define PIEZO_GPIO_NEG_PORT GPIOA
#define PIEZO_GPIO_NEG_PIN GPIO_Pin_3 // TIM5_CH4
#define PIEZO_GPIO_AF_NEG_PIN GPIO_PinSource3
#define PIEZO_GPIO_AF_NEG GPIO_AF_TIM5
#define PIEZO_PWM_BITS (8)
#define PIEZO_PWM_PERIOD ((1<<PIEZO_PWM_BITS) - 1)
#define PIEZO_PWM_PRESCALE (0)
/* This should be calculated.. */
#define PIEZO_BASE_FREQ (329500)
static bool isInit = false;
/* Public functions */
void piezoInit()
{
if (isInit)
return;
//Init structures
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//Clock the gpio and the timers
RCC_AHB1PeriphClockCmd(PIEZO_GPIO_POS_PERIF | PIEZO_GPIO_NEG_PERIF, ENABLE);
RCC_APB1PeriphClockCmd(PIEZO_TIM_PERIF, ENABLE);
// Configure the GPIO for the timer output
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Pin = PIEZO_GPIO_POS_PIN;
GPIO_Init(PIEZO_GPIO_POS_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIEZO_GPIO_NEG_PIN;
GPIO_Init(PIEZO_GPIO_NEG_PORT, &GPIO_InitStructure);
//Map timers to alternate functions
GPIO_PinAFConfig(PIEZO_GPIO_POS_PORT, PIEZO_GPIO_AF_POS_PIN, PIEZO_GPIO_AF_POS);
GPIO_PinAFConfig(PIEZO_GPIO_NEG_PORT, PIEZO_GPIO_AF_NEG_PIN, PIEZO_GPIO_AF_NEG);
//Timer configuration
TIM_TimeBaseStructure.TIM_Period = PIEZO_PWM_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler = PIEZO_PWM_PRESCALE;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(PIEZO_TIM, &TIM_TimeBaseStructure);
// PWM channels configuration
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
// Configure OC3
TIM_OC3Init(PIEZO_TIM, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(PIEZO_TIM, TIM_OCPreload_Enable);
// Configure OC4 inverted
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(PIEZO_TIM, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(PIEZO_TIM, TIM_OCPreload_Enable);
//Enable the timer PWM outputs
TIM_CtrlPWMOutputs(PIEZO_TIM, ENABLE);
TIM_SetCompare3(PIEZO_TIM, 0x00);
TIM_SetCompare4(PIEZO_TIM, 0x00);
//Enable the timer
TIM_Cmd(PIEZO_TIM, ENABLE);
isInit = true;
}
bool piezoTest(void)
{
return isInit;
}
void piezoSetRatio(uint8_t ratio)
{
TIM_SetCompare3(PIEZO_TIM, ratio);
TIM_SetCompare4(PIEZO_TIM, ratio);
}
void piezoSetFreq(uint16_t freq)
{
TIM_PrescalerConfig(PIEZO_TIM, (PIEZO_BASE_FREQ/freq), TIM_PSCReloadMode_Update);
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* swd.c - Low level SWD functionality
*/
#include <stdbool.h>
#include "stm32fxxx.h"
/*FreeRtos includes*/
#include "FreeRTOS.h"
#include "task.h"
#include "swd.h"
static bool isInit = false;
#define SWD_SPI SPI2
#define SWD_SPI_CLK RCC_APB1Periph_SPI2
#define SWD_SPI_CLK_INIT RCC_APB1PeriphClockCmd
#define SWD_SPI_SCK_PIN GPIO_Pin_13
#define SWD_SPI_SCK_GPIO_PORT GPIOB
#define SWD_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB
#define SWD_SPI_SCK_SOURCE GPIO_PinSource13
#define SWD_SPI_SCK_AF GPIO_AF_SPI2
#define SWD_SPI_MISO_PIN GPIO_Pin_15
#define SWD_SPI_MISO_GPIO_PORT GPIOB
#define SWD_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOB
#define SWD_SPI_MISO_SOURCE GPIO_PinSource15
#define SWD_SPI_MISO_AF GPIO_AF_SPI2
static void initGPIO(void) {
GPIO_InitTypeDef GPIO_InitStructure;
SWD_SPI_CLK_INIT(SWD_SPI_CLK, ENABLE);
RCC_AHB1PeriphClockCmd(SWD_SPI_SCK_GPIO_CLK | SWD_SPI_MISO_GPIO_CLK, ENABLE);
GPIO_PinAFConfig(SWD_SPI_SCK_GPIO_PORT, SWD_SPI_SCK_SOURCE, SWD_SPI_SCK_AF);
GPIO_PinAFConfig(SWD_SPI_MISO_GPIO_PORT, SWD_SPI_MISO_SOURCE, SWD_SPI_MISO_AF);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = SWD_SPI_SCK_PIN;
GPIO_Init(SWD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
/* In bi-directional mode only MISO is used */
GPIO_InitStructure.GPIO_Pin = SWD_SPI_MISO_PIN;
GPIO_Init(SWD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
}
static void initSPI(void) {
SPI_InitTypeDef SPI_InitStructure;
initGPIO();
/* Set up SPI in bi-directional mode */
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SWD_SPI, &SPI_InitStructure);
SPI_Cmd(SWD_SPI, ENABLE);
}
//Initialize the green led pin as output
void swdInit()
{
if(isInit)
return;
initSPI();
isInit = true;
}
/* Code for debugging and testing, should be removed later */
uint8_t tx_data[35];
uint8_t rx_data[35];
uint32_t counter = 0;
uint16_t number_of_txd_bytes = 0;
uint32_t transfer_size = 35;
uint8_t header = 0xA5;
uint8_t idx = 0;
bool swdTest(void) {
// Start = 1
// DP access = 0
// Read access = 1
// DP reg = 00 (IDCODE)
// Parity = odd bits -> 1
// Stop = 0
// Park = 1 (not 0!)
// First at least fifty ones, then the sequence below to switch from JTAG to SWD and then at least 50 ones again.
// The the SWD is reset and ready to use. Note that once this is done the nRF will only go into simulated off mode since
// a debugger is connected.
// 111...01111001 11100111...111
// The command for reading IDCODE is
/// 10100101
// Should read out (and does):0x0BB11477 (according to OpenOCD)
//T ACK |------------DATA--------------|P
//? 100 111011100010100010001101110100001
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
#if 0
tx_data[idx++] = 0x9E;
tx_data[idx++] = 0xE7;
#else
tx_data[idx++] = 0x79;
tx_data[idx++] = 0xE7;
#endif
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFF;
tx_data[idx++] = 0xFC;
tx_data[idx++] = header;
// Rest is 0x00
/* As long as the SPI is enabled in bi-di mode the clock is enabled. So
* we write data as normal, but when reading there's no need to output any
* data to trigger the clock. Direction needs to be set accordingly.
*/
while(number_of_txd_bytes < transfer_size)
{
if (number_of_txd_bytes < idx)
{
SPI_BiDirectionalLineConfig(SWD_SPI, SPI_Direction_Tx);
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SWD_SPI, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SWD_SPI, tx_data[number_of_txd_bytes]);
// Make sure that we have sent data in case next loop will be RX, the
// mode is switched before we manage to send the data!
while (SPI_I2S_GetFlagStatus(SWD_SPI, SPI_I2S_FLAG_BSY) == SET);
}
else
{
SPI_BiDirectionalLineConfig(SWD_SPI, SPI_Direction_Rx);
while (SPI_I2S_GetFlagStatus(SWD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/*!< Return the byte read from the SPI bus */
rx_data[number_of_txd_bytes] = (uint8_t) SPI_I2S_ReceiveData(SWD_SPI);
}
number_of_txd_bytes++;
}
SPI_Cmd(SWD_SPI, DISABLE);
return isInit;
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* uart1.c - uart1 driver
*/
#include <string.h>
/*FreeRtos includes*/
#include "FreeRTOS.h"
#include "queue.h"
/*ST includes */
#include "stm32fxxx.h"
#include "config.h"
#include "nvic.h"
#include "uart1.h"
#include "cfassert.h"
#include "config.h"
#include "nvicconf.h"
static xQueueHandle uart1queue;
static bool isInit = false;
void uart1Init(const uint32_t baudrate)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIO and USART clock */
RCC_AHB1PeriphClockCmd(UART1_GPIO_PERIF, ENABLE);
ENABLE_UART1_RCC(UART1_PERIF, ENABLE);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UART1_GPIO_PORT, &GPIO_InitStructure);
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(UART1_GPIO_PORT, &GPIO_InitStructure);
//Map uart to alternate functions
GPIO_PinAFConfig(UART1_GPIO_PORT, UART1_GPIO_AF_TX_PIN, UART1_GPIO_AF_TX);
GPIO_PinAFConfig(UART1_GPIO_PORT, UART1_GPIO_AF_RX_PIN, UART1_GPIO_AF_RX);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(UART1_TYPE, &USART_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_MID_PRI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
uart1queue = xQueueCreate(64, sizeof(uint8_t));
USART_ITConfig(UART1_TYPE, USART_IT_RXNE, ENABLE);
//Enable UART
USART_Cmd(UART1_TYPE, ENABLE);
USART_ITConfig(UART1_TYPE, USART_IT_RXNE, ENABLE);
isInit = true;
}
bool uart1Test(void)
{
return isInit;
}
bool uart1GetDataWithTimout(uint8_t *c)
{
if (xQueueReceive(uart1queue, c, UART1_DATA_TIMEOUT_TICKS) == pdTRUE)
{
return true;
}
*c = 0;
return false;
}
void uart1SendData(uint32_t size, uint8_t* data)
{
uint32_t i;
if (!isInit)
return;
for(i = 0; i < size; i++)
{
while (!(UART1_TYPE->SR & USART_FLAG_TXE));
UART1_TYPE->DR = (data[i] & 0x00FF);
}
}
int uart1Putchar(int ch)
{
uart1SendData(1, (uint8_t *)&ch);
return (unsigned char)ch;
}
void uart1Getchar(char * ch)
{
xQueueReceive(uart1queue, ch, portMAX_DELAY);
}
void __attribute__((used)) USART3_IRQHandler(void)
{
uint8_t rxData;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if (USART_GetITStatus(UART1_TYPE, USART_IT_RXNE))
{
rxData = USART_ReceiveData(UART1_TYPE) & 0x00FF;
xQueueSendFromISR(uart1queue, &rxData, &xHigherPriorityTaskWoken);
}
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* uart2.c - uart2 driver
*/
#include <string.h>
/*ST includes */
#include "stm32fxxx.h"
#include "config.h"
#include "uart2.h"
#include "cfassert.h"
#include "config.h"
static bool isInit = false;
void uart2Init(const uint32_t baudrate)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO and USART clock */
RCC_AHB1PeriphClockCmd(UART2_GPIO_PERIF, ENABLE);
ENABLE_UART2_RCC(UART2_PERIF, ENABLE);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UART2_GPIO_PORT, &GPIO_InitStructure);
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(UART2_GPIO_PORT, &GPIO_InitStructure);
//Map uart to alternate functions
GPIO_PinAFConfig(UART2_GPIO_PORT, UART2_GPIO_AF_TX_PIN, UART2_GPIO_AF_TX);
GPIO_PinAFConfig(UART2_GPIO_PORT, UART2_GPIO_AF_RX_PIN, UART2_GPIO_AF_RX);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(UART2_TYPE, &USART_InitStructure);
//Enable UART
USART_Cmd(UART2_TYPE, ENABLE);
isInit = true;
}
bool uart2Test(void)
{
return isInit;
}
void uart2SendData(uint32_t size, uint8_t* data)
{
uint32_t i;
if (!isInit)
return;
for(i = 0; i < size; i++)
{
while (!(UART2_TYPE->SR & USART_FLAG_TXE));
UART2_TYPE->DR = (data[i] & 0x00FF);
}
}
int uart2Putchar(int ch)
{
uart2SendData(1, (uint8_t *)&ch);
return (unsigned char)ch;
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* uart_syslink.c - Uart syslink to nRF51 and raw access functions
*/
#include <stdint.h>
#include <string.h>
/*ST includes */
#include "stm32fxxx.h"
/*FreeRtos includes*/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"
#include "config.h"
#include "uart_syslink.h"
#include "crtp.h"
#include "cfassert.h"
#include "nvicconf.h"
#include "config.h"
#include "queuemonitor.h"
#define UARTSLK_DATA_TIMEOUT_MS 1000
#define UARTSLK_DATA_TIMEOUT_TICKS (UARTSLK_DATA_TIMEOUT_MS / portTICK_RATE_MS)
#define CCR_ENABLE_SET ((uint32_t)0x00000001)
static bool isInit = false;
static xSemaphoreHandle waitUntilSendDone;
static xSemaphoreHandle uartBusy;
static xQueueHandle uartslkDataDelivery;
static uint8_t dmaBuffer[64];
static uint8_t *outDataIsr;
static uint8_t dataIndexIsr;
static uint8_t dataSizeIsr;
static bool isUartDmaInitialized;
static DMA_InitTypeDef DMA_InitStructureShare;
static uint32_t initialDMACount;
static uint32_t remainingDMACount;
static bool dmaIsPaused;
static void uartslkPauseDma();
static void uartslkResumeDma();
/**
* Configures the UART DMA. Mainly used for FreeRTOS trace
* data transfer.
*/
void uartslkDmaInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
// USART TX DMA Channel Config
DMA_InitStructureShare.DMA_PeripheralBaseAddr = (uint32_t)&UARTSLK_TYPE->DR;
DMA_InitStructureShare.DMA_Memory0BaseAddr = (uint32_t)dmaBuffer;
DMA_InitStructureShare.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructureShare.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructureShare.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructureShare.DMA_BufferSize = 0;
DMA_InitStructureShare.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructureShare.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructureShare.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructureShare.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructureShare.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructureShare.DMA_Priority = DMA_Priority_High;
DMA_InitStructureShare.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructureShare.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
DMA_InitStructureShare.DMA_Channel = UARTSLK_DMA_CH;
NVIC_InitStructure.NVIC_IRQChannel = UARTSLK_DMA_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_HIGH_PRI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
isUartDmaInitialized = true;
}
void uartslkInit(void)
{
// initialize the FreeRTOS structures first, to prevent null pointers in interrupts
waitUntilSendDone = xSemaphoreCreateBinary(); // initialized as blocking
uartBusy = xSemaphoreCreateBinary(); // initialized as blocking
xSemaphoreGive(uartBusy); // but we give it because the uart isn't busy at initialization
uartslkDataDelivery = xQueueCreate(1024, sizeof(uint8_t));
DEBUG_QUEUE_MONITOR_REGISTER(uartslkDataDelivery);
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef extiInit;
/* Enable GPIO and USART clock */
RCC_AHB1PeriphClockCmd(UARTSLK_GPIO_PERIF, ENABLE);
ENABLE_UARTSLK_RCC(UARTSLK_PERIF, ENABLE);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = UARTSLK_GPIO_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UARTSLK_GPIO_PORT, &GPIO_InitStructure);
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_Pin = UARTSLK_GPIO_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(UARTSLK_GPIO_PORT, &GPIO_InitStructure);
//Map uartslk to alternate functions
GPIO_PinAFConfig(UARTSLK_GPIO_PORT, UARTSLK_GPIO_AF_TX_PIN, UARTSLK_GPIO_AF_TX);
GPIO_PinAFConfig(UARTSLK_GPIO_PORT, UARTSLK_GPIO_AF_RX_PIN, UARTSLK_GPIO_AF_RX);
#if defined(UARTSLK_OUTPUT_TRACE_DATA) || defined(ADC_OUTPUT_RAW_DATA) || defined(IMU_OUTPUT_RAW_DATA_ON_UART)
USART_InitStructure.USART_BaudRate = 2000000;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
#else
USART_InitStructure.USART_BaudRate = 1000000;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
#endif
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(UARTSLK_TYPE, &USART_InitStructure);
uartslkDmaInit();
// Configure Rx buffer not empty interrupt
NVIC_InitStructure.NVIC_IRQChannel = UARTSLK_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_SYSLINK_PRI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(UARTSLK_TYPE, USART_IT_RXNE, ENABLE);
//Setting up TXEN pin (NRF flow control)
RCC_AHB1PeriphClockCmd(UARTSLK_TXEN_PERIF, ENABLE);
bzero(&GPIO_InitStructure, sizeof(GPIO_InitStructure));
GPIO_InitStructure.GPIO_Pin = UARTSLK_TXEN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UARTSLK_TXEN_PORT, &GPIO_InitStructure);
extiInit.EXTI_Line = UARTSLK_TXEN_EXTI;
extiInit.EXTI_Mode = EXTI_Mode_Interrupt;
extiInit.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
extiInit.EXTI_LineCmd = ENABLE;
EXTI_Init(&extiInit);
EXTI_ClearITPendingBit(UARTSLK_TXEN_EXTI);
NVIC_EnableIRQ(EXTI4_IRQn);
//Enable UART
USART_Cmd(UARTSLK_TYPE, ENABLE);
isInit = true;
}
bool uartslkTest(void)
{
return isInit;
}
bool uartslkGetDataWithTimout(uint8_t *c)
{
if (xQueueReceive(uartslkDataDelivery, c, UARTSLK_DATA_TIMEOUT_TICKS) == pdTRUE)
{
return true;
}
*c = 0;
return false;
}
void uartslkSendData(uint32_t size, uint8_t* data)
{
uint32_t i;
if (!isInit)
return;
for(i = 0; i < size; i++)
{
#ifdef UARTSLK_SPINLOOP_FLOWCTRL
while(GPIO_ReadInputDataBit(UARTSLK_TXEN_PORT, UARTSLK_TXEN_PIN) == Bit_SET);
#endif
while (!(UARTSLK_TYPE->SR & USART_FLAG_TXE));
UARTSLK_TYPE->DR = (data[i] & 0x00FF);
}
}
void uartslkSendDataIsrBlocking(uint32_t size, uint8_t* data)
{
xSemaphoreTake(uartBusy, portMAX_DELAY);
outDataIsr = data;
dataSizeIsr = size;
dataIndexIsr = 1;
uartslkSendData(1, &data[0]);
USART_ITConfig(UARTSLK_TYPE, USART_IT_TXE, ENABLE);
xSemaphoreTake(waitUntilSendDone, portMAX_DELAY);
outDataIsr = 0;
xSemaphoreGive(uartBusy);
}
int uartslkPutchar(int ch)
{
uartslkSendData(1, (uint8_t *)&ch);
return (unsigned char)ch;
}
void uartslkSendDataDmaBlocking(uint32_t size, uint8_t* data)
{
if (isUartDmaInitialized)
{
xSemaphoreTake(uartBusy, portMAX_DELAY);
// Wait for DMA to be free
while(DMA_GetCmdStatus(UARTSLK_DMA_STREAM) != DISABLE);
//Copy data in DMA buffer
memcpy(dmaBuffer, data, size);
DMA_InitStructureShare.DMA_BufferSize = size;
initialDMACount = size;
// Init new DMA stream
DMA_Init(UARTSLK_DMA_STREAM, &DMA_InitStructureShare);
// Enable the Transfer Complete interrupt
DMA_ITConfig(UARTSLK_DMA_STREAM, DMA_IT_TC, ENABLE);
/* Enable USART DMA TX Requests */
USART_DMACmd(UARTSLK_TYPE, USART_DMAReq_Tx, ENABLE);
/* Clear transfer complete */
USART_ClearFlag(UARTSLK_TYPE, USART_FLAG_TC);
/* Enable DMA USART TX Stream */
DMA_Cmd(UARTSLK_DMA_STREAM, ENABLE);
xSemaphoreTake(waitUntilSendDone, portMAX_DELAY);
xSemaphoreGive(uartBusy);
}
}
static void uartslkPauseDma()
{
if (DMA_GetCmdStatus(UARTSLK_DMA_STREAM) == ENABLE)
{
// Disable transfer complete interrupt
DMA_ITConfig(UARTSLK_DMA_STREAM, DMA_IT_TC, DISABLE);
// Disable stream to pause it
DMA_Cmd(UARTSLK_DMA_STREAM, DISABLE);
// Wait for it to be disabled
while(DMA_GetCmdStatus(UARTSLK_DMA_STREAM) != DISABLE);
// Disable transfer complete
DMA_ClearITPendingBit(UARTSLK_DMA_STREAM, UARTSLK_DMA_FLAG_TCIF);
// Read remaining data count
remainingDMACount = DMA_GetCurrDataCounter(UARTSLK_DMA_STREAM);
dmaIsPaused = true;
}
}
static void uartslkResumeDma()
{
if (dmaIsPaused)
{
// Update DMA counter
DMA_SetCurrDataCounter(UARTSLK_DMA_STREAM, remainingDMACount);
// Update memory read address
UARTSLK_DMA_STREAM->M0AR = (uint32_t)&dmaBuffer[initialDMACount - remainingDMACount];
// Enable the Transfer Complete interrupt
DMA_ITConfig(UARTSLK_DMA_STREAM, DMA_IT_TC, ENABLE);
/* Clear transfer complete */
USART_ClearFlag(UARTSLK_TYPE, USART_FLAG_TC);
/* Enable DMA USART TX Stream */
DMA_Cmd(UARTSLK_DMA_STREAM, ENABLE);
dmaIsPaused = false;
}
}
void uartslkDmaIsr(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
// Stop and cleanup DMA stream
DMA_ITConfig(UARTSLK_DMA_STREAM, DMA_IT_TC, DISABLE);
DMA_ClearITPendingBit(UARTSLK_DMA_STREAM, UARTSLK_DMA_FLAG_TCIF);
USART_DMACmd(UARTSLK_TYPE, USART_DMAReq_Tx, DISABLE);
DMA_Cmd(UARTSLK_DMA_STREAM, DISABLE);
remainingDMACount = 0;
xSemaphoreGiveFromISR(waitUntilSendDone, &xHigherPriorityTaskWoken);
}
void uartslkIsr(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
// the following if statement replaces:
// if (USART_GetITStatus(UARTSLK_TYPE, USART_IT_RXNE) == SET)
// we do this check as fast as possible to minimize the chance of an overrun,
// which occasionally cause problems and cause packet loss at high CPU usage
if ((UARTSLK_TYPE->SR & (1<<5)) != 0) // if the RXNE interrupt has occurred
{
uint8_t rxDataInterrupt = (uint8_t)(UARTSLK_TYPE->DR & 0xFF);
xQueueSendFromISR(uartslkDataDelivery, &rxDataInterrupt, &xHigherPriorityTaskWoken);
}
else if (USART_GetITStatus(UARTSLK_TYPE, USART_IT_TXE) == SET)
{
if (outDataIsr && (dataIndexIsr < dataSizeIsr))
{
USART_SendData(UARTSLK_TYPE, outDataIsr[dataIndexIsr] & 0x00FF);
dataIndexIsr++;
}
else
{
USART_ITConfig(UARTSLK_TYPE, USART_IT_TXE, DISABLE);
xSemaphoreGiveFromISR(waitUntilSendDone, &xHigherPriorityTaskWoken);
}
}
else
{
/** if we get here, the error is most likely caused by an overrun!
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun error)
* - and IDLE (Idle line detected) pending bits are cleared by software sequence:
* - reading USART_SR register followed reading the USART_DR register.
*/
asm volatile ("" : "=m" (UARTSLK_TYPE->SR) : "r" (UARTSLK_TYPE->SR)); // force non-optimizable reads
asm volatile ("" : "=m" (UARTSLK_TYPE->DR) : "r" (UARTSLK_TYPE->DR)); // of these two registers
}
}
void uartslkTxenFlowctrlIsr()
{
EXTI_ClearFlag(UARTSLK_TXEN_EXTI);
if (GPIO_ReadInputDataBit(UARTSLK_TXEN_PORT, UARTSLK_TXEN_PIN) == Bit_SET)
{
uartslkPauseDma();
//ledSet(LED_GREEN_R, 1);
}
else
{
uartslkResumeDma();
//ledSet(LED_GREEN_R, 0);
}
}
void __attribute__((used)) EXTI4_Callback(void)
{
uartslkTxenFlowctrlIsr();
}
void __attribute__((used)) USART6_IRQHandler(void)
{
uartslkIsr();
}
void __attribute__((used)) DMA2_Stream7_IRQHandler(void)
{
uartslkDmaIsr();
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie Firmware
*
* Copyright (C) Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @file watchdog.c - Implementaion of hardware watchdog
*
*/
#define DEBUG_MODULE "SYS"
#include "debug.h"
#include "watchdog.h"
#include "cfassert.h"
bool watchdogNormalStartTest(void)
{
bool wasNormalStart = true;
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST)) {
RCC_ClearFlag();
wasNormalStart = false;
DEBUG_PRINT("The system resumed after watchdog timeout [WARNING]\n");
printAssertSnapshotData();
}
return wasNormalStart;
}
void watchdogInit(void)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// The watchdog uses the LSI oscillator for checking the timeout. The LSI
// oscillator frequency is not very exact and the range is fairly large
// and also differs between the Crazyflie 1.0 and 2.0:
// MIN TYP MAX
// Crazyflie 1.0 30 40 60 (in kHz)
// Crazyflie 2.0 17 32 47 (in kHz)
//
IWDG_SetPrescaler(IWDG_Prescaler_32);
// Divide the clock with 32 which gives
// an interval of 17kHz/32 (CF2 min) to 60kHz/32 (CF1 max) =>
// 1875 Hz to 531 Hz for the watchdog timer.
//
// The goal timeout is >100 ms, but it's acceptable
// that the max timeout is a bit higher. Scaling the
// reload counter for the fastest LSI then gives a
// timeout of 100ms, which in turn gives a timeout
// of 353ms for the slowest LSI. So the watchdog timeout
// will be between 100ms and 353ms on all platforms.
//
// At prescaler 32 each bit is 1 ms this gives:
// 1875 Hz * 0.1 s / 1 => 188
IWDG_SetReload(188);
watchdogReset();
IWDG_Enable();
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2014 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ws2812.c: Neopixel LED driver
* Mostly from Elia's electonic blog: http://eliaselectronics.com/driving-a-ws2812-rgb-led-with-an-stm32/
*/
#include <string.h>
// ST lib includes
#include "stm32fxxx.h"
#include "nvicconf.h"
#include "FreeRTOS.h"
#include "semphr.h"
//#define TIM1_CCR1_Address 0x40012C34 // physical memory address of Timer 3 CCR1 register
static TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
static TIM_OCInitTypeDef TIM_OCInitStructure;
static GPIO_InitTypeDef GPIO_InitStructure;
static DMA_InitTypeDef DMA_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
static xSemaphoreHandle allLedDone = NULL;
// The minimum is to have 2 leds (1 per half buffer) in the buffer, this
// consume 42Bytes and will trigger the DMA interrupt at ~2KHz.
// Putting 2 there will divide by 2 the interrupt frequency but will also
// double the memory consumption (no free lunch ;-)
#define LED_PER_HALF 1
#define TIMING_ONE 75
#define TIMING_ZERO 29
static union {
uint16_t buffer[2*LED_PER_HALF*24];
struct {
uint16_t begin[LED_PER_HALF*24];
uint16_t end[LED_PER_HALF*24];
} __attribute__((packed));
} led_dma;
void ws2812Init(void)
{
uint16_t PrescalerValue;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOB Configuration: TIM3 Channel 1 as alternate function push-pull */
// Configure the GPIO PB4 for the timer output
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//Map timer to alternate functions
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3);
/* Compute the prescaler value */
PrescalerValue = 0;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = (105 - 1); // 800kHz
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
// TIM_Cmd(TIM3, ENABLE); // Go!!!
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(TIM3, ENABLE); // enable Timer 3
/* configure DMA */
/* DMA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* DMA1 Channel2 Config */
DMA_DeInit(DMA1_Stream5);
// USART TX DMA Channel Config
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR2;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)led_dma.buffer; // this is the buffer memory
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_LOW_PRI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Stream5, DMA_IT_HT, ENABLE);
/* TIM3 CC2 DMA Request enable */
TIM_DMACmd(TIM3, TIM_DMA_CC2, ENABLE);
vSemaphoreCreateBinary(allLedDone);
}
static void fillLed(uint16_t *buffer, uint8_t *color)
{
int i;
for(i=0; i<8; i++) // GREEN data
{
buffer[i] = ((color[1]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
}
for(i=0; i<8; i++) // RED
{
buffer[8+i] = ((color[0]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
}
for(i=0; i<8; i++) // BLUE
{
buffer[16+i] = ((color[2]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
}
}
static int current_led = 0;
static int total_led = 0;
static uint8_t (*color_led)[3] = NULL;
void ws2812Send(uint8_t (*color)[3], int len)
{
int i;
if(len<1) return;
//Wait for previous transfer to be finished
xSemaphoreTake(allLedDone, portMAX_DELAY);
// Set interrupt context ...
current_led = 0;
total_led = len;
color_led = color;
for(i=0; (i<LED_PER_HALF) && (current_led<total_led+2); i++, current_led++) {
if (current_led<total_led)
fillLed(led_dma.begin+(24*i), color_led[current_led]);
else
bzero(led_dma.begin+(24*i), sizeof(led_dma.begin));
}
for(i=0; (i<LED_PER_HALF) && (current_led<total_led+2); i++, current_led++) {
if (current_led<total_led)
fillLed(led_dma.end+(24*i), color_led[current_led]);
else
bzero(led_dma.end+(24*i), sizeof(led_dma.end));
}
DMA1_Stream5->NDTR = sizeof(led_dma.buffer) / sizeof(led_dma.buffer[0]); // load number of bytes to be transferred
DMA_Cmd(DMA1_Stream5, ENABLE); // enable DMA channel 2
TIM_Cmd(TIM3, ENABLE); // Go!!!
}
void ws2812DmaIsr(void)
{
portBASE_TYPE xHigherPriorityTaskWoken;
uint16_t * buffer;
int i;
if (total_led == 0)
{
TIM_Cmd(TIM3, DISABLE);
DMA_Cmd(DMA1_Stream5, DISABLE);
}
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5))
{
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);
buffer = led_dma.begin;
}
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5))
{
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
buffer = led_dma.end;
}
for(i=0; (i<LED_PER_HALF) && (current_led<total_led+2); i++, current_led++) {
if (current_led<total_led)
fillLed(buffer+(24*i), color_led[current_led]);
else
bzero(buffer+(24*i), sizeof(led_dma.end));
}
if (current_led >= total_led+2) {
xSemaphoreGiveFromISR(allLedDone, &xHigherPriorityTaskWoken);
TIM_Cmd(TIM3, DISABLE); // disable Timer 3
DMA_Cmd(DMA1_Stream5, DISABLE); // disable DMA stream4
total_led = 0;
}
}
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2015 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* buzzdeck.h - Functions for interfacing with decks with buzzers
*/
#ifndef __BUZZER_H__
#define __BUZZER_H__
#include <stdint.h>
#include <stdbool.h>
/** Functionpointers used to control the buzzer */
struct buzzerControl
{
void (*off)();
void (*on)(uint32_t freq);
};
/**
* Initilize the buzzer sub-system.
*/
void buzzerInit();
/**
* Test the buzzer sub-system.
*/
bool buzzerTest();
/**
* Turn the buzzer off.
*/
void buzzerOff();
/**
* Turn the buzzer on and set it to a specific frequency (if supported).
*/
void buzzerOn(uint32_t freq);
/**
* Set function pointers for controlling the buzzer hardware.
*/
void buzzerSetControl(struct buzzerControl * bc);
#endif //__BUZZER_H__
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2012 BitCraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* eskylink.h: esky 2.4GHz-compatible link driver
*/
#ifndef __ESKYLINK_H__
#define __ESKYLINK_H__
#include "crtp.h"
void eskylinkInit();
bool eskylinkTest();
struct crtpLinkOperations * eskylinkGetLink();
void eskylinkReInit(void);
#endif
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* debug.h - Various debug functions
*/
#ifndef DEBUG_H_
#define DEBUG_H_
/**
* Initializes peripherals used for creating trace
* information
*/
void debugInitTrace(void);
/**
* Sends trace information using the UART1. This function is
* used with the freertos traceTASK_SWITCHED_IN() macro.
* @param Task number currently running
*/
void debugSendTraceInfo(unsigned int taskNbr);
#endif /* DEBUG_H_ */
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* imu.h - inertial measurement unit header file
*/
#ifndef IMU_H_
#define IMU_H_
#include <stdbool.h>
#include "filter.h"
#include "imu_types.h"
/**
* IMU update frequency dictates the overall update frequency.
*/
#define IMU_UPDATE_FREQ 500
#define IMU_UPDATE_DT (float)(1.0/IMU_UPDATE_FREQ)
/**
* Set ACC_WANTED_LPF1_CUTOFF_HZ to the wanted cut-off freq in Hz.
* The highest cut-off freq that will have any affect is fs /(2*pi).
* E.g. fs = 350 Hz -> highest cut-off = 350/(2*pi) = 55.7 Hz -> 55 Hz
*/
#define IMU_ACC_WANTED_LPF_CUTOFF_HZ 4
/**
* Attenuation should be between 1 to 256.
*
* f0 = fs / 2*pi*attenuation ->
* attenuation = fs / 2*pi*f0
*/
#define IMU_ACC_IIR_LPF_ATTENUATION (IMU_UPDATE_FREQ / (2 * 3.1415 * IMU_ACC_WANTED_LPF_CUTOFF_HZ))
#define IMU_ACC_IIR_LPF_ATT_FACTOR (int)(((1<<IIR_SHIFT) / IMU_ACC_IIR_LPF_ATTENUATION) + 0.5)
void imu6Init(void);
bool imu6Test(void);
bool imu6ManufacturingTest(void);
void imu6Read(Axis3f* gyro, Axis3f* acc);
void imu9Read(Axis3f* gyroOut, Axis3f* accOut, Axis3f* magOut);
bool imu6IsCalibrated(void);
bool imuHasBarometer(void);
bool imuHasMangnetometer(void);
#endif /* IMU_H_ */
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* imu_types.h - Types used by IMU and releted functions.
*/
#ifndef IMU_TYPES_H_
#define IMU_TYPES_H_
typedef union {
struct {
int16_t x;
int16_t y;
int16_t z;
};
int16_t axis[3];
} Axis3i16;
typedef union {
struct {
int32_t x;
int32_t y;
int32_t z;
};
int32_t axis[3];
} Axis3i32;
typedef union {
struct {
int64_t x;
int64_t y;
int64_t z;
};
int64_t axis[3];
} Axis3i64;
typedef union {
struct {
float x;
float y;
float z;
};
float axis[3];
} Axis3f;
#endif /* IMU_TYPES_H_ */
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* ledseq.h - LED sequence handler
*/
#ifndef __LEDSEQ_H__
#define __LEDSEQ_H__
/* A LED sequence is made of a list of actions. Each action contains the new
* state of the LED and either a time to wait before executing the next action
* or a command LOOP or STOP.
*
* The sequences are stored in a list by priority order ([0] is the highest
* priority). The list ordered by priority is defined at the beginning of
* ledseq.c
*
* Each sequence effects only one LED. For each LED only the runnable sequence
* with the highest priority is run.
*/
#include <stdint.h>
#include <stdbool.h>
#include <led.h>
#define LEDSEQ_CHARGE_CYCLE_TIME_500MA 1000
#define LEDSEQ_CHARGE_CYCLE_TIME_MAX 500
//Led sequence action
#define LEDSEQ_WAITMS(X) (X)
#define LEDSEQ_STOP -1
#define LEDSEQ_LOOP -2
typedef struct {
bool value;
int action;
} ledseq_t;
//Public API
void ledseqInit(void);
bool ledseqTest(void);
void ledseqEnable(bool enable);
void ledseqRun(led_t led, const ledseq_t * sequence);
void ledseqStop(led_t led, const ledseq_t * sequence);
void ledseqSetTimes(ledseq_t *sequence, int32_t onTime, int32_t offTime);
//Existing led sequences
extern const ledseq_t seq_armed[];
extern const ledseq_t seq_calibrated[];
extern const ledseq_t seq_alive[];
extern const ledseq_t seq_lowbat[];
extern const ledseq_t seq_linkup[];
extern const ledseq_t seq_altHold[];
extern const ledseq_t seq_charged[];
extern ledseq_t seq_charging[];
extern ledseq_t seq_chargingMax[];
extern const ledseq_t seq_bootloader[];
extern const ledseq_t seq_testPassed[];
#endif
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2012 BitCraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* nrf24link.c: nRF24L01 implementation of the CRTP link
*/
#ifndef __NRF24LINK_H__
#define __NRF24LINK_H__
#include "crtp.h"
void nrf24linkInit();
bool nrf24linkTest();
struct crtpLinkOperations * nrf24linkGetLink();
void nrf24linkReInit(void);
#endif
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ow.h - One-wire functions
*/
#ifndef __OW_H__
#define __OW_H__
#include <stdint.h>
#include "syslink.h"
#define OW_MAX_SIZE 112
#define OW_READ_SIZE 29
#define OW_MAX_WRITE_SIZE 26 // Use even numbers because of 16bits segments
typedef struct owCommand_s {
uint8_t nmem;
union {
struct {
uint8_t memId[8];
} __attribute__((packed)) info;
struct {
uint16_t address;
uint8_t data[29];
} __attribute__((packed)) read;
struct write {
uint16_t address;
uint16_t length;
char data[27];
} __attribute__((packed)) write;
};
} __attribute__((packed)) OwCommand;
typedef struct owSerialNum_s
{
union {
struct {
uint8_t type;
uint8_t id[6];
uint8_t crc;
};
uint8_t data[8];
};
} OwSerialNum;
void owInit();
bool owTest();
void owSyslinkRecieve(SyslinkPacket *slp);
bool owScan(uint8_t *nMem);
bool owGetinfo(uint8_t selectMem, OwSerialNum *serialNum);
bool owRead(uint8_t selectMem, uint16_t address, uint8_t length, uint8_t *data);
bool owWrite(uint8_t selectMem, uint16_t address, uint8_t length, uint8_t *data);
#endif //__OW_H__
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* pm.h - Power Management driver and functions.
*/
#ifndef PM_H_
#define PM_H_
#include "adc.h"
#include "syslink.h"
#ifndef CRITICAL_LOW_VOLTAGE
#define PM_BAT_CRITICAL_LOW_VOLTAGE 3.0f
#else
#define PM_BAT_CRITICAL_LOW_VOLTAGE CRITICAL_LOW_VOLTAGE
#endif
#ifndef CRITICAL_LOW_TIMEOUT
#define PM_BAT_CRITICAL_LOW_TIMEOUT M2T(1000 * 5) // 5 sec default
#else
#define PM_BAT_CRITICAL_LOW_TIMEOUT CRITICAL_LOW_VOLTAGE
#endif
#ifndef LOW_VOLTAGE
#define PM_BAT_LOW_VOLTAGE 3.2f
#else
#define PM_BAT_LOW_VOLTAGE LOW_VOLTAGE
#endif
#ifndef LOW_TIMEOUT
#define PM_BAT_LOW_TIMEOUT M2T(1000 * 5) // 5 sec default
#else
#define PM_BAT_LOW_TIMEOUT LOW_TIMEOUT
#endif
#ifndef SYSTEM_SHUTDOWN_TIMEOUT
#define PM_SYSTEM_SHUTDOWN_TIMEOUT M2T(1000 * 60 * 5) // 5 min default
#else
#define PM_SYSTEM_SHUTDOWN_TIMEOUT M2T(1000 * 60 * SYSTEM_SHUTDOWN_TIMEOUT)
#endif
#define PM_BAT_DIVIDER 3.0f
#define PM_BAT_ADC_FOR_3_VOLT (int32_t)(((3.0f / PM_BAT_DIVIDER) / 2.8f) * 4096)
#define PM_BAT_ADC_FOR_1p2_VOLT (int32_t)(((1.2f / PM_BAT_DIVIDER) / 2.8f) * 4096)
#define PM_BAT_IIR_SHIFT 8
/**
* Set PM_BAT_WANTED_LPF_CUTOFF_HZ to the wanted cut-off freq in Hz.
*/
#define PM_BAT_WANTED_LPF_CUTOFF_HZ 1
/**
* Attenuation should be between 1 to 256.
*
* f0 = fs / 2*pi*attenuation.
* attenuation = fs / 2*pi*f0
*/
#define PM_BAT_IIR_LPF_ATTENUATION (int)(ADC_SAMPLING_FREQ / (int)(2 * 3.1415f * PM_BAT_WANTED_LPF_CUTOFF_HZ))
#define PM_BAT_IIR_LPF_ATT_FACTOR (int)((1<<PM_BAT_IIR_SHIFT) / PM_BAT_IIR_LPF_ATTENUATION)
typedef enum
{
battery,
charging,
charged,
lowPower,
shutDown,
} PMStates;
typedef enum
{
charge100mA,
charge500mA,
chargeMax,
} PMChargeStates;
typedef enum
{
USBNone,
USB500mA,
USBWallAdapter,
} PMUSBPower;
void pmInit(void);
bool pmTest(void);
/**
* Power management task
*/
void pmTask(void *param);
void pmSetChargeState(PMChargeStates chgState);
void pmSyslinkUpdate(SyslinkPacket *slp);
/**
* Returns the battery voltage i volts as a float
*/
float pmGetBatteryVoltage(void);
/**
* Returns the min battery voltage i volts as a float
*/
float pmGetBatteryVoltageMin(void);
/**
* Returns the max battery voltage i volts as a float
*/
float pmGetBatteryVoltageMax(void);
/**
* Updates and calculates battery values.
* Should be called for every new adcValues sample.
*/
void pmBatteryUpdate(AdcGroup* adcValues);
/**
* Returns true if the battery is currently in use
*/
bool pmIsDischarging(void);
/**
* Enable or disable external battery voltage measuring.
*/
void pmEnableExtBatteryVoltMeasuring(uint8_t pin, float multiplier);
/**
* Measure an external voltage.
*/
float pmMeasureExtBatteryVoltage(void);
/**
* Enable or disable external battery current measuring.
*/
void pmEnableExtBatteryCurrMeasuring(uint8_t pin, float ampPerVolt);
/**
* Measure an external current.
*/
float pmMeasureExtBatteryCurrent(void);
#endif /* PM_H_ */
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2015 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* proximity.h - Interface to hardware abstraction layer for proximity sensors
*/
#ifndef __PROXIMITY_H__
#define __PROXIMITY_H__
#include <stdint.h>
/**
* \def PROXIMITY_ENABLED
* Enable the proximity measurement subsystem.
*/
//#define PROXIMITY_ENABLED
/**
* \def PROXIMITY_TASK_FREQ
* The frequency the proximity task runs at. This is the same as the sampling frequency for the distance measurements.
*
* Of the supported sensor, the following maximum frequencies apply:
*
* MaxBotix LV-MaxSonar-EZ4 (MB1040): 20Hz
*/
#define PROXIMITY_TASK_FREQ 20
/**
* Number of samples in the sliding window. Used for average and median calculations.
* When using median calculations, this should be an odd number.
*
* Initial testing suggests the following values:
*
* MaxBotix LV-MaxSonar-EZ4 (MB1040): 9 (for median values, with PROXIMITY_TASK_FREQ=20Hz)
*/
#define PROXIMITY_SWIN_SIZE 9
/**
* \def PROXIMITY_LOG_ENABLED
* Uncomment to enable log variables.
*/
//#define PROXIMITY_LOG_ENABLED
void proximityInit(void);
uint32_t proximityGetDistance(void);
uint32_t proximityGetDistanceAvg(void);
uint32_t proximityGetDistanceMedian(void);
uint32_t proximityGetAccuracy(void);
#endif
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2012 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* radiolink.c - Radio link layer
*/
#ifndef __RADIO_H__
#define __RADIO_H__
#include <stdint.h>
#include <stdbool.h>
#include "syslink.h"
void radiolinkInit(void);
bool radiolinkTest(void);
void radiolinkSetChannel(uint8_t channel);
void radiolinkSetDatarate(uint8_t datarate);
void radiolinkSetAddress(uint64_t address);
void radiolinkSyslinkDispatch(SyslinkPacket *slp);
struct crtpLinkOperations * radiolinkGetLink();
#endif //__RADIO_H__
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2011-2016 Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* sensors.h - Sensors interface
*/
#ifndef __SENSORS_H__
#define __SENSORS_H__
#include "stabilizer_types.h"
void sensorsInit(void);
bool sensorsTest(void);
bool sensorsAreCalibrated(void);
/**
* More extensive test of the sensors
*/
bool sensorsManufacturingTest(void);
// For legacy control
void sensorsAcquire(sensorData_t *sensors, const uint32_t tick);
// Allows individual sensor measurement
bool sensorsReadGyro(Axis3f *gyro);
bool sensorsReadAcc(Axis3f *acc);
bool sensorsReadMag(Axis3f *mag);
bool sensorsReadBaro(baro_t *baro);
#endif //__SENSORS_H__
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2012 BitCraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* syslink.h: Implementation of the link between MCU
*/
#ifndef __SYSLINK_H__
#define __SYSLINK_H__
#include <stdbool.h>
#define SYSLINK_MTU 32
#define CRTP_START_BYTE 0xAA
#define SYSLINK_START_BYTE1 0xBC
#define SYSLINK_START_BYTE2 0xCF
// Defined packet types
#define SYSLINK_GROUP_MASK 0xF0
#define SYSLINK_RADIO_GROUP 0x00
#define SYSLINK_RADIO_RAW 0x00
#define SYSLINK_RADIO_CHANNEL 0x01
#define SYSLINK_RADIO_DATARATE 0x02
#define SYSLINK_RADIO_CONTWAVE 0x03
#define SYSLINK_RADIO_RSSI 0x04
#define SYSLINK_RADIO_ADDRESS 0x05
#define SYSLINK_RADIO_RAW_BROADCAST 0x06
#define SYSLINK_PM_GROUP 0x10
#define SYSLINK_PM_SOURCE 0x10
#define SYSLINK_PM_ONOFF_SWITCHOFF 0x11
#define SYSLINK_PM_BATTERY_VOLTAGE 0x12
#define SYSLINK_PM_BATTERY_STATE 0x13
#define SYSLINK_PM_BATTERY_AUTOUPDATE 0x14
#define SYSLINK_OW_GROUP 0x20
#define SYSLINK_OW_SCAN 0x20
#define SYSLINK_OW_GETINFO 0x21
#define SYSLINK_OW_READ 0x22
#define SYSLINK_OW_WRITE 0x23
typedef struct _SyslinkPacket
{
uint8_t type;
uint8_t length;
char data[SYSLINK_MTU];
} __attribute__((packed)) SyslinkPacket;
typedef enum
{
waitForFirstStart,
waitForSecondStart,
waitForType,
waitForLengt,
waitForData,
waitForChksum1,
waitForChksum2
} SyslinkRxState;
void syslinkInit();
bool syslinkTest();
int syslinkSendPacket(SyslinkPacket *slp);
#endif