1 Star 2 Fork 2

蓝凌风/EmbeddedLib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
swm32_bsp.c 61.40 KB
一键复制 编辑 原始数据 按行查看 历史
蓝凌风 提交于 2021-08-10 08:30 . 1、增加SWM32的BSP
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
#include "bsp.h"
#include "string.h"
#ifdef USE_PRINTF
#include "stdio.h"
#include "stdlib.h"
#include "stdarg.h"
#endif
/***************************************************************************************************
* GPIO API
*/
#ifdef USE_GPIO
#if 0
static void _g_afio_gpio_init(AFIO_GPIO *afio_gpio)
{
_g_set_clk(afio_gpio->gpiox);
/* Configure IO in output push-pull mode to drive external GPIO */
LL_GPIO_SetPinMode((GPIO_TypeDef *)afio_gpio->gpiox, afio_gpio->gpio_pinx, LL_GPIO_MODE_ALTERNATE);
/* Reset value is LL_GPIO_OUTPUT_PUSHPULL */
LL_GPIO_SetPinOutputType((GPIO_TypeDef *)afio_gpio->gpiox, afio_gpio->gpio_pinx, LL_GPIO_OUTPUT_PUSHPULL);
/* Reset value is LL_GPIO_SPEED_FREQ_LOW */
LL_GPIO_SetPinSpeed((GPIO_TypeDef *)afio_gpio->gpiox, afio_gpio->gpio_pinx, LL_GPIO_SPEED_FREQ_LOW);
/* Reset value is LL_GPIO_PULL_NO */
LL_GPIO_SetPinPull((GPIO_TypeDef *)afio_gpio->gpiox, afio_gpio->gpio_pinx, LL_GPIO_PULL_UP);
#ifndef STM32F1
if(afio_gpio->gpio_pinx<GPIO_PIN_7)
LL_GPIO_SetAFPin_0_7(afio_gpio->gpiox,afio_gpio->gpio_pinx,afio_gpio->gpio_af);
else
LL_GPIO_SetAFPin_8_15(afio_gpio->gpiox,afio_gpio->gpio_pinx,afio_gpio->gpio_af);
#endif
}
AFIO_GPIO new_afio_gpio(GPIO_TypeDef * gpiox,uint32_t gpio_pinx,uint32_t gpio_afx)
{
AFIO_GPIO temp;
temp.gpiox = gpiox;
temp.gpio_pinx = gpio_pinx;
temp.gpio_af = gpio_afx;
temp.init = _g_afio_gpio_init;
temp.init(&temp);
return temp;
}
#endif
static void _g_outputport_init(OutputPort *outputport)
{
GPIO_Init(outputport->gpiox, outputport->gpio_pinx, 1, 0, 0);
}
static void _g_toggle(OutputPort *outputport)
{
GPIO_InvBit((GPIO_TypeDef *)outputport->gpiox,outputport->gpio_pinx);
}
static void _g_setbit(OutputPort *outputport)
{
GPIO_SetBit((GPIO_TypeDef *)outputport->gpiox,outputport->gpio_pinx);
}
static void _g_resetbit(OutputPort *outputport)
{
GPIO_ClrBit((GPIO_TypeDef *)outputport->gpiox,outputport->gpio_pinx);
}
static void _g_write_bit(OutputPort *outputport,uint8_t bit)
{
if(bit)
{
_g_setbit(outputport);
}else
{
_g_resetbit(outputport);
}
}
OutputPort new_outport(GPIO_TypeDef * gpiox,uint32_t gpio_pinx)
{
OutputPort temp;
temp.gpiox = gpiox;
temp.gpio_pinx = gpio_pinx;
temp.init = _g_outputport_init;
temp.set_bit = _g_setbit;
temp.reset_bit = _g_resetbit;
temp.toggle = _g_toggle;
temp.write_bit = _g_write_bit;
temp.init(&temp);
return temp;
}
#if 0
static void _g_input_init(InputPort *inputport)
{
/* enable the key clock */
_g_set_clk(inputport->gpiox);
/* Configure IO in output push-pull mode to drive external GPIO */
LL_GPIO_SetPinMode(inputport->gpiox, inputport->gpio_pinx, LL_GPIO_MODE_INPUT);
#ifndef STM32F1
/* Reset value is LL_GPIO_SPEED_FREQ_LOW */
LL_GPIO_SetPinSpeed(inputport->gpiox, inputport->gpio_pinx, LL_GPIO_SPEED_FREQ_HIGH);
#endif
/* Reset value is LL_GPIO_PULL_NO */
LL_GPIO_SetPinPull(inputport->gpiox, inputport->gpio_pinx, LL_GPIO_PULL_UP);
}
static void _g_exti_init(InputPort *inputport)
{
#ifdef GD32F4XX
rcu_periph_clock_enable(RCU_SYSCFG);
/* enable and set key EXTI interrupt to the lowest priority */
uint8_t pin_source;
uint8_t irqn;
switch(inputport->gpio_pinx)
{
case GPIO_PIN_0:irqn = EXTI0_IRQn; pin_source = EXTI_SOURCE_PIN0; inputport->exit_line = EXTI_0;break;
case GPIO_PIN_1:irqn = EXTI1_IRQn; pin_source = EXTI_SOURCE_PIN1; inputport->exit_line = EXTI_1;break;
case GPIO_PIN_2:irqn = EXTI2_IRQn; pin_source = EXTI_SOURCE_PIN2;inputport->exit_line = EXTI_2;break;
case GPIO_PIN_3:irqn = EXTI3_IRQn; pin_source = EXTI_SOURCE_PIN3;inputport->exit_line = EXTI_3;break;
case GPIO_PIN_4:irqn = EXTI4_IRQn; pin_source = EXTI_SOURCE_PIN4;inputport->exit_line = EXTI_4;break;
case GPIO_PIN_5:irqn = EXTI5_9_IRQn; pin_source = EXTI_SOURCE_PIN5;inputport->exit_line = EXTI_5;break;
case GPIO_PIN_6:irqn = EXTI5_9_IRQn; pin_source = EXTI_SOURCE_PIN6;inputport->exit_line = EXTI_6;break;
case GPIO_PIN_7:irqn = EXTI5_9_IRQn; pin_source = EXTI_SOURCE_PIN7;inputport->exit_line = EXTI_7;break;
case GPIO_PIN_8:irqn = EXTI5_9_IRQn; pin_source = EXTI_SOURCE_PIN8;inputport->exit_line = EXTI_8;break;
case GPIO_PIN_9:irqn = EXTI5_9_IRQn; pin_source = EXTI_SOURCE_PIN9;inputport->exit_line = EXTI_9;break;
case GPIO_PIN_10:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN10;inputport->exit_line = EXTI_10;break;
case GPIO_PIN_11:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN11;inputport->exit_line = EXTI_11;break;
case GPIO_PIN_12:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN12;inputport->exit_line = EXTI_12;break;
case GPIO_PIN_13:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN13;inputport->exit_line = EXTI_13;break;
case GPIO_PIN_14:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN14;inputport->exit_line = EXTI_14;break;
case GPIO_PIN_15:irqn = EXTI10_15_IRQn;pin_source = EXTI_SOURCE_PIN15;inputport->exit_line = EXTI_15;break;
default:break;
}
uint8_t port_source;
switch(inputport->gpiox)
{
case GPIOA:port_source = EXTI_SOURCE_GPIOA;break;
case GPIOB:port_source = EXTI_SOURCE_GPIOB;break;
case GPIOC:port_source = EXTI_SOURCE_GPIOC;break;
case GPIOD:port_source = EXTI_SOURCE_GPIOD;break;
case GPIOE:port_source = EXTI_SOURCE_GPIOE;break;
case GPIOF:port_source = EXTI_SOURCE_GPIOF;break;
case GPIOG:port_source = EXTI_SOURCE_GPIOG;break;
case GPIOH:port_source = EXTI_SOURCE_GPIOH;break;
case GPIOI:port_source = EXTI_SOURCE_GPIOI;break;
default:break;
}
nvic_irq_enable(irqn , 0U, 2U);
/* connect key EXTI line to key GPIO pin */
syscfg_exti_line_config(port_source,pin_source);
/* configure key EXTI line */
exti_init(inputport->exit_line, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(inputport->exit_line);
#endif
}
static uint8_t _g_read(InputPort *inputport)
{
return LL_GPIO_IsInputPinSet(inputport->gpiox,inputport->gpio_pinx);
}
InputPort new_inputport(GPIO_TypeDef * gpiox,uint32_t gpio_pinx,uint8_t inputmode,uint8_t trig_type)
{
InputPort temp;
temp.gpiox = gpiox;
temp.gpio_pinx = gpio_pinx;
temp.inputmode = inputmode;
temp.trig_type = trig_type;
temp.init = _g_input_init;
temp.read = _g_read;
temp.init(&temp);
return temp;
}
InputPort new_inputport_interuput(GPIO_TypeDef * gpiox,uint32_t gpio_pinx,uint8_t trig_type,pfun callback,void *arg)
{
InputPort temp;
temp.gpiox = gpiox;
temp.gpio_pinx = gpio_pinx;
temp.init = _g_input_init;
temp.read = _g_read;
temp.exti_init = _g_exti_init;
temp.callback = callback;
temp.arg = arg;
temp.init(&temp);
temp.exti_init(&temp);
return temp;
}
static void _g_opendrainport_init(OpenDrainPort *opendrainport)
{
_g_set_clk(opendrainport->gpiox);
/* Configure IO in output push-pull mode to drive external GPIO */
LL_GPIO_SetPinMode((GPIO_TypeDef *)opendrainport->gpiox, opendrainport->gpio_pinx, LL_GPIO_MODE_OUTPUT);
/* Reset value is LL_GPIO_OUTPUT_PUSHPULL */
LL_GPIO_SetPinOutputType((GPIO_TypeDef *)opendrainport->gpiox, opendrainport->gpio_pinx, LL_GPIO_OUTPUT_OPENDRAIN);
/* Reset value is LL_GPIO_SPEED_FREQ_LOW */
LL_GPIO_SetPinSpeed((GPIO_TypeDef *)opendrainport->gpiox, opendrainport->gpio_pinx, LL_GPIO_SPEED_FREQ_HIGH);
/* Reset value is LL_GPIO_PULL_NO */
LL_GPIO_SetPinPull((GPIO_TypeDef *)opendrainport->gpiox, opendrainport->gpio_pinx, LL_GPIO_PULL_UP);
}
OpenDrainPort new_opendrainport(GPIO_TypeDef * gpiox,uint32_t gpio_pinx)
{
OpenDrainPort temp;
temp.gpiox = gpiox;
temp.gpio_pinx = gpio_pinx;
temp.init = _g_opendrainport_init;
#ifndef STM32F1
temp.input = new_inputport(gpiox,gpio_pinx,0,0);
#else
temp.input = new_inputport(gpiox,gpio_pinx,LL_GPIO_MODE_INPUT,0);
#endif
temp.output = new_outport(gpiox,gpio_pinx);
temp.read = (uint8_t(*)(OpenDrainPort *))temp.input.read;
temp.set_bit = (void (*)(OpenDrainPort *))temp.output.set_bit;
temp.reset_bit = (void (*)(OpenDrainPort *))temp.output.reset_bit;
temp.toggle = (void (*)(OpenDrainPort *))temp.output.toggle;
temp.init(&temp);
return temp;
}
#endif
static void _l_on(LED *led)
{
if(led->level)
{
led->outputport.set_bit(&led->outputport);
}else{
led->outputport.reset_bit(&led->outputport);
}
}
static void _l_off(LED *led)
{
if(led->level)
{
led->outputport.reset_bit(&led->outputport);
}else{
led->outputport.set_bit(&led->outputport);
}
}
LED new_led(GPIO_TypeDef * gpiox,uint32_t gpio_pinx,uint8_t level)
{
LED temp;
temp.level = level;
temp.outputport = new_outport(gpiox,gpio_pinx);
temp.toggle =(void(*)(LED *))temp.outputport.toggle;
temp.on = _l_on;
temp.off = _l_off;
temp.outputport.init(&temp.outputport);
return temp;
}
#ifdef USE_ADC
static void _g_analog_gpio_init(GPIO_TypeDef * gpiox,uint32_t gpio_pinx)
{
_g_set_clk(gpiox);
/* Configure IO in output push-pull mode to drive external GPIO */
LL_GPIO_SetPinMode(gpiox,gpio_pinx, LL_GPIO_MODE_ANALOG);
/* Reset value is LL_GPIO_OUTPUT_PUSHPULL */
//LL_GPIO_SetPinOutputType(gpiox, gpio_pinx, LL_GPIO_OUTPUT_PUSHPULL);
/* Reset value is LL_GPIO_SPEED_FREQ_LOW */
//LL_GPIO_SetPinSpeed(gpiox, gpio_pinx, LL_GPIO_SPEED_FREQ_LOW);
/* Reset value is LL_GPIO_PULL_NO */
//LL_GPIO_SetPinPull(gpiox, gpio_pinx, LL_GPIO_PULL_UP);
}
#endif
#endif
/***************************************************************************************************
* UART API
*/
#ifdef USE_UART
static void _uart_init(UART *uart)
{
switch((uint32_t)uart->uartx)
{
#ifdef STM32F0
#if defined(USART1)
case (uint32_t)USART1: LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1);NVIC_SetPriority(USART1_IRQn,0);NVIC_EnableIRQ(USART1_IRQn);break;
#endif
#if defined(USART2)
case (uint32_t)USART2: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);NVIC_SetPriority(USART2_IRQn,0);NVIC_EnableIRQ(USART2_IRQn);break;
#endif
#if defined(USART3)
case (uint32_t)USART3: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);NVIC_SetPriority(USART3_IRQn,0);NVIC_EnableIRQ(USART3_IRQn);break;
#endif
#if defined(UART4)
case (uint32_t)UART4: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART4);NVIC_SetPriority(USART4_IRQn,0);NVIC_EnableIRQ(USART4_IRQn);break;
#endif
#if defined(UART5)
case (uint32_t)UART5: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART5);NVIC_SetPriority(USART5_IRQn,0);NVIC_EnableIRQ(USART5_IRQn);break;
#endif
#if defined(USART6)
case (uint32_t)USART6: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART6);NVIC_SetPriority(USART6_IRQn,0);NVIC_EnableIRQ(USART6_IRQn);break;
#endif
#if defined(USART7)
case (uint32_t)USART7: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART7);NVIC_SetPriority(USART7_IRQn,0);NVIC_EnableIRQ(USART7_IRQn);break;
#endif
#if defined(USART8)
case (uint32_t)USART8: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART8);NVIC_SetPriority(USART8_IRQn,0);NVIC_EnableIRQ(USART8_IRQn);break;
#endif
#elif defined(STM32F1)
#if defined(USART1)
case (uint32_t)USART1: LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);NVIC_SetPriority(USART1_IRQn,0);NVIC_EnableIRQ(USART1_IRQn);break;
#endif
#if defined(USART2)
case (uint32_t)USART2: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);NVIC_SetPriority(USART2_IRQn,0);NVIC_EnableIRQ(USART2_IRQn);break;
#endif
#if defined(USART3)
case (uint32_t)USART3: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);NVIC_SetPriority(USART3_IRQn,0);NVIC_EnableIRQ(USART3_IRQn);break;
#endif
#if defined(UART4)
case (uint32_t)UART4: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART4);NVIC_SetPriority(UART4_IRQn,0);NVIC_EnableIRQ(UART4_IRQn);break;
#endif
#if defined(UART5)
case (uint32_t)UART5: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART5);NVIC_SetPriority(UART5_IRQn,0);NVIC_EnableIRQ(UART5_IRQn);break;
#endif
#if defined(USART6)
case (uint32_t)USART6: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART6);NVIC_SetPriority(USART6_IRQn,0);NVIC_EnableIRQ(USART6_IRQn);break;
#endif
#if defined(USART7)
case (uint32_t)USART7: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART7);NVIC_SetPriority(USART7_IRQn,0);NVIC_EnableIRQ(USART7_IRQn);break;
#endif
#if defined(USART8)
case (uint32_t)USART8: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART8);NVIC_SetPriority(USART8_IRQn,0);NVIC_EnableIRQ(USART8_IRQn);break;
#endif
#endif
default :break;
}
/* USART configure */
/* Disable USART prior modifying configuration registers */
/* Note: Commented as corresponding to Reset value */
// LL_USART_Disable(USARTx_INSTANCE);
/* TX/RX direction */
LL_USART_SetTransferDirection(uart->uartx, LL_USART_DIRECTION_TX_RX);
/* 8 data bit, 1 start bit, 1 stop bit, no parity */
LL_USART_ConfigCharacter(uart->uartx, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);
/* No Hardware Flow control */
/* Reset value is LL_USART_HWCONTROL_NONE */
// LL_USART_SetHWFlowCtrl(uart->uartx, LL_USART_HWCONTROL_NONE);
/* Oversampling by 16 */
/* Reset value is LL_USART_OVERSAMPLING_16 */
//LL_USART_SetOverSampling(uart->uartx, LL_USART_OVERSAMPLING_16);
/* Set Baudrate to 115200 using APB frequency set to 48000000 Hz */
/* Frequency available for USART peripheral can also be calculated through LL RCC macro */
/* Ex :
Periphclk = LL_RCC_GetUSARTClockFreq(Instance); or LL_RCC_GetUARTClockFreq(Instance); depending on USART/UART instance
In this example, Peripheral Clock is expected to be equal to 48000000 Hz => equal to SystemCoreClock
*/
// LL_USART_SetBaudRate(uart->uartx, SystemCoreClock, LL_USART_OVERSAMPLING_16, uart->baudrate);
#if defined(USART_CR1_OVER8)
LL_USART_SetBaudRate(USARTx,
periphclk,
USART_InitStruct->OverSampling,
USART_InitStruct->BaudRate);
#else
LL_USART_SetBaudRate(uart->uartx,
SystemCoreClock,
uart->baudrate);
#endif /* USART_OverSampling_Feature */
/* (5) Enable USART *********************************************************/
LL_USART_Enable(uart->uartx);
#ifndef STM32F1
/* Polling USART initialisation */
while((!(LL_USART_IsActiveFlag_TEACK(uart->uartx))) || (!(LL_USART_IsActiveFlag_REACK(uart->uartx))))
{
}
#endif
}
static void _uart_senddata(UART *uart,uint8_t buf)
{
while (!LL_USART_IsActiveFlag_TXE(uart->uartx) && !LL_USART_IsActiveFlag_TC(uart->uartx));
LL_USART_TransmitData8(uart->uartx,buf);
}
static void _uart_sendbuf(UART *uart,uint8_t *buf, uint16_t size)
{
for (uint16_t i = 0; i < size; i++)
{
_uart_senddata(uart,buf[i]);
}
}
static void _uart_sendString(UART *uart,char *buf)
{
while (*buf != 0)
{
_uart_senddata(uart,*buf);
buf++;
}
}
#ifdef USE_PRINTF
static void _uart_printf(UART *uart, const char* fmt, ...)
{
uint16_t len;
char printfbuf[300];
memset(printfbuf, 0, 300);
va_list ap;
va_start(ap, fmt);
len = vsprintf(printfbuf, fmt, ap);
va_end(ap);
_uart_sendbuf(uart, (uint8_t*)printfbuf, len);
}
#endif
static void _uart_RecvFixCntIT(UART *uart,uint8_t *buf,uint16_t size)
{
if(0 == size){
return ;
}
if(0 != buf)
{
memset(buf,0,size);
}
#ifdef CMSIS_OS
/* create a binary semaphore used for informing ethernetif of frame reception */
if(0 == uart->uart_recv_sem)
{
osSemaphoreDef(SEM_UART_RX);
uart->uart_recv_sem = osSemaphoreCreate(osSemaphore(SEM_UART_RX) , 1 );
osSemaphoreWait(uart->uart_recv_sem,timeout);
}
#endif
uart->recvbuf = buf;
uart->recvsize = size;
uart->recvcnt = 0;
uart->isgetrecv = 0;
uart->RecvMode = RECV_MODE_FIX_IT;
/* Enable RXNE and Error interrupts */
LL_USART_EnableIT_RXNE(uart->uartx);
LL_USART_EnableIT_ERROR(uart->uartx);
//usart_interrupt_flag_clear(uart->uartx, USART_INT_FLAG_RBNE);
}
static void _uart_RecvTimeoutIT(UART *uart,uint8_t *buf,uint16_t size,uint8_t timeout)
{
if(0 == size){
return ;
}
if(0 != buf)
{
memset(buf,0,size);
}
#ifdef CMSIS_OS
/* create a binary semaphore used for informing ethernetif of frame reception */
if(0 == uart->uart_recv_sem)
{
osSemaphoreDef(SEM_UART_RX);
uart->uart_recv_sem = osSemaphoreCreate(osSemaphore(SEM_UART_RX) , 1 );
osSemaphoreWait(uart->uart_recv_sem,timeout);
}
#endif
uart->recvbuf = buf;
uart->recvsize = size;
uart->recvcnt = 0;
uart->isgetrecv = 0;
uart->RecvMode = RECV_MODE_TIMEOUT_IT;
uart->timeout = timeout;
#ifndef STM32F1
LL_USART_EnableRxTimeout(uart->uartx);
LL_USART_SetRxTimeout(uart->uartx, uart->timeout);
LL_USART_EnableIT_RTO(uart->uartx);
#endif
/* Enable RXNE and Error interrupts */
LL_USART_EnableIT_RXNE(uart->uartx);
LL_USART_EnableIT_ERROR(uart->uartx);
}
#ifdef CMSIS_OS
static uint8_t _uart_waitforrecv(UART *uart,uint32_t waittime)
{
return osSemaphoreWait( uart->uart_recv_sem, waittime);
}
#endif
void Uart_timeout_Handle(UART *uart)
{
if(uart->rxtimeoutcnt)
{
uart->rxtimeoutcnt++;
if(uart->rxtimeoutcnt > uart->rxtimeoutset)
{
uart->rxtimeoutcnt = 0;
uart->isgetrecv = 1;
}
}
}
void Uart_Interrupt_Handle(UART *uart)
{
uint8_t temp;
if( LL_USART_IsActiveFlag_RXNE(uart->uartx) && LL_USART_IsEnabledIT_RXNE(uart->uartx))
{
// usart_interrupt_flag_clear(uart->uartx, USART_INT_FLAG_RBNE);
/* receive data */
if(uart->recvcnt < uart->recvsize)
{
temp = (LL_USART_ReceiveData8(uart->uartx) & 0xFF);
*(uart->recvbuf + uart->recvcnt++) = temp;
uart->rxtimeoutcnt = 1;
}
}
#ifndef STM32F1
else if(LL_USART_IsActiveFlag_RTO(uart->uartx))
{
LL_USART_ClearFlag_RTO(uart->uartx);
if(uart->RecvMode == RECV_MODE_TIMEOUT_IT)
{
uart->isgetrecv = 1;
LL_USART_DisableIT_RXNE(uart->uartx);
LL_USART_DisableIT_ERROR(uart->uartx);
LL_USART_DisableIT_RTO(uart->uartx);
if(uart->RecvCallBack != NULL)
{
uart->RecvCallBack(uart->RecvCBArg);
_uart_RecvTimeoutIT(uart,uart->recvbuf,uart->recvsize,uart->timeout);
}
}
}
#endif
if(uart->RecvMode == RECV_MODE_FIX_IT)
{
if(uart->recvcnt == uart->recvsize)
{
uart->isgetrecv = 1;
#ifdef CMSIS_OS
osSemaphoreRelease(uart->uart_recv_sem);
#endif
LL_USART_DisableIT_RXNE(uart->uartx);
LL_USART_DisableIT_ERROR(uart->uartx);
if(uart->RecvCallBack != NULL)
{
uart->RecvCallBack(uart->RecvCBArg);
uart->isgetrecv = 0;
}
}
}
#ifndef STM32F1
if(LL_USART_IsActiveFlag_ORE(uart->uartx))
{
LL_USART_ClearFlag_ORE(uart->uartx);
}
if(LL_USART_IsActiveFlag_FE(uart->uartx))
{
LL_USART_ClearFlag_FE(uart->uartx);
}
#endif
}
static void _uart_SetRecvCallBack(UART *uart,pfun callback,void *arg)
{
if(callback != NULL) uart->RecvCallBack = callback;
if(arg != NULL)uart->RecvCBArg = arg;
}
UART new_uart(GPIO_TypeDef * txd_gpiox,uint32_t txd_gpio_pinx,GPIO_TypeDef * rxd_gpiox,uint32_t rxd_gpio_pinx,USART_TypeDef * uartx,uint32_t baudrate)
{
UART temp;
#ifndef STM32F1
temp.txd_pin = new_afio_gpio(txd_gpiox,txd_gpio_pinx,LL_GPIO_AF_1);
temp.rxd_pin = new_afio_gpio(rxd_gpiox,rxd_gpio_pinx,LL_GPIO_AF_1);
#else
temp.txd_pin = new_afio_gpio(txd_gpiox,txd_gpio_pinx,0);
temp.rxd_pin = new_inputport(rxd_gpiox,rxd_gpio_pinx,LL_GPIO_MODE_INPUT,0);
#endif
temp.uartx = uartx;
temp.baudrate = baudrate;
temp.init = _uart_init;
temp.senddata = _uart_senddata;
temp.sendbuf = _uart_sendbuf;
#ifdef USE_PRINTF
temp.printf = _uart_printf;
#endif
temp.sendString=_uart_sendString;
temp.RecvFixCntIT = _uart_RecvFixCntIT;
temp.SetRecvCallBack = _uart_SetRecvCallBack;
temp.RecvTimeoutIT = _uart_RecvTimeoutIT;
temp.RecvCallBack = NULL;
temp.RecvCBArg = NULL;
#ifdef CMSIS_OS
temp.uart_recv_sem = NULL;
temp.WaitforRecv = _uart_waitforrecv;
#endif
temp.init(&temp);
return temp;
}
#ifdef DEBUG
UART *log_uart;
void uart_set_log_uart(UART *uart)
{
log_uart = uart;
}
#endif
#endif
/***************************************************************************************************
* ADC API
*/
#ifdef USE_ADC
static void _adc_add_chanel(ADC_CTL *adc,GPIO_TypeDef * ch_gpiox,uint32_t ch_gpio_pinx,uint32_t ch
#ifndef STM32F0
,uint32_t SamplingTime
#endif
)
{
adc->adc_chanel[adc->used_chanel_num].ch_gpiox = ch_gpiox;
adc->adc_chanel[adc->used_chanel_num].ch_gpio_pinx = ch_gpio_pinx;
adc->adc_chanel[adc->used_chanel_num].chx = ch;
#ifndef STM32F0
adc->adc_chanel[adc->used_chanel_num].SamplingTime = SamplingTime;
#endif
adc->used_chanel_num++;
}
static void _adc_init(ADC_CTL *adc)
{
for(uint8_t i = 0;i < adc->used_chanel_num;i++)
{
if(adc->adc_chanel[i].ch_gpiox != NULL && adc->adc_chanel[i].ch_gpio_pinx!= NULL)
_g_analog_gpio_init(adc->adc_chanel[i].ch_gpiox,adc->adc_chanel[i].ch_gpio_pinx);
}
/* Enable ADC clock (core clock) */
switch ((uint32_t)adc->adcx)
{
#ifdef STM32F0
#ifdef ADC1
case (uint32_t)ADC1: LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);break;
#endif
#ifdef ADC2
case (uint32_t)ADC2: LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC2);break;
#endif
#ifdef ADC3
case (uint32_t)ADC3: LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC3);break;
#endif
#elif defined(STM32F1)
#ifdef ADC1
case (uint32_t)ADC1: LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);adc->IRQn = ADC1_IRQn;break;
#endif
#ifdef ADC2
case (uint32_t)ADC2: LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC2);adc->IRQn = ADC1_2_IRQn;break;
#endif
#ifdef ADC3
case (uint32_t)ADC3: LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC3);IRQn = ADC3_IRQn;break;
#endif
#endif
default:
break;
}
/*## Configuration of ADC hierarchical scope: ADC instance #################*/
/* Note: Hardware constraint (refer to description of the functions */
/* below): */
/* On this STM32 serie, setting of these features is conditioned to */
/* ADC state: */
/* ADC must be disabled. */
if (LL_ADC_IsEnabled(adc->adcx) == 0)
{
/* Note: Call of the functions below are commented because they are */
/* useless in this example: */
/* setting corresponding to default configuration from reset state. */
/* Set ADC group regular trigger source */
LL_ADC_REG_SetTriggerSource(adc->adcx, LL_ADC_REG_TRIG_SOFTWARE); //default software trigger
#ifdef STM32F0
/* Set ADC clock (conversion clock) */
LL_ADC_SetClock(adc->adcx, LL_ADC_CLOCK_SYNC_PCLK_DIV2);
/* Set ADC data resolution */
LL_ADC_SetResolution(adc->adcx, LL_ADC_RESOLUTION_12B);
/* Set ADC conversion data alignment */
LL_ADC_SetResolution(adc->adcx, LL_ADC_DATA_ALIGN_RIGHT);
/* Set ADC low power mode */
LL_ADC_SetLowPowerMode(adc->adcx, LL_ADC_LP_MODE_NONE);
#elif defined(STM32F1)
/* Set ADC group regular continuous mode */
LL_ADC_REG_SetContinuousMode(adc->adcx, LL_ADC_REG_CONV_SINGLE); //default
/* Set ADC conversion data alignment */
LL_ADC_SetDataAlignment(adc->adcx, LL_ADC_DATA_ALIGN_RIGHT);
/* Set Set ADC sequencers scan mode, for all ADC groups */
/* (group regular, group injected). */
LL_ADC_SetSequencersScanMode(adc->adcx, LL_ADC_SEQ_SCAN_DISABLE);
#endif
/* Set ADC group regular sequencer */
/* Note: On this STM32 serie, ADC group regular sequencer is */
/* not fully configurable: sequencer length and each rank */
/* affectation to a channel are fixed by channel HW number. */
/* Refer to description of function */
/* "LL_ADC_REG_SetSequencerChannels()". */
/* Case of STM32F0xx: */
/* ADC Channel ADC_CHANNEL_TEMPSENSOR is on ADC channel 16, */
/* there is 1 other channel enabled with lower channel number. */
/* Therefore, ADC_CHANNEL_TEMPSENSOR will be converted by the */
/* sequencer as the 2nd rank. */
/* ADC Channel ADC_CHANNEL_VREFINT is on ADC channel 17, */
/* there are 2 other channels enabled with lower channel number. */
/* Therefore, ADC_CHANNEL_VREFINT will be converted by the */
/* sequencer as the 3rd rank. */
/* Set ADC group regular sequencer discontinuous mode */
LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_1RANK);
/* Set ADC channels sampling time */
/* Note: On this STM32 serie, sampling time is common to all channels */
/* of the entire ADC instance. */
/* Therefore, sampling time is configured here under ADC instance */
/* scope (not under channel scope as on some other STM32 devices */
/* on which sampling time is channel wise). */
/* Note: Considering interruption occurring after each ADC group */
/* regular sequence conversions */
/* (IT from DMA transfer complete), */
/* select sampling time and ADC clock with sufficient */
/* duration to not create an overhead situation in IRQHandler. */
#ifdef STM32F0
LL_ADC_SetSamplingTimeCommonChannels(adc->adcx, LL_ADC_SAMPLINGTIME_239CYCLES_5);
uint32_t chanel = 0;
for(uint8_t i = 0;i < adc->used_chanel_num;i++)
{
switch (adc->adc_chanel[i].chx)
{
case 0: chanel |= LL_ADC_CHANNEL_0; break;
case 1: chanel |= LL_ADC_CHANNEL_1; break;
case 2: chanel |= LL_ADC_CHANNEL_2; break;
case 3: chanel |= LL_ADC_CHANNEL_3; break;
case 4: chanel |= LL_ADC_CHANNEL_4; break;
case 5: chanel |= LL_ADC_CHANNEL_5; break;
case 6: chanel |= LL_ADC_CHANNEL_6; break;
case 7: chanel |= LL_ADC_CHANNEL_7; break;
case 8: chanel |= LL_ADC_CHANNEL_8; break;
case 9: chanel |= LL_ADC_CHANNEL_9; break;
case 10: chanel |= LL_ADC_CHANNEL_10; break;
case 11: chanel |= LL_ADC_CHANNEL_11; break;
case 12: chanel |= LL_ADC_CHANNEL_12; break;
case 13: chanel |= LL_ADC_CHANNEL_13; break;
case 14: chanel |= LL_ADC_CHANNEL_14; break;
case 15: chanel |= LL_ADC_CHANNEL_15; break;
case 16: chanel |= LL_ADC_CHANNEL_16; break;
case 17: chanel |= LL_ADC_CHANNEL_17; break;
default:
break;
}
}
LL_ADC_REG_SetSequencerChannels(adc->adcx, chanel);
#else
uint32_t adc_reg_rank = 0;
LL_ADC_REG_SetSequencerLength(adc->adcx,(adc->used_chanel_num-1) <<ADC_SQR1_L_Pos);
for(uint8_t i = 0;i < adc->used_chanel_num;i++)
{
switch(i)
{
case 0: adc_reg_rank = LL_ADC_REG_RANK_1;break;
case 1: adc_reg_rank = LL_ADC_REG_RANK_2;break;
case 2: adc_reg_rank = LL_ADC_REG_RANK_3;break;
case 3: adc_reg_rank = LL_ADC_REG_RANK_4;break;
case 4: adc_reg_rank = LL_ADC_REG_RANK_5;break;
case 5: adc_reg_rank = LL_ADC_REG_RANK_6;break;
case 6: adc_reg_rank = LL_ADC_REG_RANK_7;break;
case 7: adc_reg_rank = LL_ADC_REG_RANK_8;break;
case 8: adc_reg_rank = LL_ADC_REG_RANK_9;break;
case 9: adc_reg_rank = LL_ADC_REG_RANK_10;break;
case 10: adc_reg_rank = LL_ADC_REG_RANK_11;break;
case 11: adc_reg_rank = LL_ADC_REG_RANK_11;break;
case 12: adc_reg_rank = LL_ADC_REG_RANK_12;break;
case 13: adc_reg_rank = LL_ADC_REG_RANK_13;break;
case 14: adc_reg_rank = LL_ADC_REG_RANK_14;break;
case 15: adc_reg_rank = LL_ADC_REG_RANK_15;break;
case 16: adc_reg_rank = LL_ADC_REG_RANK_16;break;
}
switch (adc->adc_chanel[i].chx)
{
case 0: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_0);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_0, adc->adc_chanel[i].SamplingTime);
break;
case 1: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_1);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_1, adc->adc_chanel[i].SamplingTime);
break;
case 2: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_2);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_2, adc->adc_chanel[i].SamplingTime);
break;
case 3: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_3);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_3, adc->adc_chanel[i].SamplingTime);
break;
case 4: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_4);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_4, adc->adc_chanel[i].SamplingTime);
break;
case 5: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_5);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_5, adc->adc_chanel[i].SamplingTime);
break;
case 6: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_6);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_6, adc->adc_chanel[i].SamplingTime);
break;
case 7: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_7);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_7, adc->adc_chanel[i].SamplingTime);
break;
case 8: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_8);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_8, adc->adc_chanel[i].SamplingTime);
break;
case 9: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_9);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_9, adc->adc_chanel[i].SamplingTime);
break;
case 10: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_10, adc->adc_chanel[i].SamplingTime);
break;
case 11: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_11);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_11, adc->adc_chanel[i].SamplingTime);
break;
case 12: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_12);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_12, adc->adc_chanel[i].SamplingTime);
break;
case 13: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_13);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_13, adc->adc_chanel[i].SamplingTime);
break;
case 14: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_14);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_14, adc->adc_chanel[i].SamplingTime);
break;
case 15: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_15);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_15, adc->adc_chanel[i].SamplingTime);
break;
case 16: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_16);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc->adcx),LL_ADC_PATH_INTERNAL_TEMPSENSOR);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_16, adc->adc_chanel[i].SamplingTime);
break;
case 17: LL_ADC_REG_SetSequencerRanks(adc->adcx, adc_reg_rank, LL_ADC_CHANNEL_17);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc->adcx),LL_ADC_PATH_INTERNAL_VREFINT);
LL_ADC_SetChannelSamplingTime(adc->adcx, LL_ADC_CHANNEL_17, adc->adc_chanel[i].SamplingTime);
break;
default:
break;
}
}
#endif
/* Enable ADC */
LL_ADC_Enable(adc->adcx);
/* Run ADC self calibration */
LL_ADC_StartCalibration(adc->adcx);
while (LL_ADC_IsCalibrationOnGoing(adc->adcx) != 0);
}
}
static void _adc_SetTrigger(ADC_CTL *adc,uint32_t trig_type,void * trigger)
{
bpsConfigASSERT(trigger);
adc->Trigger = trigger;
LL_ADC_REG_StartConversionExtTrig(adc->adcx,LL_ADC_REG_TRIG_EXT_RISING);
LL_ADC_REG_SetTriggerSource(adc->adcx, trig_type);
}
static void _ADC_Configure_DMA(ADC_CTL *adc)
{
/*## Configuration of NVIC #################################################*/
/* Configure NVIC to enable DMA interruptions */
// NVIC_SetPriority(DMA1_Channel1_IRQn, 1); /* DMA IRQ lower priority than ADC IRQ */
//NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/*## Configuration of DMA ##################################################*/
/* Enable the peripheral clock of DMA */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
/* Configure the DMA transfer */
/* - DMA transfer in circular mode to match with ADC configuration: */
/* DMA unlimited requests. */
/* - DMA transfer from ADC without address increment. */
/* - DMA transfer to memory with address increment. */
/* - DMA transfer from ADC by half-word to match with ADC configuration: */
/* ADC resolution 12 bits. */
/* - DMA transfer to memory by half-word to match with ADC conversion data */
/* buffer variable type: half-word. */
LL_DMA_ConfigTransfer(DMA1,
LL_DMA_CHANNEL_1,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY |
(adc->IsCircular?LL_DMA_MODE_CIRCULAR:LL_DMA_MODE_NORMAL)|
LL_DMA_PERIPH_NOINCREMENT |
LL_DMA_MEMORY_INCREMENT |
LL_DMA_PDATAALIGN_HALFWORD |
LL_DMA_MDATAALIGN_HALFWORD |
LL_DMA_PRIORITY_HIGH );
/* Set DMA transfer addresses of source and destination */
LL_DMA_ConfigAddresses(DMA1,
LL_DMA_CHANNEL_1,
LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
(uint32_t)adc->buf,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
/* Set DMA transfer size */
LL_DMA_SetDataLength(DMA1,
LL_DMA_CHANNEL_1,
adc->bufsize);
/* Enable DMA transfer interruption: transfer complete */
//LL_DMA_EnableIT_TC(DMA1,
// LL_DMA_CHANNEL_1);
/* Enable DMA transfer interruption: transfer error */
//LL_DMA_EnableIT_TE(DMA1,
// LL_DMA_CHANNEL_1);
/*## Activation of DMA #####################################################*/
/* Enable the DMA transfer */
LL_DMA_EnableChannel(DMA1,
LL_DMA_CHANNEL_1);
}
void ADCx_DMA_IRQHandler(ADC_CTL *adc)
{
/* Check whether DMA transfer complete caused the DMA interruption */
if(LL_DMA_IsActiveFlag_TC1(DMA1) == 1)
{
/* Clear flag DMA global interrupt */
/* (global interrupt flag: half transfer and transfer complete flags) */
LL_DMA_ClearFlag_GI1(DMA1);
/* Call interruption treatment function */
if(adc->ConvCmpCallback != NULL)
{
adc->ConvCmpCallback(adc->ConvCmpCBArg);
}
}
/* Check whether DMA transfer error caused the DMA interruption */
if(LL_DMA_IsActiveFlag_TE1(DMA1) == 1)
{
/* Clear flag DMA transfer error */
LL_DMA_ClearFlag_TE1(DMA1);
/* Call interruption treatment function */
//AdcDmaTransferError_Callback();
}
}
static void _adc_SoftwareTrigger(ADC_CTL *adc)
{
#ifdef STM32F0
if ((LL_ADC_IsEnabled(adc->adcx) == 1) &&
(LL_ADC_IsDisableOngoing(adc->adcx) == 0) &&
(LL_ADC_REG_IsConversionOngoing(adc->adcx) == 0) )
{
LL_ADC_REG_StartConversion(adc->adcx);
}
while (LL_ADC_IsActiveFlag_EOC(ADC1) == 0);
LL_ADC_ClearFlag_EOC(ADC1);
#else
if (LL_ADC_IsEnabled(adc->adcx) == 1)
{
LL_ADC_REG_StartConversionSWStart(adc->adcx);
}
while (LL_ADC_IsActiveFlag_EOS(adc->adcx) == 0);
LL_ADC_ClearFlag_EOS(adc->adcx);
#endif
/* Retrieve ADC conversion data */
/* (data scale corresponds to ADC resolution: 12 bits) */
adc->buf[adc->bufcnt++] = LL_ADC_REG_ReadConversionData12(adc->adcx);
if(adc->bufcnt >= adc->bufsize)
{
if(adc->ConvCmpCallback != NULL)
{
adc->ConvCmpCallback(adc->ConvCmpCBArg);
}
adc->bufcnt = 0;
}
}
void _adc_StartIT(ADC_CTL *adc,uint32_t priority)
{
/* Configure NVIC to enable ADC1 interruptions */
adc->priority = priority;;
adc->mode = ADC_IT_MODE;
NVIC_SetPriority(adc->IRQn, adc->priority);
NVIC_EnableIRQ(adc->IRQn);
LL_ADC_EnableIT_EOS(adc->adcx);
if(LL_ADC_REG_GetTriggerSource(adc->adcx) == LL_ADC_REG_TRIG_SOFTWARE)
{
LL_ADC_REG_StartConversionSWStart(adc->adcx);
}else{
Timer_Base * trigger = (Timer_Base *)adc->Trigger;
trigger->start(trigger);
}
}
void _adc_StopIT(ADC_CTL *adc)
{
adc->mode = ADC_POLL_MODE;
NVIC_DisableIRQ(adc->IRQn);
LL_ADC_DisableIT_EOS(adc->adcx);
if(LL_ADC_REG_GetTriggerSource(adc->adcx) != LL_ADC_REG_TRIG_SOFTWARE)
{
Timer_Base *trigger = (Timer_Base *)adc->Trigger;
trigger->stop(trigger);
}
}
void _adc_StartDMA(ADC_CTL *adc,uint8_t IsCircular)
{
static uint8_t isalreadyconfig;
if(!isalreadyconfig)
{
adc->mode = ADC_DMA_MODE;
adc->IsCircular = IsCircular;
_ADC_Configure_DMA(adc);
LL_ADC_REG_SetDMATransfer(adc->adcx,LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
LL_ADC_SetSequencersScanMode(adc->adcx, LL_ADC_SEQ_SCAN_ENABLE);
LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE);
LL_ADC_REG_SetContinuousMode(adc->adcx, LL_ADC_REG_CONV_CONTINUOUS);
isalreadyconfig = 1;
}
if(LL_ADC_REG_GetTriggerSource(adc->adcx) == LL_ADC_REG_TRIG_SOFTWARE)
{
LL_ADC_REG_StartConversionSWStart(adc->adcx);
}
}
void _adc_StopDMA(ADC_CTL *adc)
{
adc->mode = ADC_POLL_MODE;
/* Diseble the DMA transfer */
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_ADC_REG_SetDMATransfer(adc->adcx,LL_ADC_REG_DMA_TRANSFER_NONE);
}
void ADCx_IRQHandler(ADC_CTL *adc)
{
bpsConfigASSERT(adc);
if(LL_ADC_IsActiveFlag_EOS(adc->adcx) != 0)
{
/* Clear flag ADC group regular end of sequence conversions */
LL_ADC_ClearFlag_EOS(adc->adcx);
adc->buf[adc->bufcnt++] = LL_ADC_REG_ReadConversionData12(adc->adcx);
if(adc->bufcnt >= adc->bufsize)
{
adc->StopIT(adc);
adc->bufcnt = 0;
if(adc->ConvCmpCallback != NULL)
{
adc->ConvCmpCallback(adc->ConvCmpCBArg);
}
if(adc->IsCircular)_adc_StartIT(adc,adc->priority);
}
}
}
static void _adc_SetCallback(ADC_CTL *adc,pfun callback,void *arg)
{
if(callback != NULL ) adc->ConvCmpCallback = callback;
if(arg != NULL) adc->ConvCmpCBArg = arg;
}
ADC_CTL new_adc(ADC_TypeDef *adcx,uint16_t *buf,uint16_t size)
{
ADC_CTL temp;
memset(&temp,0,sizeof(ADC_CTL));
temp.adcx = adcx;
temp.buf = buf;
temp.bufsize = size;
temp.init = _adc_init;
temp.add_chanel = _adc_add_chanel;
temp._adc_SoftwareTrigger = _adc_SoftwareTrigger;
temp.SetTrigger = _adc_SetTrigger;
temp.SetCallback = _adc_SetCallback;
temp.StartIT = _adc_StartIT;
temp.StopIT = _adc_StopIT;
temp.StartDMA = _adc_StartDMA;;
temp.StopDMA = _adc_StopDMA;
return temp;
}
#endif
#ifdef USE_TIMER
static void _timer_base_init(Timer_Base *timer_base,uint32_t clk,uint32_t frq)
{
/* Enable the timer peripheral clock */
switch ((uint32_t)timer_base->TIMx)
{
#ifdef TIM1
case (uint32_t)TIM1: LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);timer_base->IRQn = TIM1_UP_IRQn;break;
#endif
#ifdef TIM2
case (uint32_t)TIM2: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);timer_base->IRQn = TIM2_IRQn;break;
#endif
#ifdef TIM3
case (uint32_t)TIM3: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);timer_base->IRQn = TIM3_IRQn;break;
#endif
#ifdef TIM4
case (uint32_t)TIM4: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);timer_base->IRQn = TIM4_IRQn;break;
#endif
#ifdef TIM5
case (uint32_t)TIM5: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM5);timer_base->IRQn = TIM5_IRQn;break;
#endif
#ifdef TIM6
case (uint32_t)TIM6: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM6);timer_base->IRQn = TIM6_IRQn;break;
#endif
#ifdef TIM7
case (uint32_t)TIM7: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);timer_base->IRQn = TIM7_IRQn;break;
#endif
#ifdef TIM8
case (uint32_t)TIM8: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM8);IRQn = TIM8_IRQn;break;
#endif
default:
break;
}
/* Set the pre-scaler value to have TIMs counter clock equal to 10 kHz */
/*
In this example TIM2 input clock (TIM2CLK) is set to APB1 clock (PCLK1),
since APB1 prescaler is equal to 1.
TIM2CLK = PCLK1
PCLK1 = HCLK
=> TIM2CLK = HCLK = SystemCoreClock
To get TIM2 counter clock at 10 KHz, the Prescaler is computed as following:
Prescaler = (TIM2CLK / TIM2 counter clock) - 1
Prescaler = (SystemCoreClock /10 KHz) - 1
*/
LL_TIM_SetPrescaler(timer_base->TIMx, __LL_TIM_CALC_PSC(SystemCoreClock, clk));
/* Enable TIM2_ARR register preload. Writing to or reading from the */
/* auto-reload register accesses the preload register. The content of the */
/* preload register are transferred into the shadow register at each update */
/* event (UEV). */
LL_TIM_EnableARRPreload(timer_base->TIMx);
/* Set the auto-reload value to have an initial update event frequency of 10 Hz */
/* TIM2CLK = SystemCoreClock / (APB prescaler & multiplier) */
// uint32_t TimOutClock = SystemCoreClock/2;
uint32_t InitialAutoreload = __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(timer_base->TIMx), frq);
LL_TIM_SetAutoReload(timer_base->TIMx, InitialAutoreload);
LL_TIM_SetTriggerOutput(timer_base->TIMx,LL_TIM_TRGO_UPDATE);//defulat trigger
}
static void _timer_base_start(Timer_Base *timer_base)
{
/* Enable counter */
LL_TIM_EnableCounter(timer_base->TIMx);
}
static void _timer_base_startIT(Timer_Base *timer_base,uint32_t priority,void(*handle), void *arg)
{
timer_base->callback_handler = (pfun)handle;
timer_base->callback_arg = arg;
/* Enable the update interrupt */
LL_TIM_EnableIT_UPDATE(timer_base->TIMx);
/* Configure the NVIC to handle TIM2 update interrupt */
NVIC_SetPriority(timer_base->IRQn, priority);
NVIC_EnableIRQ(timer_base->IRQn);
/* Enable counter */
LL_TIM_EnableCounter(timer_base->TIMx);
}
static void _timer_base_StopIT(Timer_Base *timer_base)
{
/* Disable the update interrupt */
LL_TIM_DisableIT_UPDATE(timer_base->TIMx);
NVIC_DisableIRQ(timer_base->IRQn);
/* Disable counter */
LL_TIM_DisableCounter(timer_base->TIMx);
timer_base->callback_handler = NULL;
timer_base->callback_arg = NULL;
}
static void _timer_base_stop(Timer_Base *timer_base)
{
/* Disable counter */
LL_TIM_DisableCounter(timer_base->TIMx);
}
static uint32_t _timer_GetReload(Timer_Base *timer_base)
{
return LL_TIM_GetAutoReload(timer_base->TIMx);
}
Timer_Base new_timer_base(TIM_TypeDef *timx, uint32_t clk, uint32_t frq)
{
Timer_Base temp_timer_base;
temp_timer_base.TIMx = timx;
temp_timer_base.init = _timer_base_init;
temp_timer_base.stop = _timer_base_stop;
temp_timer_base.start = _timer_base_start;
temp_timer_base.startIT = _timer_base_startIT;
temp_timer_base.stopIT = _timer_base_StopIT;
temp_timer_base.GetReload = _timer_GetReload;
temp_timer_base.init(&temp_timer_base,clk,frq);
return temp_timer_base;
}
void TIMx_IRQHandler(Timer_Base *timer_base)
{
/* Check whether update interrupt is pending */
if(LL_TIM_IsActiveFlag_UPDATE(timer_base->TIMx) == 1)
{
/* Clear the update interrupt flag*/
LL_TIM_ClearFlag_UPDATE(timer_base->TIMx);
if(timer_base->callback_handler != NULL)timer_base->callback_handler(timer_base->callback_arg);
}
}
static void _Pwm_SetPulse(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx,uint16_t pulse)
{
bpsConfigASSERT(timer_pwm);
if(timer_pwm->channel[TIM_Channelx] == 0) return;
switch(TIM_Channelx)
{
case TIMER_PWM_CH1: LL_TIM_OC_SetCompareCH1(timer_pwm->timer_Base.TIMx, pulse);break;
case TIMER_PWM_CH2: LL_TIM_OC_SetCompareCH2(timer_pwm->timer_Base.TIMx, pulse);break;
case TIMER_PWM_CH3: LL_TIM_OC_SetCompareCH3(timer_pwm->timer_Base.TIMx, pulse);break;
case TIMER_PWM_CH4: LL_TIM_OC_SetCompareCH4(timer_pwm->timer_Base.TIMx, pulse);break;
default :break;
}
}
static void _pwm_channel_init(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx,uint16_t pwmpulse,GPIO_TypeDef *gpiox,uint32_t gpio_pinx)
{
bpsConfigASSERT(timer_pwm);
if(gpiox !=0 && gpio_pinx!=0)timer_pwm->ch_gpio[TIM_Channelx] = new_afio_gpio(gpiox,gpio_pinx,0);
/*********************************/
/* Output waveform configuration */
/*********************************/
switch(TIM_Channelx)
{
case TIMER_PWM_CH1: timer_pwm->channel[TIMER_PWM_CH1] = LL_TIM_CHANNEL_CH1; LL_TIM_OC_SetPolarity(timer_pwm->timer_Base.TIMx, LL_TIM_CHANNEL_CH1, LL_TIM_OCPOLARITY_HIGH);break;
case TIMER_PWM_CH2: timer_pwm->channel[TIMER_PWM_CH2] = LL_TIM_CHANNEL_CH2; LL_TIM_OC_SetPolarity(timer_pwm->timer_Base.TIMx, LL_TIM_CHANNEL_CH2, LL_TIM_OCPOLARITY_HIGH);break;
case TIMER_PWM_CH3: timer_pwm->channel[TIMER_PWM_CH3] = LL_TIM_CHANNEL_CH3; LL_TIM_OC_SetPolarity(timer_pwm->timer_Base.TIMx, LL_TIM_CHANNEL_CH3, LL_TIM_OCPOLARITY_HIGH); break;
case TIMER_PWM_CH4: timer_pwm->channel[TIMER_PWM_CH4] = LL_TIM_CHANNEL_CH4; LL_TIM_OC_SetPolarity(timer_pwm->timer_Base.TIMx, LL_TIM_CHANNEL_CH4, LL_TIM_OCPOLARITY_HIGH);break;
default:break;
}
/* Set output mode */
/* Reset value is LL_TIM_OCMODE_FROZEN */
LL_TIM_OC_SetMode(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx], LL_TIM_OCMODE_PWM1);
LL_TIM_EnableAutomaticOutput(timer_pwm->timer_Base.TIMx); //only for tim1 and tim8
/* Set compare value to half of the counter period */
// LL_TIM_OC_SetCompareCH1(timer_pwm->timer_Base.TIMx, ( (LL_TIM_GetAutoReload(timer_pwm->timer_Base.TIMx) + 1 ) / 2));
_Pwm_SetPulse(timer_pwm,TIM_Channelx,pwmpulse);
/* Enable TIM2_CCR1 register preload. Read/Write operations access the */
/* preload register. TIM2_CCR1 preload value is loaded in the active */
/* at each update event. */
LL_TIM_OC_EnablePreload(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx]);
}
static void _pwm_channel_n_init(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx,GPIO_TypeDef *gpiox,uint32_t gpio_pinx)
{
bpsConfigASSERT(timer_pwm);
if(gpiox !=0 && gpio_pinx!=0)timer_pwm->ch_gpio_n[TIM_Channelx] = new_afio_gpio(gpiox,gpio_pinx,0);
switch(TIM_Channelx)
{
case TIMER_PWM_CH1: timer_pwm->channel_n[TIMER_PWM_CH1] = LL_TIM_CHANNEL_CH1N; break;
case TIMER_PWM_CH2: timer_pwm->channel_n[TIMER_PWM_CH2] = LL_TIM_CHANNEL_CH2N; break;
case TIMER_PWM_CH3: timer_pwm->channel_n[TIMER_PWM_CH3] = LL_TIM_CHANNEL_CH3N; break;
default:break;
}
}
static void _Pwm_Start(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx)
{
bpsConfigASSERT(timer_pwm);
if(timer_pwm->channel[TIM_Channelx])
{
/**********************************/
/* Enable output channel 1 */
LL_TIM_CC_EnableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx]);
if(timer_pwm->channel_n[TIM_Channelx]) LL_TIM_CC_EnableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel_n[TIM_Channelx]);
if(!LL_TIM_IsEnabledCounter(timer_pwm->timer_Base.TIMx))
{
/* Enable counter */
LL_TIM_EnableCounter(timer_pwm->timer_Base.TIMx);
}
}
}
static void _Pwm_StartIT(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx,uint32_t priority,void(*handle), void *arg)
{
bpsConfigASSERT(timer_pwm);
if(timer_pwm->channel[TIM_Channelx])
{
/**********************************/
/* Enable output channel 1 */
LL_TIM_CC_EnableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx]);
if(timer_pwm->channel_n[TIM_Channelx]) LL_TIM_CC_EnableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel_n[TIM_Channelx]);
if(!LL_TIM_IsEnabledCounter(timer_pwm->timer_Base.TIMx))
{
/* Enable counter */
LL_TIM_EnableCounter(timer_pwm->timer_Base.TIMx);
}
switch(TIM_Channelx)
{
case TIMER_PWM_CH1: LL_TIM_EnableIT_CC1(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH2: LL_TIM_EnableIT_CC2(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH3: LL_TIM_EnableIT_CC3(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH4: LL_TIM_EnableIT_CC4(timer_pwm->timer_Base.TIMx);
break;
default:break;
}
timer_pwm->callback_handler = (pfun)handle;
timer_pwm->callback_arg = arg;
/* Configure the NVIC to handle TIM update interrupt */
if(timer_pwm->timer_Base.TIMx != TIM1)
{
NVIC_SetPriority(timer_pwm->timer_Base.IRQn, priority);
NVIC_EnableIRQ(timer_pwm->timer_Base.IRQn);
}else if(timer_pwm->timer_Base.TIMx == TIM1)
{
NVIC_SetPriority(TIM1_CC_IRQn, priority);
NVIC_EnableIRQ(TIM1_CC_IRQn);
}
}
}
static void _Pwm_StopIT(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx)
{
bpsConfigASSERT(timer_pwm);
if(timer_pwm->channel[TIM_Channelx])
{
LL_TIM_CC_DisableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx]);
if(timer_pwm->channel_n[TIM_Channelx]) LL_TIM_CC_DisableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel_n[TIM_Channelx]);
}
if(timer_pwm->timer_Base.TIMx != TIM1)
{
NVIC_DisableIRQ(timer_pwm->timer_Base.IRQn);
}else if (timer_pwm->timer_Base.TIMx == TIM1)
{
NVIC_DisableIRQ(TIM1_CC_IRQn);
}
switch(TIM_Channelx)
{
case TIMER_PWM_CH1: LL_TIM_DisableIT_CC1(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH2: LL_TIM_DisableIT_CC2(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH3: LL_TIM_DisableIT_CC3(timer_pwm->timer_Base.TIMx);
break;
case TIMER_PWM_CH4: LL_TIM_DisableIT_CC4(timer_pwm->timer_Base.TIMx);
break;
default:break;
}
timer_pwm->timer_Base.callback_handler = NULL;
timer_pwm->timer_Base.callback_arg = NULL;
}
static void _Pwm_Stop(Timer_Pwm *timer_pwm,uint8_t TIM_Channelx)
{
bpsConfigASSERT(timer_pwm);
if(timer_pwm->channel[TIM_Channelx])
{
LL_TIM_CC_DisableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel[TIM_Channelx]);
if(timer_pwm->channel_n[TIM_Channelx]) LL_TIM_CC_DisableChannel(timer_pwm->timer_Base.TIMx, timer_pwm->channel_n[TIM_Channelx]);
}
}
static void _Pwm_SetDeadtime(Timer_Pwm *timer_pwm,uint16_t deadtime) //ns
{
LL_TIM_OC_SetDeadTime(timer_pwm->timer_Base.TIMx, __LL_TIM_CALC_DEADTIME(SystemCoreClock, LL_TIM_GetClockDivision(timer_pwm->timer_Base.TIMx), deadtime));
}
static void _Pwm_Setlocklevel(Timer_Pwm *timer_pwm,uint8_t locklevel)
{
switch(locklevel)
{
case 0:LL_TIM_CC_SetLockLevel(timer_pwm->timer_Base.TIMx, LL_TIM_LOCKLEVEL_OFF);break;
case 1:LL_TIM_CC_SetLockLevel(timer_pwm->timer_Base.TIMx, LL_TIM_LOCKLEVEL_1);break;
case 2:LL_TIM_CC_SetLockLevel(timer_pwm->timer_Base.TIMx, LL_TIM_LOCKLEVEL_2);break;
case 3:LL_TIM_CC_SetLockLevel(timer_pwm->timer_Base.TIMx, LL_TIM_LOCKLEVEL_3);break;
}
}
void PWMx_IRQHandler(Timer_Pwm *timer_pwm)
{
/* Check whether update interrupt is pending */
if(LL_TIM_IsActiveFlag_CC1(timer_pwm->timer_Base.TIMx) && LL_TIM_IsEnabledIT_CC1(timer_pwm->timer_Base.TIMx))
{
/* Clear the update interrupt flag*/
LL_TIM_ClearFlag_CC1(timer_pwm->timer_Base.TIMx);
timer_pwm->ischannelpending[0] = SET;
if(timer_pwm->callback_handler != NULL)timer_pwm->callback_handler(timer_pwm->callback_arg);
timer_pwm->ischannelpending[0] = RESET;
}
if(LL_TIM_IsActiveFlag_CC2(timer_pwm->timer_Base.TIMx)&& LL_TIM_IsEnabledIT_CC2(timer_pwm->timer_Base.TIMx))
{
/* Clear the update interrupt flag*/
LL_TIM_ClearFlag_CC2(timer_pwm->timer_Base.TIMx);
timer_pwm->ischannelpending[1] = SET;
if(timer_pwm->callback_handler != NULL)timer_pwm->callback_handler(timer_pwm->callback_arg);
timer_pwm->ischannelpending[1] = RESET;
}
if(LL_TIM_IsActiveFlag_CC3(timer_pwm->timer_Base.TIMx)&& LL_TIM_IsEnabledIT_CC3(timer_pwm->timer_Base.TIMx))
{
/* Clear the update interrupt flag*/
LL_TIM_ClearFlag_CC3(timer_pwm->timer_Base.TIMx);
timer_pwm->ischannelpending[2] = SET;
if(timer_pwm->callback_handler != NULL)timer_pwm->callback_handler(timer_pwm->callback_arg);
timer_pwm->ischannelpending[2] = RESET;
}
if(LL_TIM_IsActiveFlag_CC4(timer_pwm->timer_Base.TIMx)&& LL_TIM_IsEnabledIT_CC4(timer_pwm->timer_Base.TIMx))
{
/* Clear the update interrupt flag*/
LL_TIM_ClearFlag_CC4(timer_pwm->timer_Base.TIMx);
timer_pwm->ischannelpending[3] = SET;
if(timer_pwm->callback_handler != NULL)timer_pwm->callback_handler(timer_pwm->callback_arg);
timer_pwm->ischannelpending[3] = RESET;
}
}
Timer_Pwm new_Timer_Pwm(TIM_TypeDef *timx, uint32_t clk, uint32_t frq)
{
bpsConfigASSERT(timx);
Timer_Pwm temp_Timer_Pwm;
memset(&temp_Timer_Pwm,0,sizeof(Timer_Pwm));
temp_Timer_Pwm.init_channel = _pwm_channel_init;
temp_Timer_Pwm.init_channel_n = _pwm_channel_n_init;
temp_Timer_Pwm.SetPulse = _Pwm_SetPulse;
temp_Timer_Pwm.Start = _Pwm_Start;
temp_Timer_Pwm.Stop = _Pwm_Stop;
temp_Timer_Pwm.StartIT = _Pwm_StartIT;
temp_Timer_Pwm.StopIT = _Pwm_StopIT;
temp_Timer_Pwm.SetDeadtime = _Pwm_SetDeadtime;
temp_Timer_Pwm.SetLocklevel = _Pwm_Setlocklevel;
temp_Timer_Pwm.timer_Base = new_timer_base(timx,clk,frq);
return temp_Timer_Pwm;
}
#endif
#ifdef USE_SPI
static void _spi_init(SPI *spi)
{
switch((uint32_t)spi->spix)
{
#ifdef SPI1
case (uint32_t)SPI1: LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);break;
#endif
#ifdef SPI2
case (uint32_t)SPI2: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);break;
#endif
#ifdef SPI3
case (uint32_t)SPI3: LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3);break;
#endif
default:break;
}
/* Configure SPI communication */
LL_SPI_SetBaudRatePrescaler(spi->spix, LL_SPI_BAUDRATEPRESCALER_DIV256);
LL_SPI_SetTransferDirection(spi->spix,LL_SPI_FULL_DUPLEX);
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_1EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_LOW);
LL_SPI_SetDataWidth(spi->spix, LL_SPI_DATAWIDTH_8BIT);
LL_SPI_SetNSSMode(spi->spix, LL_SPI_NSS_SOFT);
LL_SPI_SetMode(spi->spix, LL_SPI_MODE_MASTER);
LL_SPI_Enable(spi->spix);
}
static uint16_t _spi_readwritebyte(SPI* spi,uint16_t byte)
{
uint8_t retry = 0;
while(RESET == LL_SPI_IsActiveFlag_TXE(spi->spix))
{
retry++;
if(retry >200)return 0;
}
LL_SPI_TransmitData8(spi->spix,byte);
retry = 0;
while(RESET == LL_SPI_IsActiveFlag_RXNE(spi->spix))
{
retry++;
if(retry >200)return 0;
}
return LL_SPI_ReceiveData8(spi->spix);
}
static void _spi_readwritebuf(SPI* spi,uint8_t* TxBuf,uint8_t* RxBuf,uint8_t len)
{
uint8_t rxdata = 0;;
for(uint8_t i = 0;i < len;i++)
{
rxdata = spi->readwritebyte(spi,TxBuf[i]);
if(RxBuf!= NULL)RxBuf[i] = rxdata;
}
}
static void _spi_setmode(SPI* spi,uint8_t mode)
{
spi->mode = mode;
switch(spi->mode)
{
case 0:
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_1EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_LOW);
break;
case 1:
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_2EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_LOW);
break;
case 2:
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_1EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_HIGH);
break;
case 3:
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_2EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_HIGH);
break;
default:
LL_SPI_SetClockPhase(spi->spix, LL_SPI_PHASE_1EDGE);
LL_SPI_SetClockPolarity(spi->spix, LL_SPI_POLARITY_LOW);
break;
}
}
static void _spi_setspeed(SPI* spi,uint32_t baud)
{
LL_SPI_SetBaudRatePrescaler(spi->spix, LL_SPI_BAUDRATEPRESCALER_DIV256);
}
static void _spi_set_frame_bit(SPI* spi,uint16_t framebit)
{
LL_SPI_SetTransferBitOrder(spi->spix,framebit);
}
#if defined(GD32F20X) && defined(GD32F4X0)
static void _s_quad_spi_init(SPI *spi,uint32_t spi_gpio,uint32_t spi_io2_pinx,uint32_t spi_io3_pinx)
{
if(spi->spix != SPI0) return; //??有SPI0才支?? Quad
AFIO_GPIO spi_io2 = new_afio_gpio(spi_gpio,spi_io2_pinx,0);
AFIO_GPIO spi_io3 = new_afio_gpio(spi_gpio,spi_io3_pinx,0);
/* enable quad wire SPI_IO2 and SPI_IO3 pin output */
qspi_io23_output_enable(SPI0);
}
#endif
SPI new_spi(GPIO_TypeDef *gpiox,uint32_t sck_pinx,uint32_t miso_pinx,uint32_t mosi_pinx,SPI_TypeDef *spix)
{
SPI temp;
temp.sck = new_afio_gpio(gpiox,sck_pinx,0);
temp.miso = new_afio_gpio(gpiox,miso_pinx,0);
temp.mosi = new_afio_gpio(gpiox,mosi_pinx,0);
temp.spix = spix;
temp.buadrate = LL_SPI_BAUDRATEPRESCALER_DIV32;
temp.init = _spi_init;
temp.readwritebyte = _spi_readwritebyte;
temp.readwritebuf = _spi_readwritebuf;
temp.SetSpeed = _spi_setspeed;
temp.SetMode = _spi_setmode;
temp.Set_Frame_Bit = _spi_set_frame_bit;
temp.init(&temp);
return temp;
}
#endif
#ifdef USE_WATCHDOG
static void _WatchDog_init(uint32_t time)
{
/*##-1- Check if the system has resumed from IWDG reset ####################*/
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
{
}
/* Clear reset flags anyway */
__HAL_RCC_CLEAR_RESET_FLAGS();
/*##-2- Configure & Start the IWDG peripheral ##############################*/
/* Set counter reload value to obtain 762ms IWDG TimeOut.
Counter Reload Value = (LsiFreq(Hz) * Timeout(ms)) / (prescaler * 1000)
*/
watchdog.hiwdg.Instance = IWDG;
watchdog.hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
watchdog.hiwdg.Init.Reload = (40000 * time) / (16 * 1000); /* time ms */
watchdog.hiwdg.Init.Window = (40000 * time) / (16 * 1000); /* 400 ms */
if(HAL_IWDG_Init(&watchdog.hiwdg) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
}
static void _Freedog(void)
{
HAL_IWDG_Refresh(&watchdog.hiwdg);
}
struct _s_watchdog watchdog = {
.Init = _WatchDog_init,
.Feed = _Freedog,
};
#endif
#ifdef USE_FLASH
uint32_t GetFlashEndAddreess(void)
{
return (FLASH_BASE + (LL_GetFlashSize()*1024));
}
uint32_t Flash_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
{
uint32_t i = 0;
/* Unlock the Flash to enable the flash control register access *************/
LL_Flash_Unlock();
for (i = 0; (i <= length) && (destination <= (GetFlashEndAddreess()-4)); i++)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (LL_FLASH_Program(ProgaraType_DATA32, destination, *(uint32_t*)(p_source+i)) == HAL_OK)
{
/* Check the written value */
if (*(uint32_t*)destination != *(uint32_t*)(p_source+i))
{
/* Flash content doesn't match SRAM content */
LL_Flash_Lock();
return(FLASHIF_WRITINGCTRL_ERROR);
}
/* Increment FLASH destination address */
destination += 4;
}
else
{
/* Error occurred while writing data in Flash memory */
LL_Flash_Lock();
return (FLASHIF_WRITING_ERROR);
}
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
LL_Flash_Lock();
return (FLASHIF_OK);
}
#endif
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/mzwhhwj/EmbeddedLib.git
git@gitee.com:mzwhhwj/EmbeddedLib.git
mzwhhwj
EmbeddedLib
EmbeddedLib
master

搜索帮助