I am using the QSPI example and it works fine. However, when I add more TASKS to the project an error comes up, the error reads: "Exception vector name: Address error".
I have observed the following:
1.-Project works fine when I only use QSPI task.
2.-The other tasks work fine without QSPI task.
3.-If I insert a breakpoint into QSPI task and hit the run button continously, the error never comes up.
Within the QSPI task there is memory allocation... I asign memory with this function
send_buffer = _mem_alloc_zero(SEND_BUFFER_SIZE);
and I free memory with this function _mem_free(send_buffer);
What am I missing?
What documentation should I read?
Task is like this:
void QSPI_task
(
)
{
FILE_PTR fd;
uint_32 i=0, result;
uint_32 len;
uint_32 param = 0;
uint_16 algo[1];
printf("\n\n-------------- Begin QSPI EEPROM example --------------\n\n");
/* Open the QSPI controller */
fd = fopen(IO_PORT, (pointer)(QSPI_DEVICE_MASTER_MODE));
if (fd == NULL)
{
printf("\n Failed to open the QSPI Controller, exiting....");
_time_delay(200L);
_mqx_exit(1L);
} /* Endif */
while(1)
{
// Allocate memory for the buffers
send_buffer = _mem_alloc_zero(SEND_BUFFER_SIZE);
if (send_buffer == NULL)
{
printf("\nFailed to get buffer");
_task_block();
}
recv_buffer = _mem_alloc_zero(RECV_BUFFER_SIZE);
if (recv_buffer == NULL)
{
printf("\nFailed to get buffer");
_mem_free(send_buffer);
_task_block();
}
data_buffer = _mem_alloc_zero(RECV_BUFFER_SIZE);
if (data_buffer == NULL)
{
printf("\nFailed to get buffer");
_mem_free(send_buffer);
_mem_free(recv_buffer);
_task_block();
}
algo[0] = 0xAA;
send_buffer[0] = 0xAA;
recv_buffer[0] = 0;
recv_buffer[1] = 0;
param = QSPI_CHIP_SELECT_SET_1;
ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m);
param = QSPI_CS3;
ioctl(fd, IO_IOCTL_QSPI_CHIP_SELECT, ¶m);
result = write(fd, send_buffer, 1);
param = QSPI_CS2;
ioctl(fd, IO_IOCTL_QSPI_CHIP_SELECT, ¶m);
result = write(fd, send_buffer, 1);
//result = write(fd, &algo, 1);
/* Free the buffer memory */
_mem_free(send_buffer);
_mem_free(recv_buffer);
_mem_free(data_buffer);
_time_delay(1000L);
}
} /* Endbody */
Regards,
Jaime
Solved! Go to Solution.
Hi
When using the GPT it is necessary to read the counter to clear the interrupt (GPTC0, GPTC1, GPTC2 or GPTC3). Make sure that the read is an short word read (to be sure - I don't known whether it is relevant here but there are some registers which don't behave the same when other size accesses are made).
Regards
Mark
Hi Jaime,
briefly looking at your code and it seems to be all right. Can you provide more information about the failure? Does it happen immediately or after time? Does it happen randomly or always in the same time?
The failure happens always as soon as I hit the run button from the debug screen. It happens always at
the same time BUT if I activate a break point in the QSPI task and hit the run button continously ( when
it stops in the breakpoint ) the failure never shows.
I believe the failure has something to do with the memory. I think QSPI task is using memory from
another task, thus corrupting the program.
The failure does not come if I do the following:
Activate a BreakPoint ANYWHERE in the code.
Run the code.
Remove the BreakPoint the first time it stops there.
Run the code again.
Failure comes from memory allocation instructions since when I use a commun array to send data the program behaves correctly.
Array without using _mem_alloc_zero instruction.
uint_16 algo[1];
algo[0] = 0xAA;
result = write(fd, &algo, 1);
Hi Jaime,
I tried your code and it works without failure, no exception.
Yes, I was using main_task and QSPI_task:
TASK_TEMPLATE_STRUCT MQX_template_list[] = { { 10L, main_task, 800L, 8L, "Main", MQX_AUTO_START_TASK}, { 11L, QSPI_task, 800L, 7L, "QSPI", 0L}, { 0L, 0L, 0L, 0L, 0L, 0L }};MQX_INITIALIZATION_STRUCT MQX_init_struct ={ BSP_DEFAULT_PROCESSOR_NUMBER, BSP_DEFAULT_START_OF_KERNEL_MEMORY, BSP_DEFAULT_END_OF_KERNEL_MEMORY, BSP_DEFAULT_INTERRUPT_STACK_SIZE, (pointer)MQX_template_list, BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX, BSP_DEFAULT_MAX_MSGPOOLS, BSP_DEFAULT_MAX_MSGQS, BSP_DEFAULT_IO_CHANNEL, BSP_DEFAULT_IO_OPEN_MODE};/* DEBUG */#define QSPI_DEBUG 1 // Allow printf#define QSPI_DEBUG_STATUS 0#define QSPI_DEGUG_WRITE_BYTE 0#define QSPI_DEBUG_READ_BYTE 0#define QSPI_DEBUG_WRITE_DATA_SHORT 1#define QSPI_DEBUG_WRITE_DATA_LONG 1#define QSPI_DEBUG_READ_DATA 1volatile uint_32 _mqx_monitor_type = 3;/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_baud_rate* Comments : This function displays current baud rate and then change it* 4.00Mhz and change it back to default (1.00 Mhz) **END*----------------------------------------------------------------------*/void eeprom_baud_rate ( FILE_PTR fd){ uint_32 param = 0; /* Display current Baud */ ioctl(fd, IO_IOCTL_SERIAL_GET_BAUD, ¶m); printf ("\nCurrent Baud frequency %dHz.\n", param); /* Set a different Baud */ param = 4000000; printf ("\nChanging the Baud frequency to 4000000Hz"); ioctl(fd, IO_IOCTL_SERIAL_SET_BAUD, ¶m); /* Display current Baud */ ioctl(fd, IO_IOCTL_SERIAL_GET_BAUD, ¶m); printf ("\nCurrent Baud frequency %dHz.\n", param); /* Set to the previous Baud */ param = 1000000; printf ("\nChanging the Baud frequency to 1000000Hz"); ioctl(fd, IO_IOCTL_SERIAL_SET_BAUD, ¶m); /* Display current Baud */ ioctl(fd, IO_IOCTL_SERIAL_GET_BAUD, ¶m); printf ("\nCurrent Baud frequency %dHz.\n", param); }/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_write_enable* Comments : This function sets enable latch to enable EEPROM write * operation**END*----------------------------------------------------------------------*/void eeprom_write_enable ( FILE_PTR fd){ uint_32 result, param; printf("\nWrite Enable Latch to EEPROM"); param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); /* Write enable instruction */ send_buffer[0] = TEST_ROM_SET_WRITE_ENABLE_LATCH; result = write(fd, send_buffer, 1); param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); if (result != 1) printf("\nWrite Enable Latch: FAILED\n"); else printf("\nWrite Enable Latch: PASS\n"); }/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_read_status* Comments : This function reads EEPROM status register **END*----------------------------------------------------------------------*/void eeprom_read_status ( FILE_PTR fd){ uint_32 result, param; printf("\nREAD EEPROM STATUS.");#if QSPI_DEBUG_STATUS while(1) { // Debug#endif send_buffer[0] = TEST_ROM_READ_STATUS; recv_buffer[0] = 0; recv_buffer[1] = 0; param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); /* Begin CR 2102 */ result = write(fd, send_buffer, 1); /* End CR 2102 */ /* Read EEPROM status */ read(fd, recv_buffer, 1); param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m);#if QSPI_DEBUG /* Begin CR 2102 */ if(result != 1) /* End CR 2102 */ printf("\nSend status read command FAILED.\n"); else { printf("\nSend status read command PASS."); printf("\nEEPROM STATUS: 0x%x\n", recv_buffer[1]); }#endif #if QSPI_DEBUG_STATUS } // Debug#endif}/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_write_byte* Comments : This function writes a data byte to EEPROM * **END*----------------------------------------------------------------------*/void eeprom_write_byte(FILE_PTR fd, uint_16 addr, uchar data){ uint_32 result, param = 0; send_buffer[0] = TEST_ROM_WRITE_DATA; // Write instruction send_buffer[1] = ((addr>>8)&0xff); // First address byte send_buffer[2] = (addr&0xff); // Last address byte send_buffer[3] = data; // Data printf("\nWrite 0x%lx to Location 0x%lx EEPROM", send_buffer[3], addr); param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); result = write(fd, send_buffer, 4); param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); if(result != 4) printf("\nWrite a byte: FAILED\n"); else printf("\nWrite a byte: PASS\n"); /* There is 5 ms internal write cycle needed for EEPROM */ _time_delay(5); }/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_read_byte* Comments : This function reads 8 bits data from Microchip EEPROM 25LC640* Return: * Number of byte read. **END*----------------------------------------------------------------------*/uint_32 eeprom_read_byte ( FILE_PTR fd, uint_16 addr){ uint_32 result, param; uint_32 num = 0; send_buffer[0] = TEST_ROM_READ_DATA; // Read instrucation send_buffer[1] = ((addr>>8)&0xff); // First address byte send_buffer[2] = (addr&0xff); // Last address byte#if QSPI_DEBUG_READ_BYTE while (1) { //Debug#endif /* Bring CS low */ param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); /* write instruction and address */ /* Begin CR 2102 */ result = write(fd, send_buffer, 3); /* End CR 2102 */ /* Read data from EEPROM */ num = read(fd,recv_buffer,1); *data_buffer++ = *recv_buffer; param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); #if QSPI_DEBUG /* Begin CR2102 */ if(result != 3) /* End CR2102 */ printf("\nSend read command: FAILED."); else { printf("\nSend read command and address: 0x%x 0x%x 0x%x", send_buffer[0], send_buffer[1], send_buffer[2]); printf("\nREAD DATA: "); printf( "Location: 0x%lx; Data: 0x%lx\n", addr, *recv_buffer); }#endif#if QSPI_DEBUG_READ_BYTE } // Debug#endif return (num);}/*FUNCTION*---------------------------------------------------------------* * Function Name : eeprom_write_data* Comments : This function writes data to EEPROM * **END*----------------------------------------------------------------------*/uint_32 eeprom_write_data(FILE_PTR fd, uint_16 addr, uint_32 size, uchar_ptr data){ uint_32 result, param = 0; uint_32 i, len = size; printf("\nWrite data to EEPROM"); send_buffer[0] = TEST_ROM_WRITE_DATA; // Write instruction send_buffer[1] = ((addr>>8)&0xff); // First address byte send_buffer[2] = (addr&0xff); // Last address byte len += 3; // Write Data for (i = 0; i < size; i++) { send_buffer[i+3] = data[i]; } param = QSPI_CHIP_SELECT_SET_0; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); /* ** EEPROM 25LC640 allows up to 32 byte page ** after transmiting 32 byte we have change CS state. */ result = write(fd, send_buffer, len); param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); /* There is 5 ms internal write cycle needed for EEPROM */ _time_delay(5); if(result != len) printf("\nPage write to EEPROM: FALIED\n"); else { printf("\nWrite data to EEPROM: PASS"); printf("\nWrite data to EEPROM: "); for(i=0;i<size;i++) printf("%c", send_buffer[i+3]); printf("\n"); } return result; }/*TASK*-------------------------------------------------------------------* * Task Name : main_task* Comments :**END*----------------------------------------------------------------------*/void main_task ( uint_32 dummy ){ _task_create(0, 11L, 0); while(1) { int i; for (i = 0; i < 415646; i++); printf("main task"); }}void QSPI_task(){ FILE_PTR fd; uint_32 i=0, result; uint_32 param = 0; uint_16 algo[1]; printf("\n\n-------------- Begin QSPI EEPROM example --------------\n\n"); /* Open the QSPI controller */ fd = fopen(IO_PORT, (pointer)(QSPI_DEVICE_MASTER_MODE)); if (fd == NULL) { printf("\n Failed to open the QSPI Controller, exiting...."); _time_delay(200L); _mqx_exit(1L); } /* Endif */ while(1) { // Allocate memory for the buffers send_buffer = _mem_alloc_zero(SEND_BUFFER_SIZE); if (send_buffer == NULL) { printf("\nFailed to get buffer"); _task_block(); } recv_buffer = _mem_alloc_zero(RECV_BUFFER_SIZE); if (recv_buffer == NULL) { printf("\nFailed to get buffer"); _mem_free(send_buffer); _task_block(); } data_buffer = _mem_alloc_zero(RECV_BUFFER_SIZE); if (data_buffer == NULL) { printf("\nFailed to get buffer"); _mem_free(send_buffer); _mem_free(recv_buffer); _task_block(); } algo[0] = 0xAA; send_buffer[0] = 0xAA; recv_buffer[0] = 0; recv_buffer[1] = 0; param = QSPI_CHIP_SELECT_SET_1; ioctl(fd, IO_IOCTL_QSPI_SET_CHIP_SELECT_STATE, ¶m); param = QSPI_CS3; ioctl(fd, IO_IOCTL_QSPI_CHIP_SELECT, ¶m); result = write(fd, send_buffer, 1); param = QSPI_CS2; ioctl(fd, IO_IOCTL_QSPI_CHIP_SELECT, ¶m); result = write(fd, send_buffer, 1); //result = write(fd, &algo, 1); /* Free the buffer memory */ _mem_free(send_buffer); _mem_free(recv_buffer); _mem_free(data_buffer); printf("\nOK!"); _time_delay(1000L); }} /* Endbody */
Hi JuroV,
I still have the same problem, I don't know what is going on whit my program. I had a lot of tasks:
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
//Task number, Entry point, Stack, Pri, String, Auto?
//{ 1, HVAC_Task, 1100, 9, "HVAC", MQX_AUTO_START_TASK},
// { 2, Switch_Task, 600, 10, "Switch", MQX_AUTO_START_TASK},
// { 3, Shell_Task, 1400, 12, "Shell", MQX_AUTO_START_TASK},
// { 4, Logging_task, 1900, 11, "Logging", MQX_AUTO_START_TASK},
// { 5, USB_task, 1700L, 8L, "USB", MQX_AUTO_START_TASK},
// { 6, Tx_Task, 900L, 7L, "TX task", 0, 0, 0},
// { 7, Rx_Task, 900L, 7L, "RX task", 0, 0, 0},
// { 8, Main_Task, 800L, 8L, "Main task", MQX_AUTO_START_TASK},
// { 9, ADC_task, 800L, 8L, "ADC Init", MQX_AUTO_START_TASK},
{10, GPT_task, 2000L, 10L, "GPT Init", MQX_AUTO_START_TASK},
// {11, DMA_task, 600L, 8L, "DMA Init", MQX_AUTO_START_TASK},
// { 12, QSPI_task, 2000L, 10L, "QSPI Init", MQX_AUTO_START_TASK},
// { 13, CFM_task, 1000L, 10L, "CFM Init", MQX_AUTO_START_TASK},
{ 0, 0, 0, 0, 0, 0}
};
As you can see, I commented most of them to leave only GPT_task active. The problem continues, therefore I believe the this task is causing it.
I believe the interrupts from GPT module are causing the problem because when the application crashes the "MQX Check for errors"shows me there has been an overflow from the Interrupt Stack...
First I tried to increase the amount of stack for interrupts but I stoped since I don't know how could a few interrupts consume all of the stack available, specially when I have empty ISR.
This is the task code:
void GPT_task(){ /* Body */ indice = 0; //uint_8 algo = 0; GPT_Initialize( 0, (pointer)MY_GPT_C0F_ISR); /* GPT_Initialize( 1, (pointer)MY_GPT_C1F_ISR); GPT_Initialize( 2, (pointer)MY_GPT_C2F_ISR); GPT_Initialize( 3, (pointer)MY_GPT_C3F_ISR);*/ for(indice = 0; indice < 26 ;indice++) key[indice ] = 0x55; indice = 0; while(1) { if(indice >= 26) { printf("Tarjeta Leida"); indice = 0; } _time_delay(10); }} /* EndBody */
This is the Initialize function (which I wrote) I am calling from MQX libraries:
uint_32 GPT_Initialize( uint_8 tim_num, pointer isr){ /* Body */ uint_8 algo; volatile PSP_INTERRUPT_TABLE_INDEX index; VMCF5225_STRUCT_PTR reg_ptr = _PSP_GET_IPSBAR(); //Controlar registros del Micro volatile GPT_REG_STRUCT_PTR gpt_reg_ptr; // Estructura para controlar GPT void (_CODE_PTR_ result)(pointer); uint_32 return_code = GPT_OK; gpt_reg_ptr = (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPT); gpt_reg_ptr->GPTSCR1 &= ~MCF_GPT_GPTSCR1_GPTEN; //Detener el timer gpt_reg_ptr->GPTPACTL &= 0xFC; gpt_reg_ptr->GPTSCR2 &= 0x7F; switch(tim_num) { case(0): reg_ptr->GPIO.PTAPAR = 0x55;//Todos funcion primaria gpt_reg_ptr->GPTDDR &= ~0xF1; gpt_reg_ptr->GPTIOS &= ~0xF1; gpt_reg_ptr->GPTSCR1 = 0x00; gpt_reg_ptr->GPTCTL2 |= MCF_GPT_GPTCTL2_EDG0A; gpt_reg_ptr->GPTCTL2 &= ~MCF_GPT_GPTCTL2_EDG0B; gpt_reg_ptr->GPTSCR2 = MCF_GPT_GPTSCR2_PR(1); reg_ptr->GPIO.PTAPAR &= ~0x03; reg_ptr->GPIO.PTAPAR |= MCF_GPIO_PTAPAR_PTAPAR0(1); result = _int_install_isr (MCF5225_INT_TIMA_C0F, (void (_CODE_PTR_))isr, (pointer)gpt_reg_ptr); if(result == NULL) { return_code = _task_get_error(); } algo = 0; while(algo < 0xFF) { algo++; } if ( _mcf5225_int_init(MCF5225_INT_TIMA_C0F, GPT_C0F_INT_LEVEL, GPT_C0F_INT_SUBLEVEL, TRUE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } gpt_reg_ptr->GPTIE &= 0x0F; gpt_reg_ptr->GPTIE |= MCF_GPT_GPTIE_CI0; break; case(1): reg_ptr->GPIO.PTAPAR = 0x55; gpt_reg_ptr->GPTDDR &= ~0xF2; gpt_reg_ptr->GPTIOS &= ~0xF2; gpt_reg_ptr->GPTSCR1 = 0x00; gpt_reg_ptr->GPTCTL2 |= MCF_GPT_GPTCTL2_EDG1A; gpt_reg_ptr->GPTCTL2 &= ~MCF_GPT_GPTCTL2_EDG1B; gpt_reg_ptr->GPTSCR2 = MCF_GPT_GPTSCR2_PR(1); reg_ptr->GPIO.PTAPAR &= ~0x0C; reg_ptr->GPIO.PTAPAR |= MCF_GPIO_PTAPAR_PTAPAR1(1); result = _int_install_isr (MCF5225_INT_TIMA_C1F, (void (_CODE_PTR_))isr, (pointer)gpt_reg_ptr); if(result == NULL) { return_code = _task_get_error(); } if ( _mcf5225_int_init(MCF5225_INT_TIMA_C1F, GPT_C1F_INT_LEVEL, GPT_C1F_INT_SUBLEVEL, TRUE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } gpt_reg_ptr->GPTIE &= 0x0F; gpt_reg_ptr->GPTIE |= MCF_GPT_GPTIE_CI1; break; case(2): reg_ptr->GPIO.PTAPAR = 0x55; gpt_reg_ptr->GPTDDR &= ~0xF4; gpt_reg_ptr->GPTIOS &= ~0xF4; gpt_reg_ptr->GPTSCR1 = 0x00; gpt_reg_ptr->GPTCTL2 |= MCF_GPT_GPTCTL2_EDG2A; gpt_reg_ptr->GPTCTL2 &= ~MCF_GPT_GPTCTL2_EDG2B; gpt_reg_ptr->GPTSCR2 = MCF_GPT_GPTSCR2_PR(1); reg_ptr->GPIO.PTAPAR &= ~0x30; reg_ptr->GPIO.PTAPAR |= MCF_GPIO_PTAPAR_PTAPAR2(1); result = _int_install_isr (MCF5225_INT_TIMA_C2F, (void (_CODE_PTR_))isr, (pointer)gpt_reg_ptr); if(result == NULL) { return_code = _task_get_error(); } if ( _mcf5225_int_init(MCF5225_INT_TIMA_C2F, GPT_C2F_INT_LEVEL, GPT_C2F_INT_SUBLEVEL, TRUE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } gpt_reg_ptr->GPTIE &= 0x0F; gpt_reg_ptr->GPTIE |= MCF_GPT_GPTIE_CI2; break; case(3): reg_ptr->GPIO.PTAPAR = 0x55; gpt_reg_ptr->GPTDDR &= ~0xF8; gpt_reg_ptr->GPTIOS &= ~0xF8; gpt_reg_ptr->GPTSCR1 = 0x00; gpt_reg_ptr->GPTCTL2 |= MCF_GPT_GPTCTL2_EDG3A; gpt_reg_ptr->GPTCTL2 &= ~MCF_GPT_GPTCTL2_EDG3B; gpt_reg_ptr->GPTSCR2 = MCF_GPT_GPTSCR2_PR(1); reg_ptr->GPIO.PTAPAR &= ~0xC0; reg_ptr->GPIO.PTAPAR |= MCF_GPIO_PTAPAR_PTAPAR3(1); result = _int_install_isr (MCF5225_INT_TIMA_C3F, (void (_CODE_PTR_))isr, (pointer)gpt_reg_ptr); if(result == NULL) { return_code = _task_get_error(); } if ( _mcf5225_int_init(MCF5225_INT_TIMA_C3F, GPT_C3F_INT_LEVEL, GPT_C3F_INT_SUBLEVEL, TRUE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } gpt_reg_ptr->GPTIE &= 0x0F; gpt_reg_ptr->GPTIE |= MCF_GPT_GPTIE_CI3; break; } if ( _mcf5225_int_init(MCF5225_INT_TIMA_TOF, GPT_C3F_INT_LEVEL, GPT_C3F_INT_SUBLEVEL, FALSE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } if ( _mcf5225_int_init(MCF5225_INT_TIMA_PAIF, GPT_C3F_INT_LEVEL, GPT_C3F_INT_SUBLEVEL, FALSE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } if ( _mcf5225_int_init(MCF5225_INT_TIMA_PAOVF, GPT_C3F_INT_LEVEL, GPT_C3F_INT_SUBLEVEL, FALSE) != MQX_OK) { return (GPT_INT_ENABLE_FAILED); } gpt_reg_ptr->GPTFLG2 |= MCF_GPT_GPTFLG2_TOF; gpt_reg_ptr->GPTSCR2 &= ~MCF_GPT_GPTSCR2_TCRE; gpt_reg_ptr->GPTSCR1 |= MCF_GPT_GPTSCR1_GPTEN;//Iniciar el timer return return_code;} /* Endbody */
Well, I hope you can help me solve this since I am running out of ideas.
Best Regards
This is the declaration for that function:
void MY_GPT_C0F_ISR();
This is the definition for that function:
void MY_GPT_C0F_ISR() { clearFlag(0); // key[indice++] = 0; return; }
clearFlag(0); calls a function I wrote in MQX libraries:
void clearFlag( //Número del timer char tim_num){ /* Body */ volatile GPT_REG_STRUCT_PTR gpt_reg_ptr; // Estructura para controlar GPT gpt_reg_ptr = (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPT); //Limpia la bandera de interrupcion del timer correspondiente switch(tim_num) { case(0):gpt_reg_ptr->GPTFLG1 |= MCF_GPT_GPTFLG1_CF0; break; case(1):gpt_reg_ptr->GPTFLG1 |= MCF_GPT_GPTFLG1_CF1; break; case(2):gpt_reg_ptr->GPTFLG1 |= MCF_GPT_GPTFLG1_CF2; break; case(3):gpt_reg_ptr->GPTFLG1 |= MCF_GPT_GPTFLG1_CF3; break; default: break; }} /* Endbody */
Thanks
Hi JaimeR,
the ISR function is your source of problem. You MUST declare ISR function handled by MQX as
void function(pointer)
even if you don't use any parameter of this function.
So your solution is:
void MY_GPT_C0F_ISR(pointer dummy_param) { clearFlag(0); // key[indice++] = 0; return; }
I am afraid this is not the problem... I already add the pointer as you suggested, and it continue to happen.
I then activate the pull up resistor using the gpt_reg_ptr->GPTSCR2 = 0x20 | MCF_GPT_GPTSCR2_PR(1);.
and also added the Fast Flag Clear. This time the error doesnt come exactly after I click the RUN button
into the debugger, instead it appears when I cause the interrupt. Some times the error is the
Exception vector name... and sometimes the error is:
Codewarrior encountered an unhandled exception 0xc0000005 at address 0x039f6587
(The memory at address 0x034c0004 could not be written)
Location: CFrtos_MQX.dll:0x10026587
Crash dump written to C:\Program Files\Freescale\CodeWarrior for ColdFire V7.1\bin\IDE.exe.b3024.20091521.104145A.dump
Choose 'Abort' to end the program, 'Retry' to debug, or 'Ignore' to continue (at your own risk!)
What do you think?
Why do you enable interrupt MCF5225_INT_TIMA_TOF, MCF5225_INT_TIMA_PAIF and MCF5225_INT_TIMA_PAOVF without installing ISR? Makes no sense, although it should not be the source of problem. If you are not using those interrupts, then remove also enabling it (at the end of GPTInitialize).
Yes, that is not the source of the problem since I added those lines after the error came.
I added those lines to make sure those interrupts are never triggered and that is the reason I am setting the // [IN} Unmask the interrupt now? parameter to FALSE.
Its really wierd, I dont know what else to try, I also have other interrupts working fine, even without the dummy pointer.
Hi
When using the GPT it is necessary to read the counter to clear the interrupt (GPTC0, GPTC1, GPTC2 or GPTC3). Make sure that the read is an short word read (to be sure - I don't known whether it is relevant here but there are some registers which don't behave the same when other size accesses are made).
Regards
Mark
Thank you JuroV and Mark.
I just read GPT Channel Registers (GPTCn) since I am using Input Capture Function and error is not showing.