Horus drivers

This commit is contained in:
Bertrand Songis
2015-10-14 23:47:26 +02:00
parent 1df45cbfc2
commit 78bcc4d582
32 changed files with 10666 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
#define STICK_LV 3
#define STICK_LH 2
#define STICK_RV 0
#define STICK_RH 1
#define POT_L 13
#define POT_R 5
#define SLIDE_L 9
#define SLIDE_R 8
#define SWITCHES1 11
#define SWITCHES2 7
#define SWITCHES3 10
#define SWITCHES4 6
#define BATTERY 14
// Sample time should exceed 1uS
#define SAMPTIME 2 // sample time = 28 cycles
uint16_t Analog_values[NUMBER_ANALOG] __DMA;
#define NUMBER_ANALOG_ADC1 13
#if 0
const int8_t ana_direction[NUMBER_ANALOG] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
#endif
void adcInit()
{
// Enable clocks
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->AHB1ENR |= ADC_RCC_AHB1Periph_GPIO | RCC_AHB1ENR_DMA2EN;
configure_pins(ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH |
ADC_GPIO_PIN_POT_R1 | ADC_GPIO_SWITCHES_PIN_R3 | ADC_GPIO_SWITCHES_PIN_R4, PIN_ANALOG | PIN_PORTA);
configure_pins(ADC_GPIO_PIN_POT_R2 | ADC_GPIO_PIN_POT_L2, PIN_ANALOG | PIN_PORTB);
configure_pins(ADC_GPIO_PIN_POT_L1 | ADC_GPIO_SWITCHES_PIN_L3 | ADC_GPIO_SWITCHES_PIN_L4 | ADC_GPIO_PIN_BATT, PIN_ANALOG | PIN_PORTC);
ADC1->CR1 = ADC_CR1_SCAN;
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS;
ADC1->SQR1 = (BATTERY<<0) + ((NUMBER_ANALOG_ADC1-1) << 20); // bits 23:20 = number of conversions
ADC1->SQR2 = (SLIDE_L<<0) + (SLIDE_R<<5) + (SWITCHES1<<10) + (SWITCHES2<<15) + (SWITCHES3<<20) + (SWITCHES4<<25); // conversions 7 to 12
ADC1->SQR3 = (STICK_LH<<0) + (STICK_LV<<5) + (STICK_RV<<10) + (STICK_RH<<15) + (POT_L<<20) + (POT_R<<25); // conversions 1 to 6
ADC1->SMPR1 = SAMPTIME + (SAMPTIME<<3) + (SAMPTIME<<6) + (SAMPTIME<<9) + (SAMPTIME<<12) + (SAMPTIME<<15) + (SAMPTIME<<18) + (SAMPTIME<<21) + (SAMPTIME<<24);
ADC1->SMPR2 = SAMPTIME + (SAMPTIME<<3) + (SAMPTIME<<6) + (SAMPTIME<<9) + (SAMPTIME<<12) + (SAMPTIME<<15) + (SAMPTIME<<18) + (SAMPTIME<<21) + (SAMPTIME<<24) + (SAMPTIME<<27) ;
ADC->CCR = 0 ; //ADC_CCR_ADCPRE_0 ; // Clock div 2
DMA2_Stream0->CR = DMA_SxCR_PL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC;
DMA2_Stream0->PAR = CONVERT_PTR_UINT(&ADC1->DR);
DMA2_Stream0->M0AR = CONVERT_PTR_UINT(Analog_values);
DMA2_Stream0->NDTR = NUMBER_ANALOG_ADC1;
DMA2_Stream0->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
}
void adcRead()
{
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
ADC1->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR ) ;
DMA2->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 |DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0 ; // Write ones to clear bits
DMA2_Stream0->CR |= DMA_SxCR_EN ; // Enable DMA
ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART ;
for (unsigned int i=0; i<10000; i++) {
if (DMA2->LISR & DMA_LISR_TCIF0) {
break;
}
}
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
}
// TODO
void adcStop()
{
}
uint16_t getAnalogValue(uint32_t value)
{
// return Analog_values[ana_mapping[value]];
return 0; // Analog_values[value];
}
+172
View File
@@ -0,0 +1,172 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
const int8_t volumeScale[VOLUME_LEVEL_MAX+1] =
{
0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40,
64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127
};
#if !defined(SIMU)
bool dacIdle = true;
void setSampleRate(uint32_t frequency)
{
register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz
TIM6->CR1 &= ~TIM_CR1_CEN ;
TIM6->CNT = 0 ;
TIM6->ARR = limit<uint32_t>(2, timer, 65535) ;
TIM6->CR1 |= TIM_CR1_CEN ;
}
// Start TIMER6 at 100000Hz, used for DAC trigger
void dacTimerInit()
{
// Now for timer 6
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN ; // Enable clock
TIM6->PSC = 0 ; // Max speed
TIM6->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz
TIM6->CR2 = 0 ;
TIM6->CR2 = 0x20 ;
TIM6->CR1 = TIM_CR1_CEN ;
}
// Configure DAC0 (or DAC1 for REVA)
// Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function
// So maybe it is automatically done
void dacInit()
{
dacTimerInit();
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock
configure_pins( GPIO_Pin_4, PIN_ANALOG | PIN_PORTA ) ;
RCC->APB1ENR |= RCC_APB1ENR_DACEN ; // Enable clock
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock
// Chan 7, 16-bit wide, Medium priority, memory increments
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 |
DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ;
DMA1_Stream5->PAR = CONVERT_PTR_UINT(&DAC->DHR12R1);
// DMA1_Stream5->M0AR = CONVERT_PTR_UINT(Sine_values);
DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
// DMA1_Stream5->NDTR = 100 ;
DAC->DHR12R1 = 2010 ;
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 ; // Enable DAC
NVIC_EnableIRQ(TIM6_DAC_IRQn); // TODO needed?
NVIC_SetPriority(TIM6_DAC_IRQn, 7);
NVIC_EnableIRQ(DMA1_Stream5_IRQn);
NVIC_SetPriority(DMA1_Stream5_IRQn, 7);
}
bool dacQueue(AudioBuffer *buffer)
{
if (dacIdle) {
dacIdle = false;
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(buffer->data);
DMA1_Stream5->NDTR = buffer->size;
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
return true;
}
else {
return false;
}
}
void dacStart()
{
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
}
void dacStop()
{
DMA1_Stream5->CR &= ~DMA_SxCR_CIRC ;
}
// Sound routines
void audioInit()
{
dacInit();
}
void audioEnd()
{
DAC->CR = 0 ;
TIM6->CR1 = 0 ;
// Also need to turn off any possible interrupts
NVIC_DisableIRQ(TIM6_DAC_IRQn) ;
NVIC_DisableIRQ(DMA1_Stream5_IRQn) ;
}
extern "C" void TIM6_DAC_IRQHandler()
{
DAC->CR &= ~DAC_CR_DMAEN1 ; // Stop DMA requests
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
}
extern "C" void DMA1_Stream5_IRQHandler()
{
DMA1_Stream5->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer();
if (nextBuffer) {
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(nextBuffer->data);
DMA1_Stream5->NDTR = nextBuffer->size;
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel
DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag
}
else {
dacIdle = true;
}
}
#endif // #if !defined(SIMU)
+264
View File
@@ -0,0 +1,264 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
void watchdogInit(unsigned int duration)
{
IWDG->KR = 0x5555 ; // Unlock registers
IWDG->PR = 3 ; // Divide by 32 => 1kHz clock
IWDG->KR = 0x5555 ; // Unlock registers
IWDG->RLR = duration ; // 1.5 seconds nominal
IWDG->KR = 0xAAAA ; // reload
IWDG->KR = 0xCCCC ; // start
}
// Start TIMER7 at 2000000Hz
void init2MhzTimer()
{
// Now for timer 7
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN ; // Enable clock
TIM7->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1 ; // 0.5 uS, 2 MHz
TIM7->ARR = 65535;
TIM7->CR2 = 0;
TIM7->CR1 = TIM_CR1_CEN;
}
// Starts TIMER at 200Hz, 5mS period
void init5msTimer()
{
// Timer14
RCC->APB1ENR |= RCC_APB1ENR_TIM14EN ; // Enable clock
TIM14->ARR = 4999 ; // 5mS
TIM14->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1 ; // 1uS from 30MHz
TIM14->CCER = 0 ;
TIM14->CCMR1 = 0 ;
TIM14->EGR = 0 ;
TIM14->CR1 = 5 ;
TIM14->DIER |= 1 ;
NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn) ;
NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 7);
}
void stop5msTimer( void )
{
TIM14->CR1 = 0 ; // stop timer
NVIC_DisableIRQ(TIM8_TRG_COM_TIM14_IRQn) ;
RCC->APB1ENR &= ~RCC_APB1ENR_TIM14EN ; // Disable clock
}
// TODO use the same than board_sky9x.cpp
void interrupt5ms()
{
static uint32_t pre_scale ; // Used to get 10 Hz counter
AUDIO_HEARTBEAT();
#if defined(HAPTIC)
HAPTIC_HEARTBEAT();
#endif
if ( ++pre_scale >= 2 ) {
pre_scale = 0 ;
per10ms();
}
checkRotaryEncoder();
}
#if !defined(SIMU)
extern "C" void TIM8_TRG_COM_TIM14_IRQHandler()
{
TIM14->SR &= ~TIM_SR_UIF ;
interrupt5ms() ;
}
void pinCheck(GPIO_TypeDef * gpio, uint32_t pin, uint32_t RCC_AHB1Periph)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph, ENABLE);
GPIO_InitStruct.GPIO_Pin = pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(gpio, &GPIO_InitStruct);
for (int i=0; i<10; i++) {
GPIO_SetBits(gpio, pin);
delay_01us(10);
GPIO_ResetBits(gpio, pin);
delay_01us(10);
}
}
void boardInit()
{
pwrInit();
ledInit();
delaysInit();
ledRed();
if (0) {
// pinCheck(SERIAL_GPIO, SERIAL_GPIO_PIN_TX, SERIAL_RCC_AHB1Periph_GPIO);
// pinCheck(EEPROM_GPIO, EEPROM_GPIO_PIN_SCK, RCC_AHB1Periph_GPIOB);
// pinCheck(EEPROM_GPIO, EEPROM_GPIO_PIN_MISO, RCC_AHB1Periph_GPIOB);
// pinCheck(EEPROM_GPIO, EEPROM_GPIO_PIN_MOSI, RCC_AHB1Periph_GPIOB);
}
serial2Init(0, 0); // default serial mode (None if DEBUG not defined)
ledBlue();
__enable_irq();
TRACE("Horus started :)");
keysInit();
// adcInit();
lcdInit();
audioInit();
i2cInit();
init2MhzTimer();
init5msTimer();
usbInit();
hapticInit();
// rotencInit();
// bt_open();
#if defined(DEBUG)
DBGMCU_APB1PeriphConfig(DBGMCU_IWDG_STOP|DBGMCU_TIM1_STOP|DBGMCU_TIM2_STOP|DBGMCU_TIM3_STOP|DBGMCU_TIM4_STOP|DBGMCU_TIM5_STOP|DBGMCU_TIM6_STOP|DBGMCU_TIM7_STOP|DBGMCU_TIM8_STOP|DBGMCU_TIM9_STOP|DBGMCU_TIM10_STOP|DBGMCU_TIM11_STOP|DBGMCU_TIM12_STOP|DBGMCU_TIM13_STOP|DBGMCU_TIM14_STOP, ENABLE);
#endif
}
#endif
#if defined(USB_JOYSTICK) && !defined(SIMU)
extern USB_OTG_CORE_HANDLE USB_OTG_dev;
/*
Prepare and send new USB data packet
The format of HID_Buffer is defined by
USB endpoint description can be found in
file usb_hid_joystick.c, variable HID_JOYSTICK_ReportDesc
*/
void usbJoystickUpdate(void)
{
static uint8_t HID_Buffer[HID_IN_PACKET];
//buttons
HID_Buffer[0] = 0; //buttons
for (int i = 0; i < 8; ++i) {
if ( channelOutputs[i+8] > 0 ) {
HID_Buffer[0] |= (1 << i);
}
}
//analog values
//uint8_t * p = HID_Buffer + 1;
for (int i = 0; i < 8; ++i) {
int16_t value = channelOutputs[i] / 8;
if ( value > 127 ) value = 127;
else if ( value < -127 ) value = -127;
HID_Buffer[i+1] = static_cast<int8_t>(value);
}
USBD_HID_SendReport (&USB_OTG_dev, HID_Buffer, HID_IN_PACKET );
}
#endif //#if defined(USB_JOYSTICK) && defined(PCBTARANIS) && !defined(SIMU)
uint8_t currentTrainerMode = 0xff;
void checkTrainerSettings()
{
uint8_t requiredTrainerMode = g_model.trainerMode;
if (requiredTrainerMode != currentTrainerMode) {
switch (currentTrainerMode) {
case TRAINER_MODE_MASTER:
stop_trainer_capture();
break;
case TRAINER_MODE_SLAVE:
stop_trainer_ppm();
break;
}
currentTrainerMode = requiredTrainerMode;
switch (requiredTrainerMode) {
case TRAINER_MODE_SLAVE:
init_trainer_ppm();
break;
default:
// master is default
init_trainer_capture();
break;
}
}
}
// TODO
void eeDirty(uint8_t msk) { }
uint8_t s_eeDirtyMsk;
tmr10ms_t s_eeDirtyTime10ms;
void eeCheck(bool) { }
ModelHeader modelHeaders[MAX_MODELS];
void eeLoadModelHeaders() { }
void eeLoadModelHeader(uint8_t id, ModelHeader *header) { }
bool eeCopyModel(uint8_t dst, uint8_t src) { }
void eeSwapModels(uint8_t id1, uint8_t id2) { }
void eeDeleteModel(uint8_t idx) { }
uint8_t eeFindEmptyModel(uint8_t id, bool down) { return 0; };
void eeLoadModel(uint8_t id) { }
bool eeModelExists(uint8_t id) { return true; }
const pm_char * eeBackupModel(uint8_t i_fileSrc) { return NULL; }
const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name) { return NULL; }
void selectModel(uint8_t sub) { }
+310
View File
@@ -0,0 +1,310 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#ifndef _BOARD_FLAMENCO_H_
#define _BOARD_FLAMENCO_H_
#include "stddef.h"
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_ltdc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fmc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
#if !defined(SIMU)
#include "usbd_cdc_core.h"
#include "usbd_msc_core.h"
#include "usbd_hid_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
#include "usb_conf.h"
#include "usbd_conf.h"
#endif
#include "hal.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
#define FLASHSIZE 0x80000
#define BOOTLOADER_SIZE 0x8000
#define FIRMWARE_ADDRESS 0x08000000
#define PERI1_FREQUENCY 45000000
#define PERI2_FREQUENCY 90000000
#define TIMER_MULT_APB1 4
#define TIMER_MULT_APB2 2
#define PIN_MODE_MASK 0x0003
#define PIN_INPUT 0x0000
#define PIN_OUTPUT 0x0001
#define PIN_PERIPHERAL 0x0002
#define PIN_ANALOG 0x0003
#define PIN_PULL_MASK 0x000C
#define PIN_PULLUP 0x0004
#define PIN_NO_PULLUP 0x0000
#define PIN_PULLDOWN 0x0008
#define PIN_NO_PULLDOWN 0x0000
#define PIN_PERI_MASK 0x00F0
#define PIN_PUSHPULL 0x0000
#define PIN_ODRAIN 0x8000
#define PIN_PORT_MASK 0x0700
#define PIN_SPEED_MASK 0x6000
#define PIN_PORTA 0x0000
#define PIN_PORTB 0x0100
#define PIN_PORTC 0x0200
#define PIN_PORTD 0x0300
#define PIN_PORTE 0x0400
#define PIN_PORTF 0x0500
#define PIN_PER_1 0x0010
#define PIN_PER_2 0x0020
#define PIN_PER_3 0x0030
#define PIN_PER_5 0x0050
#define PIN_PER_6 0x0060
#define PIN_PER_8 0x0080
#define PIN_OS25 0x2000
#define PIN_OS50 0x4000
#define PIN_OS100 0x6000
void configure_pins( uint32_t pins, uint16_t config );
#define strcpy_P strcpy
#define strcat_P strcat
extern uint16_t sessionTimer;
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
#ifdef __cplusplus
extern "C" {
#endif
void delaysInit(void);
void delay_01us(uint16_t nb);
#ifdef __cplusplus
}
#endif
// SD driver
#if !defined(SIMU) || defined(SIMU_DISKIO)
uint32_t sdIsHC(void);
uint32_t sdGetSpeed(void);
#define SD_IS_HC() (sdIsHC())
#define SD_GET_SPEED() (sdGetSpeed())
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
#else
#define SD_IS_HC() (0)
#define SD_GET_SPEED() (0)
#endif
#if defined(SIMU)
#define sdInit()
#define sdDone()
#else
void sdInit(void);
void sdDone(void);
#define sdPoll10ms()
#define sdMountPoll()
uint32_t sdMounted(void);
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
#endif
// Flash Write driver
#define FLASH_PAGESIZE 256
void unlockFlash(void);
void lockFlash(void);
void writeFlash(uint32_t * address, uint32_t * buffer);
uint32_t isFirmwareStart(const void * buffer);
uint32_t isBootloaderStart(const void * buffer);
// SDRAM driver
#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000)
void SDRAM_Init(void);
void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize);
void SDRAM_ReadBuffer(uint32_t* pBuffer, uint32_t uwReadAddress, uint32_t uwBufferSize);
// Pulses driver
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_GPIO_PWR, EXTMODULE_GPIO_PIN_PWR)
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_GPIO_PWR, EXTMODULE_GPIO_PIN_PWR)
void init_no_pulses(uint32_t port);
void disable_no_pulses(uint32_t port);
void init_ppm( uint32_t module_index );
void disable_ppm( uint32_t module_index );
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive);
void init_pxx( uint32_t module_index );
void disable_pxx( uint32_t module_index );
void init_dsm2( uint32_t module_index );
void disable_dsm2( uint32_t module_index );
// Trainer driver
void init_trainer_ppm(void);
void stop_trainer_ppm(void);
void init_trainer_capture(void);
void stop_trainer_capture(void);
void init_cppm_on_heartbeat_capture(void);
void stop_cppm_on_heartbeat_capture(void);
void init_sbus_on_heartbeat_capture(void);
void stop_sbus_on_heartbeat_capture(void);
void set_trainer_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive);
// Keys driver
void keysInit(void);
uint32_t readKeys(void);
uint32_t readTrims(void);
#define TRIMS_PRESSED() (readTrims())
#define KEYS_PRESSED() (readKeys())
#define DBLKEYS_PRESSED_RGT_LFT(i) ((in & ((2<<KEY_PLUS) + (2<<KEY_MINUS))) == ((2<<KEY_PLUS) + (2<<KEY_MINUS)))
#define DBLKEYS_PRESSED_UP_DWN(i) ((in & ((2<<KEY_MENU) + (2<<KEY_PAGE))) == ((2<<KEY_MENU) + (2<<KEY_PAGE)))
#define DBLKEYS_PRESSED_RGT_UP(i) ((in & ((2<<KEY_ENTER) + (2<<KEY_MINUS))) == ((2<<KEY_ENTER) + (2<<KEY_MINUS)))
#define DBLKEYS_PRESSED_LFT_DWN(i) ((in & ((2<<KEY_PAGE) + (2<<KEY_EXIT))) == ((2<<KEY_PAGE) + (2<<KEY_EXIT)))
void checkRotaryEncoder(void);
// WDT driver
#if !defined(SIMU)
#define wdt_disable()
void watchdogInit(unsigned int duration);
#define wdt_enable(x) // watchdogInit(1500)
#define wdt_reset() // IWDG->KR = 0xAAAA
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
#endif
// ADC driver
void adcInit(void);
void adcRead(void);
inline uint16_t getAnalogValue(uint32_t value);
#if defined(REV3)
#define BATT_SCALE 120
#else
#define BATT_SCALE 150
#endif
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
// Power driver
void pwrInit(void);
uint32_t pwrCheck(void);
void pwrOn(void);
void pwrOff(void);
uint32_t pwrPressed(void);
uint32_t pwrPressedDuration(void);
#define UNEXPECTED_SHUTDOWN() (g_eeGeneral.unexpectedShutdown)
// Led driver
void ledInit(void);
void ledOff(void);
void ledRed(void);
void ledBlue(void);
// LCD driver
// Backlight driver
#define setBacklight(xx)
#define backlightEnable()
#define backlightDisable()
#define isBacklightEnable() true
// USB driver
int usbPlugged(void);
void usbInit(void);
void usbDeInit(void);
void usbSerialPutc(uint8_t c);
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
// Audio driver
void audioInit(void);
void audioEnd(void);
void dacStart(void);
void dacStop(void);
void setSampleRate(uint32_t frequency);
// I2C driver
void i2cInit(void);
#define VOLUME_LEVEL_MAX 23
#define VOLUME_LEVEL_DEF 12
extern const int8_t volumeScale[];
void setVolume(uint8_t volume);
// Telemetry driver
void telemetryPortInit(uint32_t baudrate);
void sportSendBuffer(uint8_t *buffer, uint32_t count);
// Haptic driver
void hapticInit(void);
void hapticOff(void);
#define HAPTIC_OFF() hapticOff()
void hapticOn(uint32_t pwmPercent);
// Second serial port driver
#define DEBUG_BAUDRATE 115200
void serial2Init(unsigned int mode, unsigned int protocol);
void serial2Putc(char c);
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
void serial2SbusInit(void);
void serial2Stop(void);
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
#if defined(USB_JOYSTICK) && !defined(SIMU)
void usbJoystickUpdate(void);
#endif
void checkTrainerSettings(void);
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "board_horus.h"
void delaysInit(void)
{
// Timer13
RCC->APB1ENR |= RCC_APB1ENR_TIM13EN; // Enable clock
TIM13->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 10000000 - 1; // 0.1uS
TIM13->CCER = 0;
TIM13->CCMR1 = 0;
TIM13->CR1 = 0x02;
TIM13->DIER = 0;
}
void delay_01us(uint16_t nb)
{
TIM13->EGR = 1;
TIM13->CNT = 0;
TIM13->CR1 = 0x03;
while (TIM13->CNT < nb);
TIM13->CR1 = 0x02;
}
+296
View File
@@ -0,0 +1,296 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/
#include "diskio.h"
#include <string.h> // memcpy
#include "stm32f4xx.h"
#include "sdio_sd.h"
#define BLOCK_SIZE 512 /* Block Size in Bytes */
/*-----------------------------------------------------------------------*/
/* Lock / unlock functions */
/*-----------------------------------------------------------------------*/
#if !defined(BOOT)
static OS_MutexID ioMutex;
volatile int mutexCheck = 0;
int ff_cre_syncobj (BYTE vol, _SYNC_t *mutex)
{
*mutex = ioMutex;
return 1;
}
int ff_req_grant (_SYNC_t mutex)
{
return CoEnterMutexSection(mutex) == E_OK;
}
void ff_rel_grant (_SYNC_t mutex)
{
CoLeaveMutexSection(mutex);
}
int ff_del_syncobj (_SYNC_t mutex)
{
return 1;
}
#endif
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
DSTATUS stat = 0;
/* Supports only single drive */
if (drv)
{
stat |= STA_NOINIT;
}
/*-------------------------- SD Init ----------------------------- */
if (SD_Init() != SD_OK)
{
TRACE("SD_Init() failed");
stat |= STA_NOINIT;
}
return(stat);
}
/*-----------------------------------------------------------------------*/
/* Return Disk Status */
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
DSTATUS stat = 0;
if (SD_Detect() != SD_PRESENT)
stat |= STA_NODISK;
// STA_NOTINIT - Subsystem not initailized
// STA_PROTECTED - Write protected, MMC/SD switch if available
return(stat);
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to read (1..255) */
)
{
SD_Error Status;
// TRACE("disk_read %d %p %10d %d\n",drv,buff,sector,count);
if (SD_Detect() != SD_PRESENT)
return(RES_NOTRDY);
if ((DWORD)buff & 3) // DMA Alignment failure, do single up to aligned buffer
{
DRESULT res = RES_OK;
DWORD scratch[BLOCK_SIZE / 4]; // Alignment assured, you'll need a sufficiently big stack
while(count--)
{
res = disk_read(drv, (BYTE *)scratch, sector++, 1);
if (res != RES_OK) {
TRACE("disk_read() status=%d", res);
break;
}
memcpy(buff, scratch, BLOCK_SIZE);
buff += BLOCK_SIZE;
}
return(res);
}
Status = SD_ReadMultiBlocksFIXED(buff, sector, BLOCK_SIZE, count); // 4GB Compliant
if (Status == SD_OK)
{
SDTransferState State;
Status = SD_WaitReadOperation(); // Check if the Transfer is finished
while((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK)) {
TRACE("SD_ReadMultiBlocksFIXED() wait error (State=%d Status=%d)", State, Status);
return(RES_ERROR);
}
else
return(RES_OK);
}
else {
TRACE("SD_ReadMultiBlocksFIXED() error (Status=%d)", Status);
return(RES_ERROR);
}
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to write (1..255) */
)
{
SD_Error Status;
// TRACE("disk_write %d %p %10d %d\n",drv,buff,sector,count);
if (SD_Detect() != SD_PRESENT)
return(RES_NOTRDY);
if ((DWORD)buff & 3) // DMA Alignment failure, do single up to aligned buffer
{
DRESULT res = RES_OK;
DWORD scratch[BLOCK_SIZE / 4]; // Alignment assured, you'll need a sufficiently big stack
while(count--)
{
memcpy(scratch, buff, BLOCK_SIZE);
res = disk_write(drv, (BYTE *)scratch, sector++, 1);
if (res != RES_OK)
break;
buff += BLOCK_SIZE;
}
return(res);
}
Status = SD_WriteMultiBlocksFIXED((uint8_t *)buff, sector, BLOCK_SIZE, count); // 4GB Compliant
if (Status == SD_OK)
{
SDTransferState State;
Status = SD_WaitWriteOperation(); // Check if the Transfer is finished
while((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK))
return(RES_ERROR);
else
return(RES_OK);
}
else
return(RES_ERROR);
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
return RES_OK;
}
// TODO everything here should not be in the driver layer ...
FATFS g_FATFS_Obj;
#if defined(SPORT_FILE_LOG)
FIL g_telemetryFile = {0};
#endif
#if defined(BOOT)
void sdInit(void)
{
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
f_chdir("/");
}
}
#else
// TODO shouldn't be there!
void sdInit(void)
{
ioMutex = CoCreateMutex();
if (ioMutex >= CFG_MAX_MUTEX ) {
// sd error
return;
}
TRACE("AVANT F_MOUNT");
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
TRACE("APRES F_MOUNT");
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
sdGetFreeSectors();
referenceSystemAudioFiles();
#if defined(SPORT_FILE_LOG)
f_open(&g_telemetryFile, LOGS_PATH "/sport.log", FA_OPEN_ALWAYS | FA_WRITE);
if (f_size(&g_telemetryFile) > 0) {
f_lseek(&g_telemetryFile, f_size(&g_telemetryFile)); // append
}
#endif
}
else {
TRACE("f_mount() failed");
}
}
void sdDone()
{
if (sdMounted()) {
audioQueue.stopSD();
#if defined(SPORT_FILE_LOG)
f_close(&g_telemetryFile);
#endif
f_mount(NULL, "", 0); // unmount SD
}
}
#endif
uint32_t sdMounted()
{
return g_FATFS_Obj.fs_type != 0;
}
uint32_t sdIsHC()
{
return true; // TODO (CardType & CT_BLOCK);
}
uint32_t sdGetSpeed()
{
return 330000;
}
+260
View File
@@ -0,0 +1,260 @@
#ifndef _HAL_
#define _HAL_
// Keys
#define KEYS_RCC_AHB1Periph_GPIO (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOJ)
#define KEYS_GPIO_REG_MENU GPIOC->IDR
#define KEYS_GPIO_PIN_MENU GPIO_Pin_13 // PC.13
#define KEYS_GPIO_REG_EXIT GPIOI->IDR
#define KEYS_GPIO_PIN_EXIT GPIO_Pin_8 // PI.08
#define KEYS_GPIO_REG_LEFT GPIOI->IDR
#define KEYS_GPIO_PIN_LEFT GPIO_Pin_7 // PI.07
#define KEYS_GPIO_REG_ENTER GPIOC->IDR
#define KEYS_GPIO_PIN_ENTER GPIO_Pin_1 // PC.01
#define KEYS_GPIO_REG_UP GPIOG->IDR
#define KEYS_GPIO_PIN_UP GPIO_Pin_13 // PG.13
#define KEYS_GPIO_REG_DOWN GPIOI->IDR
#define KEYS_GPIO_PIN_DOWN GPIO_Pin_6 // PI.06
#define KEYS_GPIO_REG_RIGHT GPIOC->IDR
#define KEYS_GPIO_PIN_RIGHT GPIO_Pin_4 // PC.04
// Rotary Encoder
#define ENC_GPIO GPIOH
#define ENC_GPIO_PIN_A GPIO_Pin_11 // PH.11
#define ENC_GPIO_PIN_B GPIO_Pin_10 // PH.10
// Switches
#define SWITCHES_GPIO_REG_A_H GPIOI->IDR
#define SWITCHES_GPIO_PIN_A_H GPIO_Pin_15 // PI.15
#define SWITCHES_GPIO_REG_A_L GPIOH->IDR
#define SWITCHES_GPIO_PIN_A_L GPIO_Pin_9 // PH.09
#define SWITCHES_GPIO_REG_B_H GPIOH->IDR
#define SWITCHES_GPIO_PIN_B_H GPIO_Pin_12 // PH.12
#define SWITCHES_GPIO_REG_B_L GPIOB->IDR
#define SWITCHES_GPIO_PIN_B_L GPIO_Pin_12 // PB.12
#define SWITCHES_GPIO_REG_C_H GPIOB->IDR
#define SWITCHES_GPIO_PIN_C_H GPIO_Pin_15 // PB.15
#define SWITCHES_GPIO_REG_C_L GPIOD->IDR
#define SWITCHES_GPIO_PIN_C_L GPIO_Pin_11 // PD.11
#define SWITCHES_GPIO_REG_D_H GPIOJ->IDR
#define SWITCHES_GPIO_PIN_D_H GPIO_Pin_7 // PJ.07
#define SWITCHES_GPIO_REG_D_L GPIOG->IDR
#define SWITCHES_GPIO_PIN_D_L GPIO_Pin_2 // PG.02
#define SWITCHES_GPIO_REG_E_H GPIOH->IDR
#define SWITCHES_GPIO_PIN_E_H GPIO_Pin_4 // PH.04
#define SWITCHES_GPIO_REG_E_L GPIOE->IDR
#define SWITCHES_GPIO_PIN_E_L GPIO_Pin_3 // PE.03
#define SWITCHES_GPIO_REG_F GPIOH->IDR
#define SWITCHES_GPIO_PIN_F GPIO_Pin_3 // PH.03
#define SWITCHES_GPIO_REG_G_H GPIOG->IDR
#define SWITCHES_GPIO_PIN_G_H GPIO_Pin_3 // PG.03
#define SWITCHES_GPIO_REG_G_L GPIOG->IDR
#define SWITCHES_GPIO_PIN_G_L GPIO_Pin_6 // PG.06
#define SWITCHES_GPIO_REG_H GPIOG->IDR
#define SWITCHES_GPIO_PIN_H GPIO_Pin_7 // PG.07
// Trims
#define TRIMS_GPIO_REG_LHL GPIOC->IDR
#define TRIMS_GPIO_PIN_LHL GPIO_Pin_0 // PC.00
#define TRIMS_GPIO_REG_LHR GPIOI->IDR
#define TRIMS_GPIO_PIN_LHR GPIO_Pin_4 // PI.04
#define TRIMS_GPIO_REG_LVD GPIOG->IDR
#define TRIMS_GPIO_PIN_LVD GPIO_Pin_12 // PG.12
#define TRIMS_GPIO_REG_LVU GPIOJ->IDR
#define TRIMS_GPIO_PIN_LVU GPIO_Pin_14 // PJ.14
#define TRIMS_GPIO_REG_RVD GPIOJ->IDR
#define TRIMS_GPIO_PIN_RVD GPIO_Pin_13 // PJ.13
#define TRIMS_GPIO_REG_RHL GPIOD->IDR
#define TRIMS_GPIO_PIN_RHL GPIO_Pin_3 // PD.03
#define TRIMS_GPIO_REG_RVU GPIOJ->IDR
#define TRIMS_GPIO_PIN_RVU GPIO_Pin_12 // PJ.12
#define TRIMS_GPIO_REG_RHR GPIOD->IDR
#define TRIMS_GPIO_PIN_RHR GPIO_Pin_7 // PD.07
#define TRIMS_GPIO_REG_RSD GPIOJ->IDR
#define TRIMS_GPIO_PIN_RSD GPIO_Pin_8 // PJ.08
#define TRIMS_GPIO_REG_RSU GPIOD->IDR
#define TRIMS_GPIO_PIN_RSU GPIO_Pin_13 // PD.13
#define TRIMS_GPIO_REG_LSD GPIOB->IDR
#define TRIMS_GPIO_PIN_LSD GPIO_Pin_14 // PB.14
#define TRIMS_GPIO_REG_LSU GPIOB->IDR
#define TRIMS_GPIO_PIN_LSU GPIO_Pin_13 // PB.13
// Index of all keys
#define KEYS_GPIOB_PINS (SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_H | TRIMS_GPIO_PIN_LSD | TRIMS_GPIO_PIN_LSU)
#define KEYS_GPIOC_PINS (KEYS_GPIO_PIN_MENU | KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_RIGHT | TRIMS_GPIO_PIN_LHL)
#define KEYS_GPIOD_PINS (SWITCHES_GPIO_PIN_C_L | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_RHR | TRIMS_GPIO_PIN_RSU)
#define KEYS_GPIOE_PINS (SWITCHES_GPIO_PIN_E_L)
#define KEYS_GPIOG_PINS (KEYS_GPIO_PIN_UP | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD)
#define KEYS_GPIOH_PINS (SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_E_H | SWITCHES_GPIO_PIN_F | ENC_GPIO_PIN_A | ENC_GPIO_PIN_B)
#define KEYS_GPIOI_PINS (KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_LEFT | KEYS_GPIO_PIN_DOWN | SWITCHES_GPIO_PIN_A_H | TRIMS_GPIO_PIN_LHR)
#define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_RSD)
// ADC
#define ADC_RCC_AHB1Periph_GPIO (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC)
#define ADC_GPIO_STICKS GPIOA
#define ADC_GPIO_PIN_STICK_LV GPIO_Pin_0 // PA.00
#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_1 // PA.01
#define ADC_GPIO_PIN_STICK_RV GPIO_Pin_2 // PA.02
#define ADC_GPIO_PIN_STICK_RH GPIO_Pin_3 // PA.03
#define ADC_GPIO_POT_L1 GPIOC
#define ADC_GPIO_PIN_POT_L1 GPIO_Pin_3 // PC.03
#define ADC_GPIO_POT_R1 GPIOA
#define ADC_GPIO_PIN_POT_R1 GPIO_Pin_5 // PA.05
#define ADC_GPIO_POT_L2 GPIOB
#define ADC_GPIO_PIN_POT_L2 GPIO_Pin_1 // PB.01
#define ADC_GPIO_POT_R2 GPIOB
#define ADC_GPIO_PIN_POT_R2 GPIO_Pin_0 // PB.00
#define ADC_GPIO_SWITCHES_L3 GPIOC
#define ADC_GPIO_SWITCHES_PIN_L3 GPIO_Pin_1 // PC.01
#define ADC_GPIO_SWITCHES_R3 GPIOA
#define ADC_GPIO_SWITCHES_PIN_R3 GPIO_Pin_7 // PA.07
#define ADC_GPIO_SWITCHES_L4 GPIOC
#define ADC_GPIO_SWITCHES_PIN_L4 GPIO_Pin_0 // PC.00
#define ADC_GPIO_SWITCHES_R4 GPIOA
#define ADC_GPIO_SWITCHES_PIN_R4 GPIO_Pin_6 // PA.06
#define ADC_GPIO_BATT GPIOC
#define ADC_GPIO_PIN_BATT GPIO_Pin_4 // PC.04
// Power
#define PWR_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOJ
#define PWR_GPIO GPIOJ
#define PWR_GPIO_PIN_ON GPIO_Pin_0 // PJ.00
#define PWR_GPIO_PIN_SWITCH GPIO_Pin_1 // PJ.01
// Led
#define LED_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOI
#define LED_GPIO GPIOI
#define LED_GPIO_PIN GPIO_Pin_5 // PI.05
// Serial Port (DEBUG)
#define SERIAL_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB
#define SERIAL_RCC_APB1Periph_USART RCC_APB1Periph_USART3
#define SERIAL_GPIO GPIOB
#define SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10
#define SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11
#define SERIAL_GPIO_PinSource_TX GPIO_PinSource10
#define SERIAL_GPIO_PinSource_RX GPIO_PinSource11
#define SERIAL_GPIO_AF GPIO_AF_USART3
#define SERIAL_USART USART3
#define SERIAL_USART_IRQHandler USART3_IRQHandler
#define SERIAL_USART_IRQn USART3_IRQn
// Telemetry
#define TELEMETRY_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOD
#define TELEMETRY_RCC_APB1Periph_USART RCC_APB1Periph_USART2
#define TELEMETRY_GPIO_DIR GPIOD
#define TELEMETRY_GPIO_PIN_DIR GPIO_Pin_4 // PD.04
#define TELEMETRY_GPIO GPIOD
#define TELEMETRY_GPIO_PIN_TX GPIO_Pin_5 // PD.05
#define TELEMETRY_GPIO_PIN_RX GPIO_Pin_6 // PD.06
#define TELEMETRY_GPIO_PinSource_TX GPIO_PinSource5
#define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6
#define TELEMETRY_GPIO_AF GPIO_AF_USART2
#define TELEMETRY_USART USART2
#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
#define TELEMETRY_USART_IRQn USART2_IRQn
// USB
#define USB_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOA
#define USB_GPIO GPIOA
#define USB_GPIO_PIN_VBUS GPIO_Pin_9 // PA.09
#define USB_GPIO_PIN_DM GPIO_Pin_11 // PA.11
#define USB_GPIO_PIN_DP GPIO_Pin_12 // PA.12
#define USB_GPIO_PinSource_DM GPIO_PinSource11
#define USB_GPIO_PinSource_DP GPIO_PinSource12
#define USB_GPIO_AF GPIO_AF_OTG1_FS
// LCD
#define LCD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_GPIOK | RCC_AHB1Periph_DMA2D)
#define LCD_RCC_APB2Periph (RCC_APB2Periph_TIM8 | RCC_APB2Periph_LTDC)
#define LCD_GPIO_NRST GPIOF
#define LCD_GPIO_PIN_NRST GPIO_Pin_10 // PF.10
#define LCD_GPIO_BL GPIOA
#define LCD_GPIO_PIN_BL GPIO_Pin_5 // PA.05
#define LCD_GPIO_PinSource_BL GPIO_PinSource5
#define LCD_GPIO_AF_BL GPIO_AF_TIM8
#define LTDC_IRQ_PRIO 4
#define DMA_SCREEN_IRQ_PRIO 6
// SD
#define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
#define SD_PRESENT_GPIO GPIOC
#define SD_PRESENT_GPIO_PIN GPIO_Pin_5 // PC.05
#define SD_SDIO_DMA_STREAM DMA2_Stream3
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF3
#define SD_SDIO_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3
#define SD_SDIO_DMA_FLAG_TEIF DMA_FLAG_TEIF3
#define SD_SDIO_DMA_FLAG_HTIF DMA_FLAG_HTIF3
#define SD_SDIO_DMA_FLAG_TCIF DMA_FLAG_TCIF3
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
#define SD_SDIO_FIFO_ADDRESS ((uint32_t)0x40012C80)
#define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2)
#define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000)
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000)
// Audio
// I2C Bus: CAT5137
#define I2C_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB
#define I2C_RCC_APB1Periph_I2C RCC_APB1Periph_I2C1
#define I2C I2C1
#define I2C_GPIO GPIOB
#define I2C_GPIO_PIN_SCL GPIO_Pin_8 // PB.08
#define I2C_GPIO_PIN_SDA GPIO_Pin_9 // PB.09
#define I2C_GPIO_AF GPIO_AF_I2C1
#define I2C_GPIO_PinSource_SCL GPIO_PinSource8
#define I2C_GPIO_PinSource_SDA GPIO_PinSource9
#define I2C_SPEED 400000
#define I2C_ADDRESS_CAT5137 0x5C
// Haptic
#define HAPTIC_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOA
#define HAPTIC_GPIO GPIOA
#define HAPTIC_GPIO_PIN GPIO_Pin_2
#define HAPTIC_RCC_APB2Periph_TIMER RCC_APB2ENR_TIM11EN
#define HAPTIC_GPIO_TIMER TIM11
#define HAPTIC_GPIO_AF GPIO_AF_TIM11
#define HAPTIC_GPIO_PinSource GPIO_PinSource2
// Internal Module
#define INTMODULE_RCC_AHB1Periph_GPIO (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB)
#define INTMODULE_GPIO_PWR GPIOA
#define INTMODULE_GPIO_PIN_PWR GPIO_Pin_8 // PA.08
#define INTMODULE_GPIO GPIOB
#define INTMODULE_GPIO_PIN GPIO_Pin_6 // PB.06
#define INTMODULE_GPIO_PinSource GPIO_PinSource6
// External Module
#define EXTMODULE_RCC_AHB1Periph_GPIO (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB)
#define EXTMODULE_GPIO_PWR GPIOB
#define EXTMODULE_GPIO_PIN_PWR GPIO_Pin_3 // PB.03
#define EXTMODULE_GPIO GPIOA
#define EXTMODULE_GPIO_PIN GPIO_Pin_15 // PA.15
#define EXTMODULE_GPIO_PinSource GPIO_PinSource15
// Trainer Port
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC)
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_GPIO GPIOC
#define TRAINER_GPIO_PIN_IN GPIO_Pin_6 // PC.06
#define TRAINER_GPIO_PIN_OUT GPIO_Pin_7 // PC.07
#define TRAINER_GPIO_DETECT GPIOB
#define TRAINER_GPIO_PIN_DETECT GPIO_Pin_4 // PB.04
#define TRAINER_TIMER TIM3
#define TRAINER_TIMER_IRQn TIM3_IRQn
#define TRAINER_GPIO_PinSource_IN GPIO_PinSource6
#define TRAINER_GPIO_AF GPIO_AF_TIM3
// 5ms Interrupt
#define INTERRUPT_5MS_APB1Periph RCC_APB1Periph_TIM14
#define INTERRUPT_5MS_TIMER TIM14
#define INTERRUPT_5MS_IRQn TIM8_TRG_COM_TIM14_IRQn
#define INTERRUPT_5MS_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler
// 2MHz Timer
#define TIMER_2MHz_APB1Periph RCC_APB1Periph_TIM7
#define TIMER_2MHz_TIMER TIM7
#endif
+75
View File
@@ -0,0 +1,75 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
void hapticOff(void)
{
HAPTIC_GPIO_TIMER->CCR1 = 0;
}
void hapticOn(uint32_t pwmPercent)
{
if (pwmPercent > 100) {
pwmPercent = 100;
}
HAPTIC_GPIO_TIMER->CCR1 = pwmPercent;
}
void hapticInit(void)
{
RCC_AHB1PeriphClockCmd(HAPTIC_RCC_AHB1Periph_GPIO, ENABLE);
RCC_APB2PeriphClockCmd(HAPTIC_RCC_APB2Periph_TIMER, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = HAPTIC_GPIO_PIN;
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_NOPULL;
GPIO_Init(HAPTIC_GPIO, &GPIO_InitStructure);
GPIO_PinAFConfig(HAPTIC_GPIO, HAPTIC_GPIO_PinSource, HAPTIC_GPIO_AF);
HAPTIC_GPIO_TIMER->ARR = 100 ;
HAPTIC_GPIO_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 10000 - 1;
HAPTIC_GPIO_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 ; // PWM
HAPTIC_GPIO_TIMER->CCER = TIM_CCER_CC1E ;
HAPTIC_GPIO_TIMER->CCR1 = 0 ;
HAPTIC_GPIO_TIMER->EGR = 0 ;
HAPTIC_GPIO_TIMER->CR1 = TIM_CR1_CEN ; // Counter enable
}
+116
View File
@@ -0,0 +1,116 @@
#include "board_horus.h"
void i2cInit(void)
{
RCC_AHB1PeriphClockCmd(I2C_RCC_AHB1Periph_GPIO, ENABLE);
RCC_APB1PeriphClockCmd(I2C_RCC_APB1Periph_I2C, ENABLE);
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SCL, I2C_GPIO_AF);
GPIO_PinAFConfig(I2C_GPIO, I2C_GPIO_PinSource_SDA, I2C_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_GPIO_PIN_SCL | I2C_GPIO_PIN_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C, &I2C_InitStructure);
I2C_Cmd(I2C, ENABLE);
}
#define I2C_TIMEOUT_MAX 1000
bool I2C_WaitEvent(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
bool I2C_WaitEventCleared(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
uint8_t i2cReadRegister(uint8_t address, uint8_t index)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return 0;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return 0;
I2C_Send7bitAddress(I2C, address, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return 0;
I2C_SendData(I2C, index);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return 0;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return 0;
I2C_Send7bitAddress(I2C, address, I2C_Direction_Receiver);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
return 0;
I2C_AcknowledgeConfig(I2C, DISABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
return 0;
uint8_t result = I2C_ReceiveData(I2C);
I2C_GenerateSTOP(I2C, ENABLE);
return result;
}
void i2cWriteRegister(uint8_t address, uint8_t index, uint8_t data)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return;
I2C_Send7bitAddress(I2C, address, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return;
I2C_SendData(I2C, index);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return;
I2C_SendData(I2C, data);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return;
I2C_GenerateSTOP(I2C, ENABLE);
}
void setVolume(uint8_t volume)
{
if (volume > VOLUME_LEVEL_MAX) {
volume = VOLUME_LEVEL_MAX;
}
i2cWriteRegister(I2C_ADDRESS_CAT5137, 0, volumeScale[volume]);
}
+242
View File
@@ -0,0 +1,242 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
uint32_t readKeys()
{
uint32_t result = 0;
if (~KEYS_GPIO_REG_MENU & KEYS_GPIO_PIN_MENU)
result |= 1 << KEY_MENU;
if (~KEYS_GPIO_REG_EXIT & KEYS_GPIO_PIN_EXIT)
result |= 1 << KEY_EXIT;
if (~KEYS_GPIO_REG_ENTER & KEYS_GPIO_PIN_ENTER)
result |= 1 << KEY_ENTER;
if (~KEYS_GPIO_REG_UP & KEYS_GPIO_PIN_UP)
result |= 1 << KEY_UP;
if (~KEYS_GPIO_REG_DOWN & KEYS_GPIO_PIN_DOWN)
result |= 1 << KEY_DOWN;
if (~KEYS_GPIO_REG_RIGHT & KEYS_GPIO_PIN_RIGHT)
result |= 1 << KEY_RIGHT;
if (~KEYS_GPIO_REG_LEFT & KEYS_GPIO_PIN_LEFT)
result |= 1 << KEY_LEFT;
// TRACE("readKeys(): %x", result);
return result;
}
uint32_t readTrims()
{
uint32_t result = 0;
if (~TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL)
result |= 0x01;
if (~TRIMS_GPIO_REG_LHR & TRIMS_GPIO_PIN_LHR)
result |= 0x02;
if (~TRIMS_GPIO_REG_LVD & TRIMS_GPIO_PIN_LVD)
result |= 0x04;
if (~TRIMS_GPIO_REG_LVU & TRIMS_GPIO_PIN_LVU)
result |= 0x08;
if (~TRIMS_GPIO_REG_RVD & TRIMS_GPIO_PIN_RVD)
result |= 0x10;
if (~TRIMS_GPIO_REG_RVU & TRIMS_GPIO_PIN_RVU)
result |= 0x20;
if (~TRIMS_GPIO_REG_RHL & TRIMS_GPIO_PIN_RHL)
result |= 0x40;
if (~TRIMS_GPIO_REG_RHR & TRIMS_GPIO_PIN_RHR)
result |= 0x80;
#if 0
if (~TRIMS_GPIO_REG_LSD & TRIMS_GPIO_PIN_LSD)
result |= 0x100;
if (~TRIMS_GPIO_REG_LSU & TRIMS_GPIO_PIN_LSU)
result |= 0x200;
if (~TRIMS_GPIO_REG_RSD & TRIMS_GPIO_PIN_RSD)
result |= 0x400;
if (~TRIMS_GPIO_REG_RSU & TRIMS_GPIO_PIN_RSU)
result |= 0x800;
#endif
// TRACE("readTrims(): result=0x%04x", result);
return result;
}
uint8_t trimDown(uint8_t idx)
{
return readTrims() & (1 << idx);
}
uint8_t keyDown()
{
return readKeys();
}
rotenc_t rotencValue;
void checkRotaryEncoder()
{
static uint32_t Rotary_position;
register uint32_t dummy ;
dummy = ENC_GPIO->IDR ; // Read Rotary encode
dummy >>= 10; // quick & dirty!
dummy &= 0x03 ; // pick out the two bits
if ( dummy != ( Rotary_position & 0x03 ) ) {
if ( ( Rotary_position & 0x01 ) ^ ( ( dummy & 0x02) >> 1 ) ) {
--rotencValue;
}
else {
++rotencValue;
}
Rotary_position &= ~0x03 ;
Rotary_position |= dummy ;
}
}
/* TODO common to ARM */
void readKeysAndTrims()
{
register uint32_t i;
uint8_t enuk = 0;
uint32_t in = readKeys();
for (i = 0; i < TRM_BASE; i++) {
keys[enuk++].input(in & (1 << i));
}
static rotenc_t rePreviousValue;
rotenc_t reNewValue = (rotencValue / 2);
int8_t scrollRE = reNewValue - rePreviousValue;
if (scrollRE) {
rePreviousValue = reNewValue;
if (scrollRE < 0) {
putEvent(EVT_KEY_FIRST(KEY_MINUS));
}
else {
putEvent(EVT_KEY_FIRST(KEY_PLUS));
}
}
in = readTrims();
for (i = 1; i < 4096; i <<= 1) {
if (in & i) TRACE("trim %d", enuk);
keys[enuk++].input(in & i);
}
}
#define ADD_2POS_CASE(x) \
case SW_S ## x ## 0: \
xxx = SWITCHES_GPIO_REG_ ## x & SWITCHES_GPIO_PIN_ ## x ; \
break; \
case SW_S ## x ## 2: \
xxx = ~SWITCHES_GPIO_REG_ ## x & SWITCHES_GPIO_PIN_ ## x ; \
break
#define ADD_3POS_CASE(x, i) \
case SW_S ## x ## 0: \
xxx = (SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H); \
if (IS_3POS(i)) { \
xxx = xxx && (~SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
} \
break; \
case SW_S ## x ## 1: \
xxx = (SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H) && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
break; \
case SW_S ## x ## 2: \
xxx = (~SWITCHES_GPIO_REG_ ## x ## _H & SWITCHES_GPIO_PIN_ ## x ## _H); \
if (IS_3POS(i)) { \
xxx = xxx && (SWITCHES_GPIO_REG_ ## x ## _L & SWITCHES_GPIO_PIN_ ## x ## _L); \
} \
break
#if !defined(BOOT)
bool switchState(EnumKeys enuk)
{
register uint32_t xxx = 0;
if (enuk < (int) DIM(keys)) return keys[enuk].state() ? 1 : 0;
switch ((uint8_t) enuk) {
ADD_3POS_CASE(A, 0);
ADD_3POS_CASE(B, 1);
ADD_3POS_CASE(C, 2);
ADD_3POS_CASE(D, 3);
ADD_3POS_CASE(E, 4);
ADD_2POS_CASE(F);
ADD_3POS_CASE(G, 6);
ADD_2POS_CASE(H);
default:
break;
}
// TRACE("switch %d => %d", enuk, xxx);
return xxx;
}
#endif
void keysInit()
{
RCC_AHB1PeriphClockCmd(KEYS_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOB_PINS;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOC_PINS;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOD_PINS;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOE_PINS;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOG_PINS;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOH_PINS;
GPIO_Init(GPIOH, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOI_PINS;
GPIO_Init(GPIOI, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOJ_PINS;
GPIO_Init(GPIOJ, &GPIO_InitStructure);
}
+529
View File
@@ -0,0 +1,529 @@
/**
******************************************************************************
* @file Project/lcd/lcd.c
* @author FrSky Application Team
* @Hardware version V0.2
* @date 11-July-2012
* @brief This file provides LCD Init and botom drivers.
* *
******************************************************************************
*/
#include "../../opentx.h"
#define HBP 42
#define VBP 12
#define HSW 2
#define VSW 10
#define HFP 3
#define VFP 2
#define LCD_PIXEL_WIDTH ((uint16_t)480)
#define LCD_PIXEL_HEIGHT ((uint16_t)272)
/**
* @brief LCD Direction
*/
#define LCD_DIR_HORIZONTAL 0x0000
#define LCD_DIR_VERTICAL 0x0001
/**
* @brief LCD Layer
*/
#define LCD_BACKGROUND_LAYER 0x0000
#define LCD_FOREGROUND_LAYER 0x0001
/**
* @brief The Touch panel connector for LCD panel addresses
*/
#define LCD_ADDR 0x80
#define ASSEMBLE_RGB(R ,G, B) ((((R)& 0xF8) << 8) | (((G) & 0xFC) << 3) | (((B) & 0xF8) >> 3))
#define LCD_BKLIGHT_PWM_FREQ 300
#define ABS(X) ((X) > 0 ? (X) : -(X))
#define POLY_X(Z) ((int32_t)((Points + Z)->X))
#define POLY_Y(Z) ((int32_t)((Points + Z)->Y))
/* Global variables to set the written text color */
static uint16_t CurrentTextColor = 0x0000;
static uint16_t CurrentBackColor = 0xFFFF;
/** @defgroup STM324x9I_EVAL_LCD_Private_Variables
* @{
*/
// static sFONT *LCD_Currentfonts;
#define LCD_DEFAULT_FRAME_BUFFER SDRAM_BANK_ADDR
#define FRAME_BUFFER_OFFSET ((uint32_t)0x100000)
/* Default LCD configuration with LCD Layer 1 */
static uint32_t CurrentFrameBuffer = LCD_DEFAULT_FRAME_BUFFER;
static uint32_t CurrentLayer = LCD_BACKGROUND_LAYER;
#define NRST_LOW() do { LCD_GPIO_NRST->BSRRH = LCD_GPIO_PIN_NRST; } while(0)
#define NRST_HIGH() do { LCD_GPIO_NRST->BSRRL = LCD_GPIO_PIN_NRST; } while(0)
static void LCD_AF_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOs Configuration */
/*
+------------------------+-----------------------+----------------------------+
+ LCD pins assignment +
+------------------------+-----------------------+----------------------------
| | LCD_TFT G2 <-> PJ.09 | |
| LCD_TFT R3 <-> PJ.02 | LCD_TFT G3 <-> PJ.10 | LCD_TFT B3 <-> PJ.15 |
| LCD_TFT R4 <-> PJ.03 | LCD_TFT G4 <-> PJ.11 | LCD_TFT B4 <-> PK.03 |
| LCD_TFT R5 <-> PJ.04 | LCD_TFT G5 <-> PK.00 | LCD_TFT B5 <-> PK.04 |
| LCD_TFT R6 <-> PJ.05 | LCD_TFT G6 <-> PK.01 | LCD_TFT B6 <-> PK.05 |
| LCD_TFT R7 <-> PJ.06 | LCD_TFT G7 <-> PK.02 | LCD_TFT B7 <-> PK.06 |
-------------------------------------------------------------------------------
| LCD_TFT HSYNC <-> PI.12 | LCDTFT VSYNC <-> PI.13 |
| LCD_TFT CLK <-> PI.14 | LCD_TFT DE <-> PK.07 ///
-----------------------------------------------------
|LCD_TFT backlight <-> PA.04| LCD_CS <-> PI.10 |LCD_SCK<->PI.11
-----------------------------------------------------
*/
/*GPIOI configuration*/
GPIO_PinAFConfig(GPIOI,GPIO_PinSource12,GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOI,GPIO_PinSource13,GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOI,GPIO_PinSource14,GPIO_AF_LTDC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
GPIO_Init(GPIOI,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource7, GPIO_AF_LTDC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOK, &GPIO_InitStructure);
/* GPIOJ configuration */
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource2, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource3, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource4, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource5, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource6, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource9, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource10, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource11, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOJ, GPIO_PinSource15, GPIO_AF_LTDC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | \
GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_15;
GPIO_Init(GPIOJ, &GPIO_InitStructure);
/* GPIOK configuration */
GPIO_PinAFConfig(GPIOK, GPIO_PinSource0, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource1, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource2, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource3, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource4, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource5, GPIO_AF_LTDC);
GPIO_PinAFConfig(GPIOK, GPIO_PinSource6, GPIO_AF_LTDC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOK, &GPIO_InitStructure);
}
static void LCD_Backlight_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LCD_GPIO_PIN_BL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(LCD_GPIO_BL, &GPIO_InitStructure);
GPIO_PinAFConfig(LCD_GPIO_BL, LCD_GPIO_PinSource_BL, LCD_GPIO_AF_BL);
}
static void LCD_NRSTConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LCD_GPIO_PIN_NRST;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(LCD_GPIO_NRST, &GPIO_InitStructure);
}
static void delay3(uint32_t nCount)
{
uint32_t index = 0;
for(index = (1000 * 100 * nCount); index != 0; --index)
{
__asm("nop\n");
}
}
static void lcd_reset(void)
{
NRST_HIGH();
delay3(1);
NRST_LOW(); // RESET();
delay3(20);
NRST_HIGH();
delay3(30);
}
void LCD_Init_LTDC(void)
{
LTDC_InitTypeDef LTDC_InitStruct;
/* Configure PLLSAI prescalers for LCD */
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */
/* PLLLCDCLK = PLLSAI_VCO Output/PLL_LTDC = 192/3 = 64 Mhz */
/* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/4 = 16 Mhz */
//second pam is for audio
//third pam is for LCD
RCC_PLLSAIConfig(192, 6, 3);
RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div4); //Modify by Fy
/* Enable PLLSAI Clock */
RCC_PLLSAICmd(ENABLE);
/* Wait for PLLSAI activation */
while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
{
}
/* LTDC Configuration *********************************************************/
/* Polarity configuration */
/* Initialize the horizontal synchronization polarity as active low */
LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL;
/* Initialize the vertical synchronization polarity as active low */
LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL;
/* Initialize the data enable polarity as active low */
LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL;
/* Initialize the pixel clock polarity as input pixel clock */
LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
/* Configure R,G,B component values for LCD background color */
LTDC_InitStruct.LTDC_BackgroundRedValue = 0;
LTDC_InitStruct.LTDC_BackgroundGreenValue = 0;
LTDC_InitStruct.LTDC_BackgroundBlueValue = 0;
/* Configure horizontal synchronization width */
LTDC_InitStruct.LTDC_HorizontalSync = HSW;
/* Configure vertical synchronization height */
LTDC_InitStruct.LTDC_VerticalSync = VSW;
/* Configure accumulated horizontal back porch */
LTDC_InitStruct.LTDC_AccumulatedHBP = HBP;
/* Configure accumulated vertical back porch */
LTDC_InitStruct.LTDC_AccumulatedVBP = VBP;
/* Configure accumulated active width */
LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_PIXEL_WIDTH + HBP;
/* Configure accumulated active height */
LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_PIXEL_HEIGHT + VBP;
/* Configure total width */
LTDC_InitStruct.LTDC_TotalWidth = LCD_PIXEL_WIDTH + HBP + HFP;
/* Configure total height */
LTDC_InitStruct.LTDC_TotalHeigh = LCD_PIXEL_HEIGHT + VBP + VFP;
// init ltdc
LTDC_Init(&LTDC_InitStruct);
#if 0
LTDC_ITConfig(LTDC_IER_LIE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = LTDC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = LTDC_IRQ_PRIO;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
DMA2D_ITConfig(DMA2D_CR_TCIE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA2D_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SCREEN_IRQ_PRIO;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
DMA2D->IFCR = (unsigned long)DMA2D_IFSR_CTCIF;
#endif
}
/**
* @brief Initializes the LCD Layers.
* @param None
* @retval None
*/
void LCD_LayerInit()
{
LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct;
/* Windowing configuration */
/* In this case all the active display area is used to display a picture then :
Horizontal start = horizontal synchronization + Horizontal back porch = 30
Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1
Vertical start = vertical synchronization + vertical back porch = 4
Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */
LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1;
LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PIXEL_WIDTH + HBP);
LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1;;
LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PIXEL_HEIGHT + VBP);
/* Pixel Format configuration*/
LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565;
/* Alpha constant (255 totally opaque) */
LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255;
/* Default Color configuration (configure A,R,G,B component values) */
LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0;
LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;
LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;
LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
/* Configure blending factors */
LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;
LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
/* the length of one line of pixels in bytes + 3 then :
Line Lenth = Active high width x number of bytes per pixel + 3
Active high width = LCD_PIXEL_WIDTH
number of bytes per pixel = 2 (pixel_format : RGB565)
*/
LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PIXEL_WIDTH * 2) + 3);
/* the pitch is the increment from the start of one line of pixels to the
start of the next line in bytes, then :
Pitch = Active high width x number of bytes per pixel */
LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_PIXEL_WIDTH * 2);
/* Configure the number of lines */
LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PIXEL_HEIGHT;
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_DEFAULT_FRAME_BUFFER;
/* Initialize LTDC layer 1 */
LTDC_LayerInit(LTDC_Layer1, &LTDC_Layer_InitStruct);
/* Configure Layer 2 */
LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;
LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_DEFAULT_FRAME_BUFFER + FRAME_BUFFER_OFFSET;
/* Initialize LTDC layer 2 */
LTDC_LayerInit(LTDC_Layer2, &LTDC_Layer_InitStruct);
/* LTDC configuration reload */
LTDC_ReloadConfig(LTDC_IMReload);
LTDC_LayerCmd(LTDC_Layer1, ENABLE);
LTDC_LayerCmd(LTDC_Layer2, ENABLE);
LTDC_ReloadConfig(LTDC_IMReload);
/* dithering activation */
LTDC_DitherCmd(ENABLE);
}
static inline long divRoundClosest(const long n, const long d)
{
return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);
}
void LCD_ControlLight(uint16_t dutyCycle)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t freq = LCD_BKLIGHT_PWM_FREQ;
uint32_t temp = 0;
temp = 1000000 / freq - 1;
TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 1000000 - 1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = temp;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
unsigned long tempValue;
tempValue = (unsigned long)divRoundClosest((temp+1)*(100-dutyCycle), dutyCycle);
TIM_Cmd(TIM8, DISABLE);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = (uint32_t)tempValue;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
TIM_Cmd(TIM8, ENABLE);
TIM_CtrlPWMOutputs(TIM8, ENABLE);
}
/*********************************output****************************************/
/**
* @brief Initializes the LCD.
* @param None
* @retval None
*/
void LCD_Init(void)
{
RCC_AHB1PeriphClockCmd(LCD_RCC_AHB1Periph, ENABLE);
RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph, ENABLE);
/* Reset the LCD --------------------------------------------------------*/
LCD_NRSTConfig();
lcd_reset();
/* Configure the LCD Control pins */
LCD_AF_GPIOConfig();
LCD_Init_LTDC();
//config backlight
LCD_Backlight_Config();
//Max Value
LCD_ControlLight(100);
}
/**
* @brief Sets the LCD Layer.
* @param Layerx: specifies the Layer foreground or background.
* @retval None
*/
void LCD_SetLayer(uint32_t Layerx)
{
if (Layerx == LCD_BACKGROUND_LAYER)
{
CurrentFrameBuffer = LCD_DEFAULT_FRAME_BUFFER;
CurrentLayer = LCD_BACKGROUND_LAYER;
}
else
{
CurrentFrameBuffer = LCD_DEFAULT_FRAME_BUFFER + FRAME_BUFFER_OFFSET;
CurrentLayer = LCD_FOREGROUND_LAYER;
}
}
#define LCD_COLOR_WHITE 0xFFFF
#define LCD_COLOR_RED 0xF800
void LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
{
int x = -Radius, y = 0, err = 2-2*Radius, e2;
do {
*(__IO uint16_t*) (CurrentFrameBuffer + (2*((Xpos-x) + LCD_PIXEL_WIDTH*(Ypos+y)))) = LCD_COLOR_RED;
*(__IO uint16_t*) (CurrentFrameBuffer + (2*((Xpos+x) + LCD_PIXEL_WIDTH*(Ypos+y)))) = LCD_COLOR_RED;
*(__IO uint16_t*) (CurrentFrameBuffer + (2*((Xpos+x) + LCD_PIXEL_WIDTH*(Ypos-y)))) = LCD_COLOR_RED;
*(__IO uint16_t*) (CurrentFrameBuffer + (2*((Xpos-x) + LCD_PIXEL_WIDTH*(Ypos-y)))) = LCD_COLOR_RED;
e2 = err;
if (e2 <= y) {
err += ++y*2+1;
if (-x == y && e2 <= x) e2 = 0;
}
if (e2 > x) err += ++x*2+1;
}
while (x <= 0);
}
void LCD_Clear(uint16_t Color)
{
uint16_t *index ;
/* erase memory */
for (index = (uint16_t *)CurrentFrameBuffer; index < (uint16_t *)(CurrentFrameBuffer+(FRAME_BUFFER_OFFSET)); index++)
{
*index = Color;
}
}
/**
* @brief Configure the transparency.
* @param transparency: specifies the transparency,
* This parameter must range from 0x00 to 0xFF.
* @retval None
*/
void LCD_SetTransparency(uint8_t transparency)
{
if (CurrentLayer == LCD_BACKGROUND_LAYER)
{
LTDC_LayerAlpha(LTDC_Layer1, transparency);
}
else
{
LTDC_LayerAlpha(LTDC_Layer2, transparency);
}
LTDC_ReloadConfig(LTDC_IMReload);
}
void LCD_SetColorKeying(uint32_t RGBValue)
{
uint32_t tmp = 0;
LTDC_ColorKeying_InitTypeDef LTDC_colorkeying_InitStruct;
/* configure the color Keying */
LTDC_colorkeying_InitStruct.LTDC_ColorKeyBlue = 0xFF & RGBValue;
tmp = (0xFF00 & RGBValue);
LTDC_colorkeying_InitStruct.LTDC_ColorKeyGreen = (tmp >> 8);
tmp = (0xFF0000 & RGBValue);
LTDC_colorkeying_InitStruct.LTDC_ColorKeyRed = (tmp >> 16);
if (CurrentLayer == LCD_BACKGROUND_LAYER)
{
/* Enable the color Keying for Layer1 */
LTDC_ColorKeyingConfig(LTDC_Layer1, &LTDC_colorkeying_InitStruct, ENABLE);
LTDC_ReloadConfig(LTDC_IMReload);
}
else
{
/* Enable the color Keying for Layer2 */
LTDC_ColorKeyingConfig(LTDC_Layer2, &LTDC_colorkeying_InitStruct, ENABLE);
LTDC_ReloadConfig(LTDC_IMReload);
}
}
void lcdInit(void)
{
/* Initialize the LCD */
LCD_Init();
LCD_LayerInit();
/* Enable LCD display */
LTDC_Cmd(ENABLE);
/* Set Background layer */
LCD_SetLayer(LCD_BACKGROUND_LAYER);
LCD_Clear(0);
LCD_SetTransparency(0);
/* Set Foreground layer */
LCD_SetLayer(LCD_FOREGROUND_LAYER);
LCD_Clear(0);
LCD_SetTransparency(255);
}
void lcdRefresh()
{
memcpy((void *)(SDRAM_BANK_ADDR+FRAME_BUFFER_OFFSET), (void *)SDRAM_BANK_ADDR, 480*272*2);
}
+67
View File
@@ -0,0 +1,67 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "board_horus.h"
void ledInit()
{
RCC_AHB1PeriphClockCmd(LED_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LED_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(LED_GPIO, &GPIO_InitStructure);
}
void ledOff()
{
RCC_AHB1PeriphClockCmd(LED_RCC_AHB1Periph_GPIO, DISABLE);
}
void ledRed()
{
ledInit();
GPIO_SetBits(LED_GPIO, LED_GPIO_PIN);
}
void ledBlue()
{
ledInit();
GPIO_ResetBits(LED_GPIO, LED_GPIO_PIN);
}
+321
View File
@@ -0,0 +1,321 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
void setupPulses(unsigned int port);
void setupPulsesPPM(unsigned int port);
void setupPulsesPXX(unsigned int port);
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
{
TIM1->CCR2 = idleTime;
TIM1->CCR1 = delay;
// we are using complementary output so logic has to be reversed here
TIM1->CCER = TIM_CCER_CC1NE | (positive ? 0 : TIM_CCER_CC1NP);
}
void init_no_pulses(uint32_t port)
{
EXTERNAL_MODULE_OFF();
// Timer1, channel 1
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(EXTMODULE_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(EXTMODULE_GPIO, &GPIO_InitStructure);
GPIO_SetBits(EXTMODULE_GPIO, EXTMODULE_GPIO_PIN) ; // Set high
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock
TIM1->CR1 &= ~TIM_CR1_CEN ;
TIM1->ARR = 36000 ; // 18mS
TIM1->CCR2 = 32000 ; // Update time
TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz
TIM1->CCER = TIM_CCER_CC3E ;
TIM1->CCMR2 = 0 ;
TIM1->EGR = 1 ; // Restart
TIM1->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 ; // Toggle CC1 o/p
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
TIM1->CR1 |= TIM_CR1_CEN ;
NVIC_EnableIRQ(TIM1_CC_IRQn) ;
NVIC_SetPriority(TIM1_CC_IRQn, 7);
}
void disable_no_pulses(uint32_t port)
{
NVIC_DisableIRQ(TIM1_CC_IRQn) ;
TIM1->DIER &= ~TIM_DIER_CC2IE ;
TIM1->CR1 &= ~TIM_CR1_CEN ;
}
void init_pxx(uint32_t port)
{
EXTERNAL_MODULE_ON();
// Timer1, channel1
setupPulsesPXX(EXTERNAL_MODULE);
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(EXTMODULE_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_PinAFConfig(EXTMODULE_GPIO, EXTMODULE_GPIO_PinSource, GPIO_AF_TIM1);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(EXTMODULE_GPIO, &GPIO_InitStructure);
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN ; // Enable DMA2 clock
TIM1->CR1 &= ~TIM_CR1_CEN ;
TIM1->ARR = 18000 ; // 9mS
TIM1->CCR2 = 15000 ; // Update time
TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz
TIM1->CCER = TIM_CCER_CC1E ;
TIM1->CR2 = TIM_CR2_OIS1 ; // O/P idle high
TIM1->BDTR = TIM_BDTR_MOE ; // Enable outputs
TIM1->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0 ; // Force O/P high
TIM1->EGR = 1 ; // Restart
TIM1->DIER |= TIM_DIER_CC1DE ; // Enable DMA on CC3 match
TIM1->DCR = 15 ; // TODO check // DMA to CC1
// Enable the DMA channel here, DMA2 stream 2, channel 7
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits
DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ;
DMA2_Stream2->PAR = CONVERT_PTR_UINT(&TIM1->DMAR);
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
// DMA2_Stream2->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
// DMA2_Stream2->NDTR = 100 ;
DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA
TIM1->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0 ; // Toggle CC1 o/p
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
TIM1->CR1 |= TIM_CR1_CEN ;
NVIC_EnableIRQ(TIM1_CC_IRQn);
NVIC_SetPriority(TIM1_CC_IRQn, 7);
}
void disable_pxx(uint32_t port)
{
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
NVIC_DisableIRQ(TIM1_CC_IRQn) ;
TIM1->DIER &= ~TIM_DIER_CC2IE ;
TIM1->CR1 &= ~TIM_CR1_CEN ;
EXTERNAL_MODULE_OFF();
}
#if defined(DSM2)
void init_dsm2(uint32_t port)
{
EXTERNAL_MODULE_ON();
// Timer8
setupPulsesDSM2(EXTERNAL_MODULE);
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(EXTMODULE_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_PinAFConfig(EXTMODULE_GPIO, EXTMODULE_GPIO_PinSource, GPIO_AF_TIM1);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(EXTMODULE_GPIO, &GPIO_InitStructure);
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN ; // Enable DMA2 clock
TIM1->CR1 &= ~TIM_CR1_CEN ;
TIM1->ARR = 44000 ; // 22mS
TIM1->CCR2 = 40000 ; // Update time
TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz
TIM1->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1NP ;
TIM1->CR2 = TIM_CR2_OIS1 ; // O/P idle high
TIM1->BDTR = TIM_BDTR_MOE ; // Enable outputs
TIM1->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0 ; // Force O/P high
TIM1->EGR = 1 ; // Restart
// TIM1->SR &= ~TIM_SR_UIF ; // Clear flag
// TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
TIM1->DIER |= TIM_DIER_CC1DE ; // Enable DMA on CC1 match
TIM1->DCR = 13 ; // DMA to CC1
// TIM1->CR1 = TIM_CR1_OPM ; // Just run once
// Enable the DMA channel here, DMA2 stream 2, channel 7
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits
DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ;
DMA2_Stream2->PAR = CONVERT_PTR_UINT(&TIM1->DMAR);
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
// DMA2_Stream2->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
// DMA2_Stream2->NDTR = 100 ;
DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA
TIM1->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0 ; // Toggle CC1 o/p
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
TIM1->CR1 |= TIM_CR1_CEN ;
NVIC_EnableIRQ(TIM1_CC_IRQn) ;
NVIC_SetPriority(TIM1_CC_IRQn, 7);
}
void disable_dsm2(uint32_t port)
{
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
NVIC_DisableIRQ(TIM1_CC_IRQn) ;
TIM1->DIER &= ~TIM_DIER_CC2IE ;
TIM1->CR1 &= ~TIM_CR1_CEN ;
EXTERNAL_MODULE_OFF();
}
#endif
// PPM output
// Timer 1, channel 1 on PA8 for prototype
// Pin is AF1 function for timer 1
void init_ppm(uint32_t port)
{
EXTERNAL_MODULE_ON();
// Timer1
modulePulsesData[EXTERNAL_MODULE].ppm.ptr = modulePulsesData[EXTERNAL_MODULE].ppm.pulses;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock
configure_pins( EXTMODULE_GPIO_PIN, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_3 | PIN_OS25 | PIN_PUSHPULL ) ;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Enable clock
TIM1->CR1 &= ~TIM_CR1_CEN ;
// setupPulsesPPM() is also configuring registers,
// so it has to be called after the peripheral is enabled
setupPulsesPPM(EXTERNAL_MODULE) ;
TIM1->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++ ;
TIM1->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1 ; // 0.5uS from 30MHz
TIM1->CCER = TIM_CCER_CC3E ;
TIM1->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
TIM1->BDTR = TIM_BDTR_MOE ;
TIM1->EGR = 1 ;
TIM1->DIER = TIM_DIER_UDE ;
TIM1->SR &= ~TIM_SR_UIF ; // Clear flag
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
TIM1->DIER |= TIM_DIER_CC2IE ;
TIM1->DIER |= TIM_DIER_UIE ;
TIM1->CR1 = TIM_CR1_CEN ;
NVIC_EnableIRQ(TIM1_CC_IRQn) ;
NVIC_SetPriority(TIM1_CC_IRQn, 7);
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn) ;
NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 7);
}
void disable_ppm(uint32_t port)
{
NVIC_DisableIRQ(TIM1_CC_IRQn) ;
NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn) ;
TIM1->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE ;
TIM1->CR1 &= ~TIM_CR1_CEN ;
EXTERNAL_MODULE_OFF();
}
#if !defined(SIMU)
extern "C" void TIM1_CC_IRQHandler()
{
TIM1->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear flag
setupPulses(EXTERNAL_MODULE) ;
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) {
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA
TIM1->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
}
#if defined(DSM2)
else if (s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) {
DMA2_Stream2->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 ; // Write ones to clear bits
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
DMA2_Stream2->CR |= DMA_SxCR_EN ; // Enable DMA
TIM1->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
}
#endif
else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
modulePulsesData[EXTERNAL_MODULE].ppm.ptr = modulePulsesData[EXTERNAL_MODULE].ppm.pulses;
TIM1->DIER |= TIM_DIER_UDE ;
TIM1->SR &= ~TIM_SR_UIF ; // Clear this flag
TIM1->DIER |= TIM_DIER_UIE ; // Enable this interrupt
}
else {
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
}
}
extern "C" void TIM1_UP_TIM10_IRQHandler()
{
TIM1->SR &= ~TIM_SR_UIF ; // Clear flag
TIM1->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++ ;
if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) {
TIM1->SR &= ~TIM_SR_CC2IF ; // Clear this flag
TIM1->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
}
}
#endif
+119
View File
@@ -0,0 +1,119 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../pwr.h"
#include "board_horus.h"
extern volatile uint32_t g_tmr10ms;
#define get_tmr10ms() g_tmr10ms
void pwrInit()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Clock enable */
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph_GPIO, ENABLE);
/* GPIO Configuration*/
GPIO_InitStructure.GPIO_Pin = PWR_GPIO_PIN_ON;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PWR_GPIO_PIN_SWITCH;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
// Soft power ON
GPIO_SetBits(PWR_GPIO, PWR_GPIO_PIN_ON);
// Init Module PWR
GPIO_ResetBits(EXTMODULE_GPIO_PWR, EXTMODULE_GPIO_PIN_PWR);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_GPIO_PIN_PWR;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(EXTMODULE_GPIO_PWR, &GPIO_InitStructure);
// TODO while (pwrPressed()) ;
}
void pwrOff()
{
GPIO_ResetBits(PWR_GPIO, PWR_GPIO_PIN_ON);
}
uint32_t pwrPressed()
{
return GPIO_ReadInputDataBit(PWR_GPIO, PWR_GPIO_PIN_SWITCH) == Bit_RESET;
}
#if !defined(BOOT)
uint32_t pwrPressTime = 0;
uint32_t pwrPressedDuration()
{
if (pwrPressTime == 0) {
return 0;
}
else {
return get_tmr10ms() - pwrPressTime;
}
}
uint32_t pwrCheck()
{
if (pwrPressed()) {
if (pwrPressTime == 0) {
pwrPressTime = get_tmr10ms();
}
else {
if (get_tmr10ms() - pwrPressTime > 250) {
return e_power_off;
}
}
}
else {
pwrPressTime = 0;
}
return e_power_on;
}
#endif
File diff suppressed because it is too large Load Diff
+410
View File
@@ -0,0 +1,410 @@
/**
******************************************************************************
* @file stm32f4_discovery_sdio_sd.h
* @author MCD Application Team
* @version V1.0.2
* @date 05-March-2012
* @brief This file contains all the functions prototypes for the SD Card
* stm324xg_eval_sdio_sd driver firmware library.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SDIO_SD_H
#define __SDIO_SD_H
#include "board_horus.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
// #include "stm32f4_discovery.h"
/** @addtogroup Utilities
* @{
*/
/** @addtogroup STM32_EVAL
* @{
*/
/** @addtogroup STM32F4_DISCOVERY
* @{
*/
/** @addtogroup STM32F4_DISCOVERY_SDIO_SD
* @{
*/
/** @defgroup STM32F4_DISCOVERY_SDIO_SD_Exported_Types
* @{
*/
typedef enum
{
/**
* @brief SDIO specific error defines
*/
SD_CMD_CRC_FAIL = (1), /*!< Command response received (but CRC check failed) */
SD_DATA_CRC_FAIL = (2), /*!< Data bock sent/received (CRC check Failed) */
SD_CMD_RSP_TIMEOUT = (3), /*!< Command response timeout */
SD_DATA_TIMEOUT = (4), /*!< Data time out */
SD_TX_UNDERRUN = (5), /*!< Transmit FIFO under-run */
SD_RX_OVERRUN = (6), /*!< Receive FIFO over-run */
SD_START_BIT_ERR = (7), /*!< Start bit not detected on all data signals in widE bus mode */
SD_CMD_OUT_OF_RANGE = (8), /*!< CMD's argument was out of range.*/
SD_ADDR_MISALIGNED = (9), /*!< Misaligned address */
SD_BLOCK_LEN_ERR = (10), /*!< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */
SD_ERASE_SEQ_ERR = (11), /*!< An error in the sequence of erase command occurs.*/
SD_BAD_ERASE_PARAM = (12), /*!< An Invalid selection for erase groups */
SD_WRITE_PROT_VIOLATION = (13), /*!< Attempt to program a write protect block */
SD_LOCK_UNLOCK_FAILED = (14), /*!< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */
SD_COM_CRC_FAILED = (15), /*!< CRC check of the previous command failed */
SD_ILLEGAL_CMD = (16), /*!< Command is not legal for the card state */
SD_CARD_ECC_FAILED = (17), /*!< Card internal ECC was applied but failed to correct the data */
SD_CC_ERROR = (18), /*!< Internal card controller error */
SD_GENERAL_UNKNOWN_ERROR = (19), /*!< General or Unknown error */
SD_STREAM_READ_UNDERRUN = (20), /*!< The card could not sustain data transfer in stream read operation. */
SD_STREAM_WRITE_OVERRUN = (21), /*!< The card could not sustain data programming in stream mode */
SD_CID_CSD_OVERWRITE = (22), /*!< CID/CSD overwrite error */
SD_WP_ERASE_SKIP = (23), /*!< only partial address space was erased */
SD_CARD_ECC_DISABLED = (24), /*!< Command has been executed without using internal ECC */
SD_ERASE_RESET = (25), /*!< Erase sequence was cleared before executing because an out of erase sequence command was received */
SD_AKE_SEQ_ERROR = (26), /*!< Error in sequence of authentication. */
SD_INVALID_VOLTRANGE = (27),
SD_ADDR_OUT_OF_RANGE = (28),
SD_SWITCH_ERROR = (29),
SD_SDIO_DISABLED = (30),
SD_SDIO_FUNCTION_BUSY = (31),
SD_SDIO_FUNCTION_FAILED = (32),
SD_SDIO_UNKNOWN_FUNCTION = (33),
/**
* @brief Standard error defines
*/
SD_INTERNAL_ERROR,
SD_NOT_CONFIGURED,
SD_REQUEST_PENDING,
SD_REQUEST_NOT_APPLICABLE,
SD_INVALID_PARAMETER,
SD_UNSUPPORTED_FEATURE,
SD_UNSUPPORTED_HW,
SD_ERROR,
SD_OK = 0
} SD_Error;
/**
* @brief SDIO Transfer state
*/
typedef enum
{
SD_TRANSFER_OK = 0,
SD_TRANSFER_BUSY = 1,
SD_TRANSFER_ERROR
} SDTransferState;
/**
* @brief SD Card States
*/
typedef enum
{
SD_CARD_READY = ((uint32_t)0x00000001),
SD_CARD_IDENTIFICATION = ((uint32_t)0x00000002),
SD_CARD_STANDBY = ((uint32_t)0x00000003),
SD_CARD_TRANSFER = ((uint32_t)0x00000004),
SD_CARD_SENDING = ((uint32_t)0x00000005),
SD_CARD_RECEIVING = ((uint32_t)0x00000006),
SD_CARD_PROGRAMMING = ((uint32_t)0x00000007),
SD_CARD_DISCONNECTED = ((uint32_t)0x00000008),
SD_CARD_ERROR = ((uint32_t)0x000000FF)
}SDCardState;
/**
* @brief Card Specific Data: CSD Register
*/
typedef struct
{
__IO uint8_t CSDStruct; /*!< CSD structure */
__IO uint8_t SysSpecVersion; /*!< System specification version */
__IO uint8_t Reserved1; /*!< Reserved */
__IO uint8_t TAAC; /*!< Data read access-time 1 */
__IO uint8_t NSAC; /*!< Data read access-time 2 in CLK cycles */
__IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
__IO uint16_t CardComdClasses; /*!< Card command classes */
__IO uint8_t RdBlockLen; /*!< Max. read data block length */
__IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
__IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
__IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
__IO uint8_t DSRImpl; /*!< DSR implemented */
__IO uint8_t Reserved2; /*!< Reserved */
__IO uint32_t DeviceSize; /*!< Device Size */
__IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
__IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
__IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
__IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
__IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
__IO uint8_t EraseGrSize; /*!< Erase group size */
__IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
__IO uint8_t WrProtectGrSize; /*!< Write protect group size */
__IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
__IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
__IO uint8_t WrSpeedFact; /*!< Write speed factor */
__IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
__IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
__IO uint8_t Reserved3; /*!< Reserded */
__IO uint8_t ContentProtectAppli; /*!< Content protection application */
__IO uint8_t FileFormatGrouop; /*!< File format group */
__IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
__IO uint8_t PermWrProtect; /*!< Permanent write protection */
__IO uint8_t TempWrProtect; /*!< Temporary write protection */
__IO uint8_t FileFormat; /*!< File Format */
__IO uint8_t ECC; /*!< ECC code */
__IO uint8_t CSD_CRC; /*!< CSD CRC */
__IO uint8_t Reserved4; /*!< always 1*/
} SD_CSD;
/**
* @brief Card Identification Data: CID Register
*/
typedef struct
{
__IO uint8_t ManufacturerID; /*!< ManufacturerID */
__IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
__IO uint32_t ProdName1; /*!< Product Name part1 */
__IO uint8_t ProdName2; /*!< Product Name part2*/
__IO uint8_t ProdRev; /*!< Product Revision */
__IO uint32_t ProdSN; /*!< Product Serial Number */
__IO uint8_t Reserved1; /*!< Reserved1 */
__IO uint16_t ManufactDate; /*!< Manufacturing Date */
__IO uint8_t CID_CRC; /*!< CID CRC */
__IO uint8_t Reserved2; /*!< always 1 */
} SD_CID;
/**
* @brief SD Card Status
*/
typedef struct
{
__IO uint8_t DAT_BUS_WIDTH;
__IO uint8_t SECURED_MODE;
__IO uint16_t SD_CARD_TYPE;
__IO uint32_t SIZE_OF_PROTECTED_AREA;
__IO uint8_t SPEED_CLASS;
__IO uint8_t PERFORMANCE_MOVE;
__IO uint8_t AU_SIZE;
__IO uint16_t ERASE_SIZE;
__IO uint8_t ERASE_TIMEOUT;
__IO uint8_t ERASE_OFFSET;
} SD_CardStatus;
/**
* @brief SD Card information
*/
typedef struct
{
SD_CSD SD_csd;
SD_CID SD_cid;
uint64_t CardCapacity; /*!< Card Capacity */
uint32_t CardBlockSize; /*!< Card Block Size */
uint16_t RCA;
uint8_t CardType;
} SD_CardInfo;
/**
* @}
*/
/** @defgroup STM32F4_DISCOVERY_SDIO_SD_Exported_Constants
* @{
*/
/**
* @brief SDIO Commands Index
*/
#define SD_CMD_GO_IDLE_STATE ((uint8_t)0)
#define SD_CMD_SEND_OP_COND ((uint8_t)1)
#define SD_CMD_ALL_SEND_CID ((uint8_t)2)
#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< SDIO_SEND_REL_ADDR for SD Card */
#define SD_CMD_SET_DSR ((uint8_t)4)
#define SD_CMD_SDIO_SEN_OP_COND ((uint8_t)5)
#define SD_CMD_HS_SWITCH ((uint8_t)6)
#define SD_CMD_SEL_DESEL_CARD ((uint8_t)7)
#define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8)
#define SD_CMD_SEND_CSD ((uint8_t)9)
#define SD_CMD_SEND_CID ((uint8_t)10)
#define SD_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD Card doesn't support it */
#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12)
#define SD_CMD_SEND_STATUS ((uint8_t)13)
#define SD_CMD_HS_BUSTEST_READ ((uint8_t)14)
#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15)
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16)
#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17)
#define SD_CMD_READ_MULT_BLOCK ((uint8_t)18)
#define SD_CMD_HS_BUSTEST_WRITE ((uint8_t)19)
#define SD_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< SD Card doesn't support it */
#define SD_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< SD Card doesn't support it */
#define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24)
#define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25)
#define SD_CMD_PROG_CID ((uint8_t)26) /*!< reserved for manufacturers */
#define SD_CMD_PROG_CSD ((uint8_t)27)
#define SD_CMD_SET_WRITE_PROT ((uint8_t)28)
#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29)
#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30)
#define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< To set the address of the first write
block to be erased. (For SD card only) */
#define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< To set the address of the last write block of the
continuous range to be erased. (For SD card only) */
#define SD_CMD_ERASE_GRP_START ((uint8_t)35) /*!< To set the address of the first write block to be erased.
(For MMC card only spec 3.31) */
#define SD_CMD_ERASE_GRP_END ((uint8_t)36) /*!< To set the address of the last write block of the
continuous range to be erased. (For MMC card only spec 3.31) */
#define SD_CMD_ERASE ((uint8_t)38)
#define SD_CMD_FAST_IO ((uint8_t)39) /*!< SD Card doesn't support it */
#define SD_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD Card doesn't support it */
#define SD_CMD_LOCK_UNLOCK ((uint8_t)42)
#define SD_CMD_APP_CMD ((uint8_t)55)
#define SD_CMD_GEN_CMD ((uint8_t)56)
#define SD_CMD_NO_CMD ((uint8_t)64)
/**
* @brief Following commands are SD Card Specific commands.
* SDIO_APP_CMD should be sent before sending these commands.
*/
#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< For SD Card only */
#define SD_CMD_SD_APP_STAUS ((uint8_t)13) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< For SD Card only */
#define SD_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< For SD Card only */
#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< For SD Card only */
#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< For SD Card only */
#define SD_CMD_SDIO_RW_DIRECT ((uint8_t)52) /*!< For SD I/O Card only */
#define SD_CMD_SDIO_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O Card only */
/**
* @brief Following commands are SD Card Specific security commands.
* SDIO_APP_CMD should be sent before sending these commands.
*/
#define SD_CMD_SD_APP_GET_MKB ((uint8_t)43) /*!< For SD Card only */
#define SD_CMD_SD_APP_GET_MID ((uint8_t)44) /*!< For SD Card only */
#define SD_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45) /*!< For SD Card only */
#define SD_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46) /*!< For SD Card only */
#define SD_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47) /*!< For SD Card only */
#define SD_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48) /*!< For SD Card only */
#define SD_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18) /*!< For SD Card only */
#define SD_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /*!< For SD Card only */
#define SD_CMD_SD_APP_SECURE_ERASE ((uint8_t)38) /*!< For SD Card only */
#define SD_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49) /*!< For SD Card only */
#define SD_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48) /*!< For SD Card only */
/* Uncomment the following line to select the SDIO Data transfer mode */
#if !defined (SD_DMA_MODE) && !defined (SD_POLLING_MODE)
#define SD_DMA_MODE ((uint32_t)0x00000000)
/*#define SD_POLLING_MODE ((uint32_t)0x00000002)*/
#endif
/**
* @brief SD detection on its memory slot
*/
#define SD_PRESENT ((uint8_t)0x01)
#define SD_NOT_PRESENT ((uint8_t)0x00)
/**
* @brief Supported SD Memory Cards
*/
#define SDIO_STD_CAPACITY_SD_CARD_V1_1 ((uint32_t)0x00000000)
#define SDIO_STD_CAPACITY_SD_CARD_V2_0 ((uint32_t)0x00000001)
#define SDIO_HIGH_CAPACITY_SD_CARD ((uint32_t)0x00000002)
#define SDIO_MULTIMEDIA_CARD ((uint32_t)0x00000003)
#define SDIO_SECURE_DIGITAL_IO_CARD ((uint32_t)0x00000004)
#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((uint32_t)0x00000005)
#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((uint32_t)0x00000006)
#define SDIO_HIGH_CAPACITY_MMC_CARD ((uint32_t)0x00000007)
/**
* @}
*/
/** @defgroup STM32F4_DISCOVERY_SDIO_SD_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup STM32F4_DISCOVERY_SDIO_SD_Exported_Functions
* @{
*/
void SD_DeInit(void);
SD_Error SD_Init(void);
SDTransferState SD_GetStatus(void);
SDCardState SD_GetState(void);
uint8_t SD_Detect(void);
SD_Error SD_PowerON(void);
SD_Error SD_PowerOFF(void);
SD_Error SD_InitializeCards(void);
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo);
SD_Error SD_GetCardStatus(SD_CardStatus *cardstatus);
SD_Error SD_EnableWideBusOperation(uint32_t WideMode);
SD_Error SD_SelectDeselect(uint32_t addr);
SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize);
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_ReadMultiBlocksFIXED(uint8_t *readbuff, uint32_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize);
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteMultiBlocksFIXED(uint8_t *writebuff, uint32_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
SDTransferState SD_GetTransferState(void);
SD_Error SD_StopTransfer(void);
SD_Error SD_Erase(uint32_t startaddr, uint32_t endaddr);
SD_Error SD_SendStatus(uint32_t *pcardstatus);
SD_Error SD_SendSDStatus(uint32_t *psdstatus);
SD_Error SD_ProcessIRQSrc(void);
void SD_ProcessDMAIRQ(void);
SD_Error SD_WaitReadOperation(void);
SD_Error SD_WaitWriteOperation(void);
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4_DISCOVERY_SDIO_SD_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+445
View File
@@ -0,0 +1,445 @@
#include "board_horus.h"
#define SDRAM_MEMORY_WIDTH FMC_SDMemory_Width_16b
#define SDRAM_CAS_LATENCY FMC_CAS_Latency_3
#define SDCLOCK_PERIOD FMC_SDClock_Period_2
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
/**
* @brief FMC SDRAM Mode definition register defines
*/
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
/**
* @brief FMC SDRAM Memory Read Burst feature
*/
#define SDRAM_READBURST FMC_Read_Burst_Disable
static void __Delay(__IO uint32_t nCount)
{
__IO uint32_t index = 0;
for(index = (100000 * nCount); index != 0; index--)
{
}
}
/**
* @brief Configures all SDRAM memory I/Os pins.
* @param None.
* @retval None.
*/
void SDRAM_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD |
RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG|RCC_AHB1Periph_GPIOH, ENABLE);
/*-- GPIOs Configuration -----------------------------------------------------*/
/*
+-------------------+--------------------+--------------------+--------------------+
+ SDRAM pins assignment +
+-------------------+--------------------+--------------------+--------------------+
| PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
| PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
| PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG8 <-> FMC_SDCLK |
| PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS |
| PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 |--------------------+
| PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 |
| PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS |
+-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
| PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
| PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
| PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
+-------------------+--------------------+--------------------+
| PB5 <-> FMC_SDCKE1|
| PB6 <-> FMC_SDNE1 |
| PH5 <-> FMC_SDNWE |///////
+-------------------+
*/
/* Common GPIO configuration */
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_NOPULL;
/* GPIOB configuration */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5 , GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* GPIOC configuration */
GPIO_PinAFConfig(GPIOH, GPIO_PinSource5 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOH, GPIO_PinSource6 , GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOH, &GPIO_InitStructure);
/* GPIOD configuration */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 |
GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* GPIOE configuration */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_7 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* GPIOF configuration */
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource11 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |
GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* GPIOG configuration */
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource8 , GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource15 , GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 |
GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_15;
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
/**
* @brief Executes the SDRAM memory initialization sequence.
* @param None.
* @retval None.
*/
void SDRAM_InitSequence(void)
{
FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
uint32_t tmpr = 0;
uint32_t timeout = SDRAM_TIMEOUT;
/* Step 3 --------------------------------------------------------------------*/
/* Configure a clock configuration enable command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0))
{
timeout--;
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 4 --------------------------------------------------------------------*/
/* Insert 100 ms delay */
__Delay(10);
/* Step 5 --------------------------------------------------------------------*/
/* Configure a PALL (precharge all) command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0))
{
timeout--;
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 6 --------------------------------------------------------------------*/
/* Configure a Auto-Refresh command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 8;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0))
{
timeout--;
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 7 --------------------------------------------------------------------*/
/* Program the external memory mode register */
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
/* Configure a load Mode register command*/
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr;
/* Wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0))
{
timeout--;
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 8 --------------------------------------------------------------------*/
/* Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
FMC_SetRefreshCount(1385);
/* Wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0))
{
timeout--;
}
}
/**
* @brief Executes the SDRAM memory initialization sequence.
* @param None.
* @retval None.
*/
void SDRAMTest_InitSequence(void)
{
FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
uint32_t tmpr = 0;
/* Step 3 --------------------------------------------------------------------*/
/* Configure a clock configuration enable command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 4 --------------------------------------------------------------------*/
/* Insert 100 ms delay */
__Delay(10);
/* Step 5 --------------------------------------------------------------------*/
/* Configure a PALL (precharge all) command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 6 --------------------------------------------------------------------*/
/* Configure a Auto-Refresh command */
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 4;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the first command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the second command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 7 --------------------------------------------------------------------*/
/* Program the external memory mode register */
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
/* Configure a load Mode register command*/
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr;
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
/* Send the command */
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
/* Step 8 --------------------------------------------------------------------*/
/* Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
FMC_SetRefreshCount(1386);
/* Wait until the SDRAM controller is ready */
while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
}
void SDRAM_Init(void)
{
FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure;
FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure;
/* GPIO configuration for FMC SDRAM bank */
SDRAM_GPIOConfig();
/* Enable FMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
/* FMC Configuration ---------------------------------------------------------*/
/* FMC SDRAM Bank configuration */
/* Timing configuration for 90 Mhz of SD clock frequency (168Mhz/2) */
/* TMRD: 2 Clock cycles */
FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
/* TXSR: min=70ns (7x11.11ns) */
FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;
/* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
/* TRC: min=70 (7x11.11ns) */
FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;
/* TWR: min=1+ 7ns (1+1x11.11ns) */
FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
/* TRP: 20ns => 2x11.11ns */
FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
/* TRCD: 20ns => 2x11.11ns */
FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
/* FMC SDRAM control configuration */
FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM;
/* Row addressing: [7:0] */
FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
/* Column addressing: [11:0] */
FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = SDRAM_MEMORY_WIDTH;
FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
FMC_SDRAMInitStructure.FMC_CASLatency = SDRAM_CAS_LATENCY;
FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
FMC_SDRAMInitStructure.FMC_SDClockPeriod = SDCLOCK_PERIOD;
FMC_SDRAMInitStructure.FMC_ReadBurst = SDRAM_READBURST;
FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_0;
FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
/* FMC SDRAM bank initialization */
FMC_SDRAMInit(&FMC_SDRAMInitStructure);
/* FMC SDRAM device initialization sequence */
SDRAMTest_InitSequence();
}
void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize)
{
__IO uint32_t write_pointer = (uint32_t)uwWriteAddress;
FMC_SDRAMWriteProtectionConfig(FMC_Bank1_SDRAM, DISABLE);
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
for (; uwBufferSize != 0; uwBufferSize--)
{
*(uint32_t *) (SDRAM_BANK_ADDR + write_pointer) = *pBuffer++;
write_pointer += 4;
}
}
void SDRAM_ReadBuffer(uint32_t* pBuffer, uint32_t uwReadAddress, uint32_t uwBufferSize)
{
__IO uint32_t write_pointer = (uint32_t)uwReadAddress;
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET)
{
}
for(; uwBufferSize != 0x00; uwBufferSize--)
{
*pBuffer++ = *(__IO uint32_t *)(SDRAM_BANK_ADDR + write_pointer );
write_pointer += 4;
}
}
+166
View File
@@ -0,0 +1,166 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
uint8_t serial2Mode = 0;
Fifo<512> serial2TxFifo;
extern Fifo<512> telemetryFifo;
extern Fifo<32> sbusFifo;
void uart3Setup(unsigned int baudrate)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(SERIAL_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_PinAFConfig(SERIAL_GPIO, SERIAL_GPIO_PinSource_RX, SERIAL_GPIO_AF);
GPIO_PinAFConfig(SERIAL_GPIO, SERIAL_GPIO_PinSource_TX, SERIAL_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = SERIAL_GPIO_PIN_TX | SERIAL_GPIO_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(SERIAL_RCC_APB1Periph_USART, ENABLE);
USART_InitStructure.USART_BaudRate = baudrate;
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_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(SERIAL_USART, &USART_InitStructure);
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
}
void serial2Init(unsigned int mode, unsigned int protocol)
{
USART_DeInit(SERIAL_USART);
serial2Mode = mode;
switch (mode) {
case UART_MODE_TELEMETRY_MIRROR:
uart3Setup(FRSKY_SPORT_BAUDRATE);
break;
#if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI))
case UART_MODE_DEBUG:
uart3Setup(DEBUG_BAUDRATE);
break;
#endif
case UART_MODE_TELEMETRY:
if (protocol == PROTOCOL_FRSKY_D_SECONDARY) {
uart3Setup(FRSKY_D_BAUDRATE);
}
break;
}
}
void serial2Putc(char c)
{
while (serial2TxFifo.isFull());
serial2TxFifo.push(c);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE);
}
void serial2SbusInit()
{
uart3Setup(100000);
SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ;
}
void serial2Stop()
{
USART_DeInit(SERIAL_USART);
}
uint8_t serial2TracesEnabled()
{
return 1; // (serial2Mode == 0);
}
#if !defined(SIMU)
extern "C" void SERIAL_USART_IRQHandler(void)
{
// Send
if (USART_GetITStatus(SERIAL_USART, USART_IT_TXE) != RESET) {
uint8_t txchar;
if (serial2TxFifo.pop(txchar)) {
/* Write one byte to the transmit data register */
USART_SendData(SERIAL_USART, txchar);
}
else {
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
}
}
// Receive
uint32_t status = SERIAL_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
uint8_t data = SERIAL_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
switch (serial2Mode) {
case UART_MODE_TELEMETRY:
telemetryFifo.push(data);
break;
case UART_MODE_SBUS_TRAINER:
sbusFifo.push(data);
break;
#if defined(CLI)
case UART_MODE_DEBUG:
cliRxFifo.push(data);
break;
#endif
}
}
status = SERIAL_USART->SR;
}
}
#endif
+170
View File
@@ -0,0 +1,170 @@
/*
*****************************************************************************
**
** File : stm32f4_flash.ld
**
** Abstract : Linker script for STM32F407 Device with
** 0.5MByte FLASH, 128KByte SRAM, 64KByte CCM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of 128K SRAM */
_heap_end = 0x20020000; /* end of 128K SRAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Main_Stack_Size = 1024; /* required amount of stack for interrupt stack (Main stack) */
/* Main stack end */
_main_stack_start = _estack - _Main_Stack_Size;
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
SDRAM(xrw) : ORIGIN = 0xD0000000, LENGTH = 8192K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
/* The program code and other data goes into FLASH */
.text :
{
FILL(0xFFFF)
CREATE_OBJECT_SYMBOLS
KEEP(*(.isr_vector)) /* Startup code */
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Main_Stack_Size;
. = ALIGN(4);
} >RAM
/* MEMORY_bank1 section, code must be located here explicitly */
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
.sdram (NOLOAD) :
{
*(.sdram)
*(.sdram*)
*(.sdram_rodata)
*(.sdram_rodata*)
} >SDRAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
+569
View File
@@ -0,0 +1,569 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @version V1.1.0
* @date 21-March-2015
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
* This file contains the system clock configuration for STM32F4xx devices,
* and is generated by the clock configuration tool
* stm32f4xx_Clock_Configuration_V1.1.0.xls
*
* 1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
* and Divider factors, AHB/APBx prescalers and Flash settings),
* depending on the configuration made in the clock xls tool.
* This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* 2. After each device reset the HSI (16 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to
* configure the system clock before to branch to main program.
*
* 3. If the system clock source selected by user fails to startup, the SystemInit()
* function will do nothing and HSI still used as system clock source. User can
* add some code to deal with this issue inside the SetSysClock() function.
*
* 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define
* in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
* through PLL, and you are using different crystal you have to adapt the HSE
* value to your own configuration.
*
* 5. This file configures the system clock as follows:
*=============================================================================
*=============================================================================
* Supported STM32F40xx/41xx/427x/437x devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 12000000
*-----------------------------------------------------------------------------
* PLL_M | 12
*-----------------------------------------------------------------------------
* PLL_N | 336
*-----------------------------------------------------------------------------
* PLL_P | 2
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | NA
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 5
*-----------------------------------------------------------------------------
* Prefetch Buffer | ON
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Enabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f4xx_system
* @{
*/
/** @addtogroup STM32F4xx_System_Private_Includes
* @{
*/
#include "stm32f4xx.h"
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use external SRAM mounted
on STM324xG_EVAL/STM324x7I_EVAL board as data memory */
/* #define DATA_IN_ExtSRAM */
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/******************************************************************************/
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 12
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Variables
* @{
*/
uint32_t SystemCoreClock = 180000000;
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
* @{
*/
static void SetSysClock(void);
#ifdef DATA_IN_ExtSRAM
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemFrequency variable.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
void SDRAM_Init();
void FMC_SDRAMWriteProtectionConfig(uint32_t SDRAM_Bank, FunctionalState NewState);
SDRAM_Init(); // calls SDRAM_GPIOConfig()
FMC_SDRAMWriteProtectionConfig(((uint32_t)0x00000001), DISABLE);
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings ----------------------------------*/
SetSysClock();
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
// SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
extern uint32_t g_pfnVectors ;
SCB->VTOR = (uint32_t) &g_pfnVectors ; /* Vector Table Relocation in Internal FLASH */
#endif
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
* 25 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
SYSCLK = PLL_VCO / PLL_P
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0)
{
/* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
else
{
/* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
SystemCoreClock = pllvco/pllp;
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK frequency --------------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK frequency */
SystemCoreClock >>= tmp;
}
/**
* @brief Configures the System clock source, PLL Multiplier and Divider factors,
* AHB/APBx prescalers and Flash settings
* @Note This function should be called only once the RCC clock configuration
* is reset to the default reset state (done in SystemInit() function).
* @param None
* @retval None
*/
static void SetSysClock(void)
{
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_VOS;
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
/**
* @brief Setup the external memory controller. Called in startup_stm32f4xx.s
* before jump to __main
* @param None
* @retval None
*/
#ifdef DATA_IN_ExtSRAM
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external SRAM mounted on STM324xG_EVAL/STM324x7I_EVAL board
* This SRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
/*-- GPIOs Configuration -----------------------------------------------------*/
/*
+-------------------+--------------------+------------------+------------------+
+ SRAM pins assignment +
+-------------------+--------------------+------------------+------------------+
| PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
| PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
| PD4 <-> FSMC_NOE | PE2 <-> FSMC_A23 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
| PD5 <-> FSMC_NWE | PE3 <-> FSMC_A19 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
| PD8 <-> FSMC_D13 | PE4 <-> FSMC_A20 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
| PD9 <-> FSMC_D14 | PE5 <-> FSMC_A21 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
| PD10 <-> FSMC_D15 | PE6 <-> FSMC_A22 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
| PD11 <-> FSMC_A16 | PE7 <-> FSMC_D4 | PF13 <-> FSMC_A7 |------------------+
| PD12 <-> FSMC_A17 | PE8 <-> FSMC_D5 | PF14 <-> FSMC_A8 |
| PD13 <-> FSMC_A18 | PE9 <-> FSMC_D6 | PF15 <-> FSMC_A9 |
| PD14 <-> FSMC_D0 | PE10 <-> FSMC_D7 |------------------+
| PD15 <-> FSMC_D1 | PE11 <-> FSMC_D8 |
+-------------------| PE12 <-> FSMC_D9 |
| PE13 <-> FSMC_D10 |
| PE14 <-> FSMC_D11 |
| PE15 <-> FSMC_D12 |
+--------------------+
*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Connect PDx pins to FSMC Alternate function */
GPIOD->AFR[0] = 0x00cc00cc;
GPIOD->AFR[1] = 0xcccccccc;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xaaaa0a0a;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xffff0f0f;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FSMC Alternate function */
GPIOE->AFR[0] = 0xcccccccc;
GPIOE->AFR[1] = 0xcccccccc;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xaaaaaaaa;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xffffffff;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FSMC Alternate function */
GPIOF->AFR[0] = 0x00cccccc;
GPIOF->AFR[1] = 0xcccc0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xaa000aaa;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xff000fff;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FSMC Alternate function */
GPIOG->AFR[0] = 0x00cccccc;
GPIOG->AFR[1] = 0x000000c0;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00080aaa;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x000c0fff;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FSMC Configuration ------------------------------------------------------*/
/* Enable the FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[2] = 0x00001011;
FSMC_Bank1->BTCR[3] = 0x00000201;
FSMC_Bank1E->BWTR[2] = 0x0fffffff;
/*
Bank1_SRAM2 is configured as follow:
p.FSMC_AddressSetupTime = 1;
p.FSMC_AddressHoldTime = 0;
p.FSMC_DataSetupTime = 2;
p.FSMC_BusTurnAroundDuration = 0;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
*/
}
#endif /* DATA_IN_ExtSRAM */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,137 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
extern Fifo<512> telemetryFifo;
void telemetryPortInit(uint32_t baudrate)
{
if (baudrate == 0) {
USART_DeInit(TELEMETRY_USART);
return;
}
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(TELEMETRY_RCC_AHB1Periph_GPIO, ENABLE);
GPIO_PinAFConfig(TELEMETRY_GPIO, TELEMETRY_GPIO_PinSource_RX, TELEMETRY_GPIO_AF);
GPIO_PinAFConfig(TELEMETRY_GPIO, TELEMETRY_GPIO_PinSource_TX, TELEMETRY_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = TELEMETRY_GPIO_PIN_TX | TELEMETRY_GPIO_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TELEMETRY_GPIO_PIN_DIR;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TELEMETRY_GPIO_DIR, &GPIO_InitStructure);
GPIO_ResetBits(TELEMETRY_GPIO_DIR, TELEMETRY_GPIO_PIN_DIR);
RCC_APB1PeriphClockCmd(TELEMETRY_RCC_APB1Periph_USART, ENABLE);
USART_InitStructure.USART_BaudRate = baudrate;
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_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(TELEMETRY_USART, &USART_InitStructure);
USART_Cmd(TELEMETRY_USART, ENABLE);
USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE);
NVIC_SetPriority(TELEMETRY_USART_IRQn, 6);
NVIC_EnableIRQ(TELEMETRY_USART_IRQn);
}
struct SportTxBuffer
{
uint8_t *ptr;
uint32_t count;
} sportTxBuffer;
void sportSendBuffer(uint8_t *buffer, uint32_t count)
{
sportTxBuffer.ptr = buffer ;
sportTxBuffer.count = count ;
TELEMETRY_USART->CR1 &= ~USART_CR1_RE ; // turn off receiver
TELEMETRY_USART->CR1 |= USART_CR1_TXEIE ;
}
#if !defined(SIMU)
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
extern "C" void TELEMETRY_USART_IRQHandler()
{
uint32_t status;
uint8_t data;
status = TELEMETRY_USART->SR;
if (status & USART_SR_TXE) {
if (sportTxBuffer.count) {
TELEMETRY_USART->DR = *sportTxBuffer.ptr++;
if (--sportTxBuffer.count == 0) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TXEIE; // stop Tx interrupt
TELEMETRY_USART->CR1 |= USART_CR1_TCIE; // enable complete interrupt
}
}
}
if ((status & USART_SR_TC) && (TELEMETRY_USART->CR1 & USART_CR1_TCIE)) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TCIE ; // stop Complete interrupt
TELEMETRY_USART->CR1 |= USART_CR1_RE ;
while (status & (USART_FLAG_RXNE)) {
status = TELEMETRY_USART->DR;
status = TELEMETRY_USART->SR ;
}
}
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
data = TELEMETRY_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
telemetryFifo.push(data);
}
status = TELEMETRY_USART->SR;
}
}
#endif
+171
View File
@@ -0,0 +1,171 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "../../opentx.h"
extern Fifo<32> sbusFifo;
#define setupTrainerPulses() setupPulsesPPM(TRAINER_MODULE)
// Trainer PPM output PB4, Timer 3 channel 1
void init_trainer_ppm()
{
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ;
configure_pins( TRAINER_GPIO_PIN_OUT, PIN_PERIPHERAL | PIN_PORTB | PIN_PER_2 | PIN_OS25 | PIN_PUSHPULL ) ;
configure_pins( TRAINER_GPIO_PIN_IN, PIN_PORTB | PIN_INPUT ) ;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ;
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN ;
// setupTrainerPulses() is also configuring registers,
// so it has to be called after the peripheral is enabled
setupTrainerPulses() ;
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++ ;
TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1 ; // 0.5uS
TRAINER_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE ; // PWM mode 1
TRAINER_TIMER->BDTR = TIM_BDTR_MOE ;
TRAINER_TIMER->EGR = 1 ;
TRAINER_TIMER->SR &= ~TIM_SR_UIF ; // Clear flag
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF ; // Clear flag
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE ;
TRAINER_TIMER->DIER |= TIM_DIER_UIE ;
TRAINER_TIMER->CR1 = TIM_CR1_CEN ;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn) ;
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
// TODO - testing
void stop_trainer_ppm()
{
configure_pins( TRAINER_GPIO_PIN_OUT, PIN_INPUT | PIN_PORTB ) ; // Pin as input
TRAINER_TIMER->DIER = 0 ; // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN ; // Stop counter
NVIC_DisableIRQ(TRAINER_TIMER_IRQn) ; // Stop Interrupt
}
void set_trainer_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
{
TRAINER_TIMER->CCR1 = idleTime;
TRAINER_TIMER->CCR4 = delay;
TRAINER_TIMER->CCER = TIM_CCER_CC4E | (positive ? TIM_CCER_CC4P : 0);
}
// Trainer capture, PC8, Timer 3 channel 3
void init_trainer_capture()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = TRAINER_GPIO_PIN_IN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_GPIO_PinSource_IN, TRAINER_GPIO_AF);
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ;
TRAINER_TIMER->ARR = 0xFFFF ;
TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1 ; // 0.5uS
TRAINER_TIMER->CR2 = 0 ;
TRAINER_TIMER->CCMR2 = TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0 ;
TRAINER_TIMER->CCER = TIM_CCER_CC3E ;
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF ; // Clear flags
TRAINER_TIMER->DIER |= TIM_DIER_CC3IE ;
TRAINER_TIMER->CR1 = TIM_CR1_CEN ;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn) ;
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_capture()
{
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN ; // Stop counter
TRAINER_TIMER->DIER = 0; // Stop Interrupt
NVIC_DisableIRQ(TRAINER_TIMER_IRQn) ; // Stop Interrupt
}
#if !defined(SIMU)
extern "C" void TIM3_IRQHandler()
{
uint16_t capture = 0;
bool doCapture = false ;
// What mode? in or out?
if ( (TRAINER_TIMER->DIER & TIM_DIER_CC3IE ) && ( TRAINER_TIMER->SR & TIM_SR_CC3IF ) ) {
// capture mode on trainer jack
capture = TRAINER_TIMER->CCR3 ;
doCapture = true;
}
if ( ( TRAINER_TIMER->DIER & TIM_DIER_CC2IE ) && ( TRAINER_TIMER->SR & TIM_SR_CC2IF ) ) {
// capture mode on heartbeat pin (external module)
capture = TRAINER_TIMER->CCR2 ;
doCapture = true ;
}
if (doCapture) {
captureTrainerPulses(capture);
}
// PPM out compare interrupt
if ( ( TRAINER_TIMER->DIER & TIM_DIER_CC1IE ) && ( TRAINER_TIMER->SR & TIM_SR_CC1IF ) ) {
// compare interrupt
TRAINER_TIMER->DIER &= ~TIM_DIER_CC1IE ; // stop this interrupt
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF ; // Clear flag
setupTrainerPulses() ;
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->DIER |= TIM_DIER_UDE ;
TRAINER_TIMER->SR &= ~TIM_SR_UIF ; // Clear this flag
TRAINER_TIMER->DIER |= TIM_DIER_UIE ; // Enable this interrupt
}
// PPM out update interrupt
if ( (TRAINER_TIMER->DIER & TIM_DIER_UIE) && ( TRAINER_TIMER->SR & TIM_SR_UIF ) ) {
TRAINER_TIMER->SR &= ~TIM_SR_UIF ; // Clear flag
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++ ;
if ( *trainerPulsesData.ppm.ptr == 0 ) {
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF ; // Clear this flag
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE ; // Enable this interrupt
}
}
}
#endif
+149
View File
@@ -0,0 +1,149 @@
/**
******************************************************************************
* @file usb_bsp.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file is responsible to offer board support package and is
* configurable by user.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_bsp.h"
#include "board_horus.h"
#include "usbd_conf.h"
extern uint32_t SystemCoreClock;
/**
* @brief USB_OTG_BSP_Init
* Initilizes BSP configurations
* @param None
* @retval None
*/
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(USB_RCC_AHB1Periph_GPIO, ENABLE);
/* Configure DM and DP Pins */
GPIO_InitStructure.GPIO_Pin = USB_GPIO_PIN_DM | USB_GPIO_PIN_DP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(USB_GPIO, &GPIO_InitStructure);
GPIO_PinAFConfig(USB_GPIO, USB_GPIO_PinSource_DM, USB_GPIO_AF);
GPIO_PinAFConfig(USB_GPIO, USB_GPIO_PinSource_DP, USB_GPIO_AF);
/* Configure VBUS Pin */
GPIO_InitStructure.GPIO_Pin = USB_GPIO_PIN_VBUS;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(USB_GPIO, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ;
}
void USB_OTG_BSP_Deinit(USB_OTG_CORE_HANDLE *pdev)
{
//nothing to do
}
/**
* @brief USB_OTG_BSP_EnableInterrupt
* Enable USB Global interrupt
* @param None
* @retval None
*/
void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief USB_OTG_BSP_DisableInterrupt
* Disable USB Global interrupt
* @param None
* @retval None
*/
void USB_OTG_BSP_DisableInterrupt(USB_OTG_CORE_HANDLE *pdev)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief USB_OTG_BSP_uDelay
* This function provides delay time in micro sec
* @param usec : Value of delay required in micro sec
* @retval None
*/
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
uint32_t count = 0;
const uint32_t utime = ((SystemCoreClock/1000000) * usec);
do
{
if ( ++count > utime )
{
return ;
}
}
while (1);
}
/**
* @brief USB_OTG_BSP_mDelay
* This function provides delay time in milli sec
* @param msec : Value of delay required in milli sec
* @retval None
*/
void USB_OTG_BSP_mDelay (const uint32_t msec)
{
USB_OTG_BSP_uDelay(msec * 1000);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+171
View File
@@ -0,0 +1,171 @@
/**
******************************************************************************
* @file usb_conf.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief General low level driver configuration
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF__H__
#define __USB_CONF__H__
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
/* USB Core and PHY interface configuration.
Tip: To avoid modifying these defines each time you need to change the USB
configuration, you can declare the needed define in your toolchain
compiler preprocessor.
*/
/****************** USB OTG FS PHY CONFIGURATION *******************************
* The USB OTG FS Core supports one on-chip Full Speed PHY.
*
* The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor
* when FS core is used.
*******************************************************************************/
#ifndef USE_USB_OTG_FS
#define USE_USB_OTG_FS
#endif /* USE_USB_OTG_FS */
#ifdef USE_USB_OTG_FS
#define USB_OTG_FS_CORE
#endif
/*******************************************************************************
* FIFO Size Configuration in Device mode
*
* (i) Receive data FIFO size = RAM for setup packets +
* OUT endpoint control information +
* data OUT packets + miscellaneous
* Space = ONE 32-bits words
* --> RAM for setup packets = 10 spaces
* (n is the nbr of CTRL EPs the device core supports)
* --> OUT EP CTRL info = 1 space
* (one space for status information written to the FIFO along with each
* received packet)
* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
* (MINIMUM to receive packets)
* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
* (if high-bandwidth EP is enabled or multiple isochronous EPs)
* --> miscellaneous = 1 space per OUT EP
* (one space for transfer complete status information also pushed to the
* FIFO with each endpoint's last packet)
*
* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
* that particular IN EP. More space allocated in the IN EP Tx FIFO results
* in a better performance on the USB and can hide latencies on the AHB.
*
* (iii) TXn min size = 16 words. (n : Transmit FIFO index)
* (iv) When a TxFIFO is not used, the Configuration should be as follows:
* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txm can use the space allocated for Txn.
* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txn should be configured with the minimum space of 16 words
* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
* (vi) In HS case12 FIFO locations should be reserved for internal DMA registers
* so total FIFO size should be 1012 Only instead of 1024
*******************************************************************************/
/****************** USB OTG FS CONFIGURATION **********************************/
#ifdef USB_OTG_FS_CORE
#define RX_FIFO_FS_SIZE 128
#define TX0_FIFO_FS_SIZE 64
#define TX1_FIFO_FS_SIZE 128
#define TX2_FIFO_FS_SIZE 0
#define TX3_FIFO_FS_SIZE 0
// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
#endif
/****************** USB OTG MISC CONFIGURATION ********************************/
#define VBUS_SENSING_ENABLED
/****************** USB OTG MODE CONFIGURATION ********************************/
//#define USE_HOST_MODE
#define USE_DEVICE_MODE
//#define USE_OTG_MODE
#ifndef USB_OTG_FS_CORE
#ifndef USB_OTG_HS_CORE
#error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
#endif
#endif
#ifndef USE_DEVICE_MODE
#ifndef USE_HOST_MODE
#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
#endif
#endif
#ifndef USE_USB_OTG_HS
#ifndef USE_USB_OTG_FS
#error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
#endif
#else //USE_USB_OTG_HS
#ifndef USE_ULPI_PHY
#ifndef USE_EMBEDDED_PHY
#error "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined"
#endif
#endif
#endif
/****************** C Compilers dependant keywords ****************************/
/* In HS mode and when the DMA is used, all variables and data structures dealing
with the DMA during the transaction process should be 4-bytes aligned */
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined (__GNUC__) /* GNU Compiler */
#define __ALIGN_END __attribute__ ((aligned (4)))
#define __ALIGN_BEGIN
#else
#define __ALIGN_END
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#elif defined (__TASKING__) /* TASKING Compiler */
#define __ALIGN_BEGIN __align(4)
#endif /* __CC_ARM */
#endif /* __GNUC__ */
#else
#define __ALIGN_BEGIN
#define __ALIGN_END
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if !defined(__packed)
#if defined (__CC_ARM) /* ARM Compiler */
#define __packed __packed
#elif defined (__ICCARM__) /* IAR Compiler */
#define __packed __packed
#elif defined ( __GNUC__ ) /* GNU Compiler */
#define __packed __attribute__ ((__packed__))
#elif defined (__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __CC_ARM */
#endif
#endif //__USB_CONF__H__
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+85
View File
@@ -0,0 +1,85 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*/
#include "board_horus.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h"
int usbPlugged(void)
{
// debounce
static uint8_t debounced_state = 0;
static uint8_t last_state = 0;
if (GPIO_ReadInputDataBit(USB_GPIO, USB_GPIO_PIN_VBUS)) {
if (last_state) {
debounced_state = 1;
}
last_state = 1;
}
else {
if (!last_state) {
debounced_state = 0;
}
last_state = 0;
}
return debounced_state;
}
USB_OTG_CORE_HANDLE USB_OTG_dev;
void OTG_FS_IRQHandler(void)
{
USBD_OTG_ISR_Handler(&USB_OTG_dev);
}
void usbInit(void)
{
#if defined(USB_JOYSTICK)
// initialize USB as HID device
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb);
#elif defined(USB_SERIAL)
// initialize USB as CDC device (virtual serial port)
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
#elif defined(USB_MASS_STORAGE)
// initialize USB as MSC device
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_MSC_cb, &USR_cb);
#endif
}
void usbDeInit(void)
{
USBD_DeInit(&USB_OTG_dev);
}
+222
View File
@@ -0,0 +1,222 @@
/**
******************************************************************************
* @file usbd_cdc_vcp.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Generic media access Layer.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#pragma data_alignment = 4
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
#include "opentx.h"
extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* These are external variables imported from CDC core to be used for IN
transfer management. */
extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
These data will be sent over USB IN endpoint
in the CDC core functions. */
extern volatile uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
start address when writing received data
in the buffer APP_Rx_Buffer. */
extern volatile uint32_t APP_Rx_ptr_out;
/* Private function prototypes -----------------------------------------------*/
static uint16_t VCP_Init (void);
static uint16_t VCP_DeInit (void);
static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len);
// static uint16_t VCP_COMConfig(uint8_t Conf);
CDC_IF_Prop_TypeDef VCP_fops =
{
VCP_Init,
VCP_DeInit,
VCP_Ctrl,
0,
VCP_DataRx
};
} // extern "C"
bool cdcConnected = false;
/* Private functions ---------------------------------------------------------*/
/**
* @brief VCP_Init
* Initializes the Media on the STM32
* @param None
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_Init(void)
{
cdcConnected = true;
return USBD_OK;
}
/**
* @brief VCP_DeInit
* DeInitializes the Media on the STM32
* @param None
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_DeInit(void)
{
cdcConnected = false;
return USBD_OK;
}
/**
* @brief VCP_Ctrl
* Manage the CDC class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
{
switch (Cmd)
{
case SEND_ENCAPSULATED_COMMAND:
/* Not needed for this driver */
break;
case GET_ENCAPSULATED_RESPONSE:
/* Not needed for this driver */
break;
case SET_COMM_FEATURE:
/* Not needed for this driver */
break;
case GET_COMM_FEATURE:
/* Not needed for this driver */
break;
case CLEAR_COMM_FEATURE:
/* Not needed for this driver */
break;
case SET_LINE_CODING:
/* Not needed for this driver */
break;
case GET_LINE_CODING:
/* Not needed for this driver */
break;
case SET_CONTROL_LINE_STATE:
/* Not needed for this driver */
break;
case SEND_BREAK:
/* Not needed for this driver */
break;
default:
break;
}
return USBD_OK;
}
// some debug vars
uint16_t usbWraps = 0;
uint16_t charsWritten = 0;
void usbSerialPutc(uint8_t c)
{
if (!cdcConnected) return;
uint32_t txDataLen;
do {
txDataLen = APP_RX_DATA_SIZE + APP_Rx_ptr_in - APP_Rx_ptr_out;
if (txDataLen >= APP_RX_DATA_SIZE) {
txDataLen -= APP_RX_DATA_SIZE;
}
} while (txDataLen >= (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE));
APP_Rx_Buffer[APP_Rx_ptr_in] = c;
++charsWritten;
/* To avoid buffer overflow */
if (APP_Rx_ptr_in >= APP_RX_DATA_SIZE-1) {
APP_Rx_ptr_in = 0;
++usbWraps;
}
else {
APP_Rx_ptr_in++;
}
}
/**
* @brief VCP_DataRx
* Data received over USB OUT endpoint is available here
*
* @note
* This function will block any OUT packet reception on USB endpoint
* until exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @note
* This function is executed inside the USBD_OTG_ISR_Handler() interrupt handler!
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
*/
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
{
// TODO: try implementing inbound flow control:
// if the cliRxFifo does not have enough free space to receive all
// available characters, return VCP_FAIL. Maybe that will throttle down
// the sender and we will receive the same packet at a later time.
#if defined(CLI)
//copy data to the application FIFO
for (uint32_t i = 0; i < Len; i++)
{
cliRxFifo.push(Buf[i]);
}
#endif
return USBD_OK;
}
// /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+71
View File
@@ -0,0 +1,71 @@
/**
******************************************************************************
* @file usbd_conf.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief USB Device configuration file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF__H__
#define __USBD_CONF__H__
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
#define USBD_CFG_MAX_NUM 1
#define USBD_ITF_MAX_NUM 1
#define USB_MAX_STR_DESC_SIZ 64
#define USBD_SELF_POWERED
/* Class Layer Parameter */
#define MSC_IN_EP 0x81
#define MSC_OUT_EP 0x01
#define MSC_MAX_PACKET 64
#define MSC_MEDIA_PACKET 4096
#define HID_IN_EP 0x81
#define HID_OUT_EP 0x01
#define HID_IN_PACKET 9
#define HID_OUT_PACKET 9
#define CDC_IN_EP 0x81 /* EP1 for data IN */
#define CDC_OUT_EP 0x01 /* EP1 for data OUT */
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */
#define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */
#define APP_RX_DATA_SIZE 512 // USB serial port output buffer. TODO: tune this buffer size /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
#define APP_FOPS VCP_fops
#endif //__USBD_CONF__H__
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+242
View File
@@ -0,0 +1,242 @@
/**
******************************************************************************
* @file usbd_desc.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the USBD descriptors and string formating method.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_req.h"
#include "usbd_conf.h"
#include "usb_regs.h"
#include "board_horus.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_DESC
* @brief USBD descriptors module
* @{
*/
/** @defgroup USBD_DESC_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Defines
* @{
*/
#define USBD_VID 0x0483
#define USBD_LANGID_STRING 0x409
#define USBD_MANUFACTURER_STRING "FrSky"
#define USBD_SERIALNUMBER_FS_STRING "00000000001B"
#if defined(BOOT)
#define USBD_PID 0x5720
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Bootloader"
#define USBD_CONFIGURATION_FS_STRING "MSC Config"
#define USBD_INTERFACE_FS_STRING "MSC Interface"
#elif defined(USB_JOYSTICK)
#define USBD_PID 0x5710
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Joystick"
#define USBD_CONFIGURATION_FS_STRING "HID Config"
#define USBD_INTERFACE_FS_STRING "HID Interface"
#elif defined(USB_SERIAL)
#define USBD_PID 0x5740 // do not change, this ID is used by the ST USB driver for Windows
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Serial Port"
#define USBD_CONFIGURATION_FS_STRING "VSP Config"
#define USBD_INTERFACE_FS_STRING "VSP Interface"
#elif defined(USB_MASS_STORAGE)
#define USBD_PID 0x5720
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Mass Storage"
#define USBD_CONFIGURATION_FS_STRING "MSC Config"
#define USBD_INTERFACE_FS_STRING "MSC Interface"
#endif
const USBD_DEVICE USR_desc =
{
USBD_USR_DeviceDescriptor,
USBD_USR_LangIDStrDescriptor,
USBD_USR_ManufacturerStrDescriptor,
USBD_USR_ProductStrDescriptor,
USBD_USR_SerialStrDescriptor,
USBD_USR_ConfigStrDescriptor,
USBD_USR_InterfaceStrDescriptor,
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN const uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
{
USB_SIZ_DEVICE_DESC, /*bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID), /*idVendor*/
HIBYTE(USBD_PID), /*idVendor*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_CFG_MAX_NUM /*bNumConfigurations*/
}; /* USB_DeviceDescriptor */
/* USB Standard Device Descriptor */
__ALIGN_BEGIN const uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN const uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END =
{
USB_SIZ_STRING_LANGID,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING),
};
/*
* @brief USBD_USR_DeviceDescriptor
* return the device descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length)
{
*length = sizeof(USBD_DeviceDesc);
memcpy(USBD_StrDesc, USBD_DeviceDesc, *length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_LangIDStrDescriptor
* return the LangID string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length)
{
*length = sizeof(USBD_LangIDDesc);
memcpy(USBD_StrDesc, USBD_LangIDDesc, *length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_ProductStrDescriptor
* return the product string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length)
{
USBD_GetString ((uint8_t*)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_ManufacturerStrDescriptor
* return the manufacturer string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length)
{
USBD_GetString ((uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_SerialStrDescriptor
* return the serial number string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length)
{
USBD_GetString ((uint8_t*)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_ConfigStrDescriptor
* return the configuration string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length)
{
USBD_GetString ((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief USBD_USR_InterfaceStrDescriptor
* return the interface string descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length)
{
USBD_GetString ((uint8_t*)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+120
View File
@@ -0,0 +1,120 @@
/**
******************************************************************************
* @file usbd_desc.h
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief header file for the usbd_desc.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DESC_H
#define __USB_DESC_H
/* Includes ------------------------------------------------------------------*/
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USB_DESC
* @brief general defines for the usb device library file
* @{
*/
/** @defgroup USB_DESC_Exported_Defines
* @{
*/
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
#define USB_STRING_DESCRIPTOR_TYPE 0x03
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
#define USB_SIZ_DEVICE_DESC 18
#define USB_SIZ_STRING_LANGID 4
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Variables
* @{
*/
extern const uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ];
extern const uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC];
extern const uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC];
extern const uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID];
extern const USBD_DEVICE USR_desc;
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_FunctionsPrototype
* @{
*/
uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length);
uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length);
#ifdef USB_SUPPORT_USER_STRING_DESC
uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length);
#endif /* USB_SUPPORT_USER_STRING_DESC */
/**
* @}
*/
#endif /* __USBD_DESC_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+479
View File
@@ -0,0 +1,479 @@
/**
******************************************************************************
* @file usbd_hid_core.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the HID core functions.
*
* @verbatim
*
* ===================================================================
* HID Class Description
* ===================================================================
* This module manages the HID class V1.11 following the "Device Class Definition
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
* This driver implements the following aspects of the specification:
* - The Boot Interface Subclass
* - The Mouse protocol
* - Usage Page : Generic Desktop
* - Usage : Joystick)
* - Collection : Application
*
* @note In HS mode and when the DMA is used, all variables and data structures
* dealing with the DMA during the transaction process should be 32-bit aligned.
*
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_hid_core.h"
#include "usbd_req.h"
#include "usbd_desc.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_HID
* @brief usbd core module
* @{
*/
/** @defgroup USBD_HID_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_HID_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_HID_Init (void *pdev,
uint8_t cfgidx);
static uint8_t USBD_HID_DeInit (void *pdev,
uint8_t cfgidx);
static uint8_t USBD_HID_Setup (void *pdev,
USB_SETUP_REQ *req);
static const uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length);
static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum);
/**
* @}
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/*
This USB HID endpoint report description defines a device with:
* 8 digital buttons
* 8 analog axes with 8bit resolution
Repot packet described as C struct is:
struct {
uint8_t buttons; //bit 0 - button 1, bit 1 - button 2, ..., mapped to channels 9-16, on if channel > 0
uint8_t X; //analog value, mapped to channel 1
uint8_t Y; //analog value, mapped to channel 2
uint8_t Z; //analog value, mapped to channel 3
uint8_t Rx; //analog value, mapped to channel 4
uint8_t Ry //analog value, mapped to channel 5
uint8_t Rz; //analog value, mapped to channel 6
uint8_t S1; //analog value, mapped to channel 7
uint8_t S2; //analog value, mapped to channel 8
}
*/
__ALIGN_BEGIN static const uint8_t HID_JOYSTICK_ReportDesc[] __ALIGN_END =
{
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x05, // USAGE (Game Pad)
0xa1, 0x01, // COLLECTION (Application)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
/** @defgroup USBD_HID_Private_Variables
* @{
*/
const USBD_Class_cb_TypeDef USBD_HID_cb =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_HID_DataIn, /*DataIn*/
NULL, /*DataOut*/
NULL, /*SOF */
NULL,
NULL,
USBD_HID_GetCfgDesc,
#ifdef USB_OTG_HS_CORE
USBD_HID_GetCfgDesc, /* use same config as per FS */
#endif
};
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0;
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB HID device Configuration Descriptor */
__ALIGN_BEGIN static const uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x01, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x00 /*0x01*/, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x00 /*0x02*/, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x11, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
sizeof(HID_JOYSTICK_ReportDesc),/*wItemLength: Total length of Report descriptor*/
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */
0x00,
0x0A, /*bInterval: Polling Interval (10 ms)*/
/* 34 */
} ;
static uint8_t ReportSent;
/**
* @}
*/
/** @defgroup USBD_HID_Private_Functions
* @{
*/
/**
* @brief USBD_HID_Init
* Initialize the HID interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_HID_Init (void *pdev,
uint8_t cfgidx)
{
/* Open EP IN */
DCD_EP_Open(pdev,
HID_IN_EP,
HID_IN_PACKET,
USB_OTG_EP_INT);
/* Open EP OUT */
DCD_EP_Open(pdev,
HID_OUT_EP,
HID_OUT_PACKET,
USB_OTG_EP_INT);
ReportSent = 1;
return USBD_OK;
}
/**
* @brief USBD_HID_Init
* DeInitialize the HID layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_HID_DeInit (void *pdev,
uint8_t cfgidx)
{
/* Close HID EPs */
DCD_EP_Close (pdev , HID_IN_EP);
DCD_EP_Close (pdev , HID_OUT_EP);
ReportSent = 1;
return USBD_OK;
}
/**
* @brief USBD_HID_Setup
* Handle the HID specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_HID_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len = 0;
const uint8_t *pbuf = NULL;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case HID_REQ_SET_PROTOCOL:
USBD_HID_Protocol = (uint8_t)(req->wValue);
break;
case HID_REQ_GET_PROTOCOL:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_Protocol,
1);
break;
case HID_REQ_SET_IDLE:
USBD_HID_IdleState = (uint8_t)(req->wValue >> 8);
break;
case HID_REQ_GET_IDLE:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_IdleState,
1);
break;
default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( req->wValue >> 8 == HID_REPORT_DESC)
{
len = MIN(sizeof(HID_JOYSTICK_ReportDesc) , req->wLength);
pbuf = HID_JOYSTICK_ReportDesc; // wiiccReportDescriptor; //
}
else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
{
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
pbuf = USBD_HID_Desc;
#else
pbuf = USBD_HID_CfgDesc + 0x12;
#endif
len = MIN(USB_HID_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev,
pbuf,
len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_AltSet,
1);
break;
case USB_REQ_SET_INTERFACE :
USBD_HID_AltSet = (uint8_t)(req->wValue);
break;
}
}
return USBD_OK;
}
/**
* @brief USBD_HID_SendReport
* Send HID Report
* @param pdev: device instance
* @param buff: pointer to report
* @retval status
*/
uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
uint8_t *report,
uint16_t len)
{
if (pdev->dev.device_status == USB_OTG_CONFIGURED )
{
if ( ReportSent )
{
ReportSent = 0;
DCD_EP_Tx (pdev, HID_IN_EP, report, len);
}
}
return USBD_OK;
}
/**
* @brief USBD_HID_GetCfgDesc
* return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static const uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (USBD_HID_CfgDesc);
return USBD_HID_CfgDesc;
}
/**
* @brief USBD_HID_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
static uint8_t USBD_HID_DataIn (void *pdev,
uint8_t epnum)
{
ReportSent = 1;
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
DCD_EP_Flush(pdev, HID_IN_EP);
return USBD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,811 @@
/**
******************************************************************************
* @file usbd_storage_msd.c
* @author MCD application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file provides the disk operations functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "../../opentx.h"
#include "../../thirdparty/FatFs/diskio.h"
#include "board_horus.h"
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#include "usbd_msc_mem.h"
#include "usb_conf.h"
#if defined(BOOT)
#define STORAGE_LUN_NBR 2
#else
/* SD card only when not running bootloader */
#define STORAGE_LUN_NBR 1
#endif
#define BLOCKSIZE 512
/* USB Mass storage Standard Inquiry Data */
const unsigned char STORAGE_Inquirydata[] = {//36
/* LUN 0 */
0x00,
0x80,
0x02,
0x02,
(USBD_STD_INQUIRY_LENGTH - 5),
0x00,
0x00,
0x00,
'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
'T', 'a', 'r', 'a', 'n', 'i', 's', ' ', /* Product : 16 Bytes */
'R', 'a', 'd', 'i', 'o', ' ', ' ', ' ',
'1', '.', '0', '0', /* Version : 4 Bytes */
#if defined(BOOT)
/* LUN 1 */
0x00,
0x80,
0x02,
0x02,
(USBD_STD_INQUIRY_LENGTH - 5),
0x00,
0x00,
0x00,
'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
'T', 'a', 'r', 'a', 'n', 'i', 's', ' ', /* Product : 16 Bytes */
'R', 'a', 'd', 'i', 'o', ' ', ' ', ' ',
'1', '.', '0' ,'0', /* Version : 4 Bytes */
#endif
};
#if defined(BOOT)
int32_t fat12Write( const uint8_t *buffer, uint16_t sector, uint16_t count ) ;
int32_t fat12Read( uint8_t *buffer, uint16_t sector, uint16_t count ) ;
#endif
int8_t STORAGE_Init (uint8_t lun);
int8_t STORAGE_GetCapacity (uint8_t lun,
uint32_t *block_num,
uint32_t *block_size);
int8_t STORAGE_IsReady (uint8_t lun);
int8_t STORAGE_IsWriteProtected (uint8_t lun);
int8_t STORAGE_Read (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len);
int8_t STORAGE_Write (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len);
int8_t STORAGE_GetMaxLun (void);
USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops =
{
STORAGE_Init,
STORAGE_GetCapacity,
STORAGE_IsReady,
STORAGE_IsWriteProtected,
STORAGE_Read,
STORAGE_Write,
STORAGE_GetMaxLun,
(int8_t *)STORAGE_Inquirydata,
};
USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops;
__IO uint32_t count = 0;
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
int8_t STORAGE_Init (uint8_t lun)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TODO if no SD ... if( SD_Init() != 0)
{
return (-1);
}
*/
return (0);
}
/**
* @brief return medium capacity and block size
* @param lun : logical unit number
* @param block_num : number of physical block
* @param block_size : size of a physical block
* @retval Status
*/
int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_size)
{
#if defined(BOOT)
if (lun == 1) {
*block_size = BLOCKSIZE;
*block_num = 3 + EESIZE/BLOCKSIZE + FLASHSIZE/BLOCKSIZE;
}
else
#endif
{
if (!SD_CARD_PRESENT())
return -1;
*block_size = BLOCKSIZE;
static DWORD sector_count = 0;
if (sector_count == 0) {
if (disk_ioctl(0, GET_SECTOR_COUNT, &sector_count) != RES_OK) {
sector_count = 0;
return -1;
}
}
*block_num = sector_count;
}
return 0;
}
#if defined(BOOT)
uint8_t lunReady[2] ;
#else
uint8_t lunReady[1] ;
#endif
void usbPluggedIn()
{
if (lunReady[0] == 0) {
lunReady[0] = 1;
}
#if defined(BOOT)
if (lunReady[1] == 0) {
lunReady[1] = 1;
}
#endif
}
/**
* @brief check whether the medium is ready
* @param lun : logical unit number
* @retval Status
*/
int8_t STORAGE_IsReady (uint8_t lun)
{
#if defined(BOOT)
if (lun == 1) {
if (lunReady[1] == 0) {
return -1 ;
}
return 0 ;
}
else
#endif
{
if (lunReady[0] == 0) {
return -1 ;
}
return SD_CARD_PRESENT() ? 0 : -1;
}
}
/**
* @brief check whether the medium is write-protected
* @param lun : logical unit number
* @retval Status
*/
int8_t STORAGE_IsWriteProtected (uint8_t lun)
{
return 0;
}
/**
* @brief Read data from the medium
* @param lun : logical unit number
* @param buf : Pointer to the buffer to save data
* @param blk_addr : address of 1st block to be read
* @param blk_len : nmber of blocks to be read
* @retval Status
*/
int8_t SD_ReadSectors(uint8_t *buff, uint32_t sector, uint32_t count);
int8_t STORAGE_Read (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
#if defined(BOOT)
if (lun == 1) {
if (fat12Read(buf, blk_addr, blk_len) != 0)
return -1;
}
else
#endif
{
if (SD_ReadSectors(buf, blk_addr, blk_len) != 0) {
return -1;
}
}
return 0;
}
/**
* @brief Write data to the medium
* @param lun : logical unit number
* @param buf : Pointer to the buffer to write from
* @param blk_addr : address of 1st block to be written
* @param blk_len : nmber of blocks to be read
* @retval Status
*/
int8_t SD_WriteSectors(const uint8_t *buf, uint32_t sector, uint32_t count);
int8_t STORAGE_Write (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
#if defined(BOOT)
if (lun == 1) {
if (fat12Write(buf, blk_addr, blk_len) != 0)
return -1;
}
else
#endif
{
if (SD_WriteSectors(buf, blk_addr, blk_len) != 0)
return -1;
}
return (0);
}
/**
* @brief Return number of supported logical unit
* @param None
* @retval number of logical unit
*/
int8_t STORAGE_GetMaxLun (void)
{
return STORAGE_LUN_NBR - 1;
}
#if defined(BOOT)
//------------------------------------------------------------------------------
/**
* FAT12 boot sector partition.
*/
const char g_FATboot[BLOCKSIZE] =
{
0xeb, 0x3c, 0x90, // Jump instruction.
0x39, 0x58, 0x20, 0x54, 0x45, 0x41, 0x4D, 0x00, // OEM Name
0x00, 0x02, // Bytes per sector
0x08, // Sectors per FS cluster.
0x01, 0x00, // Reserved sector count
0x01, // Number of FATs
0x10, 0x00, // Number of root directory entries
3+(EESIZE/BLOCKSIZE), (FLASHSIZE/BLOCKSIZE)>>8, // Total sectors
0xf8, // Media descriptor
0x01, 0x00, // Sectors per FAT table
0x20, 0x00, // Sectors per track
0x40, 0x00, // Number of heads
0x00, 0x00, 0x00, 0x00, // Number of hidden sectors
0x00, 0x00, 0x00, 0x00, // Large number of sectors.
0x00, // Physical drive number
0x00, // Reserved
0x29, // Extended boot signature
0xCE, 0xFA, 0x5C, 0xD1, // Disk ID (serial number)
0x56, 0x49, 0x52, 0x54, 0x46, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, // Volume label
0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, // FAT file system type
0x00, 0x00, // OS boot code
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
};
#if defined(REV4a)
const char g_FAT[BLOCKSIZE] =
{
0xF8, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xA0, 0x00, 0x0B,
0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0xF0, 0xFF, 0x13, 0x40, 0x01, 0x15, 0x60,
0x01, 0x17, 0x80, 0x01, 0x19, 0xA0, 0x01, 0x1B, 0xC0, 0x01, 0x1D, 0xE0, 0x01, 0x1F, 0x00, 0x02,
0x21, 0x20, 0x02, 0x23, 0x40, 0x02, 0x25, 0x60, 0x02, 0x27, 0x80, 0x02, 0x29, 0xA0, 0x02, 0x2B,
0xC0, 0x02, 0x2D, 0xE0, 0x02, 0x2F, 0x00, 0x03, 0x31, 0x20, 0x03, 0x33, 0x40, 0x03, 0x35, 0x60,
0x03, 0x37, 0x80, 0x03, 0x39, 0xA0, 0x03, 0x3B, 0xC0, 0x03, 0x3D, 0xE0, 0x03, 0x3F, 0x00, 0x04,
0x41, 0x20, 0x04, 0x43, 0x40, 0x04, 0x45, 0x60, 0x04, 0x47, 0x80, 0x04, 0x49, 0xA0, 0x04, 0x4B,
0xC0, 0x04, 0x4D, 0xE0, 0x04, 0x4F, 0x00, 0x05, 0x51, 0x20, 0x05, 0x53, 0x40, 0x05, 0x55, 0x60,
0x05, 0x57, 0x80, 0x05, 0x59, 0xA0, 0x05, 0x5B, 0xC0, 0x05, 0x5D, 0xE0, 0x05, 0x5F, 0x00, 0x06,
0x61, 0x20, 0x06, 0x63, 0x40, 0x06, 0x65, 0x60, 0x06, 0x67, 0x80, 0x06, 0x69, 0xA0, 0x06, 0x6B,
0xC0, 0x06, 0x6D, 0xE0, 0x06, 0x6F, 0x00, 0x07, 0x71, 0x20, 0x07, 0x73, 0x40, 0x07, 0x75, 0x60,
0x07, 0x77, 0x80, 0x07, 0x79, 0xA0, 0x07, 0x7B, 0xC0, 0x07, 0x7D, 0xE0, 0x07, 0x7F, 0x00, 0x08,
0x81, 0x20, 0x08, 0x83, 0x40, 0x08, 0x85, 0x60, 0x08, 0x87, 0x80, 0x08, 0x89, 0xA0, 0x08, 0x8B,
0xC0, 0x08, 0x8D, 0xE0, 0x08, 0x8F, 0x00, 0x09, 0x91, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#else
const char g_FAT[BLOCKSIZE] =
{
0xF8, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xF0, 0xFF, 0x0B,
0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0x20, 0x01, 0x13, 0x40, 0x01, 0x15, 0x60,
0x01, 0x17, 0x80, 0x01, 0x19, 0xA0, 0x01, 0x1B, 0xC0, 0x01, 0x1D, 0xE0, 0x01, 0x1F, 0x00, 0x02,
0x21, 0x20, 0x02, 0x23, 0x40, 0x02, 0x25, 0x60, 0x02, 0x27, 0x80, 0x02, 0x29, 0xA0, 0x02, 0x2B,
0xC0, 0x02, 0x2D, 0xE0, 0x02, 0x2F, 0x00, 0x03, 0x31, 0x20, 0x03, 0x33, 0x40, 0x03, 0x35, 0x60,
0x03, 0x37, 0x80, 0x03, 0x39, 0xA0, 0x03, 0x3B, 0xC0, 0x03, 0x3D, 0xE0, 0x03, 0x3F, 0x00, 0x04,
0x41, 0x20, 0x04, 0x43, 0x40, 0x04, 0x45, 0x60, 0x04, 0x47, 0x80, 0x04, 0x49, 0xA0, 0x04, 0x4B,
0xC0, 0x04, 0x4D, 0xE0, 0x04, 0x4F, 0x00, 0x05, 0x51, 0x20, 0x05, 0x53, 0x40, 0x05, 0x55, 0x60,
0x05, 0x57, 0x80, 0x05, 0x59, 0xA0, 0x05, 0x5B, 0xC0, 0x05, 0x5D, 0xE0, 0x05, 0x5F, 0x00, 0x06,
0x61, 0x20, 0x06, 0x63, 0x40, 0x06, 0x65, 0x60, 0x06, 0x67, 0x80, 0x06, 0x69, 0xA0, 0x06, 0x6B,
0xC0, 0x06, 0x6D, 0xE0, 0x06, 0x6F, 0x00, 0x07, 0x71, 0x20, 0x07, 0x73, 0x40, 0x07, 0x75, 0x60,
0x07, 0x77, 0x80, 0x07, 0x79, 0xA0, 0x07, 0x7B, 0xC0, 0x07, 0x7D, 0xE0, 0x07, 0x7F, 0x00, 0x08,
0x81, 0x20, 0x08, 0x83, 0x40, 0x08, 0x85, 0x60, 0x08, 0x87, 0x80, 0x08, 0x89, 0xF0, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif
// File Attributes
// 0 0x01 Read Only.
// 1 0x02 Hidden.
// 2 0x04 System.
// 3 0x08 Volume Label.
// 4 0x10 Subdirectory.
// 5 0x20 Archive.
// 6 0x40 Device.
// 7 0x80 Reserved.
typedef struct
{
uint8_t name[8];
uint8_t ext[3];
uint8_t attribute;
uint8_t reserved;
uint8_t create_time_ms;
uint16_t create_time;
uint16_t create_date;
uint16_t access_date;
uint16_t ea_index;
uint16_t modify_time;
uint16_t modify_date;
uint16_t start_cluster;
uint32_t file_size;
} FATDirEntry_t;
// First 16 FAT root directory entries (1 sector)
const FATDirEntry_t g_DIRroot[16] =
{
{
{ 'T', 'A', 'R', 'A', 'N', 'I', 'S', ' '},
{ ' ', ' ', ' '},
0x08, // Volume
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ 'E', 'E', 'P', 'R', 'O', 'M', ' ', ' '},
{ 'B', 'I', 'N'},
0x20, // Archive
0x00,
0x3E,
0xA301,
0x3D55,
0x3D55,
0x0000,
0xA302,
0x3D55,
0x0002,
EESIZE
},
{
{ 'F', 'I', 'R', 'M', 'W', 'A', 'R', 'E'},
{ 'B', 'I', 'N'},
0x20, // Archive
0x00,
0x3E,
0xA301,
0x3D55,
0x3D55,
0x0000,
0xA302,
0x3D55,
0x0002 + (EESIZE/BLOCKSIZE)/8,
FLASHSIZE
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
{
{ '\x00', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{ ' ', ' ', ' '},
0x00,
0x00,
0x00,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x0000,
0x00000000
},
};
// count is number of 512 byte sectors
int32_t fat12Read( uint8_t *buffer, uint16_t sector, uint16_t count )
{
while ( count )
{
if (sector == 0) {
memcpy(buffer, g_FATboot, BLOCKSIZE ) ;
}
else if (sector == 1/*Reserved sector count*/) {
// FAT table.
memcpy(buffer, g_FAT, BLOCKSIZE);
}
else if (sector == 2) {
memcpy(buffer, g_DIRroot, BLOCKSIZE ) ;
}
else if (sector < 3 + (EESIZE/BLOCKSIZE)) {
eepromReadBlock(buffer, (sector-3)*BLOCKSIZE, BLOCKSIZE);
}
else if (sector < 3 + (EESIZE/BLOCKSIZE) + (FLASHSIZE/BLOCKSIZE)) {
uint32_t address;
address = sector - 3 - (EESIZE/BLOCKSIZE);
address *= BLOCKSIZE;
address += FIRMWARE_ADDRESS;
memcpy(buffer, (uint8_t *)address, BLOCKSIZE);
}
buffer += BLOCKSIZE ;
sector++ ;
count-- ;
}
return 0 ;
}
int32_t fat12Write(const uint8_t *buffer, uint16_t sector, uint16_t count)
{
enum FatWriteOperation {
FATWRITE_NONE,
FATWRITE_EEPROM,
FATWRITE_FIRMWARE
};
static unsigned int operation = FATWRITE_NONE;
TRACE("FAT12 Write(sector=%d, count=%d)", sector, count);
if (sector < 3) {
// reserved, read-only
}
else if (sector < 3 + (EESIZE/BLOCKSIZE)) {
// eeprom
while (count) {
if (operation == FATWRITE_NONE && isEepromStart(buffer)) {
TRACE("EEPROM start found in sector %d", sector);
operation = FATWRITE_EEPROM;
}
if (operation == FATWRITE_EEPROM) {
eepromWriteBlock((uint8_t *)buffer, (sector-3)*BLOCKSIZE, BLOCKSIZE);
}
buffer += BLOCKSIZE;
sector++;
count--;
if (sector-3 >= (EESIZE/BLOCKSIZE)) {
TRACE("EEPROM end written at sector %d", sector-1);
operation = FATWRITE_NONE;
}
}
}
else if (sector < 3 + (EESIZE/BLOCKSIZE) + (FLASHSIZE/BLOCKSIZE)) {
// firmware
uint32_t address;
address = sector - 3 - (EESIZE/BLOCKSIZE);
address *= BLOCKSIZE;
address += FIRMWARE_ADDRESS;
while (count) {
for (uint32_t i=0; i<BLOCKSIZE/FLASH_PAGESIZE; i++) {
if (address >= FIRMWARE_ADDRESS+BOOTLOADER_SIZE/*protect bootloader*/ && address <= FIRMWARE_ADDRESS+FLASHSIZE-FLASH_PAGESIZE) {
if (address == FIRMWARE_ADDRESS+BOOTLOADER_SIZE && isFirmwareStart(buffer)) {
TRACE("FIRMWARE start found in sector %d", sector);
operation = FATWRITE_FIRMWARE;
}
if (operation == FATWRITE_FIRMWARE) {
writeFlash((uint32_t *)address, (uint32_t *)buffer);
}
}
address += FLASH_PAGESIZE;
buffer += FLASH_PAGESIZE;
}
sector++;
count--;
if (sector-3-(EESIZE/BLOCKSIZE) >= (FLASHSIZE/BLOCKSIZE)) {
TRACE("FIRMWARE end written at sector %d", sector-1);
operation = FATWRITE_NONE;
}
}
}
return 0 ;
}
#endif
+128
View File
@@ -0,0 +1,128 @@
/**
******************************************************************************
* @file usbd_usr.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief This file includes the user application layer
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
*
* 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "../../opentx.h"
extern "C" {
#include "usbd_usr.h"
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
const USBD_Usr_cb_TypeDef USR_cb =
{
USBD_USR_Init,
USBD_USR_DeviceReset,
USBD_USR_DeviceConfigured,
USBD_USR_DeviceSuspended,
USBD_USR_DeviceResumed,
USBD_USR_DeviceConnected,
USBD_USR_DeviceDisconnected,
};
}
/**
* @brief Whatever the user application needs to do when USB is initialised
* @param None
* @retval None
*/
void USBD_USR_Init(void)
{
}
/**
* @brief Displays the message on LCD on device reset event
* @param speed : device speed
* @retval None
*/
void USBD_USR_DeviceReset (uint8_t speed)
{
}
/**
* @brief Displays the message on LCD on device config event
* @param None
* @retval Staus
*/
void USBD_USR_DeviceConfigured (void)
{
}
/**
* @brief Displays the message on LCD on device suspend event
* @param None
* @retval None
*/
void USBD_USR_DeviceSuspended(void)
{
}
/**
* @brief Displays the message on LCD on device resume event
* @param None
* @retval None
*/
void USBD_USR_DeviceResumed(void)
{
}
/**
* @brief USBD_USR_DeviceConnected
* Displays the message on LCD on device connection Event
* @param None
* @retval Staus
*/
void USBD_USR_DeviceConnected (void)
{
}
/**
* @brief USBD_USR_DeviceDisonnected
* Displays the message on LCD on device disconnection Event
* @param None
* @retval Staus
*/
void USBD_USR_DeviceDisconnected (void)
{
#if !defined(BOOT) && defined(USB_MASS_STORAGE)
NVIC_SystemReset();
#endif
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/