UART 와 USB 모두 Bootloader에서 각자의 프로토콜을 가져가지 않고 둘다 동일한 프로토콜을 사용하여 다운로드하도록 하고 싶었습니다.
그래서 기존에 UART에서 사용하고 있던 Ymodem을 사용하여 프로그램을 업데이트를 하도록 하였습니다.
약간 더 손보면 효율이 높아지지만 게으름으로 인해 기존에 있던 코드를 그대로 활용하였습니다.
/*******************************************************************************
* Function Name :
* Description :
* Parameters :
* Return : None
*******************************************************************************/
void USB_Test(void)
{
uint8_t arr[64] = {'a', 'b', 'c', };
USB_Send_Data(arr, 10);
while (1){
uint8_t ch = 0;
if(USB_GetChar(&ch)){
USB_Send_Data(&ch, 0);
}
}
}
uint32_t SerialKeyPressed(uint8_t *key)
{
u8 ch = 0;
if(USBUARTFlag == 0 ){
if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) != RESET){
*key = (uint8_t)USARTx->DR;
return 1;
}
else{
return 0;
}
}
else{
if(USB_GetChar(&ch)){
*key = ch;
return 1;
}
else{
return 0;
}
}
}
void SerialPutChar(uint8_t c)
{
if(USBUARTFlag == 0){
USART_SendData(USARTx, c);
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
{;}
}
else{
USB_Send_Data(&c, 0);
}
}
귀찮게시리 USB_Send_Data를 2종류로 보내는 이유는 1바이트씩 연달아 보낼때에 보내기전에 Send를 또 해서 씹히는 경우가 있기 때문입니다. 그래서 한바이트씩 계속 밀어낼때는 len을 0으로 하여 보내고 여러바이트를 보낼때는 len에 보낼 길이를 넣었습니다.
/* External variables --------------------------------------------------------*/
#define USB_DISCONNECT GPIOA
#define USB_DISCONNECT_PIN GPIO_Pin_15
#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOA
/* Defines -------------------------------------------------------------------*/
#define RBUF_SIZE 1024
#define USBDATA_SIZE 5
/* Type declarations ---------------------------------------------------------*/
typedef struct{
u16 RxInCnt,RxOutCnt;
u16 TxInCnt,TxOutCnt;
u8 RxBuf[RBUF_SIZE];
}tUart;
tUart stUSB;
void USB_Send_Data(uint8_t* data_buffer, uint8_t len)
{
if(len == 0){
buffer_in[count_in] = *(data_buffer);
count_in++;
UserToPMABufferCopy(buffer_in, ENDP1_TXADDR, count_in);
SetEPTxCount(ENDP1, count_in);
SetEPTxValid(ENDP1);
}
else{
UserToPMABufferCopy (data_buffer, ENDP1_TXADDR, len);
SetEPTxCount (ENDP1, len);
SetEPTxValid(ENDP1);
}
}
/*******************************************************************************
* Function Name : EP3_IN_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void EP3_OUT_Callback(void)
{
__IO uint32_t count_out = 0, i;
uint8_t buffer_out[VIRTUAL_COM_PORT_DATA_SIZE];
count_out = GetEPRxCount(ENDP3);
PMAToUserBufferCopy(buffer_out, ENDP3_RXADDR, count_out);
for(i = 0; i < count_out; i++){
stUSB.RxBuf[stUSB.RxInCnt] = buffer_out[i];
if(stUSB.RxInCnt<RBUF_SIZE-1) stUSB.RxInCnt++;
else stUSB.RxInCnt = 0;
}
SetEPRxValid(ENDP3);
}
/*******************************************************************************
* Function Name :
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
uint8_t USB_GetChar(uint8_t *data)
{
if(stUSB.RxInCnt == stUSB.RxOutCnt) return 0;
else *data = stUSB.RxBuf[stUSB.RxOutCnt];
if(stUSB.RxOutCnt<RBUF_SIZE-1) stUSB.RxOutCnt++;
else stUSB.RxOutCnt = 0;
return 1;
}
/*******************************************************************************
* Function Name : EP1_IN_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void EP1_IN_Callback(void)
{
count_in = 0;
}
'초보의 아웅다웅 설계하기 > STM32' 카테고리의 다른 글
STM32H7 hal Driver를 사용한 RX Interrupt (0) | 2021.02.11 |
---|---|
STM32H7 USB CDC VCP (0) | 2021.01.11 |
STM32L432KC - TOUCH (0) | 2020.12.01 |
STM32 USB CDC-ACM(Virtual Com Port) 리눅스 확인 (0) | 2020.11.20 |
SSD1353 TEST Program (0) | 2020.09.09 |