1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

OP-21/Bootloader - House cleaning only, shouldn't brake anything.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2250 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
zedamota 2010-12-18 20:41:13 +00:00 committed by zedamota
parent 0b985b2168
commit 7f00e88321
7 changed files with 61 additions and 660 deletions

View File

@ -118,7 +118,6 @@ SRC += $(OPSYSTEM)/main.c
SRC += $(OPSYSTEM)/pios_board.c
SRC += $(OPSYSTEM)/op_dfu.c
SRC += $(OPSYSTEM)/stopwatch.c
SRC += $(OPSYSTEM)/ssp_timer.c
SRC += $(OPSYSTEM)/ssp.c

View File

@ -1,55 +0,0 @@
/**
******************************************************************************
* @addtogroup OpenPilotBL OpenPilot BootLoader
* @{
*
* @file ssp_timer.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Timer functions to be used with the SSP.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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; either version 3 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _SSP_TIMER_H
#define _SSP_TIMER_H
/////////////////////////////////////////////////////////////////////////////
// Global definitions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Global Types
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Prototypes
/////////////////////////////////////////////////////////////////////////////
extern s32 SSP_TIMER_Init(u32 resolution);
extern s32 SSP_TIMER_Reset(void);
extern u32 SSP_TIMER_ValueGet(void);
/////////////////////////////////////////////////////////////////////////////
// Export global variables
/////////////////////////////////////////////////////////////////////////////
#endif /* _SSP_TIMER_H */

View File

@ -42,9 +42,9 @@
// Prototypes
/////////////////////////////////////////////////////////////////////////////
extern s32 STOPWATCH_Init(u32 resolution);
extern s32 STOPWATCH_Reset(void);
extern u32 STOPWATCH_ValueGet(void);
extern s32 STOPWATCH_Init(u32 resolution, TIM_TypeDef* TIM);
extern s32 STOPWATCH_Reset(TIM_TypeDef* TIM);
extern u32 STOPWATCH_ValueGet(TIM_TypeDef* TIM);
/////////////////////////////////////////////////////////////////////////////

View File

