Exemple #1
0
void timer_init()
{
        /* set default inc to 1, set compensation inc to 1 (though this is never used)*/
        PIEP_GLOBAL_CFG = GLOBAL_CFG_DEFAULT_INC(1) | GLOBAL_CFG_CMP_INC(1);

	/* Enable interrupts from cmp1 */
        PIEP_CMP_CFG |= CMP_CFG_CMP_EN(1);

        /* set the value of cmp1 = (time_unit in us) * (no. of clk cycle for 1 us) */
        PIEP_CMP_CMP1 =  ((US * TIME_UNIT) + PIEP_COUNT);

	/* clear the interrupt from cmp1 in case it has been set by mistake */
        PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(1); 

        /* start the timer */
        PIEP_GLOBAL_CFG |= GLOBAL_CFG_CNT_ENABLE;
}
Exemple #2
0
int main(void) //(int argc, char *argv[])
{
    printf("Bingo, enter 1st simulator DSP APP~!\n");
#if 0
    u8 i, _i;
    u32 cnt, next;
    u32 msk, setmsk, clrmsk;
    u32 delta, deltamin, tnext, hi, lo;
    u32 *nextp;
    const u32 *hilop;
    u32 period;
    u32 enmask; /* enable mask */
    u32 stmask; /* state mask */
    static u32 next_hi_lo[MAX_PWMS][3];
#endif
/*
 * init Obj objects of each Chn.
 */

    ChanelObj chnObj[MAX_PWMS];
    u32 i = 0;
    u32 currTime = 0;
    //u32 sartRiseTime = 0;
    //u32 startFallTime = 0;
    for (i = 0; i < MAX_PWMS; i++)
    {
        chnObj[i].chid = i + 1;
        chnObj[i].enmask = 0;
    }

    u32 prevTime = 0;
    time64 currTs64;

    while (1)
    {
        u32 index = 0;

        //step 1 : update current time.
        currTime = read_PIEP_COUNT();
        if(prevTime > currTime)
        {
            // reverse
            currTs64.time_p2++;

        }
        currTs64.time_p1 = currTime;

        prevTime = currTime;

        update_flag();


        //step 2: judge current if it is arrive at rising edge time
        for (index = 0; index < MAX_PWMS; index++)
        {
            //it is time that arriving rising edge........
            if(TIME_GREATER(currTs64, chnObj[index].time_of_hi))
            {
                chnObj[index].enmask = PWM_CMD ->enmask;
                chnObj[index].period_time.time_p1 = PWM_CMD ->periodhi[index][0];


                // update time stamp
                //chnObj[index].time_of_lo.time_p2 = 0;
                //chnObj[index].time_of_lo.time_p1 = PWM_CMD ->periodhi[index][1];

                // chnObj[index].time_of_lo = time_add(chnObj[index].time_of_lo, currTs64);
                TIME_ADD(chnObj[index].time_of_lo, currTs64, PWM_CMD ->periodhi[index][1]);
                //rising_edge_time = current + period
                // chnObj[index].time_of_hi = time_add(chnObj[index].period_time, currTs64);
                TIME_ADD(chnObj[index].time_of_hi, currTs64, PWM_CMD ->periodhi[index][0]);

                if (chnObj[index].enmask & (1U << index))
                {
                   // sartRiseTime = read_PIEP_COUNT();
                    //fall_edge_time = current + hi_duty


                    __R30 |= (1U << index); //pull up

                    printf("<high> chn: %d cur [%08x-%08x]  r30 %x  hi [%08x-%08x]  lo [%08x-%08x]  perid %d(high: %d) \n" ,chnObj[index].chid,
                            currTs64.time_p2, currTs64.time_p1, __R30,
                            chnObj[index].time_of_hi.time_p2, chnObj[index].time_of_hi.time_p1,
                            chnObj[index].time_of_lo.time_p2, chnObj[index].time_of_lo.time_p1,
                            time_sub(currTs64, ts[index][0]), PWM_CMD ->periodhi[index][1]);
                    ts[index][0] = currTs64;

                }


                continue;
            }

            //it is time that arriving falling edge........
            if(TIME_GREATER(currTs64, chnObj[index].time_of_lo))
            {

            	TIME_ADD(chnObj[index].time_of_lo, currTs64, PWM_CMD ->periodhi[index][0]);

                if (chnObj[index].enmask & (1U << index))
                {
                    __R30 &= ~(1U << index); //pull down


                    printf("<low> chn: %d cur [%08x-%08x]  r30 %x  hi [%08x-%08x]  lo [%08x-%08x]  high-len %d \n" ,chnObj[index].chid,
                            currTs64.time_p2, currTs64.time_p1, __R30,
                            chnObj[index].time_of_hi.time_p2, chnObj[index].time_of_hi.time_p1,
                            chnObj[index].time_of_lo.time_p2, chnObj[index].time_of_lo.time_p1,
                            time_sub(currTs64, ts[index][0]));
                    ts[index][1] = currTs64;
                }

            }
        }
    }
#if 0


    //static struct cxt cxt;
#if 0
    /* enable OCP master port */
    PRUCFG_SYSCFG &= ~SYSCFG_STANDBY_INIT;
    PRUCFG_SYSCFG = (PRUCFG_SYSCFG &
            ~(SYSCFG_IDLE_MODE_M | SYSCFG_STANDBY_MODE_M)) |
    SYSCFG_IDLE_MODE_NO | SYSCFG_STANDBY_MODE_NO;

    /* our PRU wins arbitration */
    PRUCFG_SPP |= SPP_PRU1_PAD_HP_EN;
    pwm_setup();

    /* configure timer */
    PIEP_GLOBAL_CFG = GLOBAL_CFG_DEFAULT_INC(1) |
    GLOBAL_CFG_CMP_INC(1);
    PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(1); /* clear the interrupt */
    PIEP_CMP_CMP1 = 0x0;
    PIEP_CMP_CFG |= CMP_CFG_CMP_EN(1);
    PIEP_GLOBAL_CFG |= GLOBAL_CFG_CNT_ENABLE;
#endif

    /* initialize */
    cnt = read_PIEP_COUNT();

    enmask = cfg.enmask;
    stmask = 0; /* starting all low */

    clrmsk = 0;
    for (i = 0, msk = 1, nextp = &next_hi_lo[0][0], hilop = &cfg.hilo[0][0];
            i < MAX_PWMS; i++, msk <<= 1, nextp += 3, hilop += 2)
    {
        if ((enmask & msk) == 0)
        {
            nextp[1] = PRU_us(100); /* default */
            nextp[2] = PRU_us(100);
            continue;
        }
        nextp[0] = cnt; /* next */
        nextp[1] = 200000; /* hi */
        nextp[2] = 208000; /* lo */
        PWM_CMD ->periodhi[i][0] = 408000;
        PWM_CMD ->periodhi[i][1] = 180000;
    }
    PWM_CMD ->enmask = 0;
    clrmsk = enmask;
    setmsk = 0;
    /* guaranteed to be immediate */
    deltamin = 0;
    next = cnt + deltamin;
    PWM_CMD ->magic = PWM_REPLY_MAGIC;

    while (1)
    {

        update_flag();

        if (PWM_CMD ->magic == PWM_CMD_MAGIC)
        {
            msk = PWM_CMD ->enmask;
            for (i = 0, nextp = &next_hi_lo[0][0]; i < MAX_PWMS;
                    i++, nextp += 3)
            {
                //Enable
                if ((PWM_EN_MASK & (msk & (1U << i)))
                        && (enmask & (msk & (1U << i))) == 0)
                {
                    enmask |= (msk & (1U << i));

                    __R30 |= (msk & (1U << i));

                    // first enable
                    if (enmask == (msk & (1U << i)))
                        cnt = read_PIEP_COUNT();

                    nextp[0] = cnt;	//since we start high, wait this amount

                    deltamin = 0;
                    next = cnt;
                }
                //Disable
                if ((PWM_EN_MASK & (msk & (1U << i)))
                        && ((msk & ~(1U << i)) == 0))
                {
                    enmask &= ~(1U << i);
                    __R30 &= ~(1U << i);
                }

                //get and set pwm_vals
                if (PWM_EN_MASK & (msk & (1U << i)))
                {
                    if (b_true == full_period)
                    {

                        //nextp = &next_hi_lo[i * 3];
                        nextp[1] = PWM_CMD ->periodhi[i][1];
                        period = PWM_CMD ->periodhi[i][0];
                        nextp[2] = period - nextp[1];

                    }
                }
                PWM_CMD ->hilo_read[i][0] = nextp[0];
                PWM_CMD ->hilo_read[i][1] = nextp[1];

            }

            // guaranteed to be immediate
            deltamin = 0;

            PWM_CMD ->magic = PWM_REPLY_MAGIC;
        }
        PWM_CMD ->enmask_read = enmask;
        /* if nothing is enabled just skip it all */
        if (enmask == 0)
            continue;

        setmsk = 0;
        clrmsk = (u32) -1;
        deltamin = PRU_ms(100); /* (1U << 31) - 1; */
        next = cnt + deltamin;

        for (_i = 0; _i < MAX_PWMS; _i++)
        {
            if (enmask & (1U << (_i)))
            { //
                nextp = &next_hi_lo[(_i)][0]; //
                tnext = nextp[0]; //
                hi = nextp[1]; //
                lo = nextp[2]; //
                /* avoid signed arithmetic */ //
                while (((delta = (tnext - cnt)) & (1U << 31)) != 0)
                { //
                    /* toggle the state */ //
                    if (stmask & (1U << (_i)))
                    { //
                        stmask &= ~(1U << (_i)); //
                        clrmsk &= ~(1U << (_i)); //
                        tnext += lo; //

                        printf("CH %d: next hi: %08x\n", _i, tnext);
                        // flag when all motor channel finish full period
                        ch_num_period++;
                        if (!((ch_num_period) %= MAX_PWMS))
                        {
                            full_period = b_true;
                            printf(
                                    "----------------full period--------------\n");
                        }
                    }
                    else
                    { //
                        stmask |= (1U << (_i)); //
                        setmsk |= (1U << (_i)); //
                        tnext += hi; //
                        full_period = b_false;

                        //if(flag == Period_change)

                    } //
                } //
                if (delta <= deltamin)
                { //
                    deltamin = delta; //
                    next = tnext; //
                } //
                nextp[0] = tnext; //
            } //
        }
#if 0
#define SINGLE_PWM(_i) \
	do { \
		if (enmask & (1U << (_i))) { \
			nextp = &next_hi_lo[(_i)][0]; \
			tnext = nextp[0]; \
			hi = nextp[1]; \
			lo = nextp[2]; \
			/* avoid signed arithmetic */ \
			while (((delta = (tnext - cnt)) & (1U << 31)) != 0) { \
				/* toggle the state */ \
				if (stmask & (1U << (_i))) { \
					stmask &= ~(1U << (_i)); \
					clrmsk &= ~(1U << (_i)); \
					tnext += lo; \
				} else { \
					stmask |= (1U << (_i)); \
					setmsk |= (1U << (_i)); \
					tnext += hi; \
				} \
			} \
			if (delta <= deltamin) { \
				deltamin = delta; \
				next = tnext; \
			} \
			nextp[0] = tnext; \
		} \
	} while (0)

#if MAX_PWMS > 0 && (PWM_EN_MASK & BIT(0))
        SINGLE_PWM(0);
#endif
#if MAX_PWMS > 1 && (PWM_EN_MASK & BIT(1))
        SINGLE_PWM(1);
#endif
#if MAX_PWMS > 2 && (PWM_EN_MASK & BIT(2))
        SINGLE_PWM(2);
#endif
#if MAX_PWMS > 3 && (PWM_EN_MASK & BIT(3))
        SINGLE_PWM(3);
#endif
#if MAX_PWMS > 4 && (PWM_EN_MASK & BIT(4))
        SINGLE_PWM(4);
#endif
#if MAX_PWMS > 5 && (PWM_EN_MASK & BIT(5))
        SINGLE_PWM(5);
#endif
#if MAX_PWMS > 6 && (PWM_EN_MASK & BIT(6))
        SINGLE_PWM(6);
#endif
#if MAX_PWMS > 7 && (PWM_EN_MASK & BIT(7))
        SINGLE_PWM(7);
#endif
#if MAX_PWMS > 8 && (PWM_EN_MASK & BIT(8))
        SINGLE_PWM(8);
#endif
#if MAX_PWMS > 9 && (PWM_EN_MASK & BIT(9))
        SINGLE_PWM(9);
#endif
#if MAX_PWMS > 10 && (PWM_EN_MASK & BIT(10))
        SINGLE_PWM(10);
#endif
#if MAX_PWMS > 11 && (PWM_EN_MASK & BIT(11))
        SINGLE_PWM(11);
#endif
#if MAX_PWMS > 12 && (PWM_EN_MASK & BIT(12))
        SINGLE_PWM(12);
#endif
#endif

        /* results in set bits where there are changes */

        __R30 = (__R30 & (clrmsk & 0xfff)) | (setmsk & 0xfff);

        /* loop while nothing changes */
        do
        {
            cnt = read_PIEP_COUNT();
            //if(PWM_CMD->magic == PWM_CMD_MAGIC){
            //	break;
            //}
        } while (((next - cnt) & (1U << 31)) == 0);
    }
#endif
    printf("Bingo, leave 1st simulator DSP APP~!\n");
}
Exemple #3
0
/*
 * main.c
 */
