MQX Lite LED task not work - arm

I am using FRDM-KL25Z arm board from freescale and I have successfully Written LED blink program using code warrior IDE. I am also able to run all the sample program from freescale start up kit.
Now I am writing A MQX Lite program to blink LED's using MQX tasks.
I made three tasks One for Initialising and 2 other for blinkin the LEDs on the board using task.
The task declaration in task_template_list.c is below
#define TASK_TEMPLATE_LIST_END {0, 0, 0, 0, 0, 0, 0}
/* MQX task template list */
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task: InitTask */
{
/* Task number */ INITTASK_TASK,
/* Entry point */ (TASK_FPTR)InitTask,
/* Stack size */ INITTASK_TASK_STACK_SIZE,
/* Task priority */ 8U,
/* Task name */ "inittask",
/* Task attributes */ (MQX_AUTO_START_TASK),
/* Task parameter */ (uint32_t)(0)
},
/* Task: LEDTask */
{
/* Task number */ LEDTASK_TASK,
/* Entry point */ (TASK_FPTR)LEDTask,
/* Stack size */ LEDTASK_TASK_STACK_SIZE,
/* Task priority */ 10U,
/* Task name */ "ledtask",
/* Task attributes */ (0),
/* Task parameter */ (uint32_t)(0)
},
/* Task: GR_LED_ON */
{
/* Task number */ GR_LED_ON_TASK,
/* Entry point */ (TASK_FPTR)GR_LED_ON,
/* Stack size */ GR_LED_ON_TASK_STACK_SIZE,
/* Task priority */ 9U,
/* Task name */ "gr_led_on",
/* Task attributes */ (0),
/* Task parameter */ (uint32_t)(0)
},
TASK_TEMPLATE_LIST_END
};
Now in the mqx_tasks.c I have written a code like below
/* ###################################################################
** Filename : mqx_tasks.c
** Project : ProcessorExpert
** Processor : MKL25Z128VLK4
** Component : Events
** Version : Driver 01.00
** Compiler : GNU C Compiler
** Date/Time : 2013-05-27, 17:44, # CodeGen: 0
** Abstract :
** This is user's event module.
** Put your event handler code here.
** Settings :
** Contents :
** InitTask - void InitTask(uint32_t task_init_data);
**
** ###################################################################*/
/*!
** #file mqx_tasks.c
** #version 01.00
** #brief
** This is user's event module.
** Put your event handler code here.
*/
/*!
** #addtogroup mqx_tasks_module mqx_tasks module documentation
** #{
*/
/* MODULE mqx_tasks */
#include "Cpu.h"
#include "Events.h"
#include "mqx_tasks.h"
#ifdef __cplusplus
extern "C" {
#endif
/* User includes (#include below this line is not maintained by Processor Expert) */
#define RED_LED_LOC (1<<18)
#define GREEN_LED_LOC (1<<19)
#define BLUE_LED_LOC (1<<1)
#define RED_LED_OFF GPIOB_PSOR = RED_LED_LOC
#define RED_LED_ON GPIOB_PCOR = RED_LED_LOC
void Delay(int Ticks)
{
int i;
for(i=0;i<Ticks;i++)
{
}
}
/*
** ===================================================================
** Event : InitTask (module mqx_tasks)
**
** Component : Task1 [MQXLite_task]
** Description :
** MQX task routine. The routine is generated into mqx_tasks.c
** file.
** Parameters :
** NAME - DESCRIPTION
** task_init_data -
** Returns : Nothing
** ===================================================================
*/
void InitTask(uint32_t task_init_data)
{
//First order of business is to enable the Clocks to the ports!
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTD_MASK;
//Now, setup the port mux for GPIO! See Page 163 and 183 of KL25 Sub-Family Reference Manual, Rev. 3, September 2012
PORTB_PCR18 = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
PORTB_PCR19 = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
PORTD_PCR1 = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK;
//Set the GPIO to outputs in the data direction register
//See Page 778 of KL25 Sub-Family Reference Manual, Rev. 3, September 2012
GPIOB_PDDR |= RED_LED_LOC | GREEN_LED_LOC;
GPIOD_PDDR |= BLUE_LED_LOC;
RED_LED_OFF;
/* _task_id task_id;
task_id=_task_create_at(0, LEDTASK_TASK, 0, LEDTask_task_stack, LEDTASK_TASK_STACK_SIZE);
if(task_id=MQX_NULL_TASK_ID){
printf("\n can not create led task");
}else{
printf("\n LED task created");
}
task_id=_task_create_at(0, GR_LED_ON_TASK, 0, GR_LED_ON_task_stack, GR_LED_ON_TASK_STACK_SIZE);
if(task_id=MQX_NULL_TASK_ID){
printf("\n can not create led task");
}else{
printf("\n LED task created");
}*/
_task_create_at(0, GR_LED_ON_TASK, 0, GR_LED_ON_task_stack, GR_LED_ON_TASK_STACK_SIZE);
_task_create_at(0, LEDTASK_TASK, 0, LEDTask_task_stack, LEDTASK_TASK_STACK_SIZE);
}
/*
** ===================================================================
** Event : LEDTask (module mqx_tasks)
**
** Component : Task2 [MQXLite_task]
** Description :
** MQX task routine. The routine is generated into mqx_tasks.c
** file.
** Parameters :
** NAME - DESCRIPTION
** task_init_data -
** Returns : Nothing
** ===================================================================
*/
void LEDTask(uint32_t task_init_data)
{
int value=0;
while(TRUE)
{
//The dedicated GPIO Set and clear registers make bit banging easier. Just write to the port what bits
//you want set or cleared. The or-ing / not-anding is done in *hardware*
//see pages 775 - 778 of KL25 Sub-Family Reference Manual, Rev. 3, September 2012
// RED_LED_OFF;
// Delay(1000000);
GPIOB_PSOR = GREEN_LED_LOC;
Delay(1000000);
GPIOD_PSOR = BLUE_LED_LOC;
Delay(1000000);
// RED_LED_ON;
// Delay(1000000);
GPIOB_PCOR = GREEN_LED_LOC;
Delay(1000000);
GPIOD_PCOR = BLUE_LED_LOC;
Delay(1000000);
value=value^1;
}
}
/*
** ===================================================================
** Event : GR_LED_ON (module mqx_tasks)
**
** Component : Task3 [MQXLite_task]
** Description :
** MQX task routine. The routine is generated into mqx_tasks.c
** file.
** Parameters :
** NAME - DESCRIPTION
** task_init_data -
** Returns : Nothing
** ===================================================================
*/
void GR_LED_ON(uint32_t task_init_data)
{
int value=0;
while(TRUE)
{
//The dedicated GPIO Set and clear registers make bit banging easier. Just write to the port what bits
//you want set or cleared. The or-ing / not-anding is done in *hardware*
//see pages 775 - 778 of KL25 Sub-Family Reference Manual, Rev. 3, September 2012
/* GPIOB_PSOR = GREEN_LED_LOC;
Delay(1000000);
GPIOD_PSOR = BLUE_LED_LOC;
Delay(1000000);*/
RED_LED_ON;
Delay(1000000);
/* GPIOB_PCOR = GREEN_LED_LOC;
Delay(1000000);
GPIOD_PCOR = BLUE_LED_LOC;
Delay(1000000);*/
RED_LED_OFF;
Delay(1000000);
value=value^1;
}
}
/* END mqx_tasks */
#ifdef __cplusplus
} /* extern "C" */
#endif
/*!
** #}
*/
/*
** ###################################################################
**
** This file was created by Processor Expert 10.2 [05.06]
** for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/
**
But when I debug the program I only blinks the LED of the higher priority and the other task is not working .....
Can anyone suggest me what mistake I am doing .
Thanks**

You've made a fatal mistake with your Delay() function !
What you have written in Delay() is an active loop that consumes all the CPU,
leaving no CPU time available for threads with lower priorities.
Please use _time_delay() (MQX API) instead of your Delay() function, then everything should be OK.

Related

Trying to blink LED STM32Cube IDE STM32F411E-DISCO

I'm trying to get started with STM32Cube IDE by blinking an LED on the board (PD15). I generated the starter C code by selecting the correct board, then added the following to the main loop:
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
HAL_Delay(200);
I know the board works because I can run the example code "Demonstrations" which uses all of the LEDs, unfortunately the source isn't provided. I think the problem might be with the auto generated code so here is the full code:
#include "main.h"
#include "usb_host.h"
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}
}
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
From the thread on the original post, my problem was that I was not initializing the GPIO ports properly, and the following line was missing from below the HAL_Init() line:
__HAL_RCC_GPIOD_CLK_ENABLE();
With the changes I am able to control the LEDs

i.MX 8M EVK : how to calculate the frequency values for a 1ms timer?

I want to implement a simple "GPT" timer that generates an interrupt every 1ms.
However, I get an interrupt exactly every 3ms (instead of the desired 1ms).
Where is my error? What values should I set to get a 1ms timer?
Here is my calculation for the GPT timer:
EXPLANATION OF TIMER VALUES:
We take for source clock the PLL1 DIV2 400MHz
We define the root divisor at 4 => 400MHz / 4 = 100MHz
100MHz = one increment every 10ns
We want an interrupt to be generated every 1 ms
So we have :
Output_compare_value = delay_time x GPT_frequency
Output_compare_value = 1 x 10^-3 x (1/(10 x 10^-9)) = 100000
Here is my code (I change the state of a GPIO at each interrupt to check the operation of my timer on the oscilloscope):
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_gpt.h"
#include "fsl_gpio.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define GPT_IRQ_ID GPT1_IRQn
#define EXAMPLE_GPT GPT1
//#define EXAMPLE_GPT_CLK_FREQ \
// (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootGpt1)) / \
// (CLOCK_GetRootPostDivider(kCLOCK_RootGpt1)) / 2) /* SYSTEM PLL1 DIV2 */
#define EXAMPLE_GPT_CLK_FREQ 100000
#define EXAMPLE_GPT_IRQHandler GPT1_IRQHandler
#define EXAMPLE_LED_GPIO GPIO3
#define EXAMPLE_LED_GPIO_PIN 23U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool gptIsrFlag = false;
/* The PIN status */
volatile bool g_pinSet = false;
/*******************************************************************************
* Code
******************************************************************************/
void EXAMPLE_GPT_IRQHandler(void)
{
/* Clear interrupt flag.*/
GPT_ClearStatusFlags(EXAMPLE_GPT, kGPT_OutputCompare1Flag);
gptIsrFlag = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U)
__DSB();
#endif
}
/*!
* #brief Main function
*/
int main(void)
{
uint32_t gptFreq;
gpt_config_t gptConfig;
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
/* Board pin, clock, debug console init */
/* Board specific RDC settings */
BOARD_RdcInit();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
CLOCK_SetRootMux(kCLOCK_RootGpt1, kCLOCK_GptRootmuxSysPll1Div2); /* Set GPT1 source to SYSTEM PLL1 DIV2 400MHZ */
CLOCK_SetRootDivider(kCLOCK_RootGpt1, 1U, 4U); /* Set root clock to 400MHZ / 4 = 100MHZ */
GPT_GetDefaultConfig(&gptConfig);
/* Initialize GPT module */
GPT_Init(EXAMPLE_GPT, &gptConfig);
/* Divide GPT clock source frequency by 3 inside GPT module */
GPT_SetClockDivider(EXAMPLE_GPT, 1);
/* Get GPT clock frequency */
gptFreq = EXAMPLE_GPT_CLK_FREQ;
/* GPT frequency is divided by 3 inside module */
gptFreq /= 1;
/* Set both GPT modules to 1 second duration */
GPT_SetOutputCompareValue(EXAMPLE_GPT, kGPT_OutputCompare_Channel1, gptFreq);
/* Enable GPT Output Compare1 interrupt */
GPT_EnableInterrupts(EXAMPLE_GPT, kGPT_OutputCompare1InterruptEnable);
/* Enable at the Interrupt */
EnableIRQ(GPT_IRQ_ID);
PRINTF("\r\nPress any key to start the example");
GETCHAR();
/* Init output LED GPIO. */
GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);
/* Start Timer */
PRINTF("\r\nStarting GPT timer ...");
GPT_StartTimer(EXAMPLE_GPT);
while (true)
{
/* Check whether occur interupt and toggle LED */
if (true == gptIsrFlag)
{
PRINTF("\r\n GPT interrupt is occurred !");
gptIsrFlag = false;
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
g_pinSet = false;
}
else
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
g_pinSet = true;
}
}
else
{
__WFI();
}
}
}
I found out what my problem was with the timer. The truth is that all my values were fine, but it was the execution of the logging that was taking time (line PRINTF("GPT interrupt is occurred !");) So I could have lowered my reload value even more, but I would still have the logging that was taking time to run.

Call different CAN-controllers in one function?

My first question here. I´m no proffesional programmer at all. Just for fun at home so I don´t really know the right terminology for what I´m about to ask.
I want to create a CAN-bus gateway and I have the NXP DEVKIT-MPC5748G. All the CAN-busses are set-up and working for both tx and rx. Now I want to create a function for manipulating the different CAN-controllers. Theres 8 of them so I was hoping of not write 8 equal functions only having what CAN-controller to use differ.
You setup the controllers like this:
CAN_1.CTRL1.B.CLKSRC = 0;
Just an example for setting the clock source.
CAN_1 has a macro like this:
#define CAN_1 (*(volatile struct CAN_1_7_tag *) 0xFBEC0000UL)
In that struct there is a hole lot of unions for accessing all the registers. Now I want to write a function that I can pass a parameter to tell what CAN-controller to use. I can use a switch/case style way of doing it but that code will be long and ugly.
I want to do something like this:
void Tx_Msg("type???" gwport, int mb, uint32_t id) {
gwport.[mb].CS.B.CODE = 0x8; }
But I cant figure out how to do it. Can it be done?
Thankfull for all help in the right direction. :)
Best regards, Joakim
EDIT to clarify
CAN_1_7_tag struct:
struct CAN_1_7_tag {
CAN_MCR_tag MCR; /* Module Configuration Register */
CAN_CTRL1_tag CTRL1; /* Control 1 register */
CAN_TIMER_tag TIMER; /* Free Running Timer */
uint8_t CAN_reserved0[4];
CAN_RXMGMASK_tag RXMGMASK; /* Rx Mailboxes Global Mask Register */
CAN_RX14MASK_tag RX14MASK; /* Rx 14 Mask register */
CAN_RX15MASK_tag RX15MASK; /* Rx 15 Mask register */
CAN_ECR_tag ECR; /* Error Counter */
CAN_ESR1_tag ESR1; /* Error and Status 1 register */
CAN_IMASK2_tag IMASK2; /* Interrupt Masks 2 register */
CAN_IMASK1_tag IMASK1; /* Interrupt Masks 1 register */
CAN_IFLAG2_tag IFLAG2; /* Interrupt Flags 2 register */
CAN_IFLAG1_tag IFLAG1; /* Interrupt Flags 1 register */
CAN_CTRL2_tag CTRL2; /* Control 2 register */
CAN_ESR2_tag ESR2; /* Error and Status 2 register */
uint8_t CAN_reserved1[8];
CAN_CRCR_tag CRCR; /* CRC Register */
CAN_RXFGMASK_tag RXFGMASK; /* Rx FIFO Global Mask register */
CAN_RXFIR_tag RXFIR; /* Rx FIFO Information Register */
CAN_CBT_tag CBT; /* CAN Bit Timing Register */
uint8_t CAN_reserved2[24];
CAN_IMASK3_tag IMASK3; /* Interrupt Masks 3 Register */
uint8_t CAN_reserved3[4];
CAN_IFLAG3_tag IFLAG3; /* Interrupt Flags 3 Register */
uint8_t CAN_reserved4[8];
CAN_MB_tag MB[64];
uint8_t CAN_reserved5[1024];
CAN_RXIMR_tag RXIMR[96]; /* Rx Individual Mask Registers */
uint8_t CAN_reserved6[512];
CAN_FDCTRL_tag FDCTRL; /* CAN FD Control Register */
CAN_FDCBT_tag FDCBT; /* CAN FD Bit Timing Register */
CAN_FDCRC_tag FDCRC; /* CAN FD CRC Register */
};
Example for MCR register. All registers works the same way.
typedef union CAN_MCR_union_tag { /* Module Configuration Register */
vuint32_t R;
struct {
vuint32_t MDIS:1; /* Module Disable */
vuint32_t FRZ:1; /* Freeze Enable */
vuint32_t RFEN:1; /* Rx FIFO Enable */
vuint32_t HALT:1; /* Halt FlexCAN */
vuint32_t NOTRDY:1; /* FlexCAN Not Ready */
vuint32_t WAKMSK:1; /* Wake Up Interrupt Mask */
vuint32_t SOFTRST:1; /* Soft Reset */
vuint32_t FRZACK:1; /* Freeze Mode Acknowledge */
vuint32_t SUPV:1; /* Supervisor Mode */
vuint32_t SLFWAK:1; /* Self Wake Up */
vuint32_t WRNEN:1; /* Warning Interrupt Enable */
vuint32_t LPMACK:1; /* Low-Power Mode Acknowledge */
vuint32_t WAKSRC:1; /* Wake Up Source */
vuint32_t _unused_18:1;
vuint32_t SRXDIS:1; /* Self Reception Disable */
vuint32_t IRMQ:1; /* Individual Rx Masking And Queue Enable */
vuint32_t DMA:1; /* DMA Enable */
vuint32_t _unused_14:1;
vuint32_t LPRIOEN:1; /* Local Priority Enable */
vuint32_t AEN:1; /* Abort Enable */
vuint32_t FDEN:1; /* CAN FD operation enable */
vuint32_t _unused_10:1;
vuint32_t IDAM:2; /* ID Acceptance Mode */
vuint32_t _unused_7:1;
vuint32_t MAXMB:7; /* Number Of The Last Message Buffer */
} B;
} CAN_MCR_tag;
Hope this is what you asked for.
If CAN_1 is define as:
#define CAN_1 (*(volatile struct CAN_1_7_tag *) 0xFBEC0000UL)
Then CAN_1 is a structure of type CAN_1_7_tag which is located at 0xFBEC0000UL.
The volatile qualifier is here to indicate to the compiler that is should not optimize anything relatives to the CAN_1 as it might be changed by other threads.
You can pass the CAN-controller as a pointer:
void Tx_Msg(volatile struct CAN_1_7_tag *p_gwport, int mb, uint32_t id)
{
p_gwport->CTRL1.B.CLKSRC = 0;
p_gwport->MB[mb].CS.B.CODE = 0x8;
}
Then when calling this function to send a message from a specific CAN-controller, you can use:
Tx_Msg(&CAN_1, 12, 25);
Tx_Msg(&CAN_4, 21, 45);
Thanks one more time for the help. The CAN gateway is up and running as a prototype.
This is my "final" code.
/********************************************************************************/
/* Tx function for FlexCAN 1-7 */
/********************************************************************************/
void Tx_Msg_1_7(volatile struct CAN_1_7_tag *port, uint32_t mb, uint32_t dlc, uint32_t id, uint8_t txData[])
{
int i = 0; // Used in for loops
port->MB[mb].CS.B.CODE = 0x8; // MB TX inactive
port->MB[mb].CS.B.DLC = dlc; // Message length max 8 bytes
port->MB[mb].CS.B.RTR = 0; // Remote frame disable
port->MB[mb].CS.B.SRR = 1; // Not used with standard id
if (id > 0x7FF) // CAN id 29 bits
{
port->MB[mb].CS.B.IDE = 1; // EXT CAN id
port->MB[mb].ID.B.ID_STD = id >> 18 & 0x7FF; // CAN id (11 bits)
port->MB[mb].ID.B.ID_EXT = id & 0x3FFFF; // CAN id (18 bits)
}
else // CAN id 11 bits
{
port->MB[mb].CS.B.IDE = 0; // STD CAN id
port->MB[mb].ID.B.ID_STD = id; // CAN id (11 bits)
port->MB[mb].ID.B.ID_EXT = 0; // CAN id (18 bits), always 0
}
for(i = 0; i < dlc; i++)
{
port->MB[mb].DATA.B[i] = txData[i];
}
port->MB[mb].CS.B.CODE = 0xC; // MB once transmit data
}