@ -29,7 +29,6 @@
#include <pios.h>
#include "pios_opahrs.h"
#include "stopwatch.h"
#include "ssp_timer.h"
#include "op_dfu.h"
#include "usb_lib.h"
#include "pios_iap.h"
@ -61,7 +60,8 @@ uint8_t tempcount=0;
/// SSP SECTION
/// SSP TIME SOURCE
uint32_t ssp_time;
#define SSP_TIMER TIM7
uint32_t ssp_time=0;
#define MAX_PACKET_DATA_LEN 255
#define MAX_PACKET_BUF_SIZE (1+1+MAX_PACKET_DATA_LEN+2)
#define UART_BUFFER_SIZE 1024
@ -98,7 +98,7 @@ uint32_t sspTimeSource();
#define BLUE LED1
#define RED LED2
#define LED_PWM_TIMER TIM6
int main() {
/* NOTE: Do NOT modify the following start-up sequence */
/* Any new initialization functions should be added in OpenPilotInit() */
@ -116,20 +116,7 @@ int main() {
User_DFU_request = TRUE;
PIOS_IAP_ClearRequest();
}
/*
else
{
PIOS_Board_Init();
for(uint8_t x=0;x<10;++x)
{
PIOS_LED_Toggle(LED1);
PIOS_LED_Toggle(LED2);
PIOS_DELAY_WaitmS(1000);
}
PIOS_IAP_SetRequest1();
PIOS_IAP_SetRequest2();
PIOS_SYS_Reset();
}*/
GO_dfu = (USB_connected == TRUE) || (User_DFU_request == TRUE);
if (GO_dfu == TRUE) {
@ -137,25 +124,24 @@ int main() {
ProgPort = Usb;
else
ProgPort = Serial;
//ProgPort = Serial;
PIOS_Board_Init();
PIOS_OPAHRS_Init();
if(User_DFU_request == TRUE)
DeviceState = DFUidle;
else
DeviceState = BLidle;
STOPWATCH_Init(100);
STOPWATCH_Init(100,LED_PWM_TIMER);
if (ProgPort == Serial) {
fifoBuf_init(&ssp_buffer,rx_buffer,UART_BUFFER_SIZE);
SSP_TIMER_Init(100);
SSP_TIMER_Reset();
STOPWATCH_Init(100,SSP_TIMER);//nao devia ser 1000?
STOPWATCH_Reset(SSP_TIMER);
ssp_Init(&ssp_port, &SSP_PortConfig);
}
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
} else
JumpToApp = TRUE;
STOPWATCH_Reset();
STOPWATCH_Reset(LED_PWM_TIMER);
while (TRUE) {
if (ProgPort == Serial) {
ssp_ReceiveProcess(&ssp_port);
@ -204,7 +190,7 @@ int main() {
}
if (period1 != 0) {
if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet()))
if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet(LED_PWM_TIMER)))
PIOS_LED_On(BLUE);
else
PIOS_LED_Off(BLUE);
@ -212,21 +198,20 @@ int main() {
PIOS_LED_On(BLUE);
if (period2 != 0) {
if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet()))
if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet(LED_PWM_TIMER)))
PIOS_LED_On(RED);
else
PIOS_LED_Off(RED);
} else
PIOS_LED_Off(RED);
if (STOPWATCH_ValueGet() > 100 * 50 * 100)
STOPWATCH_Reset();
if ((STOPWATCH_ValueGet() > 60000) && (DeviceState == BLidle))
if (STOPWATCH_ValueGet(LED_PWM_TIMER) > 100 * 50 * 100)
STOPWATCH_Reset(LED_PWM_TIMER);
if ((STOPWATCH_ValueGet(LED_PWM_TIMER) > 60000) && (DeviceState == BLidle))
JumpToApp = TRUE;
processRX();
DataDownload(start);
//DelayWithDown(10);//1000000);
}
}
@ -265,12 +250,10 @@ uint8_t processRX() {
for (int32_t x = 0; x < 63; ++x) {
mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
}
//PIOS_IRQ_Enable();
processComand(mReceive_Buffer);
}
} else if (ProgPort == Serial) {
if (fifoBuf_getUsed(&ssp_buffer) >= 63) {
for (int32_t x = 0; x < 63; ++x) {
mReceive_Buffer[x] = fifoBuf_getByte(&ssp_buffer);
@ -282,9 +265,9 @@ uint8_t processRX() {
}
uint32_t sspTimeSource() {
if (SSP_TIMER_ValueGet() > 5000) {
if (STOPWATCH_ValueGet(SSP_TIMER) > 5000) {
++ssp_time;
SSP_TIMER_Reset();
STOPWATCH_Reset(SSP_TIMER);
}
return ssp_time;
}

View File

@ -1,300 +0,0 @@
/**
******************************************************************************
* @addtogroup OpenPilotSystem OpenPilot System
* @brief These files are the core system files of OpenPilot.
* They are the ground layer just above PiOS. In practice, OpenPilot actually starts
* in the main() function of openpilot.c
* @{
* @addtogroup OpenPilotCore OpenPilot Core
* @brief This is where the OP firmware starts. Those files also define the compile-time
* options of the firmware.
* @{
* @file openpilot.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Sets up and runs main OpenPilot tasks.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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; either version 3 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* OpenPilot Includes */
//#include "openpilot.h"
#include <pios.h>
#include "pios_opahrs.h"
#include "stopwatch.h"
#include "op_dfu.h"
#include "usb_lib.h"
/* Prototype of PIOS_Board_Init() function */
extern void PIOS_Board_Init(void);
extern void FLASH_Download();
#define BSL_HOLD_STATE ((PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) ? 0 : 1)
/* Private typedef -----------------------------------------------------------*/
typedef void (*pFunction)(void);
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
pFunction Jump_To_Application;
uint32_t JumpAddress;
/// LEDs PWM
uint32_t period1 = 50; // *100 uS -> 5 mS
uint32_t sweep_steps1 = 100; // * 5 mS -> 500 mS
uint32_t period2 = 50; // *100 uS -> 5 mS
uint32_t sweep_steps2 = 100; // * 5 mS -> 500 mS
/* Extern variables ----------------------------------------------------------*/
DFUStates DeviceState;
uint8_t JumpToApp = FALSE;
uint8_t GO_dfu = FALSE;
uint8_t USB_connected = FALSE;
uint8_t User_DFU_request = FALSE;
static uint8_t mReceive_Buffer[64];
uint8_t comm_port;
/* Private function prototypes -----------------------------------------------*/
uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count);
uint8_t processRX();
void jump_to_app();
#define BLUE LED1
#define RED LED2
int main() {
/* NOTE: Do NOT modify the following start-up sequence */
/* Any new initialization functions should be added in OpenPilotInit() */
/* Brings up System using CMSIS functions, enables the LEDs. */
PIOS_SYS_Init();
if (BSL_HOLD_STATE == 0)
USB_connected = TRUE;
if( USB_connected == TRUE ) {
comm_port = PIOS_COM_TELEM_USB;
} else {
// check for user request to enter bootloader
// if true then:
// if( check_user_request() == TRUE ) {
// USER_DFU_request = TRUE;
// comm_port = PIOS_COM_TELEM_RF;
// ssp_Init( rf_port, rf_port_config );
// }
}
if ((USB_connected==TRUE) || (User_DFU_request==TRUE)) {
GO_dfu = TRUE;
PIOS_Board_Init();
PIOS_OPAHRS_Init();
DeviceState = BLidle;
STOPWATCH_Init(100);
USB_connected = TRUE;
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
//OPDfuIni(false);
} else {
JumpToApp = TRUE;
}
STOPWATCH_Reset();
while (TRUE) {
if (JumpToApp == TRUE) {
jump_to_app();
}
flash_led();
if (STOPWATCH_ValueGet() > 100 * 50 * 100)
STOPWATCH_Reset();
if ((STOPWATCH_ValueGet() > 60000) && (DeviceState == BLidle))
JumpToApp = TRUE;
//processRX();
processComm();
DataDownload(start);
//DelayWithDown(10);//1000000);
}
}
void jump_to_app() {
if (((*(__IO uint32_t*) START_OF_USER_CODE) & 0x2FFE0000) == 0x20000000) { /* Jump to user application */
FLASH_Lock();
RCC_APB2PeriphResetCmd(0xffffffff, ENABLE);
RCC_APB1PeriphResetCmd(0xffffffff, ENABLE);
RCC_APB2PeriphResetCmd(0xffffffff, DISABLE);
RCC_APB1PeriphResetCmd(0xffffffff, DISABLE);
_SetCNTR(0); // clear interrupt mask
_SetISTR(0); // clear all requests
JumpAddress = *(__IO uint32_t*) (START_OF_USER_CODE + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) START_OF_USER_CODE);
Jump_To_Application();
} else {
DeviceState = failed_jump;
return;
}
}
uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count) {
uint32_t pwm_duty = ((count / pwm_period) % pwm_sweep_steps)
/ (pwm_sweep_steps / pwm_period);
if ((count % (2 * pwm_period * pwm_sweep_steps)) > pwm_period
* pwm_sweep_steps)
pwm_duty = pwm_period - pwm_duty; // negative direction each 50*100 ticks
return ((count % pwm_period) > pwm_duty) ? 1 : 0;
}
uint8_t processRX() {
while(PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_USB)>=63)
{
for (int32_t x = 0; x < 63; ++x) {
mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
}
//PIOS_IRQ_Enable();
processComand(mReceive_Buffer);
}
return TRUE;
}
#define PACKET_SIZE 64
uint8_t packet_available = false;
uint8_t data_buffer[PACKET_SIZE];
// this function is called from the serial transport layer receive state machine when a valid
// data packet is received.
void PacketCallback(uint8_t *buf, uint16_t length )
{
uint16_t x;
for( x = 0; x < length; x++ ) {
data_buffer[x] = buf[x];
}
if( packet_available == true ) {
// overrun condition...
// TODO act on overrun condition
} else {
packet_available = true;
}
}
void processComm(void)
{
uint16_t x = 0;
if (comm_port == PIOS_COM_TELEM_RF ) {
ssp_ReceiveProcess(); // pump the receive state machine
ssp_SendProcess(); // pump the transmit state machine.
// check to see if any data is available. this is updated in the callback function from the receive state machine.
if( packet_available == true ) {
// reset packet_available to let the call back function know that the packet data has been copied
// from the buffer. this will allow an overrun condition to be detected.
// also note that the only way the receive buffer is modified is through the ssp_ReceiveBuffer() function,
// otherwise data is buffered at the PIOS_COM layer.
}
} else {
if( PIOS_COM_ReceiveBufferUsed( PIOS_COM_TELEM_USB ) >= 63 ) {
for( x = 0; x < 63; x++ ) {
data_buffer[x] = PIOS_COM_Receivebuffer(PIOS_COM_TELEM_USB);
}
packet_available = true;
}
}
if( packet_available == true) {
processCommand( data_buffer);
packet_available = false;
}
}
// an alternate processComm func if both USB and serial used the same transport layer
void alt_ProcessComm(void)
{
ssp_ReceiveProcess(port);
ssp_SendProcess(port);
if( packet_available == true) {
packet_available = false;
processComand(data_buffer);
}
}
// sends out data...
uint16_t SendBuffer( uint8_t buf, uint16_t length )
{
if( comm_port == PIOS_COM_TELEM_RF ) {
ssp_SendData( rf_port, buf, length );
// or ssp_SendDataBlock( rf_port, buf, length );
} else {
PIOS_COM_BufferPut( PIOS_COM_TELEM_USB, buf, length );
}
}
void flash_led(void)
{
switch (DeviceState) {
case Last_operation_Success:
case uploadingStarting:
case DFUidle:
period1 = 50;
sweep_steps1 = 100;
PIOS_LED_Off(RED);
period2 = 0;
break;
case uploading:
period1 = 50;
sweep_steps1 = 100;
period2 = 25;
sweep_steps2 = 50;
break;
case downloading:
period1 = 25;
sweep_steps1 = 50;
PIOS_LED_Off(RED);
period2 = 0;
break;
case BLidle:
period1 = 0;
PIOS_LED_On(BLUE);
period2 = 0;
break;
default://error
period1 = 50;
sweep_steps1 = 100;
period2 = 50;
sweep_steps2 = 100;
}
if (period1 != 0) {
if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet())) {
PIOS_LED_On(BLUE);
} else {
PIOS_LED_Off(BLUE);
}
} else {
PIOS_LED_On(BLUE);
}
if (period2 != 0) {
if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet())) {
PIOS_LED_On(RED);
} else {
PIOS_LED_Off(RED);
}
} else {
PIOS_LED_Off(RED);
}
}

