HAL Libraries: What is the difference between DMA implementation in hal_dma.h and hal_uart.h libraires? - uart

I am trying to connect STM32G070 microcontroller with Quectel BC660K-GL via UART in DMA mode, using HAL libraries. There are two libraries both defining DMA communication functions (stm32g0xx_hal_uart.h and stm32g0xx_hal_dma.h). I am using Description of STM32G0 HAL and low-layer drivers manual. According to the manual _hal_dma.h defines Interrupt mode IO operation (page 215.), while _hal_uart.h provides, according to the description given in the library, Non-Blocking mode API's with DMA (lines 1054-1059). Hence I'm using DMA in order to offload CPU, which library would be preferred?

Related

STM32 boot loader

I'm learning about embedded systems and have an idea about one small project and I want to use Cortex M0+ based MCU STM32G081KBT6. I saw a lot of tutorials with this MCU type, but all of them are based on developer board and with them it is very simple to upload code with USB cable. I want to make my custom PCB for this. So my question is what I have to do so I can upload my code to this microcontroller?
From a datasheet I think I have to use SWDIO (PA13) and SWCLK(PA14) ports for Boot, but if someone can help me do I have to use also some resistors, can I make it USB to wire transfer with this, or I have to use some external device to make it possible? Or there is some easier and better solution to upload code from my laptop to microcontroller?
Thanks for the replies.
There two main options:
SWD
Implement an SWD programming connector. Basically the pins GND, SWDIO, SWCLK and preferably 3.3V are made available. No resisters are needed. You can fit a 4 pin header, an official 10 pin SWD connector or just 4 pads (for connecting using an adapter with pogo pins).
This option requires an SWD debug adapter like ST-Link or J-Link. In addition to uploading firmware, this option supports debugging.
USART
Make the USART (RX, TX) pins plus GND and 3.3V available on the board. This option requires a USB-to-serial adapter.
It's also possible to use I2C or SPI instead, though there are no standard solutions for connecting to your board that I'm aware of.
USB isn't an option for this particular chip. It is supported on many of the more expensive STM32 chips though.
I strongly recommend the first option. It is far more versatile than the other options. And an ST-Link adapter isn't expensive.
Details regarding the bootloader capabilities and pins:
https://www.st.com/resource/en/application_note/cd00167594-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf

Data input/output on Basys3 board's USB port

I'm trying to configure/write VHDL code that would let me output or input data from the USB port on a Basys3 FPGA board. Problem is I have yet to found any threads or questions that talk about this topic.
The nearest thing to an answer I've found is this:
Provide input data to FPGA using USB
and it does not contain what I'm looking for.
Any clues anyone¿?
The Basys3 board has a usb-uart bridge chip as described in the reference manual. This will appear to a PC (or any device with a usb host and the appropriate usb-serial drivers) as a virtual com port. Sending data to and from a PC com port is quite easy.
You will need a uart implementation on the FPGA. There are lots of example designs on the web. One way is to implement a soft core microblaze processor with a uart peripheral in the FPGA. This example looks like it includes foundation for the functionality you desire.
The simplest implementation from the PC side is using a terminal program such as putty, Tera Term or realterm. Most languages include com(serial) port libraries or bindings. This type of interface tops out at a raw bandwidth of around 3-12Mbits per second depending on the drivers and implementation.
Read the manual for the Basys 3 board. It will explain how you can interface with USB devices plugged into the USB port. Be warned, however, that your options are pretty limited.
Short version: if you plug in a USB mouse or keyboard, they will be exposed to your design as an emulated PS/2 device. USB storage devices can be used to configure the FPGA. Other devices are not supported.

How to code ARM interrupt functions in C

