1 /*********************************************************************************************************//**
2  * @file    ht32f5xxxx_div.c
3  * @version $Rev:: 6656         $
4  * @date    $Date:: 2023-01-16 #$
5  * @brief   This file provides all the DIV firmware functions.
6  *************************************************************************************************************
7  * @attention
8  *
9  * Firmware Disclaimer Information
10  *
11  * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12  *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13  *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14  *    other intellectual property laws.
15  *
16  * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17  *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18  *    other than HOLTEK and the customer.
19  *
20  * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21  *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22  *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23  *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24  *
25  * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26  ************************************************************************************************************/
27 
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32f5xxxx_div.h"
30 
31 /** @addtogroup HT32F5xxxx_Peripheral_Driver HT32F5xxxx Peripheral Driver
32   * @{
33   */
34 
35 /** @defgroup DIV DIV
36   * @brief DIV driver modules
37   * @{
38   */
39 
40 /* Private constants ---------------------------------------------------------------------------------------*/
41 #define DIVCR_START     (0x00000001)
42 #define DIVCR_ZEF       (0x00000004)
43 #define DIVCR_COM       (0x00000008)
44 
45 /* Global variables ----------------------------------------------------------------------------------------*/
46 u32 guRemainder;
47 
48 /* Global functions ----------------------------------------------------------------------------------------*/
49 /** @defgroup DIV_Exported_Functions DIV exported functions
50   * @{
51   */
52 /*********************************************************************************************************//**
53  * @brief Deinitialize the DIV peripheral registers to their default reset values.
54  * @retval None
55  ************************************************************************************************************/
DIV_DeInit(void)56 void DIV_DeInit(void)
57 {
58   RSTCU_PeripReset_TypeDef RSTCUReset = {{0}};
59 
60   RSTCUReset.Bit.DIV = 1;
61   RSTCU_PeripReset(RSTCUReset, ENABLE);
62 }
63 
64 /*********************************************************************************************************//**
65  * @brief Calculate the Quotient of dividend/divisor.
66  * @param dividend
67  * @param divisor
68  * @retval The quotient of dividend/divisor
69  ************************************************************************************************************/
DIV_Div32(s32 dividend,s32 divisor)70 s32 DIV_Div32(s32 dividend, s32 divisor)
71 {
72   HT_DIV->DDR = dividend;
73   HT_DIV->DSR = divisor;
74   HT_DIV->CR = DIVCR_START;
75 
76   while ((HT_DIV->CR & DIVCR_COM) != DIVCR_COM);
77 
78   #if (DIV_ENABLE_DIVIDE_BY_ZERO_CHECK == 1)
79   {
80     if (DIV_IsDivByZero() == TRUE)
81     {
82       while (1);
83     }
84   }
85   #endif
86 
87   return (HT_DIV->QTR);
88 }
89 
90 /*********************************************************************************************************//**
91  * @brief Calculate the 32-bit unsigned of dividend/divisor.
92  * @param dividend
93  * @param divisor
94  * @retval The quotient of dividend/divisor
95  ************************************************************************************************************/
DIV_uDiv32(u32 dividend,u32 divisor)96 u32 DIV_uDiv32(u32 dividend, u32 divisor)
97 {
98   u32 uResult = 0;
99   guRemainder = 0;
100   if (dividend < divisor)
101   {
102     guRemainder = dividend;
103     return 0;
104   }
105 
106   if (dividend == divisor)
107   {
108     return 1;
109   }
110 
111   if (divisor & 0x80000000)
112   {
113     guRemainder = dividend - divisor;
114     return 1;
115   }
116 
117   if (dividend & 0x80000000)
118   {
119     HT_DIV->DDR = 0x7FFFFFFF;
120     HT_DIV->DSR = divisor;
121     HT_DIV->CR = DIVCR_START;
122 
123     while ((HT_DIV->CR & DIVCR_COM) != DIVCR_COM);
124     #if (DIV_ENABLE_DIVIDE_BY_ZERO_CHECK == 1)
125     {
126       if (DIV_IsDivByZero() == TRUE)
127       {
128         while (1);
129       }
130     }
131     #endif
132 
133     uResult = HT_DIV->QTR;
134     guRemainder = HT_DIV->RMR;
135     dividend -= 0x7FFFFFFF;
136   }
137 
138   HT_DIV->DDR = dividend;
139   HT_DIV->DSR = divisor;
140   HT_DIV->CR = DIVCR_START;
141 
142   while ((HT_DIV->CR & DIVCR_COM) != DIVCR_COM);
143   #if (DIV_ENABLE_DIVIDE_BY_ZERO_CHECK == 1)
144   {
145     if (DIV_IsDivByZero() == TRUE)
146     {
147       while (1);
148     }
149   }
150   #endif
151 
152   uResult += HT_DIV->QTR;
153   guRemainder += HT_DIV->RMR;
154 
155   if (guRemainder >= divisor)
156   {
157     guRemainder -= divisor;
158     uResult++;
159   }
160 
161   return uResult;
162 }
163 
164 /*********************************************************************************************************//**
165  * @brief  Retuen the remainder of last unsigned dividend/divisor calculatation.
166  * @retval guRemainder: The remainder of dividend/divisor
167  ************************************************************************************************************/
DIV_uGetLastRemainder(void)168 u32 DIV_uGetLastRemainder(void)
169 {
170   return guRemainder;
171 }
172 
173 /*********************************************************************************************************//**
174  * @brief  Calculate the remainder of dividend/divisor.
175  * @param dividend
176  * @param divisor
177  * @retval The remainder of dividend/divisor
178  ************************************************************************************************************/
DIV_Mod(s32 dividend,s32 divisor)179 s32 DIV_Mod(s32 dividend, s32 divisor)
180 {
181   DIV_Div32(dividend, divisor);
182 
183   return (HT_DIV->RMR);
184 }
185 
186 /*********************************************************************************************************//**
187  * @brief  Get Divide by Zero Case.
188  * @retval TRUE or FALSE
189  ************************************************************************************************************/
DIV_IsDivByZero(void)190 bool DIV_IsDivByZero(void)
191 {
192   if ((HT_DIV->CR & DIVCR_ZEF) == DIVCR_ZEF)
193   {
194     return TRUE;
195   }
196 
197   return FALSE;
198 }
199 
200 /**
201   * @}
202   */
203 
204 
205 /**
206   * @}
207   */
208 
209 /**
210   * @}
211   */
212