STM32 Use DMA to generate bit pattern on GPIO PIN - stm32

I am trying to generate a bit pattern on a GPIO pin. I have set-up the DMA engine to transfer from an array of GPIO pin states to the GPIO BSRR register
Here is the code I am using to configure the DMA
hdma_tim16_ch1_up.Instance = DMA1_Channel3;
hdma_tim16_ch1_up.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim16_ch1_up.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim16_ch1_up.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim16_ch1_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim16_ch1_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim16_ch1_up.Init.Mode = DMA_NORMAL;
hdma_tim16_ch1_up.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_tim16_ch1_up) != HAL_OK)
{
Error_Handler();
}
/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one channel to perform all the requested DMAs. */
__HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_CC1],hdma_tim16_ch1_up);
__HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_UPDATE],hdma_tim16_ch1_up);
Here is the code I use to setup the transfer:
uint32_t outputbuffer[] = {
0x0000100,0x01000000,
0x0000100,0x01000000,
0x0000100,0x01000000,
0x0000100,0x01000000,
0x0000100,0x01000000,
0x0000100,0x01000000,
0x0000100,0x01000000
/* ... */
};
if (HAL_DMA_Start_IT(htim16.hdma[TIM_DMA_ID_UPDATE], (uint32_t)outputbuffer, (uint32_t)&GPIOG->BSRR, 14) != HAL_OK)
{
/* Return error status */
return HAL_ERROR;
}
__HAL_TIM_ENABLE_DMA(&htim16,TIM_DMA_UPDATE);
HAL_TIM_Base_Start_IT(&htim16);
I am expecting to see every time the counter overflows, the DMA transfers 32 bits from the array and increments to the next array position until the DMA CNDTR register reads 0.
I set up a GPIO pin to toggle every time the timer over flows and I setup an alternating bit pattern in the array. I would expect the two GPIO pins to be similar in their output shape but I get one longer pulse on the line connected to the DMA. Any tips would be greatly appreciated

configure TIM2 as input capture direct mode (TIM2_CH1)
configure TIM2 DMA direction "memory to peripheral"
configure TIM2 data width Half word / Half word
configure GPIO pins as GPIO_OUTPUT, for example 16 pins GPIOD0..GPIOD15
copy and paste HAL_TIM_IC_Start_DMA() function from HAL library and give it a new name MY_TIM_IC_Start_DMA()
find HAL_DMA_Start_IT() function call in MY_TIM_IC_Start_DMA()
replace (uint32_t)&htim->Instance->CCR1 with (uint32_t)&GPIOD->ODR
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&GPIOD->ODR, (uint32_t)pData, Length) != HAL_OK)
Now you can start DMA to GPIO transfer by calling
MY_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1,(uint32_t*)gpioBuffer,GPIO_BUFFER_SIZE);
Actual transfer must be triggered by providing pulses on TIM2_CH1 input pin (for example, by using output compare pin from other timer channel). Those pulses originally was used to save Timer2 CCR1 register values to DMA buffer. Code was tweaked to transfer DMA buffer value to GPIOD ODR register.
For GPIO to Memory transfer change TIM2 DMA direction to "peripheral to memory", configure GPIO pins as GPIO_INPUT and use GPIOD->IDR instead of ODR in HAL_DMA_Start_IT parameters in modified MY_TIM_IC_Start_DMA() function.

Related

STM32cubemx PWM + ADC DMA out of sync

