2008-04-15 05:54 PM
STM32 Clock, Flash, and USB
2011-05-17 03:29 AM
Hi Lanchon, Philipp and Friends,
Had time for the USB again. :) Thanks to you I have finally managed to get things working somewhat. Take a look at the code below: ****************************************************************** * stm32f10x_it.c * ****************************************************************** u8 bTXBuffer[VIRTUAL_COM_PORT_DATA_SIZE]; u8 bTXWriteCount = 0; u8 bTXReadCount = 0; u8 bRXBuffer[VIRTUAL_COM_PORT_DATA_SIZE]; u8 bRXWriteCount = 0; extern bool USBTXReady; void SysTickHandler(void) { if (!(bRXWriteCount < VIRTUAL_COM_PORT_DATA_SIZE) || USBTXReady) { UserToPMABufferCopy(bRXBuffer, ENDP1_TXADDR, bRXWriteCount); SetEPTxCount(ENDP1, bRXWriteCount); SetEPTxValid(ENDP1); bRXWriteCount = 0; } } void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { bRXBuffer[bRXWriteCount] = (u8) USART_ReceiveData(USART1); bRXWriteCount++; // if (!(bRXWriteCount < VIRTUAL_COM_PORT_DATA_SIZE) || USBTXReady) { // UserToPMABufferCopy(bRXBuffer, ENDP1_TXADDR, bRXWriteCount); // SetEPTxCount(ENDP1, bRXWriteCount); // SetEPTxValid(ENDP1); // bRXWriteCount = 0; // } USBTXReady = FALSE; // Clear the USART1 Receive interrupt USART_ClearITPendingBit(USART1, USART_IT_RXNE); } if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) { if (bTXReadCount < bTXWriteCount) { USART_SendData(USART1, (u16) bTXBuffer[bTXReadCount++]); } else { bTXReadCount = 0; bTXWriteCount = 0; SetEPRxValid(ENDP3); } // Clear the USART1 Transmit interrupt USART_ClearITPendingBit(USART1, USART_IT_TXE); } } ****************************************************************** ****************************************************************** * usb_mem.c * ****************************************************************** void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) { u8 i; u32 *pdwVal; pdwVal = (u32 *) ((wPMABufAddr * 2) + PMAAddr); for (i = 0; i < wNBytes; i++) { if (!(i & 1)) { *pdwVal = (u16) *pbUsrBuf; } else { *pdwVal |= (((u16) *pbUsrBuf) << 8); pdwVal++; } pbUsrBuf++; } } void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) { u8 i; u32 *pdwVal; pdwVal = (u32 *) ((wPMABufAddr * 2) + PMAAddr); for (i = 0; i < wNBytes; i++) { if (!(i & 1)) { *pbUsrBuf = (u8) *pdwVal; } else { *pbUsrBuf = (u8) (*pdwVal >> 8); pdwVal++; } pbUsrBuf++; } } ****************************************************************** ****************************************************************** * usb_endp.c * ****************************************************************** bool USBTXReady = TRUE; extern u8 bTXBuffer[VIRTUAL_COM_PORT_DATA_SIZE]; extern u8 bTXWriteCount; void EP3_OUT_Callback(void) { bTXWriteCount = GetEPRxCount(ENDP3); PMAToUserBufferCopy(bTXBuffer, ENDP3_RXADDR, bTXWriteCount); } void EP1_IN_Callback(void) { USBTXReady = TRUE; } ****************************************************************** ****************************************************************** * main.c * ****************************************************************** /* AHB clock divided by 8 selected as SysTick clock source */ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /* Set SysTick reload value to 0x1770 */ /* SysTick = HCLK / (8 * 6000) = 1000 Hz => 1 ms */ SysTick_SetReload(0x1770); /* Enable SysTick counter */ SysTick_CounterCmd(SysTick_Counter_Enable); /* Enable SysTick interrupt */ SysTick_ITConfig(ENABLE); ****************************************************************** As you may have noticed, I have commented out a segment from the USART1 receive interrupt. Before explaining why let me mention a bug that I have... * Since data is sent to the USB at every USART receive interrupt, there is a possibility that some of the last few bytes never get to be transmitted because the USB could be busy. I saw no way of getting around this, so I thought of using the SysTick interrupt set at a optimized time (I set it to 1ms for now) to poll the USB busy indicator and the buffer. This way all data could be sent to the USB without loss and as fast as possible. Now the question of the day is.... :) I cant seem to get the SysTick Interrupt to envoke the Handler function. I tried toggling a pin but it is always a constant low. Any ideas of getting the SysTick to tick? On the USB to USART side I found no problems. At least with the speeds I was testing at. The buffer size seemed to be enough. Btw, I did try to use the USART Idle interrupt to fire up the function so that the last few bytes will be transmitted from the USART to USB... But this idea didnt get me anywhere productive. Hence the SysTick polling solution. Any bugs you notice, comments and help on the SysTick will be greatly appreciated. Thanks Lanchon for all the help so far. -Mad2011-05-17 03:29 AM
yes, that's why I eliminated all that code from the stdio/vcom code I posted.
2011-05-17 03:29 AM
Hi,
Can STOne-32 give some guidance on the SysTick? Just some tips on the Systick Hanlder using the STM32 FM Library. I can't find any useful information on the Reference Manual or FM Library User Manual... Maybe Im just not seeing it... -Mad [ This message was edited by: mvi on 15-04-2008 17:13 ]2011-05-17 03:29 AM
Hi,
I got the SysTick working. Looks like the SysTick is turned off until a event takes place on the USB/USART. Maybe Im not handling the NVIC correctly. Also the frequency of the SysTick is half of what I expected. So a few things to debug. With these few bugs on the table, the USART->USB still doesnt function as I expected. So still a negative there... -Mad2011-05-17 03:29 AM
> Since data is sent to the USB at every USART receive interrupt, there is a possibility that some of the last few bytes never get to be transmitted because the USB could be busy. I saw no way of getting around this...
I told you how. read the part starting with ''say X is the USB transfer size'' carefully. > some guidance on the SysTick? it's an ARM peripheral, I'd expect detailed info in the cortex-m3 core manual published directly by ARM.