View File

@ -1,229 +0,0 @@
// test functions for the SSP module.
// this module performs unit test on the SSP functions.
#include "ssp.h"
#include "buffer.h"
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define MAX_PACKET_DATA_LEN 255
#define MAX_PACKET_BUF_SIZE (1+1+255+2)
// master buffers...
uint8_t masterTxBuf[MAX_PACKET_BUF_SIZE];
uint8_t masterRxBuf[MAX_PACKET_BUF_SIZE];
// slave buffers...
uint8_t slaveTxBuf[MAX_PACKET_BUF_SIZE];
uint8_t slaveRxBuf[MAX_PACKET_BUF_SIZE];
void masterCallBack(uint8_t *buf, uint16_t len);
int16_t masterSerialRead(void);
void masterSerialWrite(uint8_t);
uint32_t masterGetTime(void);
void slaveCallBack(uint8_t *buf, uint16_t len);
int16_t slaveSerialRead(void);
void slaveSerialWrite(uint8_t);
uint32_t slaveGetTime(void);
PortConfig_t masterPortConfig = {
.rxBuf = masterRxBuf,
.rxBufSize = MAX_PACKET_DATA_LEN,
.txBuf = masterTxBuf,
.txBufSize = 255,
.max_retry = 3,
.timeoutLen = 100,
.pfCallBack = masterCallBack,
.pfSerialRead = masterSerialRead,
.pfSerialWrite = masterSerialWrite,
.pfGetTime = masterGetTime,
};
PortConfig_t slavePortConfig = {
.rxBuf = slaveRxBuf,
.rxBufSize = MAX_PACKET_DATA_LEN,
.txBuf = slaveTxBuf,
.txBufSize = 255,
.max_retry = 3,
.timeoutLen = 100,
.pfCallBack = slaveCallBack,
.pfSerialRead = slaveSerialRead,
.pfSerialWrite = slaveSerialWrite,
.pfGetTime = slaveGetTime,
};
Port_t master_port;
Port_t slave_port;
cBuffer m2sBuffer;
cBuffer s2mBuffer;
#define BUFFER 1024
// buffer space for the simulated serial buffers.
uint8_t m2sDataBuffer[BUFFER];
uint8_t s2mDataBuffer[BUFFER];
void ssp_test(void)
{
uint8_t masterSendBuf[255];
// uint8_t slaveSendBuf[255];
Port_t *master = &master_port;
Port_t *slave = &slave_port;
int16_t packet_status;
int16_t retval;
uint8_t master_respond = TRUE;
uint8_t slave_respond = TRUE;
uint8_t master_send_respond = TRUE;
bufferInit(&m2sBuffer, m2sDataBuffer, BUFFER);
bufferInit(&s2mBuffer, s2mDataBuffer, BUFFER);
ssp_Init( master, &masterPortConfig);
ssp_Init( slave, &slavePortConfig);
masterSendBuf[0] = 0;
masterSendBuf[1] = 1;
masterSendBuf[2] = 2;
masterSendBuf[3] = 3;
masterSendBuf[4] = 4;
ssp_Synchronise(master);
while (1) {
packet_status = ssp_SendData( master, masterSendBuf, 5 ); // send the data
while( packet_status == SSP_TX_WAITING ) { // check the status
if( slave_respond == TRUE ) {
(void)ssp_ReceiveProcess(slave); // process simulated input to the slave
}
if( master_respond == TRUE ) {
(void)ssp_ReceiveProcess( master ); // process any bytes received.
}
if( master_send_respond == TRUE ) {
packet_status = ssp_SendProcess( master );// check the packet
}
}
if (packet_status == SSP_TX_ACKED ) {
retval = TRUE;
} else {
// figure out what happened to the packet
// possible errors are: timeout, busy, bufoverrun (tried to send too much data.
retval = FALSE;
}
// just a more explicit way to see what happened...
switch( packet_status ) {
case SSP_TX_ACKED:
// quick data manipulation to see something different...
for (int32_t x = 0; x < 5; ++x) {
masterSendBuf[x] += 5;
}
retval = TRUE;
break;
case SSP_TX_BUSY:
retval = FALSE;
break;
case SSP_TX_TIMEOUT:
retval = FALSE;
break;
case SSP_TX_BUFOVERRUN:
retval = false;
break;
default:
retval = -3;
break;
}
#ifdef OLD_CODE
do {
packetStatus = ssp_SendPacketData( master, masterSendBuf, 5);
if( packetStatus == SSP_TX_FAIL) {
ssp_ReceiveProcess(slave);
ssp_ReceiveProcess(master);
ssp_SendProcess(master);
}
} while( packetStatus != SSP_TX_WAITING );
do {
// let the slave process simulated input.
ssp_ReceiveProcess(slave);
// process simulated input from the slave to master. Slave 'may' have sent an ACK
if( ssp_ReceiveProcess(master) == SSP_RX_COMPLETE) {
// at this point an ACK or 'data' packet was received.
}
packetStatus = ssp_SendProcess(master);
} while ( packetStatus == SSP_TX_WAITING);
#endif
}
}
// these functions implement a simulated serial in/out for both a master
// and a slave device. In reality these functions do not send anything out
// but just puts them into a circular buffer.
// In a real system these would use the PIOS_COM_xxxx functions.
void masterCallBack(uint8_t *buf, uint16_t len)
{
len = len;
}
// simulates checking for character from a serial buffer.
int16_t masterSerialRead(void)
{
int16_t retval = -1;
static uint16_t count = 0;
if( bufferBufferedData(&s2mBuffer)) {
retval = bufferGetFromFront( &s2mBuffer);
}
count++;
if( count % 5 == 0 ) {
ssp_ReceiveByte(&slave_port);
}
return retval;
}
void masterSerialWrite(uint8_t b)
{
bufferAddToEnd( &m2sBuffer, b);
}
uint32_t masterTime = 0;
uint32_t slaveTime = 0;
uint32_t masterGetTime(void)
{
masterTime++;
return masterTime;
}
void slaveCallBack(uint8_t *buf, uint16_t len)
{
len = len;
}
int16_t slaveSerialRead(void)
{
int16_t retval = -1;
if( bufferBufferedData(&m2sBuffer)) {
retval = bufferGetFromFront( &m2sBuffer);
}
return retval;
}
void slaveSerialWrite(uint8_t b)
{
bufferAddToEnd( &s2mBuffer, b);
}
uint32_t slaveGetTime(void)
{
slaveTime++;
return slaveTime;
}

