mirror of
https://github.com/eddyem/IR-controller.git
synced 2025-12-06 02:35:14 +03:00
378 lines
12 KiB
C
378 lines
12 KiB
C
/*
|
||
* hw_config.c - USB & USART configuration
|
||
*
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
* MA 02110-1301, USA.
|
||
*/
|
||
|
||
#include "includes.h"
|
||
|
||
#define USART1_IRQHandler Dummy
|
||
#define USART2_IRQHandler Dummy
|
||
#define USART3_IRQHandler Dummy
|
||
void Dummy(){};
|
||
|
||
// Configure ports
|
||
__IO uint16_t ADC_value; // ADC DMA value
|
||
|
||
/**
|
||
* Configure GPIO ports (all pins have 2MHz speed)
|
||
* @param mode - port mode
|
||
* @param GPIOx - port address
|
||
* @param pin - pin[s] to configure
|
||
* @param spd - GPIO speed
|
||
*/
|
||
void GPIO_pin_config_common(GPIOMode_TypeDef mode, GPIO_TypeDef* GPIOx, uint16_t pin, GPIOSpeed_TypeDef spd){
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
GPIO_InitStructure.GPIO_Speed = spd;
|
||
GPIO_InitStructure.GPIO_Pin = pin;
|
||
GPIO_InitStructure.GPIO_Mode = mode;
|
||
GPIO_Init(GPIOx, &GPIO_InitStructure);
|
||
}
|
||
|
||
// default - slow
|
||
#define GPIO_pin_config(a,b,c) GPIO_pin_config_common(a,b,c, GPIO_Speed_2MHz)
|
||
#define GPIO_pin_config_fast(a,b,c) GPIO_pin_config_common(a,b,c, GPIO_Speed_50MHz)
|
||
|
||
void Ports_Config(){
|
||
EXTI_InitTypeDef EXTI_InitStructure;
|
||
DMA_InitTypeDef DMA_InitStructure;
|
||
ADC_InitTypeDef ADC_InitStructure;
|
||
// enable AFIO clock
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||
// enable clocks for used ports
|
||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA
|
||
| RCC_APB2Periph_GPIOB
|
||
| RCC_APB2Periph_GPIOC
|
||
| RCC_APB2Periph_GPIOD
|
||
,ENABLE);
|
||
/*
|
||
* Button (A0)
|
||
*/
|
||
GPIO_pin_config(GPIO_Mode_IN_FLOATING, GPIOA, GPIO_Pin_0);
|
||
// Connect Button EXTI Line to Button GPIO Pin
|
||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
|
||
// Configure Button EXTI line
|
||
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
|
||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||
EXTI_Init(&EXTI_InitStructure);
|
||
// Enable Button EXTI Interrupt
|
||
NVIC_EnableIRQ(EXTI0_IRQn);
|
||
/*
|
||
* LED (PC12) & USB software connect-disconnect (PC11) pins
|
||
*/
|
||
GPIO_pin_config(GPIO_Mode_Out_PP, GPIOC, GPIO_Pin_12 | GPIO_Pin_11);
|
||
// put USB into disconnect state
|
||
GPIO_SetBits(GPIOC, GPIO_Pin_11);
|
||
/*
|
||
* Hall sensor (PD2)
|
||
*/
|
||
GPIO_pin_config(GPIO_Mode_IN_FLOATING, Hall_GPIOx, Hall_PIN);
|
||
// Configure Hall EXTI
|
||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource2);
|
||
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
|
||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||
EXTI_Init(&EXTI_InitStructure);
|
||
// Enable Hall IRQ
|
||
NVIC_EnableIRQ(EXTI2_IRQn);
|
||
/*
|
||
* ADC (PB0)
|
||
*/
|
||
// 0. Configure ADC8 (PB0) as analog input (clocking GPIOB sat on in onewire.c)
|
||
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
|
||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
|
||
GPIO_pin_config(GPIO_Mode_AIN, GPIOB, GPIO_Pin_0);
|
||
// 1. DMA for converted value (DMA1 clocking sat on at onewire.c)
|
||
//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||
DMA_DeInit(DMA1_Channel1);
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_value;
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||
DMA_InitStructure.DMA_BufferSize = 1;
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
|
||
DMA_Cmd(DMA1_Channel1, ENABLE);
|
||
// 2. ADC1 config
|
||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
|
||
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
||
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
|
||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||
ADC_InitStructure.ADC_NbrOfChannel = 1;
|
||
ADC_Init(ADC1, &ADC_InitStructure);
|
||
// Connect ADC to ADC8 (PB0),
|
||
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
|
||
// Enable ADC1 DMA
|
||
ADC_DMACmd(ADC1, ENABLE);
|
||
ADC_Cmd(ADC1, ENABLE);
|
||
// Calibration of ADC1
|
||
ADC_ResetCalibration(ADC1);
|
||
while(ADC_GetResetCalibrationStatus(ADC1));
|
||
ADC_StartCalibration(ADC1);
|
||
while(ADC_GetCalibrationStatus(ADC1));
|
||
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // turn conversion on
|
||
/*
|
||
* ADG506 control port (PC0..4)
|
||
* PC0..PC3 - analog channel address, PC4 - analog enable switch
|
||
*/
|
||
GPIO_pin_config(GPIO_Mode_Out_PP, GPIOC, ((uint16_t)0x1f));
|
||
//GPIO_pin_config(GPIO_Mode_Out_OD, GPIOC, ((uint16_t)0x1f));
|
||
/*
|
||
* 1-wire
|
||
* PA2 - USART_2TX (for USART3 - PB10 or remap to other pins)
|
||
* PA3 - USART_2RX (for USART3 - PB11 or remap)
|
||
*/
|
||
GPIO_pin_config_fast(GPIO_Mode_AF_OD, GPIOB, GPIO_Pin_10); // to omit Shottke diode
|
||
GPIO_pin_config_fast(GPIO_Mode_IN_FLOATING, GPIOB, GPIO_Pin_11);
|
||
// turn on USART2 (USART3 - RCC_APB1Periph_USART3)
|
||
// to remap pins run GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE)
|
||
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||
/*
|
||
* Stepper motors
|
||
* PA8/TIM1_CH1 - PUL (step) for all motors
|
||
* PB1 - DIR for all motors
|
||
* PC5..PC9 - ENx - pins to activate proper motor
|
||
* all are push-pull
|
||
*/
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // enable timer 1 clocking
|
||
GPIO_pin_config(GPIO_Mode_AF_PP, SM_PUL_GPIOx, SM_PUL_PIN); // PA8 - PUL (by timer)
|
||
GPIO_pin_config(GPIO_Mode_Out_PP, SM_DIR_GPIOx, SM_DIR_PIN); // PB1 - DIR
|
||
// channels EN configured as open-drain output because (+) of "EN" on stepper driver side have +5V
|
||
GPIO_pin_config(GPIO_Mode_Out_OD, SM_EN_GPIOx, SM_EN_PINS); // PC5..PC9 - Enx
|
||
// enable timer1 IRQ
|
||
NVIC_EnableIRQ(TIM1_CC_IRQn);
|
||
/*
|
||
* ZacWire
|
||
* PA1 (TIM2_CH2) used to capture data by PWM input mode
|
||
* PB5 used for power management: TSic thermometers get power only for a measurement
|
||
* !!! When using a lot of such thermometers powering them is better with multiplexer
|
||
*/
|
||
// Power pin: 5v tolerant
|
||
//GPIO_pin_config(GPIO_Mode_Out_PP, ZW_PWR_GPIOx, ZW_PWR_PIN);
|
||
GPIO_pin_config(GPIO_Mode_Out_OD, ZW_PWR_GPIOx, ZW_PWR_PIN);
|
||
ZW_PWR_GPIOx->BRR = ZW_PWR_PIN; // turn off power
|
||
// data pin: floating input (PA8)
|
||
GPIO_pin_config(GPIO_Mode_IN_FLOATING, ZW_DATA_GPIOx, ZW_DATA_PIN);
|
||
// enable timer2 clocking & its IRQ
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||
NVIC_EnableIRQ(TIM2_IRQn);
|
||
}
|
||
|
||
|
||
// USB
|
||
uint8_t USART_Rx_Buffer[USART_RX_DATA_SIZE];
|
||
uint32_t USART_Rx_ptr_in = 0;
|
||
|
||
// USB clock (48 MHz)
|
||
void Set_USBClock(void){
|
||
// Select USBCLK source
|
||
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
|
||
// Enable the USB clock
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
|
||
}
|
||
|
||
// USB RX interrupts
|
||
void USB_Interrupts_Config(void){
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
||
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
/*
|
||
NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
*/
|
||
}
|
||
|
||
|
||
// Software disconnect
|
||
void USB_Cable_Config (FunctionalState NewState){
|
||
if (NewState != DISABLE)
|
||
GPIO_ResetBits(GPIOC, GPIO_Pin_11);
|
||
else
|
||
GPIO_SetBits(GPIOC, GPIO_Pin_11);
|
||
}
|
||
|
||
// Low power mode (if not required - just set flag)
|
||
void Enter_LowPowerMode(void){
|
||
bDeviceState = SUSPENDED;
|
||
}
|
||
|
||
// enter full power mode (if not required - just set flag)
|
||
void Leave_LowPowerMode(void){
|
||
DEVICE_INFO *pInfo = &Device_Info;
|
||
if (pInfo->Current_Configuration != 0){
|
||
bDeviceState = CONFIGURED;
|
||
}else{
|
||
bDeviceState = ATTACHED;
|
||
}
|
||
}
|
||
|
||
// Clocks
|
||
void RCC_Config(void){
|
||
ErrorStatus HSEStartUpStatus;
|
||
// Configuration of SYSCLK, HCLK, PCLK2 <20> PCLK1
|
||
RCC_DeInit();
|
||
RCC_HSEConfig(RCC_HSE_ON);
|
||
HSEStartUpStatus = RCC_WaitForHSEStartUp();
|
||
if (HSEStartUpStatus == SUCCESS){
|
||
RCC_HCLKConfig(RCC_SYSCLK_Div1);
|
||
RCC_PCLK2Config(RCC_HCLK_Div1);
|
||
RCC_PCLK1Config(RCC_HCLK_Div2);
|
||
// PLLCLK = 8MHz * 9 = 72 MHz
|
||
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
|
||
RCC_PLLCmd(ENABLE);
|
||
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}
|
||
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
||
while(RCC_GetSYSCLKSource() != 0x08){}
|
||
}else{
|
||
// HSE start error - clock configuration will be wrong
|
||
// maybe say about it?
|
||
while (1){}
|
||
}
|
||
}
|
||
|
||
// send data to USB
|
||
void Handle_USBAsynchXfer (void){
|
||
uint16_t USB_Tx_ptr, USB_Tx_length;
|
||
static uint32_t USART_Rx_ptr_out = 0, USART_Rx_length = 0;
|
||
|
||
if (USART_Rx_ptr_out == USART_RX_DATA_SIZE){
|
||
USART_Rx_ptr_out = 0;
|
||
}
|
||
if(USART_Rx_ptr_out == USART_Rx_ptr_in){
|
||
return;
|
||
}
|
||
if(USART_Rx_ptr_out > USART_Rx_ptr_in){ /* rollback */
|
||
USART_Rx_length = USART_RX_DATA_SIZE - USART_Rx_ptr_out;
|
||
}else{
|
||
USART_Rx_length = USART_Rx_ptr_in - USART_Rx_ptr_out;
|
||
}
|
||
USB_Tx_ptr = USART_Rx_ptr_out;
|
||
// if data length > packet size
|
||
if (USART_Rx_length > SomeDev_DATA_SIZE){
|
||
USB_Tx_length = SomeDev_DATA_SIZE;
|
||
USART_Rx_ptr_out += SomeDev_DATA_SIZE;
|
||
USART_Rx_length -= SomeDev_DATA_SIZE;
|
||
}else{
|
||
USB_Tx_length = USART_Rx_length;
|
||
USART_Rx_ptr_out += USART_Rx_length;
|
||
USART_Rx_length = 0;
|
||
}
|
||
UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
|
||
SetEPTxCount(ENDP1, USB_Tx_length);
|
||
SetEPTxValid(ENDP1);
|
||
}
|
||
|
||
|
||
void USB_Send_Data(uint8_t data){
|
||
USART_Rx_Buffer[USART_Rx_ptr_in] = data;
|
||
USART_Rx_ptr_in++;
|
||
if(USART_Rx_ptr_in >= USART_RX_DATA_SIZE){
|
||
USART_Rx_ptr_in = 0;
|
||
}
|
||
}
|
||
|
||
/*
|
||
bool USART_Config(void)
|
||
{
|
||
|
||
switch (linecoding.format)
|
||
{
|
||
case 0:
|
||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||
break;
|
||
case 1:
|
||
USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
|
||
break;
|
||
case 2:
|
||
USART_InitStructure.USART_StopBits = USART_StopBits_2;
|
||
break;
|
||
default :
|
||
{
|
||
USART_Config_Default();
|
||
return (FALSE);
|
||
}
|
||
}
|
||
|
||
switch (linecoding.paritytype)
|
||
{
|
||
case 0:
|
||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||
break;
|
||
case 1:
|
||
USART_InitStructure.USART_Parity = USART_Parity_Even;
|
||
break;
|
||
case 2:
|
||
USART_InitStructure.USART_Parity = USART_Parity_Odd;
|
||
break;
|
||
default :
|
||
{
|
||
USART_Config_Default();
|
||
return (FALSE);
|
||
}
|
||
}
|
||
|
||
switch (linecoding.datatype)
|
||
{
|
||
case 0x07:
|
||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||
break;
|
||
case 0x08:
|
||
if (USART_InitStructure.USART_Parity == USART_Parity_No)
|
||
{
|
||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||
}
|
||
else
|
||
{
|
||
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
|
||
}
|
||
|
||
break;
|
||
default :
|
||
{
|
||
USART_Config_Default();
|
||
return (FALSE);
|
||
}
|
||
}
|
||
|
||
USART_InitStructure.USART_BaudRate = linecoding.bitrate;
|
||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||
|
||
initPORT(&USART_InitStructure);
|
||
|
||
return (TRUE);
|
||
}
|
||
*/
|