int main() {

       	u8 i;
	u32 cnt, next;
	u32 msk, setmsk, clrmsk;
	u32 delta, deltamin, tnext, hi, lo;
	u32 *nextp;
	const u32 *hilop;
    u32 period;
	u32 enmask;	/* enable mask */
	u32 stmask;	/* state mask */
    u32 temp;
	static u32 next_hi_lo[MAX_PWMS][3];
	static struct cxt cxt;
	/* enable OCP master port */
	PRUCFG_SYSCFG &= ~SYSCFG_STANDBY_INIT;
	PRUCFG_SYSCFG = (PRUCFG_SYSCFG &
			~(SYSCFG_IDLE_MODE_M | SYSCFG_STANDBY_MODE_M)) |
			SYSCFG_IDLE_MODE_NO | SYSCFG_STANDBY_MODE_NO;

	/* our PRU wins arbitration */
	PRUCFG_SPP |=  SPP_PRU1_PAD_HP_EN;
	pwm_setup();

	/* configure timer */
	PIEP_GLOBAL_CFG = GLOBAL_CFG_DEFAULT_INC(1) |
			  GLOBAL_CFG_CMP_INC(1);
	PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(1); /* clear the interrupt */
        PIEP_CMP_CMP1   = 0x0;
	PIEP_CMP_CFG |= CMP_CFG_CMP_EN(1);
        PIEP_GLOBAL_CFG |= GLOBAL_CFG_CNT_ENABLE;

	/* initialize */
	cnt = read_PIEP_COUNT();

	enmask = cfg.enmask;
	stmask = 0;		/* starting all low */

	clrmsk = 0;
	for (i = 0, msk = 1, nextp = &next_hi_lo[0][0], hilop = &cfg.hilo[0][0];
			i < MAX_PWMS;
			i++, msk <<= 1, nextp += 3, hilop += 2) {
		if ((enmask & msk) == 0) {
			nextp[1] = PRU_us(100);	/* default */
			nextp[2] = PRU_us(100);
			continue;
		}
		nextp[0] = cnt;		/* next */
		nextp[1] = 200000;	/* hi */
        nextp[2] = 208000;	/* lo */
        PWM_CMD->periodhi[i][0] = 408000;
        PWM_CMD->periodhi[i][1] = 180000;        
	}
    PWM_CMD->enmask = 0;
	clrmsk = enmask;
	setmsk = 0;
	/* guaranteed to be immediate */
	deltamin = 0;
	next = cnt + deltamin;
    PWM_CMD->magic = PWM_REPLY_MAGIC;
    
	while(1) {


        //if(PWM_CMD->magic == PWM_CMD_MAGIC) 
        {
			msk = PWM_CMD->enmask;
            for(i=0, nextp = &next_hi_lo[0][0]; i<MAX_PWMS; 
                i++, nextp += 3){
                //Enable
                if ((PWM_EN_MASK & (msk&(1U<<i))) && (enmask & (msk&(1U<<i))) == 0) {
        		        enmask |= (msk&(1U<<i));

#ifdef __GNUC__
                        temp = read_r30(); 
    				    temp |= (msk&(1U<<i));
                        write_r30(temp);
#else
    				    __R30 |= (msk&(1U<<i));
#endif
                        nextp[0] = cnt;	//since we start high, wait this amount 

                        // first enable
                        if (enmask == (msk&(1U<<i)))
            			    cnt = read_PIEP_COUNT();
                        deltamin = 0;
                        next = cnt;
                }
                //Disable
        		if ((PWM_EN_MASK & (msk&(1U<<i))) && ((msk & ~(1U<<i)) == 0)) {
        			enmask &= ~(1U<<i);
#ifdef __GNUC__
                        temp = read_r30(); 
        			    temp &= ~(1U<<i);
                        write_r30(temp);
#else
        			__R30 &= ~(1U<<i);
#endif
        		}
                
                //get and set pwm_vals
                if (PWM_EN_MASK & (msk&(1U<<i))) {

            			//nextp = &next_hi_lo[i * 3];
                		nextp[1] = PWM_CMD->periodhi[i][1];
                        period = PWM_CMD->periodhi[i][0]; 
                		nextp[2] =period - nextp[1];
                        
                }
                PWM_CMD->hilo_read[i][0] = nextp[0];
                PWM_CMD->hilo_read[i][1] = nextp[1];
                
                
            }
                    
			// guaranteed to be immediate 
			deltamin = 0;
        
            PWM_CMD->magic = PWM_REPLY_MAGIC;
		}
        PWM_CMD->enmask_read = enmask;
		/* if nothing is enabled just skip it all */
		if (enmask == 0)
			continue;

		setmsk = 0;
		clrmsk = (u32)-1;
		deltamin = PRU_ms(100); /* (1U << 31) - 1; */
		next = cnt + deltamin;

#define SINGLE_PWM(_i) \
	do { \
		if (enmask & (1U << (_i))) { \
			nextp = &next_hi_lo[(_i)][0]; \
			tnext = nextp[0]; \
			hi = nextp[1]; \
			lo = nextp[2]; \
			/* avoid signed arithmetic */ \
			while (((delta = (tnext - cnt)) & (1U << 31)) != 0) { \
				/* toggle the state */ \
				if (stmask & (1U << (_i))) { \
					stmask &= ~(1U << (_i)); \
					clrmsk &= ~(1U << (_i)); \
					tnext += lo; \
				} else { \
					stmask |= (1U << (_i)); \
					setmsk |= (1U << (_i)); \
					tnext += hi; \
				} \
			} \
			if (delta <= deltamin) { \
				deltamin = delta; \
				next = tnext; \
			} \
			nextp[0] = tnext; \
		} \
	} while (0)



#if MAX_PWMS > 0 && (PWM_EN_MASK & BIT(0))
		SINGLE_PWM(0);
#endif
#if MAX_PWMS > 1 && (PWM_EN_MASK & BIT(1))
		SINGLE_PWM(1);
#endif
#if MAX_PWMS > 2 && (PWM_EN_MASK & BIT(2))
		SINGLE_PWM(2);
#endif
#if MAX_PWMS > 3 && (PWM_EN_MASK & BIT(3))
		SINGLE_PWM(3);
#endif
#if MAX_PWMS > 4 && (PWM_EN_MASK & BIT(4))
		SINGLE_PWM(4);
#endif
#if MAX_PWMS > 5 && (PWM_EN_MASK & BIT(5))
		SINGLE_PWM(5);
#endif
#if MAX_PWMS > 6 && (PWM_EN_MASK & BIT(6))
		SINGLE_PWM(6);
#endif
#if MAX_PWMS > 7 && (PWM_EN_MASK & BIT(7))
		SINGLE_PWM(7);
#endif
#if MAX_PWMS > 8 && (PWM_EN_MASK & BIT(8))
		SINGLE_PWM(8);
#endif
#if MAX_PWMS > 9 && (PWM_EN_MASK & BIT(9))
		SINGLE_PWM(9);
#endif
#if MAX_PWMS > 10 && (PWM_EN_MASK & BIT(10))
		SINGLE_PWM(10);
#endif
#if MAX_PWMS > 11 && (PWM_EN_MASK & BIT(11))
		SINGLE_PWM(11);
#endif
#if MAX_PWMS > 12 && (PWM_EN_MASK & BIT(12))
		SINGLE_PWM(12);
#endif

		/* results in set bits where there are changes */

#ifdef __GNUC__
                        temp = read_r30(); 
                        temp = (temp & (clrmsk & 0xfff)) | (setmsk & 0xfff);
                        write_r30(temp);
#else
      __R30 = (__R30 & (clrmsk & 0xfff)) | (setmsk & 0xfff);
#endif
		
		/* loop while nothing changes */
		do {
			cnt = read_PIEP_COUNT();
			if(PWM_CMD->magic == PWM_CMD_MAGIC){
				break;
			}
		} while (((next - cnt) & (1U << 31)) == 0);
	}
	return 0;
}