Horus drivers
This commit is contained in:
@@ -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];
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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) { }
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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(<DC_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, <DC_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, <DC_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, <DC_colorkeying_InitStruct, ENABLE);
|
||||
LTDC_ReloadConfig(LTDC_IMReload);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable the color Keying for Layer2 */
|
||||
LTDC_ColorKeyingConfig(LTDC_Layer2, <DC_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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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>© 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****/
|
||||
Executable
+445
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
@@ -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>© 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
|
||||
@@ -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
|
||||
@@ -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>© 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****/
|
||||
@@ -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>© 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****/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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>© 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****/
|
||||
@@ -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>© 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****/
|
||||
|
||||
@@ -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>© 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****/
|
||||
|
||||
@@ -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>© 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****/
|
||||
@@ -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>© 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>© 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, §or_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
|
||||
@@ -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>© 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****/
|
||||
Reference in New Issue
Block a user