uSDFS
uSDFS copied to clipboard
m_sdhc_baudrate caculation wrong
line 467 in sdhc.c (cosmetic?) is in error me thinks. it reads m_sdhc_baudrate=F_CPU/((1<<minpresc)*(mindiv+1));
but minpresc is not a shift value, it should be minpresc << 1 BUT, that is not quite right either, because if minpresc is 0, you want the multiplier to be 1, so maybe int tmp = minpresc << 1; if (tmp == 0) tmp = 1; m_sdhc_baudrate=F_CPU/(tmp*(mindiv+1));
I believe that the following code should be correct
// get dividers from requested baud rate
uint32_t aux=F_CPU;
uint32_t ii=0,jj=1;
uint32_t baudrate=kbaudrate*1000;
while(aux/(16*(1<<ii))>baudrate) ii++;
while(aux/(jj*(1<<ii))>baudrate) jj++;
uint32_t minpresc=ii;
uint32_t mindiv=jj-1;
m_sdhc_baudrate=F_CPU/((1<<minpresc) * (mindiv+1));
// Change dividers
sysctl = SDHC_SYSCTL &
(~ (SDHC_SYSCTL_DTOCV_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK));
SDHC_SYSCTL = sysctl |
(SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_SDCLKFS(minpresc) | SDHC_SYSCTL_DVS(mindiv));
presc is a single bit and div is a number
This includes the (untested case) that presc = 0 is valid input and that presc=0 does not prevent div to be effective. The way I calculate is if F_CPU=96 Mhz and baudrate is 3 kHz then ii=1 and jj=16 presc=1 and div = 15 and therefore 96MHz/((1<<presc)*(div+1)) = 3kHz
Can you agree?
You chose a convenient example where ii is 1. the minpresc in the register should have values of 0, 1,2,4,8,16 32 ... your current example, i don't think will set the register value correctly
what will you get with CPU 96mhz and target baudrate 400K, 96000000/(16*15) = 400000 register: prescale value 8, divisor value 14 On Tue, Jan 17, 2017 at 12:09:21PM -0800, WMXZ-EU wrote:
I believe that the following code should be correct
// get dividers from requested baud rate uint32_t aux=F_CPU; uint32_t ii=0,jj=1; uint32_t baudrate=kbaudrate*1000; while(aux/(16*(1<<ii))>baudrate) ii++; while(aux/(jj*(1<<ii))>baudrate) jj++; uint32_t minpresc=ii; uint32_t mindiv=jj-1; m_sdhc_baudrate=F_CPU/((1<<minpresc) * (mindiv+1)); // Change dividers sysctl = SDHC_SYSCTL & (~ (SDHC_SYSCTL_DTOCV_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK)); SDHC_SYSCTL = sysctl | (SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_SDCLKFS(minpresc) | SDHC_SYSCTL_DVS(mindiv));presc is a single bit and div is a number
This includes the (untested case) that presc = 0 is valid input and that presc=0 does not prevent div to be effective. The way I calculate is if F_CPU=96 Mhz and baudrate is 3 kHz then ii=1 and jj=16 presc=1 and div = 15 and therefore 96MHz/((1<<presc)*(div+1)) = 3kHz
Can you agree?
-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/WMXZ-EU/uSDFS/issues/5#issuecomment-273284489
-- Tom Dunigan [email protected] http://tnlandforms.us