RTC on an mcu - function pointers and callbacks

The code below is an example of how to use the real time clock on an mcu.
My question is in relation to callbacks and function pointers.
I have included the struct declaration for rtc_config_t below.
My question is, on the line cfg.callback = rtc_example_callback
Why is the & sign not used before rtc_example_callback.
Why is not necessary to pass the arguments to rtc_example_callback?
The last struct memeber void *callback_data; is set to NULL, I don't understand what this does?
When or what would you want to return?
Many tanks for your inputs
#include "rtc.h"
#include "interrupt.h"
#include "isr.h"
#define ALARM (QM_RTC_ALARM_MINUTE / 6)
#define MAX_RTC_FIRINGS (5)
void rtc_example_callback(void *);
static volatile uint32_t rtc_fired = 0;
/* RTC app example */
int main(void)
{
/* Variables */
rtc_config_t cfg; //create a struct variable to configure the RTC
PRINTF("Starting: RTC\n");
/* Initialise RTC configuration */
cfg.init_val = 0;
cfg.alarm_en = true;
cfg.alarm_val = ALARM;
cfg.callback = rtc_example_callback;
cfg.callback_data = NULL;
irq_request(IRQ_RTC_0, rtc_isr_0); //submit the RTC to the interrupt service routine
clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); //switch on RTC and Periphal clock
rtc_set_config(RTC_0, &cfg); //Set the RTC configuration
/* Wait for RTC to fire 5 times and then finish. */
while (rtc_fired < MAX_RTC_FIRINGS) {
}
PRINTF("Finished: RTC\n");
clk_periph_disable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK); //turn off the clocks
return 0;
}
void rtc_example_callback(void *data)
{
PUTS("Alarm!!\n");
qm_rtc_set_alarm(RTC_0, (RTC[RTC_0].rtc_ccvr + ALARM));
rtc_fired++;
}
-----------------------------------------------------------------------
/**
* RTC configuration type.
*/
typedef struct {
uint32_t init_val; /**< Initial value in RTC clocks. */
bool alarm_en; /**< Alarm enable. */
uint32_t alarm_val; /**< Alarm value in RTC clocks. */
/**
* User callback.
*
* #param[in] data User defined data.
*/
void (*callback)(void *data);
void *callback_data; /**< Callback user data. */
} rtc_config_t;
name of the function is a pointer to the function
function will be called with arguments from rtc library, you are not invoking it (you cannot pass arguments here).
I guess that NULL assigned to custom_callback will not call custom method from library (default function or no function will be called), just assign NULL if you dont want to use custom callback.
usually library code looks like:
if(custom_callback)
{
custom_callback(some_parameters);
}
else
{
default_callback(some_parameters);
}

