Hello Gedare, On Thursday 14 of August 2014 15:12:44 Gedare Bloom wrote: > On Thu, Aug 14, 2014 at 4:53 AM, Pavel Pisa <p...@cmp.felk.cvut.cz> wrote: > I am OK with single bit masks - BSP_BIT32(7), but I prefer only single > > define per multi bit field. So my own approach is to use macros to find > > field start bit from maks > > > > /*masked fields macros*/ > > #define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask)) > > #define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1))) > > Do you get the similar effect from BSP_FLD32? > http://git.rtems.org/rtems/tree/c/src/lib/libbsp/shared/include/utility.h#n >68
You get exactly same code if mask is constant and contains only single continuous region of one bits. The main advantage is, that you can define everything required to describe field by single plain define #define MODULEx_REGy_FIELDx_m 0x00000f00 or in BSP utility language more readable #define MODULEx_REGy_FIELDx_m BSP_MSK32(8, 11) Then to access filed in register (if struct is used for registers placement in memory) you get value = __mfld2val(MODULEx_REGy_FIELDx_m, MODULEx->REGy); to setup register by values for more fields MODULEx->REGy = __val2mfld(MODULEx_REGy_FIELD1_m, val1) | __val2mfld(MODULEx_REGy_FIELD2_m, val2); To replace field value MODULEx->REGy = (MODULEx->REGy & ~MODULEx_REGy_FIELDz_m) | __val2mfld(MODULEx_REGy_FIELDz_m, val1); I see significant advantage in defining of plain masks without get/set that they suggest to be used directly in more situations. I.e. used in atomic clear mask or other special instructions. In the fact, real mask can be retrieved from set/get pair by little (or bigger) hack MODULEx_REGy_FIELDx_SET(~1) You can get the first bit position still too __builtin_ffs(MODULEx_REGy_FIELDx_SET(~1)) and bit count similar way from get or by more ops from SET. But seems to be hacky to me. Anyway all these is compiled to constants by GCC. So no overhead only final and and shift if value put into field is not constant. I have used __val2mfld/__mfld2val names with two underscores to be outside of clash with POSIX when masks are used in generic headerfiles which can be included by third party libraries. But if you accept these in BSP_ space for RTEMS, I would be happy with any other descriptive name #define BSP_TOFLD(mask,val) (((mask)&~((mask)<<1))*(val)&(mask)) #define BSP_FROMFLD(mask,val) (((val)&(mask))/((mask)&~((mask)<<1))) or under some other name BSP_MF2V BSP_V2MF ???? in http://git.rtems.org/rtems/tree/c/src/lib/libbsp/shared/include/utility.h > > for constant masks they compile optimal way and for variable > > they are usable too if CPU has ffs/clz support. > > > > http://sourceforge.net/p/ulan/sysless/ci/master/tree/arch/arm/generic/def > >ines/cpu_def.h > > > > This is how I use it in our bare HW/system-less code > > > > http://sourceforge.net/p/ulan/sysless/ci/master/tree/libs4c/spi/spi_lpcss > >p.c#l200 > > > > lpcssp_drv->ssp_regs->CR0 = > > __val2mfld(SSP_CR0_DSS_m, lpcssp_drv->data16_fl? 16 - 1 : 8 - 1) | > > __val2mfld(SSP_CR0_FRF_m, 0) | > > (msg->size_mode & SPI_MODE_CPOL? SSP_CR0_CPOL_m: 0) | > > (msg->size_mode & SPI_MODE_CPHA? SSP_CR0_CPHA_m: 0) | > > __val2mfld(SSP_CR0_SCR_m, 15); > > > > http://sourceforge.net/p/ulan/sysless/ci/master/tree/arch/arm/mach-lpc17x > >x/libs/hal/hal_gpio.c#l32 Best wishes, Pavel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel