Quickie: I think you should always select the next lower frequency. That is, most often the application will ask for the highest frequency supported by the other chip. Hence, if you cannot get that frequency, at least you should not try with anything faster, but take the next slower frequency. --Pekka On 2014–02–24, at 21:51 , Ivan Raul <supra.material@xxxxxxxxx> wrote: > Dear all. > > This is a possible implementation that I thought for the setClock method. > It is targeted to be efficient in the case that it needs to be used at > runtime. > > In general, it tires to set the output frequency to minimize the error of > Abs[(f_wanted - f_possible) / f_wanted] > given a set of prescaler values ranging from 2,4,8,...,128,256 > In the case the wanted frequency lies exactly between two possible > frequencies, the lower one is chosen: > wanted 9Mhz, possible1=6Mhz, possible2= 12Mhz -> chosen=6Mhz > > I am not sure if it is necessary, but IIRC SystemCoreClock is not a constant > value, > so I am not sure if it can be optimized at compile time. Otherwise it would > be interesting to try to optimize through constexpr. > > I am still not sure if passing a uint8_t to a function that expects an enum > is going to work without typecast, but I will check later. > > uint32_t setClock(const uint8_t ss_pin, const uint32_t hertz) const { > extern "C" { extern volatile uint32_t SystemCoreClock; } > uint32_t outputHertz = SystemCoreClock>>1; > uint32_t prevOutputHertz = outputHertz; > uint8_t wantedDivider = 0; > if (hertz<outputHertz) > { > for (wantedDivider=1; wantedDivider < 7; wantedDivider++){ > outputHertz>>=1; > if (hertz >= outputHertz){ > uint32_t diff1 = hertz - outputHertz; > uint32_t diff2 = prevOutputHertz - hertz; > if (diff2<diff1) > wantedDivider--; > break; > } > prevOutputHertz = outputHertz; > } > } > > setClockDivider(ss_pin, wantedDivider); > } > > List of output frequencies for a clock of 48Mhz > > > 0 -> div=256, 187500 > 1000000 -> div=64, 750000 > 2000000 -> div=32, 1500000 > 3000000 -> div=16, 3000000 > 4000000 -> div=16, 3000000 > 5000000 -> div=8, 6000000 > 6000000 -> div=8, 6000000 > 7000000 -> div=8, 6000000 > 8000000 -> div=8, 6000000 > 9000000 -> div=8, 6000000 > 10000000 -> div=4, 12000000 > 11000000 -> div=4, 12000000 > 12000000 -> div=4, 12000000 > 13000000 -> div=4, 12000000 > 14000000 -> div=4, 12000000 > 15000000 -> div=4, 12000000 > 16000000 -> div=4, 12000000 > 17000000 -> div=4, 12000000 > 18000000 -> div=4, 12000000 > 19000000 -> div=2, 24000000 > 20000000 -> div=2, 24000000 > 21000000 -> div=2, 24000000 > 22000000 -> div=2, 24000000 > 23000000 -> div=2, 24000000 > 24000000 -> div=2, 24000000 > 25000000 -> div=2, 24000000 > 26000000 -> div=2, 24000000 > > With Warm Regards, Ivan Raul > >