1
0
forked from me/IronOS
Files
IronOS/workspace/ts100/src/Bios.c
Ben V. Brown 0b26e669af Merge Dev into mainline (#1)
* Removing USB
Need to refine the drive to the iron tip

* Update README.md

* * Rewrite all code from scratch
* Only kept settings
* New font
* New PID
* New Menus
* Use Hardware I2C
* Faster System
* Better Heating Time
* No USB
* Full Menu System
2016-09-30 00:27:55 +10:00

273 lines
9.5 KiB
C

/*
* Setup all the basic hardware in the system and handle timer3 tick
*/
#include "Bios.h"
#include "I2C.h"
#define ADC1_DR_Address ((u32)0x4001244C)
volatile uint32_t gHeat_cnt = 0;
/*
* Setup system clocks to run off internal oscillator at 48Mhz
*/
void RCC_Config(void) {
RCC_DeInit();
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_1); // Flash 1 wait state for 48MHz
RCC_CFGR_CFG()
;
RCC_PLL_EN()
;
RCC_HSICmd(ENABLE);
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08) {
}
RCC_AHBPeriphClockCmd(
RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2 |
RCC_AHBPeriph_FLITF, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); // USBCLK = 48MHz
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000); //Enable the systick timer at 1ms
}
/*
* Shift the NVIC (Interrupt table) location relative to flash start
*/
void NVIC_Config(u16 tab_offset) {
NVIC_SetVectorTable(NVIC_VectTab_FLASH, tab_offset);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
}
/*
* Setup the GPIO
*/
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // GPIOB & AFIO
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//------ PA7 TMP36 Analog input ----------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------ OLED_RST_PIN(PB9) ---------------------------------------------//
GPIO_InitStructure.GPIO_Pin = OLED_RST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------- Heat_Pin - Iron enable output PB4-----------------------------//
GPIO_InitStructure.GPIO_Pin = HEAT_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//----------- PB0 Iron temp input---------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//---------- INPUT Voltage Detection Pin VB PB1(Ai9) -------------------//
GPIO_InitStructure.GPIO_Pin = VB_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//-------- K1 = PA9, K2 = PA6 ------------------------------------------//
GPIO_InitStructure.GPIO_Pin = KEY1_PIN | KEY2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//--------INT 1 == PB5 -------------------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//pullup just in case something resets the accel
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*
* Init the ADC's
* Setup ADC1 to read via DMA to device ram automatically
*/
void Adc_Init(void) {
u32 timeout = 10 * 0x1000;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* DMA1 channel1 configuration ---------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
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);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
// ADC1 configuration ------------------------------------------------------//
ADC_DeInit(ADC1);
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 = 2;
ADC_Init(ADC1, &ADC_InitStructure);
// ADC2 configuration ------------------------------------------------------//
ADC_DeInit(ADC2);
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(ADC2, &ADC_InitStructure);
// ADC1,2 regular channel7 channel9 and channel8 configuration ----------//
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2,
ADC_SampleTime_239Cycles5); //28 or 55
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1,
ADC_SampleTime_239Cycles5); //28 or 55
ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 1,
ADC_SampleTime_55Cycles5); //28 or 55
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 */
ADC_Cmd(ADC2, ENABLE); /* Enable ADC2 */
ADC_ResetCalibration(ADC1); /* Enable ADC1 reset calibaration register */
while (ADC_GetResetCalibrationStatus(ADC1))
if (!timeout--)
return; /* Check the end of ADC1 reset calibration register */
ADC_ResetCalibration(ADC2); /* Enable ADC2 reset calibaration register */
timeout = 10 * 0x1000;
while (ADC_GetResetCalibrationStatus(ADC2))
if (!timeout--)
return; /* Check the end of ADC2 reset calibration register */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
}
/*
* Init Timer3 to fire every 50us to be used to control the irons software PWM
* This needs to be really fast as there is a cap used between this and the driver circuitry
* That prevents a stuck mcu heating the tip
*/
void Init_Timer3(void) {
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
TIM_TimeBaseStructure.TIM_Prescaler = 48 - 1; //(48MHz)/48 = 1MHz
TIM_TimeBaseStructure.TIM_Period = 50 - 1; // Interrupt per 50us
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//We want to enable the EXTI IRQ for the two buttons on PA6 and PA9
void Init_EXTI(void) {
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,
GPIO_PinSource6 | GPIO_PinSource9);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,
GPIO_PinSource5); //PB5 == accelerometer
/* Configure EXTI5/6/9 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line5 | EXTI_Line6 | EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //trigger on up and down
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI9_5 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//Start the system watchdog with a timeout specified
//Note you cannot turn this off once you turn it on
void Start_Watchdog(uint32_t ms) {
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
/* IWDG counter clock: 40KHz(LSI) / 32 = 1.25 KHz (min:0.8ms -- max:3276.8ms */
IWDG_SetPrescaler(IWDG_Prescaler_32);
/* Set counter reload value to XXms */
IWDG_SetReload(ms * 10 / 8);
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();
}
//Reset the system watchdog
void Clear_Watchdog(void) {
IWDG_ReloadCounter();
}
//TIM3_ISR handles the tick of the timer 3 IRQ
void TIM3_ISR(void) {
volatile static u8 heat_flag = 0;
//heat flag == used to make the pin toggle
//As the output is passed through a cap, the iron is on whilever we provide a square wave drive output
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
// Clear interrupt flag
if (gHeat_cnt > 0) {
--gHeat_cnt;
if (heat_flag)
HEAT_OFF(); //write the pin off
else
HEAT_ON(); //write the pin on
heat_flag = !heat_flag;
} else {
HEAT_OFF(); //set the pin low for measurements
heat_flag = 0;
}
}