Re: CPM2 SCC/SMC break handling broken

2006-10-30 Thread Ricardo Scop
Hi Laurent,

On Monday 30 October 2006 13:40, Vitaly Bordug wrote:
> On Mon, 30 Oct 2006 16:23:51 +0100
>
> Laurent Pinchart <[EMAIL PROTECTED]> wrote:
> > Hi Ricardo,
> >
> > > > > > I need to generate a break on a CPM2 SMC serial port (same issue
> > > > > > with SCC serial ports).
> > > > > >
> > > > > > The tcsendbreak() man page states that the function should
> > > > > > generate a break between 250ms and 500ms, but testing showed that
> > > > > > the break is one character long (10 bits in 8N1 mode).
> > > > >
> > > > > [snip]
> > > > >
> > > > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR
> > > > > > characters. The BRKCR register is initialized to 1, so only 1
> > > > > > break character is sent, which won't last between 250ms and
> > > > > > 500ms.
> > > > >
> > > > > [snip]
> > > > >
> > > > > > Could anyone think of a proper solution which would not disturb
> > > > > > the other drivers too much ?
> > > > >
> > > > > Well, one could always set the BRKCR parameter to the maximum
> > > > > number of break characters permitted by it's size, since the break
> > > > > condition will anyway end as soon as the RESTART TX command is
> > > > > issued as a consequence of the tty->driver->break_ctl(tty, 0) call.
> > > > > But I did not test this.
> > > >
> > > > That's a very good idea, but the documentation is a bit misleading
> > > > here. I tested the CPM2 behaviour, and found out that the break will
> > > > last BRKCR characters, even if a RESTART TX command is sent sooner.
> > > >
> > > > The user manual states
> > > >
> > > > "The SMC sends a programmable number of break characters according to
> > > > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is
> > > > issued before completion."
> > > >
> > > > I suppose they meant that, if a RESTART TX command is issued before
> > > > completion of the break sequence, the SMC will send data at the end
> > > > of the break sequence. This is at least the behaviour I noticed after
> > > > trying your idea.
> > >
> > > Too bad :( One more good idea to the junk bin.
> > >
> > > Hmm, just a wild shot you can try, while you're at that: what about
> > > setting BRKCR to zero and issuing another STOP TRANSMIT, just before
> > > the RESTART TRANSMIT?
> >
> > Wow, congratulations. I wouldn't have thought about that.
Thanks.

BTW, thank you for trying that out. My fingers are much lazier than my brain.

Cheers,

-- 
Ricardo Scop.


___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Re: CPM2 SCC/SMC break handling broken

2006-10-30 Thread Vitaly Bordug
On Mon, 30 Oct 2006 16:23:51 +0100
Laurent Pinchart <[EMAIL PROTECTED]> wrote:

> Hi Ricardo,
> 
> > > > > I need to generate a break on a CPM2 SMC serial port (same issue with
> > > > > SCC serial ports).
> > > > >
> > > > > The tcsendbreak() man page states that the function should generate a
> > > > > break between 250ms and 500ms, but testing showed that the break is
> > > > > one character long (10 bits in 8N1 mode).
> > > >
> > > > [snip]
> > > >
> > > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters.
> > > > > The BRKCR register is initialized to 1, so only 1 break character is
> > > > > sent, which won't last between 250ms and 500ms.
> > > >
> > > > [snip]
> > > >
> > > > > Could anyone think of a proper solution which would not disturb the
> > > > > other drivers too much ?
> > > >
> > > > Well, one could always set the BRKCR parameter to the maximum number of
> > > > break characters permitted by it's size, since the break condition will
> > > > anyway end as soon as the RESTART TX command is issued as a consequence
> > > > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
> > >
> > > That's a very good idea, but the documentation is a bit misleading here.
> > > I tested the CPM2 behaviour, and found out that the break will last BRKCR
> > > characters, even if a RESTART TX command is sent sooner.
> > >
> > > The user manual states
> > >
> > > "The SMC sends a programmable number of break characters according to
> > > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is issued
> > > before completion."
> > >
> > > I suppose they meant that, if a RESTART TX command is issued before
> > > completion of the break sequence, the SMC will send data at the end of
> > > the break sequence. This is at least the behaviour I noticed after trying
> > > your idea.
> >
> > Too bad :( One more good idea to the junk bin.
> >
> > Hmm, just a wild shot you can try, while you're at that: what about setting
> > BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART
> > TRANSMIT?
> 
> Wow, congratulations. I wouldn't have thought about that.
> 
> static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
> {
> struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
> int line = pinfo - cpm_uart_ports;
> volatile u16 *brkcr = IS_SMC(pinfo) ? &pinfo->smcup->smc_brkcr
> : &pinfo->sccup->scc_brkcr;
> 
> pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
> break_state);
> 
> if (break_state)
> {
> *brkcr = 32767;
> cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
> }
> else
> {
> *brkcr = 0;
> cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
> cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
> }
> }
> 
> This is a bit hackish though, but it works and doesn't require any API 
> modification.
> 
> Vitaly, could you give me your opinion ?
I'm fine with this change. Can you provide a sorta more complete reference why 
it is required?
I understood in general, but as author, you can explain the reason more clear I 
beleive...


Thanks.
-V

___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Re: CPM2 SCC/SMC break handling broken

2006-10-30 Thread Laurent Pinchart
Hi Ricardo,

> > > > I need to generate a break on a CPM2 SMC serial port (same issue with
> > > > SCC serial ports).
> > > >
> > > > The tcsendbreak() man page states that the function should generate a
> > > > break between 250ms and 500ms, but testing showed that the break is
> > > > one character long (10 bits in 8N1 mode).
> > >
> > > [snip]
> > >
> > > > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters.
> > > > The BRKCR register is initialized to 1, so only 1 break character is
> > > > sent, which won't last between 250ms and 500ms.
> > >
> > > [snip]
> > >
> > > > Could anyone think of a proper solution which would not disturb the
> > > > other drivers too much ?
> > >
> > > Well, one could always set the BRKCR parameter to the maximum number of
> > > break characters permitted by it's size, since the break condition will
> > > anyway end as soon as the RESTART TX command is issued as a consequence
> > > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
> >
> > That's a very good idea, but the documentation is a bit misleading here.
> > I tested the CPM2 behaviour, and found out that the break will last BRKCR
> > characters, even if a RESTART TX command is sent sooner.
> >
> > The user manual states
> >
> > "The SMC sends a programmable number of break characters according to
> > BRKCR and reverts to idle or sends data if a RESTART TRANSMIT is issued
> > before completion."
> >
> > I suppose they meant that, if a RESTART TX command is issued before
> > completion of the break sequence, the SMC will send data at the end of
> > the break sequence. This is at least the behaviour I noticed after trying
> > your idea.
>
> Too bad :( One more good idea to the junk bin.
>
> Hmm, just a wild shot you can try, while you're at that: what about setting
> BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART
> TRANSMIT?

Wow, congratulations. I wouldn't have thought about that.

static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
int line = pinfo - cpm_uart_ports;
volatile u16 *brkcr = IS_SMC(pinfo) ? &pinfo->smcup->smc_brkcr
: &pinfo->sccup->scc_brkcr;

pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);

if (break_state)
{
*brkcr = 32767;
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
}
else
{
*brkcr = 0;
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
}
}

