baudcalc.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include "config.h"
  5. static uint8_t uart_lookupratio(float f_fr) {
  6. uint16_t errors[72]={0,67,71,77,83,91,100,111,125,
  7. 133,143,154,167,182,200,214,222,231,
  8. 250,267,273,286,300,308,333,357,364,
  9. 375,385,400,417,429,444,455,462,467,
  10. 500,533,538,545,556,571,583,600,615,
  11. 625,636,643,667,692,700,714,727,733,
  12. 750,769,778,786,800,818,833,846,857,
  13. 867,875,889,900,909,917,923,929,933};
  14. uint8_t ratios[72]={0x10,0xf1,0xe1,0xd1,0xc1,0xb1,0xa1,0x91,0x81,
  15. 0xf2,0x71,0xd2,0x61,0xb2,0x51,0xe3,0x92,0xd3,
  16. 0x41,0xf4,0xb3,0x72,0xa3,0xd4,0x31,0xe5,0xb4,
  17. 0x83,0xd5,0x52,0xc5,0x73,0x94,0xb5,0xd6,0xf7,
  18. 0x21,0xf8,0xd7,0xb6,0x95,0x74,0xc7,0x53,0xd8,
  19. 0x85,0xb7,0xe9,0x32,0xd9,0xa7,0x75,0xb8,0xfb,
  20. 0x43,0xda,0x97,0xeb,0x54,0xb9,0x65,0xdb,0x76,
  21. 0xfd,0x87,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe};
  22. int fr = (f_fr-1)*1000;
  23. int i=0, i_result=0;
  24. int err=0, lasterr=1000;
  25. for(i=0; i<72; i++) {
  26. if(fr<errors[i]) {
  27. err=errors[i]-fr;
  28. } else {
  29. err=fr-errors[i];
  30. }
  31. if(err<lasterr) {
  32. i_result=i;
  33. lasterr=err;
  34. }
  35. }
  36. return ratios[i_result];
  37. }
  38. static uint32_t baud2divisor(unsigned int baudrate) {
  39. uint32_t int_ratio;
  40. uint32_t error;
  41. uint32_t dl=0;
  42. float f_ratio;
  43. float f_fr;
  44. float f_dl;
  45. float f_pclk = (float)CONFIG_CPU_FREQUENCY / CONFIG_UART_PCLKDIV;
  46. uint8_t fract_ratio;
  47. f_ratio=(f_pclk / 16 / baudrate);
  48. int_ratio = (int)f_ratio;
  49. error=(f_ratio*1000)-(int_ratio*1000);
  50. if(error>990) {
  51. int_ratio++;
  52. } else if(error>10) {
  53. f_fr=1.5;
  54. f_dl=f_pclk / (16 * baudrate * (f_fr));
  55. dl = (int)f_dl;
  56. f_fr=f_pclk / (16 * baudrate * dl);
  57. fract_ratio = uart_lookupratio(f_fr);
  58. }
  59. if(!dl) {
  60. return int_ratio;
  61. } else {
  62. return ((fract_ratio<<16)&0xff0000) | dl;
  63. }
  64. }
  65. int main(int argc, char *argv[])
  66. {
  67. if (argc != 2)
  68. {
  69. printf("usage: %s baud\n", argv[0]);
  70. return -1;
  71. }
  72. printf("Baud %d : 0x%X\n", atoi(argv[1]), baud2divisor(atoi(argv[1])));
  73. return 0;
  74. }