1 /**************************************************************************//**
2  * @file     hbi.c
3  * @version  V3.00
4  * @brief    HyperBus Interface (HBI) driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10 
11 
12 /** @addtogroup Standard_Driver Standard Driver
13   @{
14 */
15 
16 /** @addtogroup HBI_Driver HBI Driver
17   @{
18 */
19 
20 #define WAIT_WHILE_RETURN(x, timeout, ret)   while(x){if((timeout)-- <= 0) return (ret);}
21 #define WAIT_WHILE_BREAK(x, timeout, err)   while(x){if((timeout)-- <= 0){g_HBI_i32ErrCode = (err); break;}}
22 
23 int32_t g_HBI_i32ErrCode = 0;       /*!< HBI global error code */
24 
25 /** @addtogroup HBI_EXPORTED_FUNCTIONS HBI Exported Functions
26   @{
27 */
28 
29 
30 /**
31   * @brief      Reset HBI Device
32   * @return     None
33   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
34   */
HBI_Reset(void)35 void HBI_Reset(void)
36 {
37     int32_t i32TimeOutCnt = HBI_TIMEOUT;
38 
39     HBI->CMD = HBI_CMD_RESET_HRAM;
40     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
41 }
42 
43 /**
44   * @brief      Exit from Hybrid sleep and deep Power down function
45   * @return     None
46   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
47   */
HBI_ExitHSAndDPD(void)48 void HBI_ExitHSAndDPD(void)
49 {
50     int32_t i32TimeOutCnt = HBI_TIMEOUT;
51 
52     HBI->CMD = HBI_CMD_EXIT_HS_PD;
53     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
54 }
55 
56 /**
57   * @brief      Read HyperRAM register space
58   * @param[in]  u32Addr  Address of HyperRAM register space
59   *                 - \ref HYPERRAM_ID_REG0       : 0x0000_0000 = Identification Register 0
60   *                 - \ref HYPERRAM_ID_REG1       : 0x0000_0002 = Identification Register 1
61   *                 - \ref HYPERRAM_CONFIG_REG0   : 0x0000_1000 = Configuration Register 0
62   *                 - \ref HYPERRAM_CONFIG_REG1   : 0x0000_1002 = Configuration Register 1
63   * @return   The data of HyperRAM register.
64   * @return   -1  An illeagal register space
65   * @return   -2  Wait Hyper RAM time-out
66   */
HBI_ReadHyperRAMReg(uint32_t u32Addr)67 int32_t HBI_ReadHyperRAMReg(uint32_t u32Addr)
68 {
69     int32_t i32TimeOutCnt = HBI_TIMEOUT;
70 
71     if( (u32Addr == HYPERRAM_ID_REG0) || (u32Addr == HYPERRAM_ID_REG1) || (u32Addr == HYPERRAM_CONFIG_REG0) || (u32Addr == HYPERRAM_CONFIG_REG1) )
72     {
73         HBI->ADR = u32Addr;
74         HBI->CMD = HBI_CMD_READ_HRAM_REGISTER;
75         WAIT_WHILE_RETURN(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
76         return *((uint16_t *)&HBI->RDATA);
77     }
78     else
79     {
80         return -1;
81     }
82 }
83 
84 /**
85   * @brief      Write HyperRAM register space
86   * @param[in]  u32Addr  Address of HyperRAM register space
87   *                 - \ref HYPERRAM_ID_REG0       : 0x0000_0000 = Identification Register 0
88   *                 - \ref HYPERRAM_ID_REG1       : 0x0000_0002 = Identification Register 1
89   *                 - \ref HYPERRAM_CONFIG_REG0   : 0x0000_1000 = Configuration Register 0
90   *                 - \ref HYPERRAM_CONFIG_REG1   : 0x0000_1002 = Configuration Register 1
91   * @param[in]
92   * @return   0   success.
93   * @return   -1  An illeagal register space
94   * @return   -2  Wait Hyper RAM time-out
95   */
HBI_WriteHyperRAMReg(uint32_t u32Addr,uint32_t u32Value)96 int32_t HBI_WriteHyperRAMReg(uint32_t u32Addr, uint32_t u32Value)
97 {
98     int32_t i32TimeOutCnt = HBI_TIMEOUT;
99 
100     if( (u32Addr == HYPERRAM_ID_REG0) || (u32Addr == HYPERRAM_ID_REG1) || (u32Addr == HYPERRAM_CONFIG_REG0) || (u32Addr == HYPERRAM_CONFIG_REG1) )
101     {
102         HBI->ADR = u32Addr;
103         HBI->WDATA = u32Value;
104         HBI->CMD = HBI_CMD_WRITE_HRAM_REGISTER;
105         WAIT_WHILE_RETURN(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
106         return 0;
107     }
108     else
109     {
110         return -1;
111     }
112 }
113 
114 /**
115   * @brief      Read 2 Bytes from HyperRAM space
116   * @param[in]  u32Addr  Address of HyperRAM space
117   * @return     The 16 bit data of HyperRAM space.
118   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
119   */
HBI_Read2Byte(uint32_t u32Addr)120 uint32_t HBI_Read2Byte(uint32_t u32Addr)
121 {
122     int32_t i32TimeOutCnt = HBI_TIMEOUT;
123 
124     if(u32Addr & 0x1)
125     {
126         g_HBI_i32ErrCode = HBI_ERR_ALIGN;
127     }
128 
129     HBI->ADR = u32Addr;
130     HBI->CMD = HBI_CMD_READ_HRAM_2_BYTE;
131     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
132     return *((uint16_t *)&HBI->RDATA);
133 }
134 
135 /**
136   * @brief      Read 4 bytes from HyperRAM space
137   * @param[in]  u32Addr  Address of HyperRAM space
138   * @return     The 32bit data of HyperRAM space.
139   */
HBI_Read4Byte(uint32_t u32Addr)140 uint32_t HBI_Read4Byte(uint32_t u32Addr)
141 {
142     int32_t i32TimeOutCnt = HBI_TIMEOUT;
143 
144     if(u32Addr & 0x3)
145     {
146         g_HBI_i32ErrCode = HBI_ERR_ALIGN;
147     }
148 
149     HBI->ADR = u32Addr;
150     HBI->CMD = HBI_CMD_READ_HRAM_4_BYTE;
151     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
152     return HBI->RDATA;
153 }
154 
155 /**
156   * @brief      Write 1 byte to HyperRAM space
157   * @param[in]  u32Addr  Address of HyperRAM space
158   * @param[in]  u8Data   8 bits data to be written to HyperRAM space
159   * @return     None.
160   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
161   */
HBI_Write1Byte(uint32_t u32Addr,uint8_t u8Data)162 void HBI_Write1Byte(uint32_t u32Addr, uint8_t u8Data)
163 {
164     int32_t i32TimeOutCnt = HBI_TIMEOUT;
165 
166     HBI->ADR = u32Addr;
167     HBI->WDATA = u8Data;
168     HBI->CMD = HBI_CMD_WRITE_HRAM_1_BYTE;
169     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
170 }
171 
172 /**
173   * @brief      Write 2 bytes to HyperRAM space
174   * @param[in]  u32Addr  Address of HyperRAM space
175   * @param[in]  u16Data  16 bits data to be written to HyperRAM space
176   * @return     None.
177   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
178   */
HBI_Write2Byte(uint32_t u32Addr,uint16_t u16Data)179 void HBI_Write2Byte(uint32_t u32Addr, uint16_t u16Data)
180 {
181     int32_t i32TimeOutCnt = HBI_TIMEOUT;
182 
183     if(u32Addr & 0x1)
184     {
185         g_HBI_i32ErrCode = HBI_ERR_ALIGN;
186     }
187 
188     HBI->ADR = u32Addr;
189     HBI->WDATA = u16Data;
190     HBI->CMD = HBI_CMD_WRITE_HRAM_2_BYTE;
191     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
192 }
193 
194 /**
195   * @brief      Write 3 bytes to HyperRAM space
196   * @param[in]  u32Addr  Address of HyperRAM space
197   * @param[in]  u32Data  24 bits data to be written to HyperRAM space
198   * @return     None.
199   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
200   */
HBI_Write3Byte(uint32_t u32Addr,uint32_t u32Data)201 void HBI_Write3Byte(uint32_t u32Addr, uint32_t u32Data)
202 {
203     int32_t i32TimeOutCnt = HBI_TIMEOUT;
204 
205     HBI->ADR = u32Addr;
206     HBI->WDATA = u32Data;
207     HBI->CMD = HBI_CMD_WRITE_HRAM_3_BYTE;
208     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
209 }
210 
211 /**
212   * @brief      Write 4 byte to HyperRAM space
213   * @param[in]  u32Addr  Address of HyperRAM space
214   * @param[in]  u32Data  32 bits data to be written to HyperRAM space
215   * @return     None.
216   * @note       This function sets g_HBI_i32ErrCode to HBI_ERR_TIMEOUT if waiting Hyper RAM time-out.
217   */
HBI_Write4Byte(uint32_t u32Addr,uint32_t u32Data)218 void HBI_Write4Byte(uint32_t u32Addr, uint32_t u32Data)
219 {
220     int32_t i32TimeOutCnt = HBI_TIMEOUT;
221     if(u32Addr & 0x3)
222     {
223         g_HBI_i32ErrCode = HBI_ERR_ALIGN;
224     }
225 
226     HBI->ADR = u32Addr;
227     HBI->WDATA = u32Data;
228     HBI->CMD = HBI_CMD_WRITE_HRAM_4_BYTE;
229     WAIT_WHILE_BREAK(HBI->CMD != HBI_CMD_HRAM_IDLE, i32TimeOutCnt, HBI_ERR_TIMEOUT);
230 }
231 
232 
233 /*@}*/ /* end of group HBI_EXPORTED_FUNCTIONS */
234 
235 /*@}*/ /* end of group HBI_Driver */
236 
237 /*@}*/ /* end of group Standard_Driver */
238