I'm trying to get STM32F103 to work with ADC and DMA both in circular mode to perform DSP processing in a basic way (see picture).
DMA fills ADC buffer, on "ADC half full" interrupt we process samples inBuffer[0..half] and put it in outBuf[0..half].
Output buffer is also fed to timer-driven PWM via DMA.
My thought is: TIM1 prescaller is (2-1), period is (1024-1), which with 72MHz timer clock has to make 35156 kHz 10-bit PWM. With buffer length of 512 samples buffer is 14,5ms long. I wait for DMA to sample 256 samples every 7,25ms, pushing out 256 samples to PWM in total pointer-to-pointer sync.
The problem is that I'm not sure if ADC and PWM buffer are syncronised.
With following code i get this:
void dspStart(void){
HAL_TIM_Base_Start(&htim1); // start timer
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); //start PWM which triggers ADC
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)inBuf, ADC_BUFFER_LEN); // start DMA w/ ADC
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_3, (uint32_t*)outBuf, ADC_BUFFER_LEN); // start PWM output
}
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc1){
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3); // yellow channel
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1){
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3); // yellow channel
}
void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim1){
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4); // blue channel
};
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim1){
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4); // blue channel
}
ADC and PWM buffers are out of sync, although buffer size is same for both DMA channels and they share same TIM1.
What did I do wrong?
STM32cubeMX setting are following:

Is the sampling data missing or incorrect in DMA memory buffer, when using ADC with DMA circle mode?

My purpose is sampling signal by ADC channel with DMA data moving in STM32Fx board. Generate a square wave to ADC channel. If using DMA mode, some data is out of order or called mess. Same result happened on STM32F207 and STM32F373 board.
(1) When I collect converted data by using ADC EOC interrupt, the data array looks like a square wave. This is OK.
(2) I would like to try DMA circle instead of EOC IRQ, but the data array seems to mess up, some data missing or incorrect. It could worse if sampling rate was increasing. Below are my test results.
The picture shows my test result: EOC IRQ vs DMA circle mode
EOC IRQ vs DMA with sampling 62.5KHz The waveform in DMA became shorter.
The picture shows very worse DMA with sampling 200KHz The data on DMA mode mess up, but it's consistent by using ADC EOC IRQ.
enter code here
<<<< ADC config >>>>
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay =
ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 DeInit */
ADC_StructInit(&ADC_InitStructure);
/* Configure the ADC1 in continuous mode */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels 6 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1,
ADC_SampleTime_480Cycles);
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
#ifdef __DMA_ENABLE__
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA since ADC1 is the Master*/
ADC_DMACmd(ADC1, ENABLE);
#else
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
ADC_ITConfig(ADC1, ADC_IT_OVR, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
<<<< DMA config >>>>
/* DMA1 clock enable */
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2, ENABLE );
/* DMA1 Channel1 Config */
DMA_DeInit(DMA2_Stream0);
DMA_DoubleBufferModeConfig(DMA2_Stream0, (uint32_t)ADCValB, DMA_Memory_1);
DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADCValA;
DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t) ADC1) + 0x4C;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = NUM_OF_ADC; // 512 buffer size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
Finally, I expect the result should be same as that using ADC EOC IRQ.
I have encountered the same problem, as a part of my complicated application, the ADC reads continuously an input PWM data and configured with DMA request in circular mode.
First, I tried to store the converted data in a memory buffer at each End Of Conversion Interrupt. This works well, so I am confident that the ADC is correctly converting the data.
Second, I started the ADC with DMA request in circular mode, (for each End Of Conversion Interrupt, the DMA handler get the ADC converted data and store in a memory buffer). At this stage, when I check the memory buffer via the Debugger - It seams that the data are messed and it's like the DMA was skipping values).
Third, I just wanted to verify, if it's a DMA problem or it's a Debugger one. I started the ADC with DMA request in "normal" mode. And all of a sudden, when opening the Debugger, the memory buffer data are correctly stored.
To summarize, the main difference between the second and the third method when opening the Debugger, is that the DMA handler is still running (in circular mode) and as a result the Debugger can't be able to show correctly the memory buffer data, due to the speed of the ADC conversion time/ DMA Handler requests (~1 µs). And in the other hand (in normal mode), the DMA handlers stops once it has completed filling the buffer.
To conclude, the DMA handler works fine and you can output the square wave with the DAC using your buffer. And if you want to view correctly the data using the Debugger you need to stop the DMA (after a period of time; for example).
HAL_ADC_Stop_DMA(&hadc);
Based on the tabular view of the data you provided, it appears that the DMA is configured properly as the data looks nearly identical to the data obtained from ADC EOC IRQ.
The only variable between relying on DMA and an IRQ is that there may be unexpected bus "collisions" between the DMA Controller and the CPU as, unlike when using an IRQ, they are both running concurrently, potentially resulting in wait states.
From the STM32 Reference Manual Section 13.4:
The DMA controller performs direct memory transfer by sharing the system bus with the Cortex-M4 ® F core. The DMA request may stop the CPU access to the system bus for some bus cycles, when the CPU and DMA are targeting the same destination (memory or peripheral).
And your observed sampling rate-dependent degradation in performance certainly corroborates this hypothesis, as the busmatrix must arbitrate more frequent accesses between the DMA Controller and the CPU.
Without seeing the rest of your code that sets up and reads from the buffer, it is hard to say what aspect of your application code may be causing this issue.