I am using arm-none-eabi-gcc toolchain, v 4.8.2, on LinuxMint 17.2 64b.
I am, at hobbyist level, trying to play with a TM4C123G board and its usual features (coding various blinkies, uart things...) but always trying to remain as close to the metal as possible without using other libraries (eg CMSIS...) whenever possible. Also no IDE (CCS, Keil...), just Linux terminal windows, the board and I... All that mostly for education purpose.
The issue : I am stuck trying to implement the usual interrupt functions like :
EnableInt (clearing bit 0, bit I, of special registry PRIMASK) :
CPSIE I
WaitForInt :
WFI
DisableInt :
CPSID I
Eg, I added this function to my .c file for EnableInt :
void EnableInt(void)
{ __asm(" cpsie i\n");
}
... this compiles but the execution does not seem to work properly (in the simplest blinky.c version, I cannot get any LED action once I have called EnableInt() in the C code). The blinky.c code can be found here.
What would be the proper way to write these interrupt routines in a .c file (ideally without using other libraries, but just setting/clearing bits of the appropriate registers...)?
EDIT : removed the bx lr instructions - but EnableInt() does not seem to work any better - still looking for a solution.
EDIT2 : Actually the function EnableInt(), defined as above, is now working. My SysTick_Handler was mapped incorrectly to the Interrupt Vector table in the startup file (while my original problem was the bx lr instructions which I removed in Edit1).
The ARM Cortex-M4 CPU which your Tivia MCU incorporates does basically not require the software environment to take special action for entry/exit the interrupt handler. The only requirement is to use the AAPCS calling standard, which should be the default with gcc if compiling for this CPU.
The CPU is supported by some tightly coupled "core" peripherals provided by ARM. These are standard for most (if not all) Cortex-M3/4 MCUs. MCU vendors can configure some features, but the basic operation is always the same.
To simplify software development, ARM has introduced the CMSIS software standard. This at least consists of some header-files which unify access to the core-peripherals and use of special CPU instructions. Among those are intrinsics to manipulate the special CPU registers like PRIMASK, BASEMASK, OPTION, etc. Another header provides definitions of the core peripherals and functions to manipulate some of them where a simple access is not sufficient.
So, one of these peripherals supports the CPU for interrupt handling: The NVIC (nested vector-interrupt controller). This prioritises interrupts aagains each other and provides the interrupt vector to the CPU which uses this vector to fetch the address of the interrupt handler.
The NVIC also includes enable-bits for all interrupt sources. So, to have an interrupt processed by the CPU, for a typical MCU you have to enable the interrupt in two or three locations:
PRIMASK/BASEMASK in the CPU: last line of defense. These are the global interrupt gates. `PRIMASK is similar to the interrupt-enable bit in the status-register of the smaller CPUs, BASEMASK is part of interrupt-priority resolution (just ignore it for the beginning).
NVIC interrupt-enable bit for each peripheral interrupt source. E.g Timer, UART, SPI, etc. Many peripherals have multiple internal sources tied to this NVIC-line. (e.g UART rx and tx interrupt).
The interrupt-enable bits in the peripheral itself. E.g. UART rx-interrupt, tx interrupt, rxerror interrupt, etc.
Some peripherals might not have internal bits, so the last one might be missing.
To get things working, you should read the Reference Manaul (Family Guide, or similar), then there is often some "porgramming the Cortex-M4" howto (e.g ST has one for the STM32 series). You should also get the documents from ARM (they are available for free download).
Finally you need the CMSIS headers from your MCU vendor (TI here). These should be tailored for your MCU. You might have to provide some `#define's.
And, yes, this is quite some stuff to read. But imo it is worth the effort. Alternatively you might start with a book. There are some out which might be helpful to get the whole picture first (it is really hard to get from the single documents - yet possible).

DSPIC33F UART DMA Example not working

I am trying to use DMA for my UART Rx and Tx. Till now I had the freeRTOS version of the serial demo working fine. It still works fine. However, now I have incorporated the UART DMA example, from the example projects.
the code is conditionally compiled, so that when a switch _HAS_DMA == 1, only then the DMA engine is configured, ram buffers are configured, and default UART ISRs as required by the FreeRTOS demo are removed.
At this point, whenever I send a serial byte stream, the running project simply gets reset.
I am using MPLAB IDE 8.92, XC16 v1.20, Explorer-16 platform, dspic33fj256gp710 part.
The DMA code included does not use any FreeRTOS API calls.
I have setup the project so that StackOverflow is detected using the FreeRTOS configuration option. But the code does not reach the Stackoverflow hook function. I have also included the U2ErrInterrupt ISR to see if incoming bytes are coming in fine, however even that interrupt is not reached.
Has any one faced this before?
interestingly, the UART DMA Loopback example from Microchip website, which uses the MPLAB C30 compiler, works fine on my board.
any pointers on this one? I could not locate any code examples in the FreeRTOS forum on how to use the DMA for UART, but it is suggested to use this method in production code for efficiency.
Need help here.
Thanks and best regards,
Vishal
OK. I found the culprit. Its me. :)).
When setting up the DMA to receive UART interrupts, one should not enable UART interrupt separately in software. Which is what I was doing. In addition, I had conditionally un-compiled the UART ISRs from my code !!!. So in effect, whenever a byte was received by the UART engine, the processor is getting confused as to who will serve this interrupt, DMA or Application code. I thing the PC would point to the designated UART RX ISR vector location, where the processor would not find anything, and this was causing the reset. Or may be there was a race condition setup between the DMA and the processor to serve this interrupt, which was causing the reset.
Now that I have setup UART so that Interrupts are not enabled separately by application, when DMA is going to serve the UART RX, my code is working fine. I am yet to integrate the whole thing with FreeRTOS deferred interrupt processing using binary semaphores, but I hope I will not see any troubles there.
There is not much documented about this though...neither in Microchip manuals nor in the FreeRTOS examples.
Also, I found that when using DMA with UART, as per the manual, the DMA receives WORDS from the UART RX engine, with lower byte having the data, and upper byte having the status. If the DMA is also used for UART Tx, and is set to transfer WORDS to UART TXREG, the two intelligently manage to send only the lower data byte out. So the receiving party still gets expected bytes. This is also not documented well.
I will try to post my code here for future generations though :)).

Making endpoint data buffers DMA able

I am currently working on a custom hardware which has SH_MOBILE architecture. Hardware comes with USB(peripheral) and a DMAC having 2 channels.
I am using R8a66597 UDC driver which is available in mainline kernel. I have added DMA related functions to the peripheral controller driver. Currently I am able to get the DMA working in TX path. But in RX path I am not able to use DMA, instead PIO is getting used. This is because the buffer address (buf in struct usb_request) is not 8 bit aligned.
I would want to know how to ensure that these data transfer buffer is DMA able?
Thanks in advance,
Srinidhi KV