[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ETRAX 100LX OS-less: more problems




Hi Ulf,

On Monday 04 November 2002 13.46, ulf.sjostedt@xxxxxxx.se wrote:
> Hi everybody!

> Problem number two is more serious.
> The setup I have described above works well provided that I
> connect the two 100LXes over an RS232 port (I have described
> this problem before).  However, I would like to use the RS422, and
> that doesn't work.  I can send from the "outside" to the "inside", but
> not the other way, that is, the 422 port does not receive any data
> when running without an OS: the receive DMA channel never
> generates any interrupts
> I have ruled out hardware problems.  It works when both boxes run
> Linux.  I haven't been able to find anything in the serial driver
> (serial.c)
> that treats the 422 port differently from the 232, but clearly I am missing
> something.
> What?

You must make sure the RTS line is set correctly since that controls the
direction of the pair normally used for RX (but swicth between RX and TX in
2-wire mode).
Try changing it to active for port 3, active = Request To Send = Ready to 
Receive.


> I enclose relevant bits of the code.  Any help is appreciated.
>
> Thanks,
>
>
> /Ulf Sjöstedt
> ulf.sjostedt@xxxxxxx.se
>
>
>
> Assembler code first:
>
>       ;; Set up genconfig.
>
>       moveq 0,$r0
>
>       ; Enable DMA channels 4 and 5 for serial port 3
>       or.d  IO_STATE (R_GEN_CONFIG, dma5, serial3)    \
>
>             | IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0
>
>       ; Enable serial port 3
>       or.w  IO_STATE (R_GEN_CONFIG, ser3, select),$r0
>       ; DEBUG: Enable serial port 2
>       or.w  IO_STATE (R_GEN_CONFIG, ser2, select),$r0
>
>       move.d      $r0,[genconfig_shadow]
>       move.d      $r0,[R_GEN_CONFIG]
>
>
>       ; Set up general ports.
>
>       move.b      CONFIG_ETRAX_DEF_R_PORT_PA_DIR,$r0
>       move.b      $r0,[port_pa_dir_shadow]
>       move.b      $r0,[R_PORT_PA_DIR]
>       move.b      CONFIG_ETRAX_DEF_R_PORT_PA_DATA,$r0
>       move.b      $r0,[port_pa_data_shadow]
>       move.b      $r0,[R_PORT_PA_DATA]
>
>       move.b      CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG,$r0
>       move.b      $r0,[port_pb_config_shadow]
>       move.b      $r0,[R_PORT_PB_CONFIG]
>       move.b      CONFIG_ETRAX_DEF_R_PORT_PB_DIR,$r0
>       move.b      $r0,[port_pb_dir_shadow]
>       move.b      $r0,[R_PORT_PB_DIR]
>       move.b      CONFIG_ETRAX_DEF_R_PORT_PB_DATA,$r0
>       move.b      $r0,[port_pb_data_shadow]
>       move.b      $r0,[R_PORT_PB_DATA]
>
>       moveq 0,$r0
>       move.d      $r0,[port_g_data_shadow]
>       move.d      $r0,[R_PORT_G_DATA]
>
>       ;; DEBUG: set up serial port 2
>
>       moveq IO_STATE (R_SERIAL2_XOFF, tx_stop, enable)            \
>
>             | IO_STATE (R_SERIAL2_XOFF, auto_xoff, disable)       \
>             | IO_FIELD (R_SERIAL2_XOFF, xoff_char, 0),$r0
>
>       move.d      $r0,[R_SERIAL2_XOFF]
>
>       ; 115.2kbaud for both transmit and receive
>       move.b IO_STATE (R_SERIAL2_BAUD, tr_baud, c115k2Hz)         \
>
>             | IO_STATE (R_SERIAL2_BAUD, rec_baud, c115k2Hz),$r0
>
>       move.b      $r0,[R_SERIAL2_BAUD]
>
>       ; Set up and enable the serial2 receiver.
>       move.b IO_STATE (R_SERIAL2_REC_CTRL, dma_err, stop)         \
>
>             | IO_STATE (R_SERIAL2_REC_CTRL, rec_enable, enable)   \
>             | IO_STATE (R_SERIAL2_REC_CTRL, rts_, active)         \
>             | IO_STATE (R_SERIAL2_REC_CTRL, sampling, middle)     \
>             | IO_STATE (R_SERIAL2_REC_CTRL, rec_stick_par, normal)      \
>             | IO_STATE (R_SERIAL2_REC_CTRL, rec_par, even)        \
>             | IO_STATE (R_SERIAL2_REC_CTRL, rec_par_en, disable)  \
>             | IO_STATE (R_SERIAL2_REC_CTRL, rec_bitnr, rec_8bit),$r0
>
>       move.b      $r0,[R_SERIAL2_REC_CTRL]
>
>       ; Set up and enable the serial2 transmitter.
>       move.b IO_FIELD (R_SERIAL2_TR_CTRL, txd, 0)                 \
>
>             | IO_STATE (R_SERIAL2_TR_CTRL, tr_enable, enable)     \
>             | IO_STATE (R_SERIAL2_TR_CTRL, auto_cts, disabled)    \
>             | IO_STATE (R_SERIAL2_TR_CTRL, stop_bits, one_bit)    \
>             | IO_STATE (R_SERIAL2_TR_CTRL, tr_stick_par, normal)  \
>             | IO_STATE (R_SERIAL2_TR_CTRL, tr_par, even)          \
>             | IO_STATE (R_SERIAL2_TR_CTRL, tr_par_en, disable)    \
>             | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0
>
>       move.b      $r0,[R_SERIAL2_TR_CTRL]
>
>
>
>       ; Set up interrupt handling.
>
>       move.d      0x40030000,$r0
>       move  $r0,$ibr
>       move.d      0x40030400, $r1
> 1:    clear.d     [$r0+]
>       cmp.d $r1, $r0
>       blo   1b
>       nop
>
>       move.d timer_int,$r1
>       move.d $r1,[0x40030088]
>       move.d eth_err_int,$r1
>       move.d $r1,[0x40030098]
>       move.d $r1,[0x4003009c]
>       move.d eth_tx_int,$r1
>       move.d $r1,[0x400300c0]
>       move.d eth_rx_int,$r1
>       move.d $r1,[0x400300c4]
>       move.d ser_tx_int,$r1
>       move.d $r1,[0x400300d0]
>       move.d ser_rx_int,$r1
>       move.d $r1,[0x400300d4]
>
>       ; Do C code initialization.
>       jsr   _initialize
>
>
>       ; All done.  Enable interrupts and go stand in the corner.
>
>       ei
>
> _corner:
>       nop
>       jump _corner
>
>
>
> ;; Interrupt handlers
>
> timer_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _timeout
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
> eth_err_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _eth_err
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
> eth_tx_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _eth_tx
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
> eth_rx_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _eth_rx
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
> ser_tx_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _ser_tx
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
> ser_rx_int:
>       push $dccr
>       di
>     subq 14*4, $sp
>       movem $r13,[$sp]
>       jsr _ser_rx
>       movem [$sp+],$r13
>       reti
>       pop $dccr
>
>
> And then C:
>
>       *R_SERIAL3_CTRL =
>             IO_STATE(R_SERIAL3_CTRL, tr_baud, c1843k2Hz) |
>             IO_STATE(R_SERIAL3_CTRL, rec_baud, c1843k2Hz) |
>             IO_STATE(R_SERIAL3_CTRL, dma_err, ignore) |
>             IO_STATE(R_SERIAL3_CTRL, rec_enable, enable) |
>             IO_STATE(R_SERIAL3_CTRL, rts_, inactive) |

Try changing this to active

>             IO_STATE(R_SERIAL3_CTRL, sampling, middle) |
>             IO_STATE(R_SERIAL3_CTRL, rec_par_en, disable) |
>             IO_STATE(R_SERIAL3_CTRL, rec_bitnr, rec_8bit) |
>             IO_STATE(R_SERIAL3_CTRL, tr_enable, enable) |
>             IO_STATE(R_SERIAL3_CTRL, auto_cts, disabled) |
>             IO_STATE(R_SERIAL3_CTRL, stop_bits, one_bit) |
>             IO_STATE(R_SERIAL3_CTRL, tr_par_en, disable) |
>             IO_STATE(R_SERIAL3_CTRL, tr_bitnr, tr_8bit);
>       *R_SERIAL3_XOFF =
>           IO_STATE(R_SERIAL3_XOFF, auto_xoff, disable);
>
>       dummy = *R_SERIAL3_READ;
>
>       /* Mask all interrupts. */
>
>       *R_VECT_MASK_CLR =
>           0xffffffff;
>       *R_IRQ_MASK0_CLR =
>           0xffffffff;
>       *R_IRQ_MASK1_CLR =
>           0xffffffff;
>       *R_IRQ_MASK2_CLR =
>           0xffffffff;
>
>       /* Reset and wait for DMA channels. */
>
>       RESET_DMA(NETWORK_TX_DMA_NBR);
>       RESET_DMA(NETWORK_RX_DMA_NBR);
>       RESET_DMA(SER0_TX_DMA_NBR);
>       RESET_DMA(SER0_RX_DMA_NBR);
>       WAIT_DMA(NETWORK_TX_DMA_NBR);
>       WAIT_DMA(NETWORK_RX_DMA_NBR);
>       WAIT_DMA(SER0_TX_DMA_NBR);
>       WAIT_DMA(SER0_RX_DMA_NBR);
>
>       /* Unmask interrupts. */
>
>       *R_VECT_MASK_SET =
>           IO_STATE(R_VECT_MASK_SET, dma5, set) |
>           IO_STATE(R_VECT_MASK_SET, dma4, set) |
>           IO_STATE(R_VECT_MASK_SET, dma1, set) |
>           IO_STATE(R_VECT_MASK_SET, dma0, set) |
>           IO_STATE(R_VECT_MASK_SET, snmp, set) |
>           IO_STATE(R_VECT_MASK_SET, timer0, set) |
>           IO_STATE(R_VECT_MASK_SET, network, set);
>
>       *R_IRQ_MASK0_SET =
>           IO_STATE(R_IRQ_MASK0_SET, underrun, set) |
>           IO_STATE(R_IRQ_MASK0_SET, excessive_col, set) |
>           IO_STATE(R_IRQ_MASK0_SET, timer0, set);
>
>       *R_IRQ_MASK2_SET =
>           IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
>           IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set) |
>           IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
>           IO_STATE(R_IRQ_MASK2_SET, dma5_eop, set) |
>           IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
>
>
>       /* Clear interrupts. */
>
>       *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
>       *R_DMA_CH1_CLR_INTR = IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do);
>       *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do);
>       *R_DMA_CH5_CLR_INTR = IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop, do) |
>                             IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, do);
>
>
>       /* Start DMA channels. */
>
>       *R_DMA_CH0_FIRST = nextUnsentEthTx;
>       *R_DMA_CH1_FIRST = nextReceivedEthRx;
>       *R_DMA_CH4_FIRST = nextUnsentSerTx;
>       *R_DMA_CH5_FIRST = nextReceivedSerRx;
>
>       *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, start);
>       *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start);
>       *R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, start);
>       *R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, start);
>
>
>       /* Start timer. */
>
>       *R_TIMER_CTRL =
>           IO_FIELD(R_TIMER_CTRL, timerdiv0, 3) |
>           IO_STATE(R_TIMER_CTRL, i0, clr) |
>           IO_STATE(R_TIMER_CTRL, tm0, run) |
>           IO_STATE(R_TIMER_CTRL, clksel0, c300Hz);