STM32F4 : EEPROM 25LC256 management through SPI

I am trying to drive a EEPROM Chip 25LC256 with a STM32F469I-DISCO but can't achieve it.
I have tried to make my own function with HAL API bases but apparently something is wrong : I don't know if I write datas on the chip since I can't read it. Let me explain more.
So my chip is a DIP 25LC256 (DS is above is you wish). PINs HOLD and WP of EEPROM are tied to VCC (3.3V). PIN CS is connected to PH6 (ARD_D10 on board) and is managed by the software. PIN SI and PIN SO are respectively connected to PB15 (ARD_D11) and PB14 (ARD_D12) with the right alternate function (GPIO_AF5_SPI2). PIN SCK is also connected to PD3 (ADR_D13).
Here is my SPI configuration code :
EEPROM_StatusTypeDef ConfigurationSPI2(SPI_HandleTypeDef *spi2Handle){
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitTypeDef gpioInit;
//// SCK [PD3]
gpioInit.Pin = GPIO_PIN_3;
gpioInit.Mode = GPIO_MODE_AF_PP;
gpioInit.Pull = GPIO_PULLDOWN;
gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
gpioInit.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOD, &gpioInit);
//// MOSI [PB15]
gpioInit.Pin = GPIO_PIN_15;
gpioInit.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &gpioInit);
//// MISO [PB14]
gpioInit.Pin = GPIO_PIN_14;
gpioInit.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &gpioInit);
//// CS [PH6]
gpioInit.Pin = GPIO_PIN_6;
gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOH, &gpioInit);
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, GPIO_PIN_SET);
//// SPI2
__HAL_RCC_SPI2_CLK_ENABLE();
spi2Handle->Instance = SPI2;
spi2Handle->Init.Mode = SPI_MODE_MASTER;
spi2Handle->Init.Direction = SPI_DIRECTION_2LINES;
spi2Handle->Init.DataSize = SPI_DATASIZE_8BIT;
spi2Handle->Init.CLKPolarity = SPI_POLARITY_LOW;
spi2Handle->Init.CLKPhase = SPI_PHASE_1EDGE;
spi2Handle->Init.NSS = SPI_NSS_SOFT;
spi2Handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
spi2Handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
spi2Handle->Init.TIMode = SPI_TIMODE_DISABLE;
spi2Handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE ;
spi2Handle->Init.CRCPolynomial = 7;
if(HAL_SPI_Init(spi2Handle) != HAL_OK){
return EEPROM_ERROR;
}
return EEPROM_OK;
}
And two functions allowing respectively (and theorically) to WRITE and READ into the the chip :
Write Function :
EEPROM_StatusTypeDef WriteEEPROM(SPI_HandleTypeDef *spi2Handle, uint8_t *txBuffer, uint16_t size, uint16_t addr){
uint8_t addrLow = addr & 0xFF;
uint8_t addrHigh = (addr >> 8);
uint8_t wrenInstruction = WREN_EEPROM; // Value : 0x06
uint8_t buffer[32] = {WRITE_EEPROM, addrHigh, addrLow}; //Value : 0x02
for(uint i = 0 ; i < size ; i++){
buffer[3+i] = txBuffer[i];
}
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, RESET);
if(HAL_SPI_Transmit(spi2Handle, &wrenInstruction, 1, TIMEOUT_EEPROM) != HAL_OK){
return EEPROM_ERROR;;
}
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, SET);
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, RESET);
if(HAL_SPI_Transmit(spi2Handle, buffer, (size + 3), TIMEOUT_EEPROM) != HAL_OK){
return EEPROM_ERROR;
}
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, SET);
return EEPROM_OK;
}
Read Function :
EEPROM_StatusTypeDef ReadEEPROM(SPI_HandleTypeDef *spi2Handle, uint8_t *rxBuffer, uint16_t size, uint16_t addr){
uint8_t addrLow = addr & 0xFF;
uint8_t addrHigh = (addr >> 8);
uint8_t txBuffer[3] = {READ_EEPROM, addrHigh, addrLow};
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, RESET);
HAL_SPI_Transmit(spi2Handle, txBuffer, 3, TIMEOUT_EEPROM);
HAL_SPI_Receive(spi2Handle, rxBuffer, size, TIMEOUT_EEPROM);
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, SET);
return EEPROM_OK;
}
I know my function are not very "beautiful" but it was a first attempt. In my main, I have tried in the first place to write into the chip the data "0x05" at the 0x01 adress then to read this data back :
uint8_t bufferEEPROM[1] = {5};
uint8_t bufferEEPROM2[1] = {1};
WriteEEPROM(&spi2Handle, bufferEEPROM, 1, 0x01);
ReadEEPROM(&spi2Handle, bufferEEPROM2, 1, 0x01);
I have an oscilloscope so since it didn't work (monitoring with STM Studio) I visualized the CLK and SI PINs then CLK and SO PINs (can only see two channel at the same time) :
As you can see, with the first picture that shows CLK (yellow) and SI (or MOSI) in blue, I have all the data expected : The WRite ENable instruction then the WRITE instruction. Following the ADDRESS, then the DATA.
After that, the Read Function starts. First the READ instruction and the ADDRESS where I want to fetch the data. The last 8 bits are supposed to be the data stored at the address (0x01 in this case). Something happens on SI PIN but I guess this is because the HAL_SPI_Receive() function actually calls HAL_SPI_TransmitReceive() with my array bufferEEPROM2 as parameter (that's why we can se 0b00000001). And so it is because of my SPI configuration parameter (Full-duplex).
Anyway, theorically I am supposed to see 0b00000101 on SO PIN but as you can see in the second picture.... nothing.
I have tried to change gpioInit.Pull for SO PIN on PULLUP and PULLDOWN but nothing changed. NOPULL is because that's the last thing I have tried.
The thing is I don't know where to start. My transmission seems to work (but is it actually ?). Is there anything wrong with my initialization ? Acutally my main question would be : why I don't receive any data from my EEPROM ?
Many thanks !
Write operations need some time to complete (your datasheet says 5 ms on page 4), during that time no operation other than read status is possible. Try polling the status register with the RDSR (0x05) opcode to find out when it becomes ready (bit 0). You could also check the status (bit 1) before and after issuing WREN to see if it was successful.
So the problem is now solved. Here are the improvements :
There was actually two issues. The first one and certainly the most important is, as berendi stated, a timing issue. In my WRITE function I didn't let the time for the EEPROM to complete its write cycle (5 ms on datasheet). I added the following code line at the end of all my WRITE functions :
HAL_Delay(10); //10 ms wait for the EEPROM to complete the write cycle
The delay value could be less I think if time is preicous (theorically 5ms). I didn't test below 10 ms though. An other thing. With the oscilloscope I also saw that my Chip Select used to went HIGH in the middle of my last clock edge. I could not say if this could also imply some issues since that's a thing I solved in the first place by adding a code line before HAl_Delay(10). All my SPI transmission functions finishes this way now :
while(HAL_GPIO_ReadPin(CLK_PORT, CLK_PIN) == GPIO_PIN_SET){
}
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
HAL_Delay(10);
This way I have the proper pattern and I can write in the EEPROM and read back what I wrote.
NB : A last thing that made me goes deeper into my misunderstanding of the events : since my write functions didn't work, I focused on STATUS REGISTER write and read function (in order to solve this step by step). The write function didn't work either and in fact it was because the WRENbit wasn't set. I though (wrong one) that the fact to write into the STATUS REGISTER didn't ask also to set WREN like the WRITE functions into the memory ask to. Actually, it is also necessary.
Thanks for the help !

DM6446 GPIO Bank 0 request_irq returns -22

I'm trying to set up an interrupt-handler in my driver for DM6446 GPIO BANK 0 interrupt.But request_irq returns -22.I know the Interrupt number for GPIO BANK-0 from the data sheet which states it to be 56.Following are the settings for GPIO in my code.I want to get interrupt on GPIO-10.
while((REG_VAL(PTSTAT) & 0x1) != 0); // Wait for power state transtion to finish
REG_VAL(MDCTL26) = 0x00000203; //To enable GPIO module and EMURSITE BIT as stated in sprue14 for state transition
REG_VAL(PTCMD) = 0x1; // Start power state transition for ALWAYSON
while((REG_VAL(PTSTAT) & 0x1) != 0); // Wait for power state transtion to finish
REG_VAL(PINMUX0) = REG_VAL(PINMUX0) & 0x80000000; //Disbale other Functionlaity on BANK 0 pins
printk(KERN_DEBUG "I2C: PINMUX0 = %x\n",REG_VAL(PINMUX0));
REG_VAL(DIR01) = REG_VAL(DIR01) | 0xFFFFFFFF; //Set direction as input for GPIO 0 and 10
REG_VAL(BINTEN) = REG_VAL(BINTEN) | 0x00000001; //Enable Interrupt for GPIO Bank 0
REG_VAL(SET_RIS_TRIG01) = REG_VAL(SET_RIS_TRIG01) | 0x00000401; // Enable rising edge interrupt of GPIO BANK 0 PIN 0 PIN 10
REG_VAL(CLR_FAL_TRIG01) = REG_VAL(CLR_FAL_TRIG01) | 0x00000401; // Disable falling edge interrupt of Bank 0
Result = request_irq(56,Gpio_Interrupt_Handler,0,"gpio",I2C_MAJOR);
if(Result < 0)
{
printk(KERN_ALERT "UNABLE TO REQUEST GPIO IRQ %d ",Result);
}
A little help shall be appreciated.
Thank you.
I have tried the gpio_to_irq as well for PIN-10 of BANK-0 but it returns irq no to be 72 but DM6446 has interrupt number upto 63 only in Data sheet.
I got it. If i use gpio_to_irq, It will return a valid IRQ number but different than the interrupt number(which i guess is also called IRQ number) specified in data sheet of Processor.If I see the /proc/interrupts, it will have an entry of that IRQ returned form gpio_to_irq but under GPIO type not the processor's Interrupt controller, which in my case for ARM shall be AINTC.All other interrupts are of AINTC type.
Moreover, Even if request_irq succeeds with interrupt number stated in data sheet,/proc/stat will report interrupts at both IRQ numbers i.e. AINTC and GPIO type.

cortex-m0 systick interrupt doesn't happens

I am writting firmware for stm32f072.
The problem is that SysTick interrupt doesn't happens.
Here is simple code for SysTick configuring:
SysTick_Config(1000);
This function is taken from CMSIS's core_cm0.h file:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
System timer counts as expected.
SysTick->CTRL's overcounting bit is set to 1 but there is no interrupt happens! Firmware doesn't jump to SysTick_Handler().
What I miss? This code is enough for stm32f1 and stm32f4 devices but not work for stm32f0.
I recommend you to take a look at the Code Snippets from ST. These are low level programs for F0 (and L0) families. Some of them use the SysTick (e.g. first two example from CLOCK CONTROLLER projects) and all things are preconfigured and hopefully works on your board too. It is written originally for the STM32F072 Discovery board. I used it with my custom board with some tiny modifications.