Hi
Thanks for your link - I have had a look around that project and have bookmarked it.
I have developed my code a little since I last posted, but am again stuck, and am hoping that someone will be able to point me in the right direction.
My idea is that I wish to receive the GPS string using USART with DMA, copy the receiving array to another buffer, and then transmit this over USB VCP.
I have tried to implement this without using any sort of interrupt driven system, but found that I kept getting chopped up GPS strings (which seems obvious to me now that this is what I should have expected).
I therefore tried to use the IDLE interrupt on the USART to disable the DMA, which I expect to stop the GPS string from being read into the microcontroller, thereby giving me time to copy the buffer into another buffer which I can pass to the USB transmit command.
In the main loop I would then check for a situation where the DMA had been disabled so that I could re-enable it again and perform the next set of transfers.
Unfortunately, as soon as I enable the IDLE interrupt, I get a hard fault, and am unable to figure out why this is happening.
#define DMA_RX_BUFFER_SIZE 64
#define UART_BUFFER_SIZE 256
uint8_t usb_tx_buf[127];
uint8_t usb_rx_buf[127];
uint8_t usart1_rx_buffer[GPSBUFFER];
uint8_t DMAArray[GPSBUFFER]; //this is the DMA usart1 rx buffer
uint8_t usbss[GPSBUFFER];
uint8_t uart1GetChar(void);
void setupUsart1Dma()
{
//1. Turn on clock for AHB Bus and DMA1
RCC->AHBENR |= RCC_AHBENR_SRAMEN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
//2. enable DMA on Usart1
DMA1->IFCR |= DMA_IFCR_CGIF5; //Global interrupt clear
// Peripheral and Memory locations to DMA registers
DMA1_Channel5 -> CPAR = (uint32_t) (&(USART1->DR));
DMA1_Channel5 -> CMAR = (uint32_t) (DMAArray);
// DMA Memory Increment| Circular Buffer|
DMA1_Channel5 -> CCR |= DMA_CCR_MINC | DMA_CCR_CIRC;
DMA1_Channel5 -> CCR &= ~(DMA_CCR_MSIZE);
DMA1_Channel5 -> CCR &= ~(DMA_CCR_PSIZE);
DMA1_Channel5 -> CCR &= ~(DMA_CCR_DIR);
USART1->CR3 |= USART_CR3_DMAR;
USART1->CR1 |= USART_CR1_IDLEIE;
DMA1_Channel5 -> CNDTR = GPSBUFFER;
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn, 15, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__enable_interrupt();
DMA1_Channel5 ->CCR |= DMA_CCR_EN;
DMA1->IFCR |= DMA_IFCR_CGIF5;
}
void usbprint(uint8_t data[], int length)
{
//length = strlen(data);
CDC_Transmit_FS(data, length);
}
void GPIOUSART()
{
RCC -> APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN;
GPIO_InitTypeDef GPIOInitStruct;
//RX Pin
GPIOInitStruct.Mode = GPIO_MODE_AF_INPUT;
GPIOInitStruct.Pin = GPIO_PIN_10;
GPIOInitStruct.Pull = GPIO_NOPULL;
GPIOInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIOInitStruct);
GPIOInitStruct.Mode = GPIO_MODE_AF_PP;
GPIOInitStruct.Pin = GPIO_PIN_9;
GPIOInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIOInitStruct);
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
USART1->BRR = 72000000/9600;
USART1->CR1 |= USART_CR1_RE;//|USART_CR1_TE |USART_CR1_IDLEIE;
USART1->CR3 |= USART_CR3_DMAR;
USART1->CR1 |= USART_CR1_UE;
//__enable_interrupt();
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
GPIOUSART();
setupUsart1Dma();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
//MX_GPIO_Init();
//MX_DMA_Init();
MX_USB_DEVICE_Init();
//MX_SPI1_Init();
//MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
__enable_interrupt();
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(100);
//usbprint("\r\nSTARTING POINT\r\n\n\n\n",21);
strncpy(usbss, DMAArray, GPSBUFFER);
HAL_Delay(100);
//memset(DMAArray, 0, GPSBUFFER);
HAL_Delay(100);
usbprint(usbss ,(GPSBUFFER-1));
HAL_Delay(100);
HAL_Delay(100);
//memset(usbss, 0, (GPSBUFFER));
HAL_Delay(100);
usbprint("\r\nSTRING ENDING HERE\r\n",22);
HAL_Delay(100);
//DMA1_Channel5 ->CCR &= ~DMA_CCR_EN;
// if (!(USART1->CR3 & USART_CR3_DMAR))
// {
// USART1->CR3 |= USART_CR3_DMAR;
// DMA1_Channel5 ->CCR |= DMA_CCR_EN;
// }
}
}
Has anyone any experience of trying to do something similar??
Any tips for finding out what is causing the hard fault?
Thanks