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; }
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"); }
/* * 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; }