This is a bit hackish though, but it works and doesn't require any API 
modification.

Vitaly, could you give me your opinion ?

> Another reasonable shot would be to disable and reenable the transmitter in
> an attempt to stop the break sequence; though I don't know what happens to
> the SMC state machine in this case.
>
> Too wild guesses? Well, maybe someone at Freescale can have a better idea.
> :)

I could try contacting them, but they will probably tell me that I should just 
set BRKCR to the number of characters I want to send. I doubt they will care 
that the kernel break handling code doesn't allow us to do that easily.

Thanks for your help.

Best regards,

Laurent Pinchart
___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Re: CPM2 SCC/SMC break handling broken

2006-10-27 Thread Ricardo Scop
Hi Laurent,

On Friday 27 October 2006 07:01, Laurent Pinchart wrote:
> Hi Ricardo,
>
> > > Hi everybody,
> > >
> > > I need to generate a break on a CPM2 SMC serial port (same issue with
> > > SCC serial ports).
> > >
> > > The tcsendbreak() man page states that the function should generate a
> > > break between 250ms and 500ms, but testing showed that the break is one
> > > character long (10 bits in 8N1 mode).
> >
> > [snip]
> >
> > > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters.
> > > The BRKCR register is initialized to 1, so only 1 break character is
> > > sent, which won't last between 250ms and 500ms.
> >
> > [snip]
> >
> > > Could anyone think of a proper solution which would not disturb the
> > > other drivers too much ?
> >
> > Well, one could always set the BRKCR parameter to the maximum number of
> > break characters permitted by it's size, since the break condition will
> > anyway end as soon as the RESTART TX command is issued as a consequence
> > of the tty->driver->break_ctl(tty, 0) call. But I did not test this.
>
> That's a very good idea, but the documentation is a bit misleading here. I
> tested the CPM2 behaviour, and found out that the break will last BRKCR
> characters, even if a RESTART TX command is sent sooner.
>
> The user manual states
>
> "The SMC sends a programmable number of break characters according to BRKCR
> and reverts to idle or sends data if a RESTART TRANSMIT is issued before
> completion."
>
> I suppose they meant that, if a RESTART TX command is issued before
> completion of the break sequence, the SMC will send data at the end of the
> break sequence. This is at least the behaviour I noticed after trying your
> idea.
Too bad :( One more good idea to the junk bin.

Hmm, just a wild shot you can try, while you're at that: what about setting 
BRKCR to zero and issuing another STOP TRANSMIT, just before the RESTART 
TRANSMIT? 

Another reasonable shot would be to disable and reenable the transmitter in an 
attempt to stop the break sequence; though I don't know what happens to the 
SMC state machine in this case.

Too wild guesses? Well, maybe someone at Freescale can have a better idea. :)

