Other Parts Discussed in Thread: TIMAC, Z-STACK, ,
Hi,
I am trying to set up the MAC timer for the CSMA algorithm.
I want to set the time period to 32,which is 31.25ns*32=1us, and the overflow period should be set to 320 to achieve 320us(backoff period required in 802.15.4 standard).
the problem is: after settting the time and overflow period, I read back those values from registers, but they are not the value I expected. the following is the value that I read back:
overflow period[1]
time period:[0]
timer value[0]
overflow value[1]
as we can see, the period values are just the same as the initial value a set for the counter and overflow counter.
also, the program will never hop to the mac timer interrupt.
here is my code:
void mac_timer_debug(void){ mac_timer_disable(); mac_timer_IRQ_disable(); mac_timer_sync_disable(); mac_timer_latch_mode(FULL_LATCH); mac_timer_set_time_period(0x20);//1us mac_timer_set_overflow_period(0x140);//320us mac_timer_set_count_value(0x0000); mac_timer_set_overflow(0x000001); mac_timer_IRQ_flag_clear(); mac_timer_IRQ_maskon(RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM); mac_timer_IRQ_enable(); printf("overflow period[%x]\n",mac_timer_read_overflow_period()); printf("time period:[%x]\n",mac_timer_read_time_period()); printf("timer value[%x]\n",mac_timer_get_count_value()); printf("overflow value[%x]\n",mac_timer_get_overflow()); mac_timer_enable(); } PROCESS(mactimer_process, "csma process"); AUTOSTART_PROCESSES(&mactimer_process); PROCESS_THREAD(mactimer_process, ev, data){ PROCESS_BEGIN(); mac_timer_debug(); PROCESS_END(); }
Following is the MAC timer driver I create:
#define MTMSEL_MTOVF() HWREG(RFCORE_SFR_MTMSEL)=0x00000000 #define MTMSEL_MTOVFPER() do{\ HWREG(RFCORE_SFR_MTMSEL)=(0x010<<RFCORE_SFR_MTMSEL_MTMOVFSEL_S);\ }while(0) #define MTMSEL_MTOVFCMP1() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMOVFSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x011<<RFCORE_SFR_MTMSEL_MTMOVFSEL_S;\ }while(0) #define MTMSEL_MTOVFCMP2() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMOVFSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x100<<RFCORE_SFR_MTMSEL_MTMOVFSEL_S;\ }while(0) #define MTMSEL_MTOVFCAP() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMOVFSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x001<<RFCORE_SFR_MTMSEL_MTMOVFSEL_S;\ }while(0) #define MTMSEL_MTTIM() do{\ HWREG(RFCORE_SFR_MTMSEL)=0x00000000;\ }while(0) #define MTMSEL_MTPER() do{\ HWREG(RFCORE_SFR_MTMSEL)=0x010;\ }while(0) #define MTMSEL_MTCMP1() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x011;\ }while(0) #define MTMSEL_MTCMP2() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x100;\ }while(0) #define MTMSEL_MTCAP() do{\ HWREG(RFCORE_SFR_MTMSEL)&=(~RFCORE_SFR_MTMSEL_MTMSEL_M);\ HWREG(RFCORE_SFR_MTMSEL)|=0x001;\ }while(0) /***************************************************************************** * 函 数 名 : mac_timer_enable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 启动定时器 * 输入参数 : 无 * 输出参数 : 无 * 返 回 值 : 无 * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_enable(void){//启动mactimer计时器 HWREG(RFCORE_SFR_MTCTRL)|=RFCORE_SFR_MTCTRL_RUN; } /***************************************************************************** * 函 数 名 : mac_timer_disable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 停止计时器 * 输入参数 : 无 * 输出参数 : 无 * 返 回 值 : 无 * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_disable(void){//停止计时器 HWREG(RFCORE_SFR_MTCTRL)&=~RFCORE_SFR_MTCTRL_RUN; } /***************************************************************************** * 函 数 名 : mac_timer_sync_enable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 开启同步模式,计时器启动时会等到32kHz时钟的rising edge时才启动 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_sync_enable(void){ HWREG(RFCORE_SFR_MTCTRL)|=RFCORE_SFR_MTCTRL_SYNC; } /***************************************************************************** * 函 数 名 : mac_timer_sync_disable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 关闭同步模式,计时器启动时会立即启动 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_sync_disable(void){ HWREG(RFCORE_SFR_MTCTRL)&=~RFCORE_SFR_MTCTRL_SYNC; } /***************************************************************************** * 函 数 名 : mac_timer_latch_mode * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 决定了在读取计时器数值时,是读取带overflow的时间戳,还是只读取计时器的数值 * 输入参数 : LATCH_MODE mode: 可以为FULL_LATCH或HALF_LATCH * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_latch_mode(LATCH_MODE mode){ if(mode==FULL_LATCH)HWREG(RFCORE_SFR_MTCTRL)|=RFCORE_SFR_MTCTRL_LATCH_MODE; else HWREG(RFCORE_SFR_MTCTRL)&=~RFCORE_SFR_MTCTRL_LATCH_MODE; } /***************************************************************************** * 函 数 名 : mac_timer_status * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 返回计时器当前状态 * 输入参数 : * 输出参数 : * 返 回 值 : 为0则为空闲,不为0则为运行中 * 调用关系 : * 其 它 : *****************************************************************************/ uint8_t mac_timer_status(void){ return HWREG(RFCORE_SFR_MTCTRL)&RFCORE_SFR_MTCTRL_STATE; } /***************************************************************************** * 函 数 名 : mac_timer_set_count_value * 负 责 人 : 邹子豪 * ���建日期 : 2021.2.23 * 函数功能 : 设置计时器当前数值 * 输入参数 : uint16_t value: 精度为31.25 ns * 输���参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_count_value(uint16_t value){ mac_timer_disable(); MTMSEL_MTTIM(); HWREG(RFCORE_SFR_MTM0)=value&0xff; HWREG(RFCORE_SFR_MTM1)=value>>8; } /***************************************************************************** * 函 数 名 : mac_timer_get_count_value * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 获取计时器当前数值 * 输入参数 : * 输出参数 : uint16_t value: 精度为31.25 ns * 返 回 值 : * 调用关系 : * 其 它 : 注意: 获得的数据不包括溢出计数器的值,如需溢出计数器的数据,使用 mac_timer_get_overflow() *****************************************************************************/ uint16_t mac_timer_get_count_value(void){ uint16_t value; MTMSEL_MTTIM(); value=HWREG(RFCORE_SFR_MTM0)&0xff; value|=(HWREG(RFCORE_SFR_MTM1)<<8)&0xff00; return value; } /***************************************************************************** * 函 数 名 : mac_timer_get_overflow * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 获取溢出计数器的数值 * 输入参数 : * 输出参数 : * 返 回 值 : overflow数值 * 调用关系 : * 其 它 : *****************************************************************************/ uint32_t mac_timer_get_overflow(void){ uint32_t ovf=0; MTMSEL_MTOVF(); ovf=HWREG(RFCORE_SFR_MTMOVF0)&0xff; ovf|=(HWREG(RFCORE_SFR_MTMOVF1)<<8)&0xff00; ovf|=(HWREG(RFCORE_SFR_MTMOVF2)<<16)&0xff0000; return ovf; } /***************************************************************************** * 函 数 名 : mac_timer_set_overflow * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.23 * 函数功能 : 设置overflow数值 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_overflow(uint32_t value){ MTMSEL_MTOVF(); HWREG(RFCORE_SFR_MTMOVF0)=value&0xff; HWREG(RFCORE_SFR_MTMOVF1)=(value>>8)&0xff; HWREG(RFCORE_SFR_MTMOVF2)=(value>>16)&0xff; } /***************************************************************************** * 函 数 名 : mac_timer_IRQ_maskon * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : 打开相应的中断 * 输入参数 : 可以为: RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE2M RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE1M RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM RFCORE_SFR_MTIRQM_MACTIMER_COMPARE2M RFCORE_SFR_MTIRQM_MACTIMER_COMPARE1M RFCORE_SFR_MTIRQM_MACTIMER_PERM * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_IRQ_maskon(uint32_t mask){ HWREG(RFCORE_SFR_MTIRQM)=mask; } /***************************************************************************** * 函 数 名 : mac_timer_IRQ_maskoff * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : 关闭相应中断 * 输入参数 : 可以为: RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE2M RFCORE_SFR_MTIRQM_MACTIMER_OVF_COMPARE1M RFCORE_SFR_MTIRQM_MACTIMER_OVF_PERM RFCORE_SFR_MTIRQM_MACTIMER_COMPARE2M RFCORE_SFR_MTIRQM_MACTIMER_COMPARE1M RFCORE_SFR_MTIRQM_MACTIMER_PERM * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_IRQ_maskoff(uint32_t mask){ HWREG(RFCORE_SFR_MTIRQM)&=~mask; } /***************************************************************************** * 函 数 名 : mac_timer_IRQ_flag_clear * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : 归零所有中断标识 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_IRQ_flag_clear(void){ HWREG(RFCORE_SFR_MTIRQF)=0; } /***************************************************************************** * 函 数 名 : mac_timer_IRQ_enable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : 打开中断 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_IRQ_enable(void){ IntEnable(INT_MACTIMR); } /***************************************************************************** * 函 数 名 : mac_timer_IRQ_disable * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : 关闭中断 * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_IRQ_disable(void){ IntDisable(INT_MACTIMR); } /***************************************************************************** * 函 数 名 : mac_timer_set_time_period * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_time_period(uint16_t period){ MTMSEL_MTPER(); HWREG(RFCORE_SFR_MTM0)=period&0xff; HWREG(RFCORE_SFR_MTM1)=period>>8; } /***************************************************************************** * 函 数 名 : mac_timer_set_overflow_period * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_overflow_period(uint32_t period){ MTMSEL_MTOVFPER(); HWREG(RFCORE_SFR_MTMOVF0)=period&0xff; HWREG(RFCORE_SFR_MTMOVF1)=(period>>8)&0xff; HWREG(RFCORE_SFR_MTMOVF2)=(period>>16)&0xff; } /***************************************************************************** * 函 数 名 : mac_timer_set_timer_compare * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_timer_compare(uint16_t cmp,MT_TIME_COMPARE which ){ if(which==MT_TIME_COMPARE1) MTMSEL_MTCMP1(); else MTMSEL_MTCMP2(); HWREG(RFCORE_SFR_MTM0)=cmp&0xff; HWREG(RFCORE_SFR_MTM1)=cmp>>8; } /***************************************************************************** * 函 数 名 : mac_timer_set_overflow_compare * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ void mac_timer_set_overflow_compare(uint32_t cmp, MT_OVF_COMPARE which){ if(which==MT_OVF_COMPARE1) MTMSEL_MTOVFCMP1(); else MTMSEL_MTOVFCMP2(); HWREG(RFCORE_SFR_MTMOVF0)=cmp&0xff; HWREG(RFCORE_SFR_MTMOVF1)=(cmp>>8)&0xff; HWREG(RFCORE_SFR_MTMOVF2)=(cmp>>16)&0xff; } /***************************************************************************** * 函 数 名 : mac_timer_read_time_capture * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ uint16_t mac_timer_read_time_capture(void){ uint16_t value; MTMSEL_MTCAP(); value=HWREG(RFCORE_SFR_MTM0)&0xff; value|=(HWREG(RFCORE_SFR_MTM1)<<8)&0xff00; return value; } /***************************************************************************** * 函 数 名 : mac_timer_read_overflow_capture * 负 责 人 : 邹子豪 * 创建日期 : 2021.2.24 * 函数功能 : * 输入参数 : * 输出参数 : * 返 回 值 : * 调用关系 : * 其 它 : *****************************************************************************/ uint32_t mac_timer_read_overflow_capture(void){ uint32_t value; MTMSEL_MTOVFCAP(); value=HWREG(RFCORE_SFR_MTMOVF0)&0xff; value|=(HWREG(RFCORE_SFR_MTMOVF1)<<8)&0xff00; value|=(HWREG(RFCORE_SFR_MTMOVF2)<<16)&0xff0000; return value; } uint32_t mac_timer_read_overflow_period(void){ uint32_t value; MTMSEL_MTOVFPER(); value=HWREG(RFCORE_SFR_MTMOVF0)&0xff; value|=(HWREG(RFCORE_SFR_MTMOVF1)<<8)&0xff00; value|=(HWREG(RFCORE_SFR_MTMOVF2)<<16)&0xff0000; return value; } uint16_t mac_timer_read_time_period(void){ uint16_t value; MTMSEL_MTPER(); value=HWREG(RFCORE_SFR_MTM0)&0xff; value|=(HWREG(RFCORE_SFR_MTM1)<<8)&0xff00; return value; } void MacTimerIntHandler(void){ printf("timer:[%x]\n",mac_timer_get_count_value()); printf("overflow:[%x]\n",mac_timer_get_overflow()); mac_timer_IRQ_flag_clear(); }