View File

@ -25,76 +25,79 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////
#include "stm32f10x_tim.h"
/////////////////////////////////////////////////////////////////////////////
// Local definitions
/////////////////////////////////////////////////////////////////////////////
#define STOPWATCH_TIMER_BASE TIM6
#define STOPWATCH_TIMER_RCC RCC_APB1Periph_TIM6
//#define STOPWATCH_TIMER_BASE TIM6
//#define STOPWATCH_TIMER_RCC RCC_APB1Periph_TIM6
uint32_t STOPWATCH_Init(u32 resolution)
{
// enable timer clock
if( STOPWATCH_TIMER_RCC == RCC_APB2Periph_TIM1 || STOPWATCH_TIMER_RCC == RCC_APB2Periph_TIM8 )
RCC_APB2PeriphClockCmd(STOPWATCH_TIMER_RCC, ENABLE);
else
RCC_APB1PeriphClockCmd(STOPWATCH_TIMER_RCC, ENABLE);
uint32_t STOPWATCH_Init(u32 resolution, TIM_TypeDef* TIM) {
uint32_t STOPWATCH_TIMER_RCC;
switch ((uint32_t)TIM) {
case (uint32_t)TIM6:
STOPWATCH_TIMER_RCC = RCC_APB1Periph_TIM6;
break;
case (uint32_t)TIM7:
STOPWATCH_TIMER_RCC = RCC_APB1Periph_TIM7;
break;
default:
STOPWATCH_TIMER_RCC = RCC_APB1Periph_TIM6;
}
// time base configuration
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 0xffff; // max period
TIM_TimeBaseStructure.TIM_Prescaler = (72 * resolution)-1; // <resolution> uS accuracy @ 72 MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(STOPWATCH_TIMER_BASE, &TIM_TimeBaseStructure);
// enable timer clock
if (STOPWATCH_TIMER_RCC == RCC_APB2Periph_TIM1 || STOPWATCH_TIMER_RCC
== RCC_APB2Periph_TIM8)
RCC_APB2PeriphClockCmd(STOPWATCH_TIMER_RCC, ENABLE);
else
RCC_APB1PeriphClockCmd(STOPWATCH_TIMER_RCC, ENABLE);
// enable interrupt request
TIM_ITConfig(STOPWATCH_TIMER_BASE, TIM_IT_Update, ENABLE);
// time base configuration
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 0xffff; // max period
TIM_TimeBaseStructure.TIM_Prescaler = (72 * resolution) - 1; // <resolution> uS accuracy @ 72 MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM, &TIM_TimeBaseStructure);
// start counter
TIM_Cmd(STOPWATCH_TIMER_BASE, ENABLE);
// enable interrupt request
TIM_ITConfig(TIM, TIM_IT_Update, ENABLE);
return 0; // no error
// start counter
TIM_Cmd(TIM, ENABLE);
return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
//! Resets the stopwatch
//! \return < 0 on errors
/////////////////////////////////////////////////////////////////////////////
uint32_t STOPWATCH_Reset(void)
{
// reset counter
STOPWATCH_TIMER_BASE->CNT = 1; // set to 1 instead of 0 to avoid new IRQ request
TIM_ClearITPendingBit(STOPWATCH_TIMER_BASE, TIM_IT_Update);
uint32_t STOPWATCH_Reset(TIM_TypeDef* TIM) {
// reset counter
TIM->CNT = 1; // set to 1 instead of 0 to avoid new IRQ request
TIM_ClearITPendingBit(TIM, TIM_IT_Update);
return 0; // no error
return 0; // no error
}
/////////////////////////////////////////////////////////////////////////////
//! Returns current value of stopwatch
//! \return 1..65535: valid stopwatch value
//! \return 0xffffffff: counter overrun
/////////////////////////////////////////////////////////////////////////////
uint32_t STOPWATCH_ValueGet(void)
{
uint32_t value = STOPWATCH_TIMER_BASE->CNT;
uint32_t STOPWATCH_ValueGet(TIM_TypeDef* TIM) {
uint32_t value = TIM->CNT;
if( TIM_GetITStatus(STOPWATCH_TIMER_BASE, TIM_IT_Update) != RESET )
value = 0xffffffff;
if (TIM_GetITStatus(TIM, TIM_IT_Update) != RESET)
value = 0xffffffff;
return value;
return value;
}