Device Tree configuration i.MX6

Hy all,
I have developed my own board based on a i.MX6 from Freescale and I want to configure the device tree.
I am using this software : Processor Expert for i.MX to generate all the pin's configurations.
The software is generating .c and .h files :
GPIO.c
I2C.c
...
iomux_config.c
iomux_config.h
...
My question is : How and where I have to implement those files in my linux kernel or in my u-boot files ? Or do I have to generate a dts file ?
Thanks in adance for your help !
EDIT :
Here is some of the generated files :
iomux_config.c :
#include "iomux_config.h"
/*
** ===================================================================
** Method : pin_init_iomux_config (component PinSettings)
*/
/*!
** #brief
** This method sets registers according routing settings. Call
** this method in user code to route desired pins into
** peripherals. The method is useful for reinitialization HW
** after some routing changes.
*/
/* ===================================================================*/
void iomux_config(void)
{
configure_audmux_pins(0u);
configure_ecspi_pins(1u);
configure_enet_pins(0u);
configure_gpio_pins(0u);
configure_gpio_pins(1u);
configure_gpio_pins(3u);
configure_gpio_pins(5u);
configure_gpio_pins(6u);
configure_i2c_pins(0u);
configure_i2c_pins(1u);
configure_i2c_pins(2u);
configure_i2c_pins(3u);
configure_ipu1_pins(0u);
configure_pwm_pins(0u);
configure_pwm_pins(1u);
configure_pwm_pins(2u);
configure_pwm_pins(3u);
configure_src_pins(0u);
configure_uart_pins(1u);
configure_uart_pins(2u);
configure_uart_pins(3u);
configure_usb_pins(0u);
configure_usdhc_pins(2u);
configure_usdhc_pins(3u);
}
/* END pin_init. */
i2c.c :
#include "iomux_config.h"
void configure_i2c_pins(uint32_t instance)
{
switch(instance) {
case HW_I2C1: /* I2C1 */
HW_IOMUXC_I2C1_SCL_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA09_SET(IOMUXC_BASE, 0x04UL);
HW_IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA09_CLR(IOMUXC_BASE, 0x03UL);
HW_IOMUXC_I2C1_SDA_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA08_SET(IOMUXC_BASE, 0x04UL);
HW_IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA08_CLR(IOMUXC_BASE, 0x03UL);
break;
case HW_I2C2: /* I2C2 */
HW_IOMUXC_I2C2_SCL_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_EB2_B_SET(IOMUXC_BASE, 0x06UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_EB2_B_CLR(IOMUXC_BASE, 0x09UL);
HW_IOMUXC_I2C2_SDA_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16_SET(IOMUXC_BASE, 0x06UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16_CLR(IOMUXC_BASE, 0x09UL);
break;
case HW_I2C3: /* I2C3 */
HW_IOMUXC_I2C3_SCL_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA17_SET(IOMUXC_BASE, 0x06UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA17_CLR(IOMUXC_BASE, 0x09UL);
HW_IOMUXC_I2C3_SDA_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x00UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA18_SET(IOMUXC_BASE, 0x06UL);
HW_IOMUXC_SW_MUX_CTL_PAD_EIM_DATA18_CLR(IOMUXC_BASE, 0x09UL);
break;
case HW_I2C4: /* I2C4 */
HW_IOMUXC_I2C4_SCL_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x01UL);
HW_IOMUXC_SW_MUX_CTL_PAD_GPIO07_SET(IOMUXC_BASE, 0x08UL);
HW_IOMUXC_SW_MUX_CTL_PAD_GPIO07_CLR(IOMUXC_BASE, 0x07UL);
HW_IOMUXC_I2C4_SDA_IN_SELECT_INPUT_WR(IOMUXC_BASE, 0x01UL);
HW_IOMUXC_SW_MUX_CTL_PAD_GPIO08_SET(IOMUXC_BASE, 0x08UL);
HW_IOMUXC_SW_MUX_CTL_PAD_GPIO08_CLR(IOMUXC_BASE, 0x07UL);
break;
default:
break;
}
}
The others are quite identical.

Resources