⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skyeye_mach_s3c44b0x.c

📁 skyeye for pxa270
💻 C
📖 第 1 页 / 共 3 页
字号:
					*pUrxh = (ARMword)pUfifo->rx[0];				} else { /* non FIFO mode */					*pUtrstat &= ~0x1;				}			}			break;		case UBRDIV0:			*data = io.ubrdiv0;			break;		case UBRDIV1:			*data = io.ubrdiv1;			break;		default:			break;	}	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_uart_write(ARMul_State *state, ARMword addr, ARMword data){	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	switch (addr) {		case ULCON0:			io.ulcon0 = data;			break;		case ULCON1:			io.ulcon1 = data;			break;		case UCON0:			io.ucon0 = data;			break;		case UCON1:			io.ucon1 = data;			break;		case UFCON0:		case UFCON1:			{				ARMword *pUfcon = (addr == UFCON0 ? &io.ufcon0 : &io.ufcon1);				*pUfcon = (data & ~0x6);				if (!((data & 0x1) == 0 || (data & 0x6) == 0)) {					ARMword *pUfstat = (addr == UFCON0 ? &io.ufstat0 : &io.ufstat1);					if (data & 0x2) *pUfstat &= ~0x10f; /* Rx FIFO reset */					if (data & 0x4) *pUfstat &= ~0x2f0; /* Tx FIFO reset */				}			}			break;		case UMCON0:			io.umcon0 = data;			break;		case UMCON1:			io.umcon1 = data;			break;		case UTXH0:		case UTXH1:			{				ARMword *pUtrstat = (addr == UTXH0 ? &io.utrstat0 : &io.utrstat1);				ARMword *pUcon = (addr == UTXH0 ? &io.ucon0 : &io.ucon1);				ARMword *pUfcon = (addr == UTXH0 ? &io.ufcon0 : &io.ufcon1);				char tmp = data & 0xff;#if 0				/* Disabled the line to show some messages when booting use incorrect bootrom */				if ((*pUcon & 0xc) == 0x0) break;#endif				if (*pUfcon & 0x1) { /* FIFO mode */					ARMword *pUfstat = (addr == UTXH0 ? &io.ufstat0 : &io.ufstat1);					if ((*pUfstat & 0x200) == 0) { /* FIFO not full */						struct s3c44b0x_uart_fifo *pUfifo = (addr == UTXH0 ? &io.ufifo0 : &io.ufifo1);						int count = ((*pUfstat >> 4) & 0xf);						pUfifo->tx[count++] = tmp;						*pUfstat &= ~0xf0;						*pUfstat |= (count == 16 ? 0x2f0 : (count << 4));					}				} else { /* non FIFO mode */					skyeye_uart_write(addr == UTXH0 ? 0 : 1, (void*)&tmp, 1, NULL);					*pUtrstat |= 0x6;					if ((*pUcon & 0xc) == 0x4) { /* Transmit Mode: Interrupt request or polling mode */						s3c44b0x_set_interrupt(addr == UTXH0 ? INT_UTXD0 : INT_UTXD1);					}				}			}			break;		case UBRDIV0:			io.ubrdiv0 = data;			break;		case UBRDIV1:			io.ubrdiv1 = data;			break;		default:			break;	}}/* Timer Routine */static int s3c44b0x_timer_check_state(int timer_index, int op_code){	int bit_offset;	if (timer_index == 5) {		switch (op_code) {			case TIMER_OP_START:				bit_offset = 24;				break;			case TIMER_OP_MANUAL:				bit_offset = 25;				break;			case TIMER_OP_RELOAD:				bit_offset = 26;				break;			default:				return 0; /* invalid */		}	} else {		bit_offset = op_code + (timer_index == 0 ? 0 : 8 + 4 * (timer_index - 1));	}	return (io.tcon & (0x1 << bit_offset));}static void s3c44b0x_timer_do_cycle(ARMul_State *state){	int i, cnt_down, cnt_divider;	for (i = 0; i < 6; i++) {		if (s3c44b0x_timer_check_state(i, TIMER_OP_START) == 0) continue;		cnt_divider = (io.tprescaler[i] + 1) << io.tdivider[i];		cnt_down = TIMER_COUNT_DOWN_PER_CYCLE / cnt_divider;		if (cnt_down == 0) {			if (io.tcnt_scaler[i] == 0) {				io.tcnt_scaler[i] = cnt_divider / TIMER_COUNT_DOWN_PER_CYCLE;				continue;			} else if ((io.tcnt_scaler[i] -= 1) != 0) {				continue;			}			cnt_down = 1;		}		if ((io.tcnt[i] -= min(io.tcnt[i], cnt_down)) > 0) continue;		if (((io.tcfg1 >> 24) & 0xf) == i + 1) { /* BDMA request */			do {				if (s3c44b0x_dma_is_valid(3) != 1) break;				if (((DMA_CCNT(io.dma[3]) >> 30) & 0x3) != 0x1) break;				s3c44b0x_dma_proccess(state, 3);			} while (0);		} else { /* interrupt mode */			s3c44b0x_set_interrupt(INT_TIMER0 - i);		}		if (s3c44b0x_timer_check_state(i, TIMER_OP_RELOAD) == 0) continue;		io.tcnt[i] = io.tcntb[i];		if (i < 5) io.tcmp[i] = io.tcmpb[i];	}	if (io.wtcon & 0x20) {		cnt_divider = (io.tprescaler[6] + 1) << io.tdivider[6];		cnt_down = TIMER_COUNT_DOWN_PER_CYCLE / cnt_divider;		if (cnt_down == 0) {			if (io.tcnt_scaler[6] == 0) {				io.tcnt_scaler[6] = cnt_divider / TIMER_COUNT_DOWN_PER_CYCLE;				goto next;			} else if ((io.tcnt_scaler[6] -= 1) != 0) {				goto next;			}			cnt_down = 1;		}		if ((io.wtcnt -= min(io.wtcnt, cnt_down)) > 0) return;		if ((io.wtcon & 0x4) != 0) { /* interrupt mode */			s3c44b0x_set_interrupt(INT_WDT);		}		if (io.wtcon & 0x1) { /* asserts reset signal */			state->NresetSig = LOW;			PRINT("****************** WATCHDOG RESET ******************\n");		}		io.wtcnt = io.wtdat;	}next:	return;}static void s3c44b0x_timer_read(ARMword addr, ARMword *data){	switch (addr) {		case TCFG0:			*data = io.tcfg0;			break;		case TCFG1:			*data = io.tcfg1;			break;		case TCON:			*data = io.tcon;			break;		case TCNTB0:		case TCNTB1:		case TCNTB2:		case TCNTB3:		case TCNTB4:		case TCNTB5:			*data = io.tcntb[(addr - TCNTB0) / 0xc];			break;		case TCMPB0:		case TCMPB1:		case TCMPB2:		case TCMPB3:		case TCMPB4:			*data = io.tcmpb[(addr - TCMPB0) / 0xc];			break;		case TCNTO0:		case TCNTO1:		case TCNTO2:		case TCNTO3:		case TCNTO4:			*data = io.tcnt[(addr - TCNTO0) / 0xc];			break;		case TCNTO5:			*data = io.tcnt[5];			break;		case WTCON:			*data = io.wtcon;			break;		case WTDAT:			*data = io.wtdat;			break;		case WTCNT:			*data = io.wtcnt;			break;		default:			break;	}	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_timer_write(ARMul_State *state, ARMword addr, ARMword data){	int i, prescaler, divider;	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	switch (addr) {		case TCFG0:		case TCFG1:			if (addr == TCFG0) {				io.tcfg0 = data;			} else {				io.tcfg1 = data;			}			for (i = 0; i < 6; i++) {				io.tprescaler[i] = ((io.tcfg0 >> ((i >> 1) << 3)) & 0xff);				io.tdivider[i] = min(4, ((io.tcfg1 >> (i << 2)) & 0xf));			}			break;		case TCON:			io.tcon = data;			for (i = 0; i < 6; i++) {				if (s3c44b0x_timer_check_state(i, TIMER_OP_MANUAL) != 0) {					io.tcnt[i] = io.tcntb[i];					if (i < 5) io.tcmp[i] = io.tcmpb[i];				}			}			break;		case TCNTB0:		case TCNTB1:		case TCNTB2:		case TCNTB3:		case TCNTB4:		case TCNTB5:			io.tcntb[(addr - TCNTB0) / 0xc] = min(data, 0xffff);			break;		case TCMPB0:		case TCMPB1:		case TCMPB2:		case TCMPB3:		case TCMPB4:			io.tcmpb[(addr - TCMPB0) / 0xc] = data;			break;		case WTCON:			io.wtcon = data;			io.tprescaler[6] = ((io.wtcon >> 8) & 0xff);			io.tdivider[6] = ((io.wtcon >> 3) & 0x3) + 4;			break;		case WTDAT:			io.wtdat = data;			break;		case WTCNT:			io.wtcnt = data;			break;		default:			break;	}}/* I/O Ports Routine */static void s3c44b0x_ports_read(ARMword addr, ARMword *data){	/* TODO */	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_ports_write(ARMul_State *state, ARMword addr, ARMword data){	/* TODO */	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);}/* RTC Routine */static void s3c44b0x_rtc_do_cycle(ARMul_State *state){	if ((io.rtcalm & 0x40) != 0 && (io.rtcalm & 0x3f) != 0) {		struct timeval curr_time;		struct tm *curr_tm;		time_t curr_timer;		unsigned int almen = 0;		if (gettimeofday(&curr_time, NULL) != 0 ||		    ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)),		     (curr_tm = gmtime(&curr_timer))) == NULL) return;		if (curr_tm->tm_sec >= io.rtc_alarm.tm_sec) almen |= 0x1;		if (curr_tm->tm_min == io.rtc_alarm.tm_min) almen |= 0x2;		if (curr_tm->tm_hour == io.rtc_alarm.tm_hour) almen |= 0x4;		if (curr_tm->tm_mday == io.rtc_alarm.tm_mday) almen |= 0x8;		if (curr_tm->tm_mon == io.rtc_alarm.tm_mon) almen |= 0x10;		if (curr_tm->tm_year == io.rtc_alarm.tm_year) almen |= 0x20;		if ((io.rtcalm & 0x3f) == almen) {			io.rtcalm &= 0x3f;			s3c44b0x_set_interrupt(INT_RTC);		}	}	if ((io.ticint & 0x80) != 0) { /* WARNING: RTC tick is unexacting */		if (io.tick_count > 0) io.tick_count -= 1;		if (io.tick_count == 0) s3c44b0x_set_interrupt(INT_TICK);	}}static void s3c44b0x_rtc_read(ARMword addr, ARMword *data){	struct timeval curr_time;	struct tm *curr_tm;	time_t curr_timer;	if (addr == RTCCON) {		*data = io.rtccon;		goto exit;	} else if ((io.rtccon & 0x1) == 0) {		goto exit;	}	switch (addr) {		case RTCALM:			*data = io.rtcalm;			goto exit;		case RTCRST:			*data = io.rtcrst;			goto exit;		case TICINT:			*data = io.ticint;			goto exit;		case ALMSEC:			*data = BIN_TO_BCD(io.rtc_alarm.tm_sec);			goto exit;		case ALMMIN:			*data = BIN_TO_BCD(io.rtc_alarm.tm_min);			goto exit;		case ALMHOUR:			*data = BIN_TO_BCD(io.rtc_alarm.tm_hour);			goto exit;		case ALMDAY:			*data = BIN_TO_BCD(io.rtc_alarm.tm_mday);			goto exit;		case ALMMON:			*data = BIN_TO_BCD(io.rtc_alarm.tm_mon + 1);			goto exit;		case ALMYEAR:			*data = io.rtc_alarm.tm_year - 100;			goto exit;		default:			break;	}	if (gettimeofday(&curr_time, NULL) != 0 ||	    ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)),	     (curr_tm = gmtime(&curr_timer))) == NULL) goto exit;	switch (addr) {		case BCDSEC:			*data = BIN_TO_BCD(curr_tm->tm_sec);			break;		case BCDMIN:			*data = BIN_TO_BCD(curr_tm->tm_min);			break;		case BCDHOUR:			*data = BIN_TO_BCD(curr_tm->tm_hour);			break;		case BCDDAY:			*data = BIN_TO_BCD(curr_tm->tm_mday);			break;		case BCDDATE:			*data = (curr_tm->tm_wday == 0 ? 7 : curr_tm->tm_wday);			break;		case BCDMON:			*data = BIN_TO_BCD(curr_tm->tm_mon + 1);			break;		case BCDYEAR:			*data = curr_tm->tm_year - 100;			break;		default:			goto exit;	}exit:	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);	return;}static void s3c44b0x_rtc_write(ARMul_State *state, ARMword addr, ARMword data){	struct timeval curr_time;	struct tm *curr_tm;	time_t curr_timer;	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	if (addr == RTCCON) {		io.rtccon = data;		goto exit;	} else if ((io.rtccon & 0x1) == 0) {		goto exit;	}	switch (addr) {		case RTCALM:			io.rtcalm = data;			goto exit;		case RTCRST:			io.rtcrst = data;			goto exit;		case TICINT:			io.ticint = data;			io.tick_count = (data & 0x7f);			io.tick_count *= (CYCLE_TIMES_PER_SECOND / 128); /* 1/128 sec per count down */			goto exit;		case ALMSEC:			io.rtc_alarm.tm_sec = BCD_TO_BIN(data);			goto exit;		case ALMMIN:			io.rtc_alarm.tm_min = BCD_TO_BIN(data);			goto exit;		case ALMHOUR:			io.rtc_alarm.tm_hour = BCD_TO_BIN(data);			goto exit;		case ALMDAY:			io.rtc_alarm.tm_mday = BCD_TO_BIN(data);			goto exit;		case ALMMON:			io.rtc_alarm.tm_mon = BCD_TO_BIN(data) - 1;			goto exit;		case ALMYEAR:			io.rtc_alarm.tm_year = data + 100;			goto exit;		default:			break;	}	if (gettimeofday(&curr_time, NULL) != 0 ||	    ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)),	     (curr_tm = gmtime(&curr_timer))) == NULL) goto exit;	switch (addr) {		case BCDSEC:			curr_tm->tm_sec = BCD_TO_BIN(data);			break;		case BCDMIN:			curr_tm->tm_min = BCD_TO_BIN(data);			break;		case BCDHOUR:			curr_tm->tm_hour = BCD_TO_BIN(data);			break;		case BCDDAY:			curr_tm->tm_mday = BCD_TO_BIN(data);			break;		case BCDDATE:			break;		case BCDMON:			curr_tm->tm_mon = BCD_TO_BIN(data) - 1;			break;		case BCDYEAR:			curr_tm->tm_mon = data + 100;			break;		default:			goto exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -