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

📄 hw_ser800.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  */#include "startup.h"#include <ppc/800cpu.h>#include <ppc/800cpm.h>// Receive buffer 8 * (16 bytes), send buffer 8 * (16 bytes)paddr32_t	ptrTxBD[6];paddr32_t	ptrRxBD[6];static voidparse_line(unsigned channel, const char *line, unsigned *baud,	unsigned *clk, unsigned *div, paddr_t *base) {// base holds the 800 chanel no, like smc1, scc2, etc.    if(*line != '.' && *line != '\0') {		if(line[1] == 'm' || line[1] == 'M') {			line += 3;			dbg_device[channel].base = *line++ - '1';		} else if(line[1] == 'c' || line[1] == 'C') {			line += 3;			dbg_device[channel].base = *line++ - '1' + 2;		}				if(*line == '^') dbg_device[channel].shift = strtoul(line+1, (char **)&line, 0);	}    if(*line == '.') ++line;    if(*line != '.' && *line != '\0') *baud = strtoul(line, (char **)&line, 0);    if(*line == '.') ++line;    if(*line != '.' && *line != '\0') *clk = strtoul(line, (char **)&line, 0);    if(*line == '.') ++line;    if(*line != '.' && *line != '\0') *div = strtoul(line, (char **)&line, 0);    if(*line == '.') ++line;    if(*line != '.' && *line != '\0') *base = strtopaddr(line, (char **)&line, 0);}static void sendCommand(uint16_t com,  PPC8CPM_CH_NUM port) {	static uint16_t chanelNo[6] = {PPC8CPM_CPCR_CH_SMC1DSP1,							PPC8CPM_CPCR_CH_SMC2DSP2,							PPC8CPM_CPCR_CH_SCC1,							PPC8CPM_CPCR_CH_SCC2,							PPC8CPM_CPCR_CH_SCC3,							PPC8CPM_CPCR_CH_SCC4};	// wait for the command register available	do {	} while(PPC800_IMMR(CPCR, 16) & PPC8CPM_CPCR_FLG);	// send command	PPC800_IMMR(CPCR, 16) = com | chanelNo[port] | PPC8CPM_CPCR_FLG;}static void setBuffers (PPC8CPM_CH_NUM port, uint32_t base) {	int i;	paddr32_t addrDPRAM, ptr;	static const paddr32_t addrBDT[6] = {		PPC8CPM_DPRAM_BDT_SMC1, 		PPC8CPM_DPRAM_BDT_SMC2, 		PPC8CPM_DPRAM_BDT_SCC1, 		PPC8CPM_DPRAM_BDT_SCC2, 		PPC8CPM_DPRAM_BDT_SCC3, 		PPC8CPM_DPRAM_BDT_SCC4,	};	static const paddr32_t addrDBuf[6] = {		PPC8CPM_DPRAM_DBUF_SMC1,		PPC8CPM_DPRAM_DBUF_SMC2,		PPC8CPM_DPRAM_DBUF_SCC1,		PPC8CPM_DPRAM_DBUF_SCC2,		PPC8CPM_DPRAM_DBUF_SCC3,		PPC8CPM_DPRAM_DBUF_SCC4	};	static const paddr32_t	baseParaRAM[6] = {		PPC8CPM_DPRAMPARA_SMC1_S,		PPC8CPM_DPRAMPARA_SMC2_S,		PPC8CPM_DPRAMPARA_SCC1_S,		PPC8CPM_DPRAMPARA_SCC2_S,		PPC8CPM_DPRAMPARA_SCC3_S,		PPC8CPM_DPRAMPARA_SCC4_S	};	paddr32_t dbuf, bdt;	addrDPRAM = (paddr32_t) &PPC800_IMMR(DPRAM, 8);	if(base < 0xffff) {		bdt = base;		dbuf = base + 0x100;	} else {		bdt = addrBDT[port];		dbuf = addrDBuf[port];	}	// relocate receive buffer	ptrRxBD[port] = ptr = addrDPRAM + bdt;	out32(ptr, ptr + PPC8CPM_BD_SIZE - addrDPRAM);	ptr += PPC8CPM_BD_SIZE;		for(i=0; i<PPC8CPM_UART_DBNUM_D; i++) {		out16(ptr, PPC8CPM_RXBD_E);		ptr += 2;		out16(ptr, 0);		ptr += 2;		out32(ptr, addrDPRAM+dbuf+PPC8CPM_UART_DBSIZE_D*i);		ptr += 4;			}	ptr -= PPC8CPM_BD_SIZE;	out16(ptr, PPC8CPM_RXBD_W|PPC8CPM_RXBD_E);	out16(addrDPRAM+baseParaRAM[port]+PPC8CPM_PARARAM_SCCSMC_RBASE,		ptrRxBD[port]-addrDPRAM + PPC8CPM_BD_SIZE); // start of real BDT is 8 bytes after	// set receive buffer size	out16(addrDPRAM+baseParaRAM[port]+PPC8CPM_PARARAM_SCCSMC_MRBLR,		1);	// set MAX_IDL	out16(addrDPRAM+baseParaRAM[port]+PPC8CPM_PARARAM_SCCUART_MAXIDL,		10);	// Init Control Characters table for SCCs	if(port > SMC2) 		out16(addrDPRAM+baseParaRAM[port]+PPC8CPM_PARARAM_SCCUART_CHARACTER1, PPC8CPM_PARARAM_SCCUART_CHAR_E);	// relocate transmit buffer	ptrTxBD[port] = ptr = addrDPRAM+bdt+PPC8CPM_BD_SIZE*(1+PPC8CPM_UART_DBNUM_D);	out32(ptr, ptr + PPC8CPM_BD_SIZE - addrDPRAM);	ptr += PPC8CPM_BD_SIZE;		for(i=0; i<PPC8CPM_UART_DBNUM_D; i++) {		out32(ptr, 0);		ptr += 4;		out32(ptr, addrDPRAM+dbuf+PPC8CPM_UART_DBSIZE_D*(PPC8CPM_UART_DBNUM_D+i));		ptr += 4;			}	ptr -= PPC8CPM_BD_SIZE;	out16(ptr, PPC8CPM_TXBD_W);	out16(addrDPRAM + baseParaRAM[port] + PPC8CPM_PARARAM_SCCSMC_TBASE,		ptrTxBD[port]-addrDPRAM + PPC8CPM_BD_SIZE);// start of real BDT is 8 bytes after	out16(addrDPRAM + baseParaRAM[port] + PPC8CPM_PARARAM_SCCSMC_RFCR,		0x1515);}voidinit_800cpm(unsigned channel, const char *init, const char *defaults) {	unsigned baud;	unsigned div;	unsigned clk;	unsigned cnt, value, brg;	paddr_t base = 0xffffffff;	PPC8CPM_CH_NUM port;	parse_line(channel, defaults, &baud, &clk, &div, &base);	parse_line(channel, init, &baud, &clk, &div, &base);	port = dbg_device[channel].base;	brg = dbg_device[channel].shift;	// set baudrate	cnt = (clk + ((baud * div) >> 1)) / (baud * div); // accurately	if(cnt < PPC8CPM_BRG_MAXCNT) {		value = PPC8CPM_BRG_EN | PPC8CPM_BRG_EXTC_BRGCLK			| PPC8CPM_BRG_CD((--cnt));	} else {		cnt = (cnt + 8) / 16;		value = PPC8CPM_BRG_EN | PPC8CPM_BRG_EXTC_BRGCLK			| PPC8CPM_BRG_CD((--cnt)) | PPC8CPM_BRG_DIV16;	}	switch(brg) {		case 0:			PPC800_IMMR(BRGC1, 32) = PPC8CPM_BRG_RST;			PPC800_IMMR(BRGC1, 32) = value;			PPC800_IMMR(BRGC1, 32) &= ~PPC8CPM_BRG_RST;			break;		case 1:			PPC800_IMMR(BRGC2, 32) = PPC8CPM_BRG_RST;			PPC800_IMMR(BRGC2, 32) = value;			PPC800_IMMR(BRGC2, 32) &= ~PPC8CPM_BRG_RST;			break;		case 2:			PPC800_IMMR(BRGC3, 32) = PPC8CPM_BRG_RST;			PPC800_IMMR(BRGC3, 32) = value;			PPC800_IMMR(BRGC3, 32) &= ~PPC8CPM_BRG_RST;			break;		case 3:			PPC800_IMMR(BRGC4, 32) = PPC8CPM_BRG_RST;			PPC800_IMMR(BRGC4, 32) = value;			PPC800_IMMR(BRGC4, 32) &= ~PPC8CPM_BRG_RST;			break;		default:			break;	}	switch(port) {		case SMC1:			// config GPIO			PPC800_IMMR(PBPAR, 32) |= _ONEBIT32B(24) | _ONEBIT32B(25);			// select mode and clock source			PPC800_IMMR(SIMODE, 32) &= ~(PPC8CPM_SIMODE_SMC1 | PPC8CPM_SIMODE_SMC1CSM);			PPC800_IMMR(SIMODE, 32) |= PPC8CPM_SIMODE_SMC1CS(brg);			// program for line paras: 8bits, no parity, & disable send/receive			PPC800_IMMR(SMCMR1, 16) = PPC8CPM_SMCMR_UART_SMUART	| PPC8CPM_SMCMR_UART_CLEN(8,0,1);			// disable int			PPC800_IMMR(SMCM1, 16) = 0;			break;		case SMC2:			// config GPIO		  	if(PPC800_GET_PARTNUM != PPC800_PARTNUM_860_821) {				PPC800_IMMR(PAPAR, 16) |= _ONEBIT16B(8) | _ONEBIT16B(9);			} else {				PPC800_IMMR(PBPAR, 32) |= _ONEBIT32B(20) | _ONEBIT32B(21);			}			// select mode and clock source			PPC800_IMMR(SIMODE, 32) &= ~(PPC8CPM_SIMODE_SMC2 | PPC8CPM_SIMODE_SMC2CSM);			PPC800_IMMR(SIMODE, 32) |= PPC8CPM_SIMODE_SMC2CS(brg);			// program for line paras: 8bits, no parity, & disable send/receive			PPC800_IMMR(SMCMR2, 16) = PPC8CPM_SMCMR_UART_SMUART	| PPC8CPM_SMCMR_UART_CLEN(8,0,1);			// disable int			PPC800_IMMR(SMCM2, 16) = 0;			break;		case SCC1:			// config GPIO			PPC800_IMMR(PAPAR, 32) |= _ONEBIT32B(14) | _ONEBIT32B(15);			// select mode and clock source			PPC800_IMMR(SICR, 32) &= ~(PPC8CPM_SICR_SC1 | PPC8CPM_SICR_R1CSM | PPC8CPM_SICR_T1CSM);			PPC800_IMMR(SICR, 32) |= PPC8CPM_SICR_R1CS(brg) | PPC8CPM_SICR_T1CS(brg);			// config GSMR			PPC800_IMMR(GSMR_H1, 32) = PPC8CPM_GSMR_H_RFW;			PPC800_IMMR(GSMR_L1, 32) = PPC8CPM_GSMR_L_TDCR16 | PPC8CPM_GSMR_L_RDCR16 | PPC8CPM_GSMR_L_MODEUART;			// program for line paras: 8bits, no parity 			PPC800_IMMR(PSMR1, 16) =	PPC8CPM_SCCMR_UART_CL8;			// disable int			PPC800_IMMR(SCCM1, 16) = 0;			break;		case SCC2:			// config GPIO			PPC800_IMMR(PAPAR, 32) |= _ONEBIT32B(12) | _ONEBIT32B(13);			// select mode and clock source			PPC800_IMMR(SICR, 32) &= ~(PPC8CPM_SICR_SC2 | PPC8CPM_SICR_R2CSM | PPC8CPM_SICR_T2CSM);			PPC800_IMMR(SICR, 32) |= PPC8CPM_SICR_R2CS(brg) | PPC8CPM_SICR_T2CS(brg);			// config GSMR			PPC800_IMMR(GSMR_H2, 32) = PPC8CPM_GSMR_H_RFW;			PPC800_IMMR(GSMR_L2, 32) = PPC8CPM_GSMR_L_TDCR16 | PPC8CPM_GSMR_L_RDCR16 | PPC8CPM_GSMR_L_MODEUART;			// program for line paras: 8bits, no parity 			PPC800_IMMR(PSMR2, 16) =	PPC8CPM_SCCMR_UART_CL8;			// disable int			PPC800_IMMR(SCCM2, 16) = 0;			break;		case SCC3:			// config GPIO			PPC800_IMMR(PAPAR, 32) |= _ONEBIT32B(10) | _ONEBIT32B(11);			// select mode and clock source			PPC800_IMMR(SICR, 32) &= ~(PPC8CPM_SICR_SC3 | PPC8CPM_SICR_R3CSM | PPC8CPM_SICR_T3CSM);			PPC800_IMMR(SICR, 32) |= PPC8CPM_SICR_R3CS(brg) | PPC8CPM_SICR_T3CS(brg);			// config GSMR			PPC800_IMMR(GSMR_H3, 32) = PPC8CPM_GSMR_H_RFW;			PPC800_IMMR(GSMR_L3, 32) = PPC8CPM_GSMR_L_TDCR16 | PPC8CPM_GSMR_L_RDCR16 | PPC8CPM_GSMR_L_MODEUART;			// program for line paras: 8bits, no parity 			PPC800_IMMR(PSMR3, 16) =	PPC8CPM_SCCMR_UART_CL8;			// disable int			PPC800_IMMR(SCCM3, 16) = 0;			break;		case SCC4:			// config GPIO			PPC800_IMMR(PAPAR, 32) |= _ONEBIT32B(8) | _ONEBIT32B(9);			// select mode and clock source			PPC800_IMMR(SICR, 32) &= ~(PPC8CPM_SICR_SC4 | PPC8CPM_SICR_R4CSM | PPC8CPM_SICR_T4CSM);			PPC800_IMMR(SICR, 32) |= PPC8CPM_SICR_R4CS(brg) | PPC8CPM_SICR_T4CS(brg);			// config GSMR			PPC800_IMMR(GSMR_H4, 32) = PPC8CPM_GSMR_H_RFW;			PPC800_IMMR(GSMR_L4, 32) = PPC8CPM_GSMR_L_TDCR16 | PPC8CPM_GSMR_L_RDCR16 | PPC8CPM_GSMR_L_MODEUART;			// program for line paras: 8bits, no parity 			PPC800_IMMR(PSMR4, 16) =	PPC8CPM_SCCMR_UART_CL8;			// disable int			PPC800_IMMR(SCCM4, 16) = 0;			break;		default:			break;	}	// set Rx TX buffers	setBuffers(port, base);	// reset para	sendCommand(PPC8CPM_CPCR_INITRXTX, port);	// enable send/receive	switch(port) {		case SMC1:			PPC800_IMMR(SMCMR1, 16) |= (PPC8CPM_SMCMR_UART_TEN | PPC8CPM_SMCMR_UART_REN);			break;		case SMC2:			PPC800_IMMR(SMCMR2, 16) |= (PPC8CPM_SMCMR_UART_TEN | PPC8CPM_SMCMR_UART_REN);			break;		case SCC1:			PPC800_IMMR(GSMR_L1, 32) |= (PPC8CPM_GSMR_L_ENR	| PPC8CPM_GSMR_L_ENT);			break;		case SCC2:			PPC800_IMMR(GSMR_L2, 32) |= (PPC8CPM_GSMR_L_ENR	| PPC8CPM_GSMR_L_ENT);			break;		case SCC3:			PPC800_IMMR(GSMR_L3, 32) |= (PPC8CPM_GSMR_L_ENR	| PPC8CPM_GSMR_L_ENT);			break;		case SCC4:			PPC800_IMMR(GSMR_L4, 32) |= (PPC8CPM_GSMR_L_ENR	| PPC8CPM_GSMR_L_ENT);			break;		default:			break;	}}voidput_800cpm(int c) {	PPC8CPM_CH_NUM	port = (PPC8CPM_CH_NUM) dbg_device[0].base;	paddr32_t		addrDPRAM = (paddr32_t) &PPC800_IMMR(DPRAM, 8);	paddr32_t		ptr = in32(ptrTxBD[port]) + addrDPRAM;	// waiting for the transmit buffer ready	do {	} while(in16(ptr) & PPC8CPM_TXBD_R);	// next available buffer	if(in16(ptr) & PPC8CPM_TXBD_W) {		out32(ptrTxBD[port], ptrTxBD[port] + PPC8CPM_BD_SIZE - addrDPRAM);	} else {		out32(ptrTxBD[port], ptr + PPC8CPM_BD_SIZE - addrDPRAM);	}	// Write a char to the buffer	out8(in32(ptr+PPC8CPM_BD_POINTER), c);	out16(ptr+PPC8CPM_BD_COUNT, 1);	out16(ptr, in16(ptr) | PPC8CPM_TXBD_R);}

⌨️ 快捷键说明

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