Hello,
I have modified PRU_IEP.h file as per new silicon revision of AM5728. I have attached header file and source file in which I am trying to get timer interrupt at certain interval. The problem is whatever the value of Timer compare register is, the interrupt duration never gets changed, means, IEP timer is not working properly. Could anyone please let me know how to configure IEP timer in Silicon Rev 2.0? I have read the TRM and configured timer accordingly. Please find attached source code. But still it looks like something is missing. So could you please help me to resolve this issue?
/***************************************************************************************
* MAIN.C
*
* Description: main source file for PRU development
*
* Author: Rakesh Modi
* (C) 2015 Zeiss Meditec
*
* Built with Code Composer Studio v6
**************************************************************************************/
#include <stdint.h>
#include <pru_cfg.h>
#include <pru_intc.h>
#include <rsc_types.h>
#include <pru_virtqueue.h>
#include <pru_rpmsg.h>
#include <sys_mailbox.h>
#include "resource_table_empty.h"
#include "dac.h"
#define SILICON 2
#define DEBUG 1
#if (SILICON==2)
#include <pru_iep_2.h>
#else
#include <pru_iep.h>
#endif
#define PRU_IEP_EVT 7
#define PRV_TBL 0x00011000
#define CAP_TBL 0x00013000
#ifndef SHARED_MEM
#if !DEBUG
#pragma DATA_SECTION(sequencer, ".sequencer")
far struct sequ sequencer[1024];
#pragma DATA_SECTION(capture, ".capture")
far struct sequ capture[1024];
#else
struct sequ sequencer[1024] = {{1000, 6777, 0x81},
{1000, 6777, 0x82},
// {1000, 6777, 0x8E},
// {100, 6777, 0x82},
};
#endif
struct sequ *temp_seq = &sequencer[0];
#endif
//******************************************************************************
// IEP Timer Config
// This function configures the PRU IEP Timer.
//******************************************************************************
#if (SILICON == 2)
void iep_timer_config(uint32_t cmp_val){
CT_IEP.GLB_CFG_bit.CNT_EN = 0; /* Disable counter */
CT_IEP.CNT_LOW = 0xFFFFFFFF; /* Reset Count register */
CT_IEP.CNT_HIGH = 0xFFFFFFFF;
CT_IEP.GLB_STS_bit.CNT_OVF = 0x1; /* Clear overflow status register */
CT_IEP.CMP_STS = 0xFFFFFFFF; /* Clear compare status */
CT_IEP.CMP0_0_bit.CMP0_0 = (cmp_val*200); /* Set compare0 value */
CT_IEP.CMP0_0_bit.CMP0_1 = (cmp_val*200);
CT_IEP.COMPEN_bit.COMPEN_CNT = 0x0; /* Disable compensation */
CT_IEP.CMP_CFG_bit.CMP0_RST_CNT_EN = 0x1; /* Disable CMP0 and reset on event */
CT_IEP.CMP_CFG_bit.CMP_EN = 0x1;
CT_IEP.GLB_CFG_bit.DEFAULT_INC = 0x1; /* Configure incr value */
CT_INTC.SECR0 = 0xFFFFFFFF; /* Clear the status of all interrupts */
CT_INTC.SECR1 = 0xFFFFFFFF;
CT_IEP.GLB_CFG_bit.CNT_EN = 0x1;
}
#else
void iep_timer_config(uint32_t cmp_val){
CT_IEP.GLB_CFG_bit.CNT_EN = 0; /* Disable counter */
CT_IEP.CNT = 0xFFFFFFFF; /* Reset Count register */
CT_IEP.GLB_STS_bit.CNT_OVF = 0x1; /* Clear overflow status register */
CT_IEP.CMP0 = cmp_val*200; /* Set compare0 value */
CT_IEP.CMP_STS_bit.CMP_HIT = 0xFF; /* Clear compare status */
CT_IEP.COMPEN_bit.COMPEN_CNT = 0x0; /* Disable compensation */
CT_IEP.CMP_CFG_bit.CMP0_RST_CNT_EN = 0x1; /* Disable CMP0 and reset on event */
CT_IEP.CMP_CFG_bit.CMP_EN = 0x1;
CT_IEP.GLB_CFG_bit.DEFAULT_INC = 0x1; /* Configure incr value */
CT_INTC.SECR0 = 0xFFFFFFFF; /* Clear the status of all interrupts */
CT_INTC.SECR1 = 0xFFFFFFFF;
CT_IEP.GLB_CFG_bit.CNT_EN = 0x1;
}
#endif
uint8_t led_toggle(struct sequ led){
uint32_t val;
val = (__R30 & 0x0007) | (led.led << 12);
//val = led.led; //This is for experiment only, remove this line in final version
__R30 = val;
iep_timer_config(led.duration);
/* Poll until R31.30 is set */
while((__R31 & 0x40000000) == 0){ }
/* Verify that the IEP is the source of the interrupt */
if((CT_INTC.HIPIR0 != PRU_IEP_EVT) )
return 1;
/* Clear Compare0 status */
CT_IEP.GLB_STS = 0x1;
__delay_cycles(2);
/* Clear the status of the interrupt */
CT_INTC.SECR0 = (1 << PRU_IEP_EVT);
return 0;
}
#if DEBUG
void intc_config(void){
/* Set interrupts 0 to 31 to active high */
CT_INTC.SIPR0 = 0xFFFFFFFF;
/* Clear mapping for sys evt 4 to 7 */
CT_INTC.CMR1 = 0x00000000;
/* Set event 7 to channel 0 */
CT_INTC.CMR1_bit.CH_MAP_7 = 0x0;
/* Map channel 0 to host 0 */
CT_INTC.HMR0_bit.HINT_MAP_0 = 0x0;
/* Enable system event (7th bit = sys interrupt 7) */
CT_INTC.ESR0 = 0x80;
/* Enable host interrupt 0 */
CT_INTC.HIER = 0x1;
/* Globally enable interrupts */
CT_INTC.GER = 0x1;
}
#endif
//if(current_tbl == (struct sequ *)CAP_TBL)
int main(void)
{
int i;
uint8_t cmd = INVALID_CMD;
struct pru_rpmsg_transport transport;
__R30 = 0x00;
/* allow OCP master port access by the PRU so the PRU can read external memories */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
/* Select OCP_CLK as IEP clock source */
CT_CFG.IEPCLK_bit.OCP_EN = 0x1;
intc_config();
while(1)
{
for(i = 0; i < 2; i++)
led_toggle(sequencer[i]);
}
return 0;
}