[U-Boot] [PATCH] inka4x0: Add hardware diagnosis functions for inka4x0

Wolfgang Denk wd at denx.de
Tue Mar 24 23:50:35 CET 2009


Dear Detlev Zundel,

In message <1237914158-15693-6-git-send-email-dzu at denx.de> you wrote:
> This patch adds advanced diagnosis functions for the inka4x0 board.
> 
> Signed-off-by: Andreas Pfefferle <ap at denx.de>
> Signed-off-by: Detlev Zundel <ap at denx.de>
...
> +	extern int inkadiag_init_r (void);
> +	/*
> +	  * The command table used for the subcommands of inkadiag
> +	  * needs to be relocated manually.
> +	  */

Incorrect multiline comment style?

> +}
> +
>  int misc_init_f (void)
>  {
>  	char tmp[10];
> diff --git a/board/inka4x0/inkadiag.c b/board/inka4x0/inkadiag.c
> new file mode 100644
> index 0000000..bdbf652
...
> +#define LED_HIGH(NUM) \
> +    do { \
> +	    out_be32((unsigned *)MPC5XXX_GPT##NUM##_ENABLE,		\
> +		     in_be32((unsigned *)MPC5XXX_GPT##NUM##_ENABLE) | 0x10); \
> +    } while (0)

Please use:

	setbits_be32 ((unsigned *)MPC5XXX_GPT##NUM##_ENABLE,  0x10); 

instead (and so on in the rest of the code).

> +		struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
> +		if (which == 1) {
> +			/* drawer1 */
> +			if (state) {
> +				gpio->simple_dvo &= ~0x1000;
> +				udelay(1);
> +				gpio->simple_dvo |= 0x1000;
> +			} else {
> +				gpio->simple_dvo |= 0x1000;
> +				udelay(1);
> +				gpio->simple_dvo &= ~0x1000;
> +			}
> +		}
> +		if (which == 2) {
> +			/* drawer 2 */
> +			if (state) {
> +				gpio->simple_dvo &= ~0x2000;
> +				udelay(1);
> +				gpio->simple_dvo |= 0x2000;
> +			} else {
> +				gpio->simple_dvo |= 0x2000;
> +				udelay(1);
> +				gpio->simple_dvo &= ~0x2000;

Please use accessor functions to write to I/O ports.

...
> +static int ser_init(volatile struct mpc5xxx_psc *psc, int baudrate)
> +{
> +	unsigned long baseclk;
> +	int div;
> +
> +	/* reset PSC */
> +	psc->command = PSC_SEL_MODE_REG_1;

Should we not use accessor function to access the device registers
(here and in the following code) ?

> +static int do_inkadiag_serial(cmd_tbl_t *cmdtp, int flag, int argc,
> +			      char *argv[]) {
> +	if (argc < 5) {
> +		cmd_usage(cmdtp);
> +		return 1;
> +	}
> +
> +	argc--;
> +	argv++;
> +
> +	unsigned int num = simple_strtol(argv[0], NULL, 0);

Please NEVER declare variables right in the middle of the code!!

Did this actually pass a compile test?

> +	if (num < 0 || num > 11) {
> +		printf("invalid argument for num: %d\n", num);
> +		return -1;
> +	}
> +
> +	unsigned int mode = simple_strtol(argv[1], NULL, 0);
> +
> +	int combrd = 0;
> +	int baudrate = simple_strtoul(argv[2], NULL, 10);
> +	int i;

Ditto.

...
> +		if (mode & 4) {
> +			/* set data terminal ready */
> +			serial_out(num, UART_MCR, UART_MCR_DTR);
> +			udelay(10);
> +			/* check data set ready and carrier detect */
> +			if ((serial_in(num, UART_MSR) &
> +			     (UART_MSR_DSR | UART_MSR_DCD))
> +			    != (UART_MSR_DSR | UART_MSR_DCD))
> +				return -1;
> +		}
> +
> +		/* write each message-character, read it back, and display it */
> +		int i, len = strlen(argv[3]);

Ditto. Please make sure to fix this globally.

> +		for (i = 0; i < len; ++i) {
> +			int j = 0;
> +			while ((serial_in(num, UART_LSR) & UART_LSR_THRE) ==
> +				0x00) {

This is actually difficult to read. Please reconsider indentation /
line wrapping / adding a blank line.

> +				if (j++ > CONFIG_SYS_HZ)
> +					break;
> +				udelay(10);
> +			}
> +			serial_out(num, UART_TX, argv[3][i]);
> +			j = 0;
> +			while ((serial_in(num, UART_LSR) & UART_LSR_DR) ==
> +				0x00) {

Ditto.

> +				if (j++ > CONFIG_SYS_HZ)
> +					break;
> +				udelay(10);
> +			}
> +			unsigned char data = serial_in(num, UART_RX);
> +			printf("%c", data);
> +		}
> +		printf("\n\n");
> +		serial_out(num, UART_MCR, 0x00);
> +	} else {
> +		int address = 0;
> +		int irq;
> +
> +		switch (num) {
> +		case 8:
> +			address = MPC5XXX_PSC6;
> +			irq = MPC5XXX_PSC6_IRQ;
> +			break;
> +		case 9:
> +			address = MPC5XXX_PSC3;
> +			irq = MPC5XXX_PSC3_IRQ;
> +			break;
> +		case 10:
> +			address = MPC5XXX_PSC2;
> +			irq = MPC5XXX_PSC2_IRQ;
> +			break;
> +		case 11:
> +			address = MPC5XXX_PSC1;
> +			irq = MPC5XXX_PSC1_IRQ;
> +			break;
> +		}

"irq" seems to be unused (accept for the assignments) in  this  code.
Wasn't there a compiler warning?

> +		volatile struct mpc5xxx_psc *psc =
> +			(struct mpc5xxx_psc *)address;

Variable declaration in the middle of the code - see above.

> +		ser_init(psc, simple_strtol(argv[2], NULL, 0));
> +		if (mode & 2) {
> +			/* set request to send */
> +			out_8(&psc->op0, PSC_OP0_RTS);
> +			udelay(10);
> +			/* check clear to send */
> +			if ((in_8(&psc->ip) & PSC_IPCR_CTS) == 0)
> +				return -1;
> +		}
> +		int i, len = strlen(argv[3]);
> +		for (i = 0; i < len; ++i) {
> +			ser_putc(psc, argv[3][i]);
> +			printf("%c", ser_getc(psc));
> +		}
> +		printf("\n\n");
> +	}
> +	return 0;
> +}
> +
> +#define BUZZER_GPT	(MPC5XXX_GPT + 0x60)	/* GPT6 */
> +static void buzzer_turn_on(unsigned int freq)
> +{
> +	struct mpc5xxx_gpt *gpt = (struct mpc5xxx_gpt *)(BUZZER_GPT);
> +
> +	const u32 prescale = gd->ipb_clk / freq / 128;
> +	const u32 count = 128;
> +	const u32 width = 64;
> +
> +	gpt->cir = (prescale << 16) | count;
> +	gpt->pwmcr = width << 16;
> +	gpt->emsr = 3;		/* Timer enabled for PWM */

Accessor functions?

> +}
> +
> +static void buzzer_turn_off(void)
> +{
> +	struct mpc5xxx_gpt *gpt = (struct mpc5xxx_gpt *)(BUZZER_GPT);
> +	gpt->emsr = 0;

Accessor functions?

> +}
> +
> +static int do_inkadiag_buzzer(cmd_tbl_t *cmdtp, int flag, int argc,
> +			      char *argv[]) {
> +
> +	if (argc != 3) {
> +		cmd_usage(cmdtp);
> +		return 1;
> +	}
> +
> +	argc--;
> +	argv++;
> +
> +	unsigned int period = simple_strtol(argv[0], NULL, 0);

Declaration in the middle of the code.

> +	if (!period)
> +		printf("Zero period is senseless\n");
> +	argc--;
> +	argv++;
> +
> +	unsigned int freq = simple_strtol(argv[0], NULL, 0);

Declaration in the middle of the code.

> +	/* avoid zero prescale in buzzer_turn_on() */
> +	if (freq > gd->ipb_clk / 128) {
> +		printf("%dHz exceeds maximum (%ldHz)\n", freq,
> +		       gd->ipb_clk / 128);
> +	} else if (!freq)
> +		printf("Zero frequency is senseless\n");
> +	else
> +		buzzer_turn_on(freq);
> +
> +	clear_ctrlc();
> +	int prev = disable_ctrlc(0);
> +
> +	printf("Buzzing for %d ms. Type ^C to abort!\n\n", period);
> +
> +	int i = 0;

Declaration in the middle of the code.

> +	while (!ctrlc() && (i++ < CONFIG_SYS_HZ))
> +		udelay(period);
> +
> +	clear_ctrlc();
> +	disable_ctrlc(prev);
> +
> +	buzzer_turn_off();
> +
> +	return 0;
> +}
> +
> +static int do_inkadiag_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
> +
> +cmd_tbl_t cmd_inkadiag_sub[] = {
> +	U_BOOT_CMD_MKENT(io, 1, 1, do_inkadiag_io, "read digital input",
> +			 "<drawer1|drawer2|other> [value] - get or set specified signal\n"),
> +	U_BOOT_CMD_MKENT(serial, 4, 1, do_inkadiag_serial, "test serial port",
> +			 "<num> <mode> <baudrate> <msg>  - test uart num [0..11] in mode\n"
> +			 "and baudrate with msg\n"),
> +	U_BOOT_CMD_MKENT(buzzer, 2, 1, do_inkadiag_buzzer, "activate buzzer",
> +			 "<period> <freq> - turn buzzer on for period ms with freq hz\n"),
> +	U_BOOT_CMD_MKENT(help, 4, 1, do_inkadiag_help, "get help",
> +			 "[command] - get help for command\n"),
> +};

Lines too long.

> +static int do_inkadiag_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
> +	extern int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp,
> +			     int flag, int argc, char *argv[]);
> +	/* do_help prints command name - we prepend inkadiag to our subcommands! */

Lines too long.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Substitute "damn" every time you're inclined to write "very"; your
editor will delete it and the writing will be just as it should be.
                - Mark Twain


More information about the U-Boot mailing list