ZNY_Pakistan/Anjiehui7_Set_ZNY/User/hal_interface.c

247 lines
6.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "includes.h"
#define DEBUG_PORT USART2
// 系统TickCount
volatile u32 Systick_TickCount = 0;
// 启动原因代码
volatile uint32_t SYS_RSTSTS = 0;
// 实现stdout的硬件输出
int stdout_putchar(int ch)
{
while(!(DEBUG_PORT->ISR & LL_USART_ISR_TXE));
DEBUG_PORT->TDR = (uint8_t) ch;
return ch;
}
u32 GetDelayTick(u32 ms)
{
return GetTickCount() + ms;
}
// 考虑了u32溢出翻转的情况
u8 IsTickOut(u32 OutTick)
{
u32 tick = GetTickCount();
if(tick > OutTick)
{
if(tick - OutTick > 0x80000000UL)
return 0;
return 1;
}
if(OutTick - tick > 0x80000000UL)
return 1;
return 0;
}
// 这个函数必须在初始化完成,中断开启以后才有效
void delay_ms(u32 ms)
{
u32 tick = GetDelayTick(ms);
do
{
} while(!IsTickOut(tick));
// for(int j=0;j<1000;j++)
// delay_us(ms);
}
void delay_us(uint16_t us)
{
uint32_t j;
while(us--)
{
j = SystemCoreClock / 1000000;
while(j--);
}
}
/* *************************************************************************
Bootloader和App跳转设计要点
1. Bootloader的程序在前面大小为8K0x08000000~0x08001FFF)
App的程序在后面从0x08002000开始大小为0x3E000
2. Bootloader的内存在前面大小为2K0x20000000~0x200007FF
App的内存在后面从0x20000800开始大小为0xF800
3. 从Bootloader跳转到App
1关闭全局中断响应__disable_irq
2禁止中断允许将各中断的允许位清零
3清除中断标志将各中断的标志位清零
4) 设置堆栈MSP为App的堆栈值
5跳转到App的程序入口
4. 从App跳转到Bootloader
直接系统复位运行Bootloader
5. Bootloader工程的特殊处理
1在Target页按照上述要求设置IROM1和IRAM1
2在Linker页勾选“Use Memory Layout from Target Dialog”
6. App工程的特殊处理
1在Target页按照上述要求设置IROM1和IRAM1
2在Linker页勾选“Use Memory Layout from Target Dialog”
3) 在system_stm32l4xx.c中修改以下代码
a. 将宏定义VECT_TAB_OFFSET改为0x2000
b. 在SystemInit函数最后重新打开全局中断响应__enable_irq)
7. 从App的任务中跳转到Bootloader按第3条的方法试验不成功。
具体原因未明,可能是因为要关掉的中断太多,没有一一试验;
也可能是因为FreeRTOS将CPU的特权模式接管了导致PSP、MSP设置无效等。
************************************************************************* */
typedef void (*pIapFun_TypeDef)(void); //定义一个函数类型的参数.
// 实现从Bootloader跳转到App
void JumpToEntry(uint32_t addr)
{
printf("\r\nJump to 0x%08X\r\n", addr);
__disable_irq();
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
__set_MSP(*(volatile uint32_t *) addr);
((pIapFun_TypeDef) (*(volatile uint32_t *) (addr + 4)))();
// 不应该到这里来
while(1)
printf(".");
}
// 实现从App跳转到Bootloader
void JumpToLoader()
{
printf("\r\nJump to 0x%08X\r\n", (uint32_t) FLASH_BASE);
// 直接复位跳转到Bootloader
HAL_NVIC_SystemReset();
// 不应该到这里来
while(1)
printf(".");
}
// 实现串口发送
USART_Handle huart1 = {USART1, 0, 0, 1, NULL, NULL, NULL};
USART_Handle huart2 = {USART2, 0, 0, 1, NULL, NULL, NULL};
USART_Handle huart3 = {USART3, 0, 0, 1, NULL, NULL, NULL};
USART_Handle hlpuart1 = {LPUART1, 0, 0, 1, NULL, NULL, NULL};
// 实现串口发送
void UART_Transmit(USART_Handle *huart, uint8_t *buf, uint16_t len)
{
while(len--)
{
while(!(huart->Instance->ISR & LL_USART_ISR_TXE));
huart->Instance->TDR = *buf++;
while(!(huart->Instance->ISR & LL_USART_ISR_TC));
}
}
// 实现以中断方式串口发送
void UART_TxISR_8BIT(USART_Handle *huart)
{
/* Check that a Tx process is ongoing */
if(!huart->BusyTx)
return;
if (huart->TxXferCount == 0U)
{
/* Disable the UART Transmit Data Register Empty Interrupt */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
}
else
{
huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
huart->pTxBuffPtr++;
huart->TxXferCount--;
}
}
uint8_t UART_Transmit_IT(USART_Handle *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if(huart->BusyTx)
return 0;
huart->pTxBuffPtr = pData;
huart->TxXferCount = Size;
huart->TxISR = UART_TxISR_8BIT;
huart->BusyTx = 1;
/* Enable the Transmit Data Register Empty interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
return 1;
}
// 应用程序的串口中断处理
void APP_USART_IRQHandler(USART_Handle *huart)
{
uint32_t isrflags = huart->Instance->ISR;
uint32_t cr1its = huart->Instance->CR1;
uint32_t errorflags = (isrflags & ((uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_NE | USART_ISR_ORE)));
// 清除错误状态
LL_USART_ClearFlag_PE(huart->Instance);
LL_USART_ClearFlag_FE(huart->Instance);
LL_USART_ClearFlag_NE(huart->Instance);
LL_USART_ClearFlag_ORE(huart->Instance);
/* If no error occurs */
if (errorflags == 0U)
{
/* UART in mode Receiver ---------------------------------------------------*/
if (((isrflags & USART_ISR_RXNE) != 0U)
&& ((cr1its & USART_CR1_RXNEIE) != 0U))
{
if(huart->RxISR)
huart->RxISR(huart);
else
huart->Instance->RDR;
}
/* UART in mode Transmit ---------------------------------------------------*/
if (((isrflags & USART_ISR_TXE) != 0U)
&& ((cr1its & USART_CR1_TXEIE) != 0U))
{
if(huart->TxISR)
huart->TxISR(huart);
else
{
// 不应该到这里
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
huart->BusyTx = 0;
}
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
{
/* Disable the UART Transmit Complete Interrupt */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
// 清除发送忙标志
huart->BusyTx = 0;
}
}
}
// 读取启动原因代码
void Get_ResetFlags()
{
if(LL_RCC_IsActiveFlag_BORRST())
SYS_RSTSTS |= 0x01;
if(LL_RCC_IsActiveFlag_PINRST())
SYS_RSTSTS |= 0x02;
if(LL_RCC_IsActiveFlag_IWDGRST())
SYS_RSTSTS |= 0x04;
if(LL_RCC_IsActiveFlag_LPWRRST())
SYS_RSTSTS |= 0x10;
if(LL_RCC_IsActiveFlag_SFTRST())
SYS_RSTSTS |= 0x20;
// 清除启动标志
__HAL_RCC_CLEAR_RESET_FLAGS();
}