From edc320c043f848099636c84e627c5bf7ba82f2ad Mon Sep 17 00:00:00 2001 From: naga sureshkumar relli Date: Mon, 13 Apr 2015 17:48:25 +0530 Subject: [PATCH] uartns550: Clock Divisor Enhancement This patch fixes the bug in uart clock divisor when setting baud rate. Signed-off-by: naga sureshkumar relli --- .../drivers/uartns550/src/xuartns550.c | 18 ++++++++++++++---- .../drivers/uartns550/src/xuartns550.h | 1 + .../drivers/uartns550/src/xuartns550_l.c | 11 +++++++++-- .../drivers/uartns550/src/xuartns550_l.h | 1 + 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.c index d50ecc77..dc078661 100644 --- a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.c +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.c @@ -62,6 +62,13 @@ * XUartNs550_CfgInitialize function. Removed compiler * warnings for unused variables in the * XUartNs550_StubHandler. +* 3.3 nsk 04/13/15 Clock Divisor Enhancement. i.e when odd clock given +* as input clock, say 31.725MHz and Baud as 1000000 +* then divisor = (31725000) / (1000000 * 16), This returns +* 1.9828, since this is integer math, it becomes 1. +* Which is almost half of the necessary value. so +* we are truncating it to nearest integer. in our +* case 1.9828 rounded to 2. * * *****************************************************************************/ @@ -648,16 +655,19 @@ int XUartNs550_SetBaudRate(XUartNs550 *InstancePtr, u32 BaudRate) * rater based upon the input clock frequency and a baud clock prescaler * of 16 */ - Divisor = InstancePtr->InputClockHz / (BaudRate * 16UL); - + Divisor = ((InstancePtr->InputClockHz +((BaudRate * 16UL)/2)) / + (BaudRate * 16UL)); /* * check for too much error between the baud rate that will be generated * using the divisor and the expected baud rate, integer division also * truncates always positive */ TargetRate = Divisor * BaudRate * 16UL; - Error = InstancePtr->InputClockHz - TargetRate; - + if (TargetRate < InstancePtr->InputClockHz) { + Error = InstancePtr->InputClockHz - TargetRate; + } else { + Error = TargetRate - InstancePtr->InputClockHz; + } /* * Error has total error now compute the percentage multiplied by 100 to * avoid floating point calculations, should be less than 3% as per diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.h b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.h index 5ca28288..b609a790 100644 --- a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.h +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550.h @@ -159,6 +159,7 @@ * 3.2 adk 15/10/14 Fixed CR:824444 changes are made in the example file * xuartns550_intr_example.c. * 3.2 adk 15/10/14 Fixed CR:826435 changes are made in the driver tcl file. +* 3.3 nsk 04/13/15 Fixed CR:857013 changes are made in xuartns550.c * * *****************************************************************************/ diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c index c7fffaf4..c5083062 100644 --- a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.c @@ -49,6 +49,13 @@ * 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. * Updated to use HAL Processor APIs. _m is removed from the * name of all the macro definitions. +* 3.3 nsk 04/13/15 Clock Divisor Enhancement. i.e when odd clock given +* as inputclock, say 31.725MHz and Baud as 1000000 +* then divisor = (31725000) / (1000000 * 16), This returns +* 1.9828, since this is integer math, it becomes 1. +* Which is almost half of the necessary value. so +* we are truncating it to nearest integer. in our +* case 1.9828 rounded to 2. * * ******************************************************************************/ @@ -158,8 +165,8 @@ void XUartNs550_SetBaud(u32 BaseAddress, u32 InputClockHz, u32 BaudRate) * rater based upon the input clock frequency and a baud clock prescaler * of 16 */ - Divisor = InputClockHz / (BaudRate * 16UL); - + Divisor = ((InputClockHz +((BaudRate * 16UL)/2)) / + (BaudRate * 16UL)); /* * Get the least significant and most significant bytes of the divisor * so they can be written to 2 byte registers diff --git a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h index 94973fbd..8abca5f6 100644 --- a/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h +++ b/XilinxProcessorIPLib/drivers/uartns550/src/xuartns550_l.h @@ -50,6 +50,7 @@ * 2.00a ktn 10/20/09 Converted all register accesses to 32 bit access. * Updated to use HAL Processor APIs. _m is removed from the * name of all the macro definitions. +* 3.3 nsk 04/13/15 Fixed CR:857013 changes are made in xuartns550_l.c * * ******************************************************************************/