/****************************************************************************** * @name cmt_init_freq * * Function Name : cmt_init_freq * Returned Value : * Comments : Initialize timer module * * *END*----------------------------------------------------------------------*/ void cmt_init_freq(uint_32 period) { #if (defined BSP_TWRMCF51JE) VMCF51JE_CMT_STRUCT_PTR cmt = &(((MCF51JE_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if (defined BSP_TWRMCF51MM) VMCF51MM_CMT_STRUCT_PTR cmt = &(((MCF51MM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if (defined BSP_MCF51JMEVB) VMCF51JM_CMT_STRUCT_PTR cmt = &(((MCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif /* CMTMSC: EOCF=0,CMTDIV1=0,CMTDIV0=0,EXSPC=0,BASE=0,FSK=0,EOCIE=0,MCGEN=0 */ cmt->CMTMSC = 0x00; /* CMTOC: IROL=0,CMTPOL=0,IROPEN=0,??=0,??=0,??=0,??=0,??=0 */ cmt->CMTOC = 0x00; /* CMTCG1: PH7=0,PH6=0,PH5=0,PH4=0,PH3=0,PH2=0,PH1=0,PH0=0,PL7=0,PL6=0,PL5=0,PL4=0,PL3=0,PL2=0,PL1=0,PL0=0 */ cmt->CMTCGH1 = 0x00; cmt->CMTCGL1 = 0x00; /* CMTCG2: SH7=0,SH6=0,SH5=0,SH4=0,SH3=0,SH2=0,SH1=0,SH0=0,SL7=0,SL6=0,SL5=0,SL4=0,SL3=0,SL2=0,SL1=0,SL0=0 */ cmt->CMTCGH2 = 0x00; cmt->CMTCGL2 = 0x00; /* CMTCMD12: MB15=0,MB14=0,MB13=0,MB12=0,MB11=0,MB10=0,MB9=0,MB8=1,MB7=0,MB6=1,MB5=1,MB4=1,MB3=0,MB2=1,MB1=1,MB0=0 */ cmt->CMTCMD1 = (uint_8)((period & 0xFF00)>>8); cmt->CMTCMD2 = (uint_8)(period & 0x00FF); /* CMTCMD34: SB15=0,SB14=0,SB13=0,SB12=0,SB11=0,SB10=0,SB9=0,SB8=0,SB7=0,SB6=0,SB5=0,SB4=0,SB3=0,SB2=0,SB1=0,SB0=0 */ cmt->CMTCMD3 = 0x00; cmt->CMTCMD4 = 0x00; /* CMTMSC: EOCF=0,CMTDIV1=0,CMTDIV0=0,EXSPC=0,BASE=0,FSK=0,EOCIE=1,MCGEN=1 */ cmt->CMTMSC = 0x01; }
/****************************************************************************** * @name cmt_init_freq * * @brief This function initializes CMT timer module * * @return None * * @comment * *******************************************************************************/ uint_32 cmt_init_freq ( /* [IN] ticks per second */ uint_32 tickfreq, /* [IN] input clock speed in Hz */ uint_32 clk, /* [IN] unmask the timer after initializing */ boolean unmask_timer ) { /* CMT memory map */ #if (defined BSP_TWRMCF51JE) VMCF51JE_CMT_STRUCT_PTR cmt = &(((MCF51JE_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if (defined BSP_TWRMCF51MM) VMCF51MM_CMT_STRUCT_PTR cmt = &(((MCF51MM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if (defined BSP_MCF51JMEVB) VMCF51JM_CMT_STRUCT_PTR cmt = &(((MCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif uint_32 rate; uint_8 prescale = 0; /* Calculate prescale */ rate = (clk / (8*tickfreq)); while (rate > (0xFFFF+1)) { prescale += 1; clk >>= 1; rate = (clk / tickfreq); } /* CMTMSC: EOCF=0,CMTDIV1=0,CMTDIV0=0,EXSPC=0,BASE=0,FSK=0,EOCIE=0,MCGEN=0 */ cmt->CMTMSC = 0x00; /* CMTOC: IROL=0,CMTPOL=0,IROPEN=0,??=0,??=0,??=0,??=0,??=0 */ cmt->CMTOC = 0x00; /* CMTCG1: PH7=0,PH6=0,PH5=0,PH4=0,PH3=0,PH2=0,PH1=0,PH0=0,PL7=0,PL6=0,PL5=0,PL4=0,PL3=0,PL2=0,PL1=0,PL0=0 */ cmt->CMTCGH1 = 0x00; cmt->CMTCGL1 = 0x00; /* CMTCG2: SH7=0,SH6=0,SH5=0,SH4=0,SH3=0,SH2=0,SH1=0,SH0=0,SL7=0,SL6=0,SL5=0,SL4=0,SL3=0,SL2=0,SL1=0,SL0=0 */ cmt->CMTCGH2 = 0x00; cmt->CMTCGL2 = 0x00; /* CMTCMD12: MB15=0,MB14=0,MB13=0,MB12=0,MB11=0,MB10=0,MB9=0,MB8=1,MB7=0,MB6=1,MB5=1,MB4=1,MB3=0,MB2=1,MB1=1,MB0=0 */ cmt->CMTCMD1 = (uint_8)((rate & 0xFF00)>>8); cmt->CMTCMD2 = (uint_8)(rate & 0x00FF); /* CMTCMD34: SB15=0,SB14=0,SB13=0,SB12=0,SB11=0,SB10=0,SB9=0,SB8=0,SB7=0,SB6=0,SB5=0,SB4=0,SB3=0,SB2=0,SB1=0,SB0=0 */ cmt->CMTCMD3 = 0x00; cmt->CMTCMD4 = 0x00; /* CMTMSC: EOCF=0,CMTDIV1=0,CMTDIV0=0,EXSPC=0,BASE=0,FSK=0,EOCIE=1,MCGEN=1 */ cmt->CMTMSC |= 0x01; cmt->CMTMSC |= prescale<<5; if(unmask_timer) EnableCmtInterrupt(); return rate; }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : DisableCmtInterrupt * Returned Value : * Comments : Disable CMT interrupt. * * *END*----------------------------------------------------------------------*/ void DisableCmtInterrupt(void) { #if(defined BSP_TWRMCF51JE) VMCF51JE_CMT_STRUCT_PTR cmt = &(((MCF51JE_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if(defined BSP_TWRMCF51MM) VMCF51MM_CMT_STRUCT_PTR cmt = &(((MCF51MM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if(defined BSP_MCF51JMEVB) VMCF51JM_CMT_STRUCT_PTR cmt = &(((MCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif /* Disable Timer Interrupt */ cmt->CMTMSC &= ~(0x02); return; }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : ClearCmtInterrupt * Returned Value : * Comments : Clear CMT Interrupt. * * *END*----------------------------------------------------------------------*/ static void ClearCmtInterrupt(void) { #if(defined BSP_TWRMCF51JE) VMCF51JE_CMT_STRUCT_PTR cmt = &(((MCF51JE_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if(defined BSP_TWRMCF51MM) VMCF51MM_CMT_STRUCT_PTR cmt = &(((MCF51MM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif #if(defined BSP_MCF51JMEVB) VMCF51JM_CMT_STRUCT_PTR cmt = &(((MCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->CMT); #endif /* Clear Timer Interrupt */ (void)cmt->CMTMSC; (void)cmt->CMTCMD2; return; }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_get_cfm_address * Returned Value : Address upon success * Comments : * This function returns the base register address of the CFM * *END*----------------------------------------------------------------------*/ pointer _bsp_get_cfm_address(uchar module) { VMCF51MM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); VMCF51XX_FTSR_STRUCT_PTR ftsr_ptr; switch (module) { case MEMORY_ARRAY_STD: case MEMORY_ARRAY_1: ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)®_ptr->FTSR1; break; case MEMORY_ARRAY_2: ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)®_ptr->FTSR2; break; default: ftsr_ptr = NULL; break; } return (pointer)ftsr_ptr; }
/*FUNCTION***************************************************************** * * Function Name : gpio_cpu_configure * Returned Value : IO_OK * Comments : * Configures pins to be GPIO based on pin map * *END*********************************************************************/ void gpio_cpu_configure ( /* [IN] pointer to file data */ GPIO_DEV_DATA_PTR dev_data_ptr ) { /* Body */ _mqx_int i; MCF51JM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); if (dev_data_ptr->type == DEV_OUTPUT) { /* set GPIO output behavior */ for (i = GPIO_PORT_A; i < GPIO_PORT_MAX; i++) { /* Set direction to output */ if(i<GPIO_PORT_H) reg_ptr->GPIO_A_G[i].PTxDD |= dev_data_ptr->pin_map.reg.portt[i]; else reg_ptr->GPIO_H_J[i-GPIO_PORT_H].PTxDD |= dev_data_ptr->pin_map.reg.portt[i]; } } else { /* DEV_INPUT type is supposed */ for (i = GPIO_PORT_A; i < GPIO_PORT_MAX; i++) { /* Set direction to input */ if(i<GPIO_PORT_H) { reg_ptr->GPIO_A_G[i].PTxDD &= ~dev_data_ptr->pin_map.reg.portt[i]; } else { reg_ptr->GPIO_H_J[i-GPIO_PORT_H].PTxDD &= ~dev_data_ptr->pin_map.reg.portt[i]; } /* Enable weak pull-ups for all inputs */ reg_ptr->GPIO_P[i].PTxPE |= dev_data_ptr->pin_map.reg.portt[i]; } } if (dev_data_ptr->irqp_map.reg.portt[GPIO_PORT_G]) { reg_ptr->KBI.KBI1PE = dev_data_ptr->irqp_map.reg.portt[GPIO_PORT_G]; reg_ptr->KBI.KBI1SC |= MCF51XX_KBIXSC_KBIE; } } /* Endbody */
/****************************************************************************** * * @name _pwm_init * * @brief This function initialyzes PWM. * * @param None * * @return None *****************************************************************************/ void _pwm_init() { /* Initialize PWM module for CFV2 families */ #if(defined BSP_M52259DEMO) || (defined BSP_M52259EVB) || (defined BSP_TWRMCF52259) VMCF5225_PWM_STRUCT_PTR pwm = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->PWM); VMCF5225_GPIO_STRUCT_PTR gpio = &(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO); #endif #if(defined BSP_M52277EVB) VMCF5227_PWM_STRUCT_PTR pwm = &(((VMCF5227_STRUCT_PTR)_PSP_GET_IPSBAR())->PWM); VMCF5227_GPIO_STRUCT_PTR gpio = &(((VMCF5227_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO); #endif #if (defined BSP_M52223EVB) VMCF5222_PWM_STRUCT_PTR pwm = &(((VMCF5222_STRUCT_PTR)_PSP_GET_IPSBAR())->PWM); VMCF5222_GPIO_STRUCT_PTR gpio = &(((VMCF5222_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO); #endif #if(defined BSP_TWRMCF52259) /* update duty (channel 0)*/ duty = &(pwm->PWMDTY[0]); /* Init IO for PWM */ gpio->PTCPAR |= 0x03; pwm->PWME = 0; /* PCKA = 1: clock A rate = bus clk / 1 = 40MHz*/ pwm->PWMPRCLK = 0x00; pwm->PWMPER[0] = 0xFF; pwm->PWMDTY[0] = 0x00; /* High at begin of period */ pwm->PWMPOL = 0x02; /* chose clock source is A */ pwm->PWMCLK = 0x00; /* No Concatenates */ pwm->PWMCTL = 0x00; /* Enable PWM */ pwm->PWME = 0x01; #endif #if(defined BSP_M52259DEMO)||(defined BSP_M52259EVB)||(defined BSP_M52223EVB)||(defined BSP_M52277EVB) /* update duty (channel 1) */ duty = &(pwm->PWMDTY[1]); #if(defined BSP_M52277EVB) /* Init IO for PWM */ gpio->PAR_LCDL = 0x200; #else /* Init IO for PWM */ gpio->PTAPAR |= 0x03; #endif /* Disable PWM */ pwm->PWME = 0; /* PCKA = 1: clock A rate = bus clk / 1 = 40MHz*/ pwm->PWMPRCLK = 0x00; pwm->PWMPER[1] = 0xFF; pwm->PWMDTY[1] = 0x00; /* High at begin of period */ pwm->PWMPOL = 0x02; /* chose clock source is A */ pwm->PWMCLK = 0x00; /* No Concatenates */ pwm->PWMCTL = 0x00; /* Enable PWM */ pwm->PWME = 0x02; #endif /* Initialize PWM module for CFV1 families */ #if (defined BSP_TWRMCF51JE)||(defined BSP_TWRMCF51MM)||(defined BSP_MCF51JMEVB) #if (defined BSP_TWRMCF51JE) VMCF51JE_TPM_STRUCT_PTR tpm = &(((MCF51JE_STRUCT_PTR)_PSP_GET_MBAR())->TPM2); VMCF51JE_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); #endif #if (defined BSP_TWRMCF51MM) VMCF51MM_TPM_STRUCT_PTR tpm = &(((MCF51MM_STRUCT_PTR)_PSP_GET_MBAR())->TPM2); VMCF51MM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); #endif #if (defined BSP_MCF51JMEVB) VMCF51JM_TPM1_STRUCT_PTR tpm = &(((MCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->TPM1); VMCF51JM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); reg_ptr->SIMX.SCGC1 |= MCF51XX_SCGC1_TPM1_MASK; #else reg_ptr->SIM.SCGC1 |= MCF51XX_SCGC1_TPM2_MASK; #endif /* update duty */ duty = (uint_16*)(&(tpm->TPMxC[0].TPMxCyV)); tpm->TPMxSC = 0; tpm->TPMxMOD = 0xFF; tpm->TPMxC[0].TPMxCySC = 0x24; tpm->TPMxSC = 0x08; #endif /* Initialize PWM module for kinetis families */ #if (defined BSP_TWR_K40X256) || (defined BSP_TWR_K60N512) || (defined BSP_TWR_K53N512) || (defined BSP_TWR_K60D100M) duty = (uint_8 *)&(FTM0_C0V); /* FTM0_CH0 enable on PTA3 ****/ PORTC_PCR1 = PORT_PCR_MUX(0x4); /* Enable clock for FTM */ SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; /* Set FTM mode */ FTM0_MODE = (FTM_MODE_WPDIS_MASK | FTM_MODE_FTMEN_MASK); FTM0_MODE &= ~FTM_MODE_FTMEN_MASK; FTM0_SC = 0; FTM0_CNTIN = 0x00; /* Set FTM modular */ FTM0_MOD = 0xFF; FTM0_QDCTRL &= ~(FTM_QDCTRL_QUADEN_MASK); FTM0_COMBINE &= ~(FTM_COMBINE_DECAPEN0_MASK \ |FTM_COMBINE_DECAPEN1_MASK \ |FTM_COMBINE_DECAPEN2_MASK \ |FTM_COMBINE_DECAPEN3_MASK \ |FTM_COMBINE_COMBINE0_MASK \ |FTM_COMBINE_COMBINE1_MASK \ |FTM_COMBINE_COMBINE2_MASK \ |FTM_COMBINE_COMBINE3_MASK); FTM0_C0SC = 0x28; /* Enable FTM */ FTM0_SC = 0x08; #endif /* Initialize PWM module for CFV3 */ #if (defined BSP_M5329EVB) VMCF5329_PWM_STRUCT_PTR pwm = &(((VMCF5329_STRUCT_PTR)_PSP_GET_IPSBAR())->PWM); VMCF5329_GPIO_STRUCT_PTR gpio = &(((VMCF5329_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO); /* update duty (channel 0)*/ duty = &(pwm->PWMDTY1); /* Init IO for PWM */ gpio->PAR_PWM |= 0x03; pwm->PWME = 0; /* PCKA = 1: clock A rate = bus clk / 1 = 40MHz*/ pwm->PWMPRCLK = 0x00; pwm->PWMPER1 = 0xFF; pwm->PWMDTY1 = 0x00; /* High at begin of period */ pwm->PWMPOL = 0x02; /* chose clock source is A */ pwm->PWMCLK = 0x00; /* No Concatenates */ pwm->PWMCTL = 0x00; /* Enable PWM */ pwm->PWME = 0x02; #endif #if (defined BSP_TWRMCF51JF) volatile MXC_MemMapPtr mxc; volatile FTM_MemMapPtr ftm1; mxc = MXC_BASE_PTR; ftm1 = FTM1_BASE_PTR; duty = (uint_16_ptr) &(ftm1->CHANNEL[0].CnV); mxc->PTAPF4 &= ~MXC_PTAPF4_A0(0xF); mxc->PTAPF4 |= MXC_PTAPF4_A0(0x4); /* Init counter value*/ ftm1->CNT = 0x0000; /* Set Modulo -> free run mode*/ ftm1->MOD = 0x00FF; /* Disable dual capture mode and combine channels */ ftm1->COMBINE[0] &= ~(FTM_COMBINE_DECAPEN_MASK | FTM_COMBINE_COMBINE_MASK); /* Select channel 0 to generate PWM signal */ ftm1->CHANNEL[0].CnSC |= FTM_CnSC_MSB_MASK; ftm1->CHANNEL[0].CnSC |= FTM_CnSC_ELSB_MASK; ftm1->CHANNEL[0].CnSC &= ~FTM_CnSC_ELSA_MASK; /* Start timer */ ftm1->SC = 0x08; #endif }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_get_usb_capability_register_base * Returned Value : Address upon success, NULL upon failure * Comments : * This function returns the address of the VUSBHS Capability Registers * *END*----------------------------------------------------------------------*/ pointer _bsp_get_usb_base(uint_8 dev_num) { return (pointer)(&((VMCF51JM_STRUCT_PTR)_PSP_GET_MBAR())->USBOTG); }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_get_pmc_address * Returned Value : Address upon success * Comments : * This function returns the base register address of the PMC * *END*----------------------------------------------------------------------*/ pointer _bsp_get_pmc_address() { VMCF51MM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); uint_8_ptr pmc_ptr = (uint_8_ptr)®_ptr->PMC; return (pointer)pmc_ptr; }
_mqx_int gpio_cpu_open ( /* [IN] the file handle for the device */ MQX_FILE_PTR fd_ptr, /* [IN] the file name */ char_ptr file_name, /* [IN] pointer to parameters */ char_ptr param_ptr ) { /* Body */ _mqx_int i; MCF51JM_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); GPIO_DEV_DATA_PTR dev_data_ptr = (GPIO_DEV_DATA_PTR) fd_ptr->DEV_DATA_PTR; /* if file_name is used, then the user wants to open peripheral */ if ((file_name != NULL) && (*file_name != 0)) { if (!strncmp(file_name, "gpio:write", 11)) /* user wants write access to GPIO */ dev_data_ptr->type = DEV_OUTPUT; else if (!strncmp(file_name, "gpio:output", 12)) /* user wants write access to GPIO */ dev_data_ptr->type = DEV_OUTPUT; else if (!strncmp(file_name, "gpio:read", 10)) /* user wants read access to GPIO */ dev_data_ptr->type = DEV_INPUT; else if (!strncmp(file_name, "gpio:input", 11)) /* user wants read access to GPIO */ dev_data_ptr->type = DEV_INPUT; else /* peripherals not used yet */ return IO_ERROR; } else return IO_ERROR; if ((param_ptr != NULL) && (dev_data_ptr->type == DEV_OUTPUT)) { /* set pins status before selecting GPIO function */ /* note that this is similar to GPIO_IOCTL_WRITE function, but no checking is performed (was done in io_gpio_open function) */ uint_32 _PTR_ pin_table; uint_32 addr; uint_8 pin; GPIO_PIN_MAP_PTR temp_pin0_map_ptr; GPIO_PIN_MAP_PTR temp_pin1_map_ptr; if (NULL == (temp_pin0_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP)))) return IO_ERROR; if (NULL == (temp_pin1_map_ptr = (GPIO_PIN_MAP_PTR) _mem_alloc_system_zero(sizeof(GPIO_PIN_MAP)))) { _mem_free(temp_pin0_map_ptr); return IO_ERROR; } /* prepare pin map */ for (pin_table = (uint_32 _PTR_) param_ptr; *pin_table != GPIO_LIST_END; pin_table++) { addr = (*pin_table & GPIO_PIN_ADDR) >> 3; /* prepare address of port */ pin = 1 << (*pin_table & 0x07); /* prepare bit mask */ if (*pin_table & GPIO_PIN_STATUS) temp_pin1_map_ptr->memory8[addr] |= pin; else temp_pin0_map_ptr->memory8[addr] |= pin; } /* first, configure pin as output */ gpio_cpu_configure(dev_data_ptr); /* ok, now we can apply new map */ /* note: applying the map after collecting pins is due to have pins applied in one instruction */ for (i = GPIO_PORT_A; i < GPIO_PORT_MAX; i++) if(i<GPIO_PORT_H) { reg_ptr->GPIO_A_G[i].PTxD = (reg_ptr->GPIO_A_G[i].PTxD | temp_pin1_map_ptr->reg.portt[i]) & ~temp_pin0_map_ptr->reg.portt[i]; } else { reg_ptr->GPIO_H_J[i-GPIO_PORT_H].PTxD = (reg_ptr->GPIO_H_J[i-GPIO_PORT_H].PTxD | temp_pin1_map_ptr->reg.portt[i]) & ~temp_pin0_map_ptr->reg.portt[i]; } _mem_free(temp_pin1_map_ptr); _mem_free(temp_pin0_map_ptr); }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_get_pmc_address * Returned Value : Address upon success * Comments : * This function returns the base register address of the PMC * *END*----------------------------------------------------------------------*/ pointer _bsp_get_pmc_address() { VMCF51AG_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); VMCF51AG_PMC_STRUCT_PTR pmc_ptr = (VMCF51AG_PMC_STRUCT_PTR)®_ptr->PMC; return (pointer)pmc_ptr; }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _bsp_get_cfm_address * Returned Value : Address upon success * Comments : * This function returns the base register address of the CFM * *END*----------------------------------------------------------------------*/ pointer _bsp_get_cfm_address() { VMCF51AG_STRUCT_PTR reg_ptr = _PSP_GET_MBAR(); VMCF51XX_FTSR_STRUCT_PTR ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)®_ptr->FTSR; return (pointer)ftsr_ptr; }