1 /**
2   ******************************************************************************
3   * @file    rtl8721d_flash_ram.c
4   * @author
5   * @version V1.0.0
6   * @date    2016-05-17
7   * @brief   This file provides firmware functions to manage the flash RAM functions.
8   ******************************************************************************
9   * @attention
10   *
11   * This module is a confidential and proprietary property of RealTek and
12   * possession or use of this module requires written permission of RealTek.
13   *
14   * Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
15   ******************************************************************************
16   */
17 
18 #include "ameba_soc.h"
19 
20 static u32 cpu_systick;
21 
22 /**
23   * @brief  This function is used to handle flash write ipc interrupt.
24   * @param Data: The pointer will be pass the IRQ handler
25   * @param IrqStatus: this specify the IPC_ISR.
26   * @param ChanNum: this specify the IPC channel number.
27   * @retval none
28   */
29 IMAGE2_RAM_TEXT_SECTION
FLASH_Write_IPC_Int(VOID * Data,u32 IrqStatus,u32 ChanNum)30 void FLASH_Write_IPC_Int(VOID *Data, u32 IrqStatus, u32 ChanNum)
31 {
32 	/* To avoid gcc warnings */
33 	( void ) Data;
34 	( void ) IrqStatus;
35 	( void ) ChanNum;
36 
37 	/*disable all interrupts first if primask is clear, or the CPU can't sleep*/
38 	if(__get_PRIMASK() == 0) {
39 		asm volatile ("cpsid i" : : : "memory");
40 		//asm volatile ("cpsid f" : : : "memory");
41 
42 		asm volatile ("wfe");
43 		asm volatile ("wfe");
44 
45 		asm volatile ("cpsie i" : : : "memory");
46 		//asm volatile ("cpsie f" : : : "memory");
47 	} else {
48 		asm volatile ("wfe");
49 		asm volatile ("wfe");
50 	}
51 }
52 
53 /**
54   * @brief  This function is used to lock CPU when write or erase flash under XIP.
55   * @note
56   *		- all interrupt include systick will be stopped.
57   * @retval none
58   */
59 IMAGE2_RAM_TEXT_SECTION
FLASH_Write_Lock(void)60 void FLASH_Write_Lock(void)
61 {
62 	u32 cpu_id = IPC_CPUID();
63 	u32 lp_sleep_state;
64 
65 	asm volatile ("cpsid i" : : : "memory");
66 	cpu_systick = SysTick->CTRL;	//disable systick exception
67 	SysTick->CTRL = 0;
68 
69 	//u32 hp_sleep_state;
70 	/*IPC request to let the other CPU sleep*/
71 	if (cpu_id == 1) {
72 		ipc_send_message(IPC_INT_CHAN_FLASHPG_REQ, (uint32_t)NULL);
73 		while(1) {
74 			lp_sleep_state = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_KM0_CTRL); 	/*get KM0 sleep status*/
75 			if(lp_sleep_state & BIT_KM0_SLEEPSYS) {
76 				break;
77 			}
78 		}
79 	} else {
80 #if defined (ARM_CORE_CM0)
81 		u32 hp_sleep_state;
82 		if(km4_status_on()) {
83 			ipc_send_message(IPC_INT_CHAN_FLASHPG_REQ, (uint32_t)NULL);
84 			while(1) {
85 				hp_sleep_state = HAL_READ32(SYSTEM_CTRL_BASE_HP, REG_HS_PLATFORM_PARA);	/*get KM4 sleep status*/
86 				if(hp_sleep_state & BIT_KM4_SLEEP_STATUS) {
87 					break;
88 				}
89 			}
90 		}
91 #endif
92 	}
93 }
94 
95 /**
96   * @brief  This function is used to unlock CPU after write or erase flash under XIP.
97   * @note
98   *		- all interrupt will be restored.
99   * @retval none
100   */
101 IMAGE2_RAM_TEXT_SECTION
FLASH_Write_Unlock(void)102 void FLASH_Write_Unlock(void)
103 {
104 	u32 cpu_id = IPC_CPUID();
105 	u32 lp_sleep_state;
106 	//u32 hp_sleep_state;
107 
108 	/*send an event using "sev" instruction to let the other CPU wake up*/
109 	asm volatile ("sev");
110 	if (cpu_id == 1) {
111 		while(1) {
112 			lp_sleep_state = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_KM0_CTRL);	/*get KM0 sleep status*/
113 			if(!(lp_sleep_state & BIT_KM0_SLEEPSYS)) {
114 				break;
115 			}
116 		}
117 	} else {
118 #if defined (ARM_CORE_CM0)
119 		u32 hp_sleep_state;
120 		if(km4_status_on()) {
121 			while(1) {
122 				hp_sleep_state = HAL_READ32(SYSTEM_CTRL_BASE_HP, REG_HS_PLATFORM_PARA);	/*get KM4 sleep status*/
123 				if(!(hp_sleep_state & BIT_KM4_SLEEP_STATUS)) {
124 					break;
125 				}
126 			}
127 		}
128 #endif
129 	}
130 
131 	SysTick->CTRL = cpu_systick;//restore systick exception
132 	asm volatile ("cpsie i" : : : "memory");
133 }
134 
135   /**
136   * @brief  This function is used to send Rx command to flash to get status register or flash id, and lock CPU when Rx
137   * @param  cmd: command that need to be sent.
138   * @param  read_len: the number of bytes that will be read by SPIC after sending cmd.
139   * @param  read_data: pointer to a byte array which is used to save received data.
140   * @note This function is only used for rx status/flash id ,not used for read flash data.
141   *		Only work in OneBitMode.
142   * @retval none
143   */
144 IMAGE2_RAM_TEXT_SECTION
FLASH_RxCmdXIP(u8 cmd,u32 read_len,u8 * read_data)145 void FLASH_RxCmdXIP(u8 cmd, u32 read_len, u8* read_data)
146 {
147 	FLASH_Write_Lock();
148 
149 	FLASH_RxCmd(cmd, read_len, read_data);
150 
151 	FLASH_Write_Unlock();
152 }
153 
154 /**
155   * @brief  FLASH_SetStatus used to set register status. FLASH_WriteEn & FLASH_WaitBusy, and lock CPU when set
156   *  		are included in this function to avoid hardfault when TxCmd in XIP
157   * @param    Cmd: command to be sent
158   * @param    Len: the number of bytes to be sent after Cmd
159   * @param    Status: pointer to byte array to be sent
160   * @retval     none
161   */
162 IMAGE2_RAM_TEXT_SECTION
FLASH_SetStatusXIP(u8 Cmd,u32 Len,u8 * Status)163 void FLASH_SetStatusXIP(u8 Cmd, u32 Len, u8* Status)
164 {
165 	FLASH_Write_Lock();
166 
167 	FLASH_SetStatus(Cmd, Len, Status);
168 
169 	FLASH_Write_Unlock();
170 }
171 
172 /**
173   * @brief  FLASH_SetStatusBits set or clear status bits., used to set protect bit or quad enable bit, and lock CPU when set
174   * @param    SetBits: 16bits valid, SetBits[7:0] is status1 & SetBits[15:8] is status2
175   * @param    NewState: ENABLE/DISABLE
176   * @retval none
177   */
178 IMAGE2_RAM_TEXT_SECTION
FLASH_SetStatusBitsXIP(u32 SetBits,u32 NewState)179 void FLASH_SetStatusBitsXIP(u32 SetBits, u32 NewState)
180 {
181 	FLASH_Write_Lock();
182 
183 	FLASH_SetStatusBits(SetBits, NewState);
184 
185 	FLASH_Write_Unlock();
186 }
187 
188 /**
189   * @brief  This function is used to write data to flash in OneBitMode and User Mode, and lock CPU when write.
190   * @param  StartAddr: Start address in flash from which SPIC writes.
191   * @param  DataPhaseLen: the number of bytes that SPIC sends in Data Phase.
192   * @param  pData: pointer to a byte array that is to be sent.
193   * @note
194   *		- page program(256B) time typical is 0.7ms: BaudRate=2.9Mbps, so one bit mode is enough.
195   *		- page program(12B) time typical is 20+2.5*11= 47.5us BaudRate = 2.02M bps, so program 12B once is enough.
196   *		- for compatibility with amebaz, which has 16-byte TX FIFO is 16 byte and max len is 16-cmdlen = 12 byte
197   * @retval none
198   */
199 IMAGE2_RAM_TEXT_SECTION
FLASH_TxData12BXIP(u32 StartAddr,u8 DataPhaseLen,u8 * pData)200 void FLASH_TxData12BXIP(u32 StartAddr, u8 DataPhaseLen, u8* pData)
201 {
202 	FLASH_Write_Lock();
203 
204 	FLASH_TxData12B(StartAddr, DataPhaseLen, pData);
205 	Cache_Flush();
206 
207 	FLASH_Write_Unlock();
208 }
209 
210 /**
211   * @brief  This function is used to erase flash, and lock CPU when erase.
212   * @param EraseType: can be one of the following  parameters:
213   		@arg EraseChip: Erase the whole chip.
214   		@arg EraseBlock: Erase specified block(64KB)
215   		@arg EraseSector: Erase specified sector(4KB)
216   * @param    Address should 4 byte align.The block/sector which
217   * 		the address in will be erased.
218   * @retval none
219   */
220 IMAGE2_RAM_TEXT_SECTION
FLASH_EraseXIP(u32 EraseType,u32 Address)221 void FLASH_EraseXIP(u32 EraseType, u32 Address)
222 {
223 	FLASH_Write_Lock();
224 
225 	FLASH_Erase(EraseType, Address);
226 	Cache_Flush();
227 
228 	FLASH_Write_Unlock();
229 }
230 
231 /**
232   * @brief  This function is used to erase some dwords, and keep other dwords unchanged in one sector.
233   * @param  address: Start address in flash to be erased.
234   * @param  dword_num: the number of dwords to be erased.
235   * @note
236   *		- this function is just used for change some dwords in one sector.
237   *		- this function will erase whole sector and then write back other dwords.
238   *		- please dont use this function if not needed !!!!!!!!!!!!!!
239   *		- FLASH_EraseXIP is recommended if need
240   * @retval none
241   */
242 IMAGE2_RAM_TEXT_SECTION
FLASH_EreaseDwordsXIP(u32 address,u32 dword_num)243 void FLASH_EreaseDwordsXIP(u32 address, u32 dword_num)
244 {
245 	u32 data[2];
246 	u32 idx = 0;
247 	u32 opt_sector = address & ~(0xFFF);
248 	u32 erase_addr = address;
249 	u32 erase_num = dword_num;
250 
251 	/* erase backup sector */
252 	FLASH_EraseXIP(EraseSector, FLASH_RESERVED_DATA_BASE);
253 
254 	/* backup this sector */
255 	for (idx = 0; idx < 0x1000; idx += 4) {
256 		u32 read_addr = opt_sector + idx;
257 
258 		_memcpy(data, (const void *)(SPI_FLASH_BASE + read_addr), 4);
259 
260 		if (erase_num > 0) {
261 			if (erase_addr == read_addr) {
262 				data[0] = 0xFFFFFFFF;
263 				erase_addr += 4;
264 				erase_num--;
265 			}
266 		}
267 
268 		FLASH_TxData12BXIP((FLASH_RESERVED_DATA_BASE + idx), 4, (u8*)data);
269 	}
270 
271 	/* erase this sector */
272 	FLASH_EraseXIP(EraseSector, opt_sector);
273 
274 	/* write this sector with target data erased */
275 	for (idx = 0; idx < 0x1000; idx += 8) {
276 		_memcpy(data, (const void *)(SPI_FLASH_BASE + FLASH_RESERVED_DATA_BASE + idx), 8);
277 		FLASH_TxData12BXIP((opt_sector + idx), 8, (u8*)data);
278 	}
279 }
280 
281 /**
282   * @brief  This function is used to write data to flash in OneBitMode and User Mode, and lock CPU when write.
283   * @param  StartAddr: Start address in flash from which SPIC writes.
284   * @param  DataPhaseLen: the number of bytes that SPIC sends in Data Phase.
285   * @param  pData: pointer to a byte array that is to be sent.
286   * @note
287   *		- page program(256B) time typical is 0.7ms: BaudRate=2.9Mbps, so one bit mode is enough.
288   *		- should use FLASH_SW_CS_Control to protect flash write
289   * @retval none
290   */
291 IMAGE2_RAM_TEXT_SECTION
FLASH_TxData256BXIP(u32 StartAddr,u32 DataPhaseLen,u8 * pData)292 void FLASH_TxData256BXIP(u32 StartAddr, u32 DataPhaseLen, u8* pData)
293 {
294 	FLASH_Write_Lock();
295 
296 	FLASH_TxData256B(StartAddr, DataPhaseLen, pData);
297 
298 	Cache_Flush();
299 	FLASH_Write_Unlock();
300 }
301 
302 /**
303   * @brief  Read a stream of data from specified address
304   * @param obj: Flash object define in application software.
305   * @param  address: Specifies the starting address to read from.
306   * @param  len: Specifies the length of the data to read.
307   * @param  data: Specified the address to save the readback data.
308   * @retval   status: Success:1 or Failure: Others.
309   * @note auto mode is ok, because we have flash cache
310   */
311 IMAGE2_RAM_TEXT_SECTION
FLASH_ReadStream(u32 address,u32 len,u8 * data)312 int  FLASH_ReadStream(u32 address, u32 len, u8 * data)
313 {
314 	assert_param(data != NULL);
315 
316 	u32 offset_to_align;
317 	u32 i;
318 	u32 read_word;
319 	u8 *ptr;
320 	u8 *pbuf;
321 
322 	offset_to_align = address & 0x03;
323 	pbuf = data;
324 	if (offset_to_align != 0) {
325 		/* the start address is not 4-bytes aligned */
326 		read_word = HAL_READ32(SPI_FLASH_BASE, (address - offset_to_align));
327 		ptr = (u8*)&read_word + offset_to_align;
328 		offset_to_align = 4 - offset_to_align;
329 		for (i=0;i<offset_to_align;i++) {
330 			*pbuf = *(ptr+i);
331 			pbuf++;
332 			len--;
333 			if (len == 0) {
334 				break;
335 			}
336 		}
337 	}
338 
339 	/* address = next 4-bytes aligned */
340 	address = (((address-1) >> 2) + 1) << 2;
341 
342 	ptr = (u8*)&read_word;
343 	if ((u32)pbuf & 0x03) {
344 		while (len >= 4) {
345 			read_word = HAL_READ32(SPI_FLASH_BASE, address);
346 			for (i=0;i<4;i++) {
347 				*pbuf = *(ptr+i);
348 				pbuf++;
349 			}
350 			address += 4;
351 			len -= 4;
352 		}
353 	} else {
354 		while (len >= 4) {
355 			*((u32 *)pbuf) = HAL_READ32(SPI_FLASH_BASE, address);
356 			pbuf += 4;
357 			address += 4;
358 			len -= 4;
359 		}
360 	}
361 
362 	if (len > 0) {
363 		read_word = HAL_READ32(SPI_FLASH_BASE, address);
364 		for (i=0;i<len;i++) {
365 			*pbuf = *(ptr+i);
366 			pbuf++;
367 		}
368 	}
369 
370 	return 1;
371 }
372 
373 /**
374   * @brief  Write a stream of data to specified address
375   * @param  address: Specifies the starting address to write to.
376   * @param  len: Specifies the length of the data to write.
377   * @param  data: Pointer to a byte array that is to be written.
378   * @retval   status: Success:1 or Failure: Others.
379   */
380 IMAGE2_RAM_TEXT_SECTION
FLASH_WriteStream(u32 address,u32 len,u8 * data)381 int  FLASH_WriteStream(u32 address, u32 len, u8 * data)
382 {
383 	// Check address: 4byte aligned & page(256bytes) aligned
384 	u32 page_begin = address &  (~0xff);
385 	u32 page_end = (address + len) & (~0xff);
386 	u32 page_cnt = ((page_end - page_begin) >> 8) + 1;
387 
388 	u32 addr_begin = address;
389 	u32 addr_end = (page_cnt == 1) ? (address + len) : (page_begin + 0x100);
390 	u32 size = addr_end - addr_begin;
391 	u8 *buffer = data;
392 	u8 write_data[12];
393 
394 	u32 offset_to_align;
395 	u32 read_word;
396 	u32 i;
397 
398 	FLASH_Write_Lock();
399 	while(page_cnt){
400 		offset_to_align = addr_begin & 0x3;
401 
402 		if(offset_to_align != 0){
403 			read_word = HAL_READ32(SPI_FLASH_BASE, addr_begin - offset_to_align);
404 			for(i = offset_to_align;i < 4;i++){
405 				read_word = (read_word &  (~(0xff << (8*i)))) |( (*buffer) <<(8*i));
406 				size--;
407 				buffer++;
408 				if(size == 0)
409 					break;
410 			}
411 			FLASH_TxData12B(addr_begin - offset_to_align, 4, (u8*)&read_word);
412 		}
413 
414 		addr_begin = (((addr_begin-1) >> 2) + 1) << 2;
415 		for(;size >= 12 ;size -= 12){
416 			_memcpy(write_data, buffer, 12);
417 			FLASH_TxData12B(addr_begin, 12, write_data);
418 
419 			buffer += 12;
420 			addr_begin += 12;
421 		}
422 
423 		for(;size >= 4; size -=4){
424 			_memcpy(write_data, buffer, 4);
425 			FLASH_TxData12B(addr_begin, 4, write_data);
426 
427 			buffer += 4;
428 			addr_begin += 4;
429 		}
430 
431 		if(size > 0){
432 			read_word = HAL_READ32(SPI_FLASH_BASE, addr_begin);
433 			for( i = 0;i < size;i++){
434 				read_word = (read_word & (~(0xff << (8*i)))) | ((*buffer) <<(8*i));
435 				buffer++;
436 			}
437 			FLASH_TxData12B(addr_begin, 4, (u8*)&read_word);
438 		}
439 
440 		page_cnt--;
441 		addr_begin = addr_end;
442 		addr_end = (page_cnt == 1) ? (address + len) : (((addr_begin>>8) + 1)<<8);
443 		size = addr_end - addr_begin;
444 	}
445 
446 	Cache_Flush();
447 	FLASH_Write_Unlock();
448 
449 	return 1;
450 }
451 
452 /**
453   * @brief    Configure SPIC IP Clock.
454   * @param  Source:  This parameter can be one of the following values:
455   *                            @arg BIT_SHIFT_FLASH_CLK_XTAL
456   *                            @arg BIT_SHIFT_FLASH_CLK_PLL
457   * @param  Protection:  if disable interrupt when switch clock:
458   * @retval   None
459   */
460 IMAGE2_RAM_TEXT_SECTION
FLASH_ClockSwitch(u32 Source,u32 Protection)461 void FLASH_ClockSwitch(u32 Source, u32 Protection)
462 {
463 	/* To avoid gcc warnings */
464 	( void ) Source;
465 	( void ) Protection;
466 #if defined (ARM_CORE_CM0)
467 	//SPIC_TypeDef *spi_flash = SPIC;
468 	u32 Temp = 0;
469 	u32 timeout = 20;
470 
471 	if (Protection) {
472 		asm volatile ("cpsid i" : : : "memory");
473 		//asm volatile ("cpsid f" : : : "memory");
474 		SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
475 	}
476 
477 	/* sequence should be followed strickly */
478 	if (Source == BIT_SHIFT_FLASH_CLK_XTAL) {
479 		/* 1. clock source switch to XTAL */
480 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_CLK_CTRL0);
481 		Temp &= ~(BIT_MASK_FLASH_CLK_SEL << BIT_SHIFT_FLASH_CLK_SEL);
482 		Temp |= Source;
483 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_LP_CLK_CTRL0, Temp);
484 		DelayUs(10);
485 
486 		/* 2. close 400M & 400MPS */
487 		Temp = HAL_READ32(PERI_ON_BASE, REG_LP_FLASH_CTRL);
488 		Temp &= ~(BIT_FLASH_CK_PS_DIV_EN | BIT_FLASH_CK_DIV_EN); /* disable clock ps div & disable clock div*/
489 		HAL_WRITE32(PERI_ON_BASE, REG_LP_FLASH_CTRL, Temp);
490 		FLASH_CalibrationNewCmd(DISABLE);
491 
492 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG);
493 		Temp &= ~BIT_EN_CK_400M;
494 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG, Temp);
495 
496 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG);
497 		Temp &= ~BIT_POW_CKGEN_400M;
498 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG, Temp);
499 
500 		/* 3. SPIC Dummy to low speed dummy */
501 		flash_init_para.FLASH_rd_sample_phase = SPIC_LOWSPEED_SAMPLE_PHASE;
502 		FLASH_SetSpiMode(&flash_init_para, flash_init_para.FLASH_cur_bitmode);
503 	} else if (Source == BIT_SHIFT_FLASH_CLK_PLL) {
504 		/* 1. enable 400M & 400MPS */
505 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG);
506 		Temp |= BIT_POW_CKGEN_400M;
507 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG, Temp);
508 
509 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG);
510 		Temp |= BIT_EN_CK_400M;
511 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_PLL_SYS_PS_REG, Temp);
512 
513 		FLASH_CalibrationNewCmd(ENABLE);
514 		Temp = HAL_READ32(PERI_ON_BASE, REG_LP_FLASH_CTRL);
515 		Temp |= (BIT_FLASH_CK_PS_DIV_EN | BIT_FLASH_CK_DIV_EN); /* enable clock ps div & enable clock div*/
516 		HAL_WRITE32(PERI_ON_BASE, REG_LP_FLASH_CTRL, Temp);
517 
518 		/* wait clock ready about 40us */
519 		while (timeout > 0) {
520 			timeout--;
521 			Temp = HAL_READ32(PERI_ON_BASE, REG_LP_FLASH_CTRL);
522 			if ((Temp & BIT_FLASH_PS_DIV_RDY) && (Temp & BIT_FLASH_DIV_RDY))
523 				break;
524 		}
525 
526 		/* 2. clock source switch */
527 		Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_CLK_CTRL0);
528 		Temp &= ~(BIT_MASK_FLASH_CLK_SEL << BIT_SHIFT_FLASH_CLK_SEL);
529 		Temp |= Source;
530 		HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_LP_CLK_CTRL0, Temp);
531 		DelayUs(10);
532 
533 		/* 3. SPIC Dummy to high speed dummy */
534 		flash_init_para.FLASH_rd_sample_phase = flash_init_para.FLASH_rd_sample_phase_cal;
535 		FLASH_SetSpiMode(&flash_init_para, flash_init_para.FLASH_cur_bitmode);
536 	}
537 
538 	if (Protection) {
539 		SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
540 		asm volatile ("cpsie i" : : : "memory");
541 		//asm volatile ("cpsie f" : : : "memory");
542 	}
543 #endif
544 }
545 
546 IMAGE2_RAM_TEXT_SECTION
FLASH_Invalidate_Auto_Write(void)547 void FLASH_Invalidate_Auto_Write(void)
548 {
549 	/* Auto write related bits in valid command register are all set to 0,
550 		just need to invalidate write single and write enable cmd in auto mode. */
551 	SPIC_TypeDef *spi_flash = SPIC;
552 
553 	/* Disable SPI_FLASH User Mode */
554 	spi_flash->ssienr = 0;
555 
556 	/* Invalidate write single and write enable cmd in auto mode */
557 	spi_flash->wr_single = 0x0;
558 	spi_flash->wr_enable = 0x0;
559 }
560 
561 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
562