I am working on lpc2468 and using UART0 of the controller for communication with sim300 gprs
module. Sometimes if i send a command for reading the signal strength of the sim the input I
receive is not correct. After looking upon the problem I found the problem that sometimes
when the UART is receiving information at same time the timer gets called and the software
goes to the timer block. in that duration some bytes sent by the module gets missed. To
prevent this i want to configure UART0 as FIQ i.e. interrupt having highest priority. can I
configure UART0 as FIQ.If yes How?
From LPC2048 data sheet,
The ARM processor core has two interrupt inputs called Interrupt
ReQuest (IRQ) and Fast Interrupt ReQuest (FIQ). The VIC takes 32
interrupt request inputs which can be programmed as FIQ or vectored
IRQ types. The programmable assignment scheme means that priorities
of interrupts from the various peripherals can be dynamically
assigned and adjusted.
So you need to find out where are the programmable registers of the Interrupt controller and change the interrupt type of UART to FIQ.
If you have simulation support, then see this to know how to change interrupt types and priorities.
Related
My MCU based control system must check 18 switch contact status fastly. I will use STM32F7 MCU and it has maximum 16 int. handler. So I have been decided to use IO expendar IC and divided groups. Now I have 12 IO external interrupt and 2 more interrupt comes from IO expander. In addition FreeRTOS will has ethernet, uart and canbus tasks for communications. Interrupts are very critical for system. There is milisecond difference between them and I have to detect all pins status correctly. I need and expert advice for this situation.
My questions are :
Is this a proper way ? Using 14 external interrupt onFreeRTOS that handles multiple communication task
Is there any better way for it ?
Using an IO expander seems like the wrong approach to your problem (additional complexity and cost). You don't have to assign a dedicated ISR to each pin. Just read the GPIOx_IDR register after any GPIO interrupt, then check the relevant bits STM32 Datasheet
I am using two STM32H743 connected via RS232. These two modules connected to same power.
They use UART with DMA. When I turn on modules at the same time, UART and DMA starts correctly.
But when i restart one of the modules while other is awake, the reset module's UART and DMA does not start therefore they cannot communicate with each other.
This problem is also happened before with STM32F4 series. MCU is connected to FPGA and they communicate via UART. When FPGA starts before MCU, DMA and UART does not start properly. What could cause this problem?
Do i need to have a high-z or floating pin states before starting UART?
After lots of debugging hours, I finally found the cause and solution.
When first bytes reach to UART peripheral, due to clock mismatch, it triggers frame error then stops the DMA. This happens more than usual when UART datarate is very high. But I had added the ErrorCallback function to handle the interrupt. Unfortunately, I misused the function.
My use :
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
HAL_UART_MspDeInit();
HAL_UART_Receive_DMA(...);
}
HAL_UART_MspDeInit does not clear structs and initializations therefore Receive_DMA function cannot start it again. So, my communication stops.
Correct use :
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
HAL_UART_DeInit();
HAL_UART_Receive_DMA(...);
}
Thanks to three typos in my code, it caused to me a lot of time. But finally, it resolved.
The UART and DMA peripherals usually have an error detector, thus has it's flags into the status register. When an error happen, the STM32 HAL will stop any transfer ongoing and wait until you treat this fail. You can check, with the debug module, the HAL status registers to troubleshoot the problem, and add the treatment to it in you code. At first you could reset the peripheral by run DeInit() and right after run Init() routine of the peripheral with error, and reset any other piece of code e.g. state machines and stuff that uses the data from this peripheral.
Is there any way to set the SDA and SCL pin of the I2C1 connection of the STM32 to low or high signal?
I use a security chip and I have to send a wake condition, with the following condition:
if SDA is held low for a period of greater than 60us, the device will exit low power mode and
after a delay of 1500us, it will be ready to receive I2C commands.
I've already tried to toggle the actual pin with HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);, but this isn't working.
I've configured my project with STM32CubeMX.
Thanks for your help.
In I2C, the START condition requires a High to Low transition, if you then send a dummy address 0, a NACK will be generated (or rather the lack of any response will be interpreted as a NACK). In a normal transaction, the software would respond to the NACK by generating a repeated START or a STOP condition, however this must be done in software, so all you have to do is nothing for 1.5ms. Thereafter you can generate the START with the device's actual address, and if the device is running it will generate an ACK.
I am not familiar with the HAL library driver, and frankly the documentation is abysmal, but it is possible that it does not give you the necessary control, and you will have to access the I2C peripheral at the register level for at least this procedure. You might try a zero-length I2C_MasterRequestWrite() call to address zero followed by a delay. An oscilloscope would be useful here to ensure the expected signal timing is being generated.
When you initialize I2C, GPIO pins mode is set to ALTERNATE MODE,so writing HAL commands won't work on it.
Using normal HAL libraries won't help you in this. You have to configure I2C protocol on your own using stm32 registers.
I recommend that the ownaddress of the slave address using the device of the using I2C channel sets like the below code.
I2C_InitStructure.I2C_OwnAddress1 = 0x30; // the unique slave address of the deviecs
because the master could be send the broadcast operation not the unique operation.
I'm using an ARM Cortex-M4 MCU. If I have an interrupt handler for a GPIO at priority 2 and an SPI driver at priority 3 (i.e., lower priority than the GPIO's), and I call a (blocking) SPI read from within the GPIO's interrupt handler, will the SPI function work?
The answer to your question depends on how it is blocking to handle the transfer, as #Notlikethat said.
If your SPI driver is a polling driver, then it will most likely work. In this case, your GPIO interrupt would spin on flags within the SPI peripheral, waiting for each part of the transfer to complete.
If your SPI driver is interrupt driven, then it will not work. Since you are executing a priority 2 interrupt (GPIO), the priority 3 interrupt (SPI) will not execute until the GPIO interrupt finishes. Depending on how your SPI driver is written, this may entirely hang your system, or it may result in a timeout.
If your SPI driver is DMA driven, then the answer is not so clear and depends on how the driver works. It is possible in this case, that your transaction would complete, but if the function has blocked waiting for a DMA interrupt, it may never arrive depending on its priority.
In any of the above cases, it would generally be considered not a good idea to do something like that inside of an interrupt. If you have an RTOS, you could use a high priority task that is waiting on a semaphore to execute the SPI transaction, or if the OS supports it, used deferred interrupt processing. If you aren't running with an RTOS, I would consider if there is a way you can signal a lower priority interrupt (i.e use PendSV at the lowest priority) or monitor a flag from within the main process. Using a lower priority interrupt, you can still preempt the main process (if that's what is needed), but all your other interrupts can continue executing. If you can monitor a flag in your main process, then that would also allow your interrupts to continue, but if you are time constrained, this may not be as possible (again, depending on how your application is structured)
i'm experiencing something that bugs me for days, so i am working on the imx6sx cortex m4 side, i have a sensor connected to one of the i2c buses, sensor is set up with data ready on INT1 which is connected to one of the gpios from the MCU. After boot, i configure the sensor so that it outputs data ready interrupt. Note that the i2c works also in interrupt mode, so if i try to read the sensor when the data ready line is asserted i have to wait in the GPIO INT Handler until the i2c transfer is complete in order to get another data ready int and so on.
My problem is that i don't want to wait in the GPIO INT Handler until the i2c transfer is complete, that's why i made the i2c on interrupts too, but if i don't wait in the GPIO Int Handler, something happens to the i2c because the sensor it's not ack the transfer, so i'n not getting other data-ready interrupts.
Please help if you have any idea what could be wrong, also the i2c bus Interrupt has a higher priority than the GPIO interrupt, and unfortunately i can't use a debugger for debugging, only the old-fashioned way, printfs in the console
Thanks
You could use INT1 to trigger a lower priority software interrupt to handle the i2c, then exit freeing the interrupt.
Consider using a RTOS to manage this for you.