Best regards,

Ricardo Scop.


___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Re: CPM2 SCC/SMC break handling broken

2006-10-27 Thread Laurent Pinchart
Hi Ricardo,

> > Hi everybody,
> >
> > I need to generate a break on a CPM2 SMC serial port (same issue with SCC
> > serial ports).
> >
> > The tcsendbreak() man page states that the function should generate a
> > break between 250ms and 500ms, but testing showed that the break is one
> > character long (10 bits in 8N1 mode).
>
> [snip]
>
> > CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The
> > BRKCR register is initialized to 1, so only 1 break character is sent,
> > which won't last between 250ms and 500ms.
>
> [snip]
>
> > Could anyone think of a proper solution which would not disturb the other
> > drivers too much ?
>
> Well, one could always set the BRKCR parameter to the maximum number of
> break characters permitted by it's size, since the break condition will
> anyway end as soon as the RESTART TX command is issued as a consequence of
> the tty->driver->break_ctl(tty, 0) call. But I did not test this.

That's a very good idea, but the documentation is a bit misleading here. I 
tested the CPM2 behaviour, and found out that the break will last BRKCR 
characters, even if a RESTART TX command is sent sooner.

The user manual states

"The SMC sends a programmable number of break characters according to BRKCR 
and reverts to idle or sends data if a RESTART TRANSMIT is issued before 
completion."

I suppose they meant that, if a RESTART TX command is issued before completion 
of the break sequence, the SMC will send data at the end of the break 
sequence. This is at least the behaviour I noticed after trying your idea.

Laurent Pinchart
___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Re: CPM2 SCC/SMC break handling broken

2006-10-26 Thread Ricardo Scop
On Thursday 26 October 2006 06:02, Laurent Pinchart wrote:
> Hi everybody,
>
> I need to generate a break on a CPM2 SMC serial port (same issue with SCC
> serial ports).
>
> The tcsendbreak() man page states that the function should generate a break
> between 250ms and 500ms, but testing showed that the break is one character
> long (10 bits in 8N1 mode).

[snip]

> CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The
> BRKCR register is initialized to 1, so only 1 break character is sent,
> which won't last between 250ms and 500ms.

[snip]

> Could anyone think of a proper solution which would not disturb the other
> drivers too much ?

Well, one could always set the BRKCR parameter to the maximum number of break 
characters permitted by it's size, since the break condition will anyway end 
as soon as the RESTART TX command is issued as a consequence of the 
tty->driver->break_ctl(tty, 0) call. But I did not test this.

HTH,

-- 
Ricardo Scop.

\|/
___ -*-
   (@ @)/|\
  /  V  \|  R SCOP Consult.
 /( )\  Linux-based communications
--^^---^^+--
[EMAIL PROTECTED]
+55 51 999-36-777
Porto Alegre, RS - BRazil
--
P. S.: "If you have any trouble sounding condescending, find a Unix user to
show you how it's done."  -- Scott Adams, creator of "Dilbert"

___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


CPM2 SCC/SMC break handling broken

2006-10-26 Thread Laurent Pinchart
Hi everybody,

I need to generate a break on a CPM2 SMC serial port (same issue with SCC 
serial ports).

The tcsendbreak() man page states that the function should generate a break 
between 250ms and 500ms, but testing showed that the break is one character 
long (10 bits in 8N1 mode).

Breaks are handled by the tty layer (drivers/char/tty_io.c), the generic 
serial layer (drivers/serial/serial_core.c) and the CPM driver 
(drivers/char/cpm_uart/cpm_uart_core.c).

As the tty driver (drivers/serial/serial_core.c) defines a break handler 
(break_ctl), the tty layer calls send_break to send the break:

static int send_break(struct tty_struct *tty, unsigned int duration)
{
tty->driver->break_ctl(tty, -1);
if (!signal_pending(current)) {
msleep_interruptible(duration);
}
tty->driver->break_ctl(tty, 0);
if (signal_pending(current))
return -EINTR;
return 0;
}

tty->driver->break_ctl just forwards the call to the CPM driver, which does

static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
int line = pinfo - cpm_uart_ports;

pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);

if (break_state)
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
else
cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
}

CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The 
BRKCR register is initialized to 1, so only 1 break character is sent, which 
won't last between 250ms and 500ms.

cpm_uart_break_ctl() is not told how long the break must last, so it can't 
modify BRKCR before sending CPM_CR_STOP_TX. A solution would be to let the 
driver handle the break itself instead of having tty_io.c calling 
send_break(). To do that, the driver (serial_core.c) must not declare a break 
handler. This would obviously break all other serial drivers. Another 
solution would be to have a new platform handler for CPM serial ports which 
will turn the I/O ports to low-level outputs. This sounds more like a hack to 
me though.

Could anyone think of a proper solution which would not disturb the other 
drivers too much ?

Laurent Pinchart
___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded