How can I tell if an interrupt has occured in MPC860?

Choon Hooi Ng choonhooi.ng at motorola.com
Wed Sep 19 11:43:50 EST 2001


Hi,
        I am currently programming my custom-build MPC860 PowerPC board
      (embedded) to detect Ir keyboard. Basically, what i have is, I have an
      infrared detector connected to SCC3 of the 860 PPC. I am using the CPM
      as the comm processor and use UART mode. See illustration below:

           [ o ]-------------------[860 PPC]
         Ir detector          scc3

      I have done all the necessary configurations steps as stated in MPC860
      User's Manual pg.23-22, and enabled the interrupt. Now, when I press
      some keys on the Ir keyboard, I am expecting the 860 to detect it and
      then generate an interrupt. But, apparently, nothing happens. My
      questions are:
      1. How can i tell if the 860 receives my irq request
      2. How can I tell if 860 receives some signals from the Ir keyboard
      and
      3. How can I find out if an interrupt does happen

      For info, the Ir k/b is using baud rate: 1200, each data-unit contains
      total 10 bits of info - 1 start bit, 7 data bits, 1 parity and 1 stop
      bit.

      I have also included my code in this posting. cpm_silitek_kb_init is
      the function that will be called after initializing the eth (enet.c).

      Really appreciate if someone could help me out on this. Thanks in
      advance.

      Rgds,
        ch

      --------------start

/**************************************************************************/
      struct cpm_silitek_kb_private {
              /* The saved address of a sent-in-place packet/buffer, for
skfree().
      */
              ushort  skb_cur;
              ushort  skb_dirty;

              /* CPM dual port RAM relative addresses.
              */
              cbd_t   *rx_bd_base;            /* Address of Rx and Tx
buffers. */
              cbd_t   *tx_bd_base;
              cbd_t   *cur_rx, *cur_tx;               /* The next free ring
entry */
              cbd_t   *dirty_tx;      /* The ring entries to be free()ed. */
              scc_t   *sccp;
              char    tx_full;
              unsigned long lock;
      };

      static char uart_rx_buf[1];             /* Receive Buffer */
      static char uart_tx_buf[1];             /* Transmit Buffer */


/***********************************************************************/
      static void
      cpm_silitek_kb_interrupt (void)
      {
        printk("interr occured\n");
      }


/***********************************************************************/
      int __init cpm_silitek_kb_init(void)
      {
              struct device *dev;
              struct cpm_silitek_kb_private *cep;
              int i, j;

              bd_t            *bd;
              volatile        cbd_t           *bdp;
              volatile        cpm8xx_t        *cp;
              volatile        scc_uart_t      *sccxp;
              volatile        immap_t         *immap;

              immap = (immap_t *)IMAP_ADDR;   /* and to internal registers
*/

              /* Get pointer to SCC area in parameter RAM. */
              sccxp = (scc_uart_t *)
(&immap->im_cpm.cp_dparam[PROFF_SCC3]);

              /* Allocate some private information.
              */
              cep = (struct cpm_silitek_kb_private *)kmalloc(sizeof(*cep),
      GFP_KERNEL);

              /* Configure port A pins for Txd and Rxd.
              */
              /* pg. 34-5 */
      /*** 1. p.g. 34-5. Configure port A to enable  RXD3. Set PAPAR[10,11];
      Clear PADIR[10,11]; Clear PAODR[10,11]  */
              immap->im_ioport.iop_papar |= 0x0030;

              /* Set output & on-chip peripheral signal with PADIR(DRn) set
to '1'
      */
              immap->im_ioport.iop_padir &= 0xFFCF;

              /* Set signal to open-drain type */
              immap->im_ioport.iop_paodr &= 0xFFCF;


      /*** 2. Config port C to enable RTS2, CTS3 & CD2. Set PCPAR[14] &
      PCSO[8,9] & clear PCPAR[8,9] & PCDIR[8,9,14] */
              /* Configure port C pins to enable CLSN and RENA.
              */
              /* Set on-chip peripheral signal to '1' */
              immap->im_ioport.iop_pcpar = 0x0000;

              /* Set bit to '1' if the on-chip peripheral signal is to
generate an
      interrupt */
              /* at the same time. */
              immap->im_ioport.iop_pcso =  0x00F0;

              /* Set output & on-chip peripheral signal with PCDIR(DRn) set
to '1'
      */
              immap->im_ioport.iop_pcdir = 0x0F0A;

      /*** 3. pg.21-40 Config BRG1. Write BRGC1 with 0x0001 0144. The DIV16
      bit is not used and
              the divider is 162 (decimal). The resulting BRG1 clock is 16x
the
      preferred bit rate */
              /*
               * Baud Rate Generators, BRGs, initialization (disable)
               */
              /*immap->im_cpm.cp_brgc1 =*/
              /*immap->im_cpm.cp_brgc2 =*/
              immap->im_cpm.cp_brgc3 =
              /*immap->im_cpm.cp_brgc4 =*/ 0x0001057c;

      /* 4. pg.21-23 Connect BRG3 to SCC3 using serial interface. Clear
      SICR[R2CS, T2CS] */
              /* Configure Serial Interface clock routing.
               * First, clear all SCC bits to zero, then set the ones we
want.
               */
               /* pg 21-24 */
              immap->im_cpm.cp_sicr |= 0x00120000;

      /*** 5.  Initialize SDMA confin reg; SDCR=0x0001 */
              /* Manual says set SDDR, but I can't find anything with that
               * name.  I think it is a misprint, and should be SDCR.  This
               * has already been set by the communication processor
      initialization.
               */
              immap->im_siu_conf.sc_sdcr = 0x0001;

      /*** 6. Connect SCC3 to NMSI. Clear SICR[SC3] */
              immap->im_cpm.cp_sicr &= 0xFFBFFFFF;


      /* 7. ??? Write RBASE & TBASE in SCC3 parameters RAM to point to the
      RxBD and Tx TxBD tables in dual-port RAM. Assuming
                      one RxBD at the start of dual-port RAM followed by one
TxBD, write
      RBASE with 0x0000 and TBASE with 0x0008 */

              i = m8xx_cpm_dpalloc(sizeof(cbd_t)); /* i points to an empty
space in
      dual port ram */
              sccxp->scc_genscc.scc_rbase = i;
              cep->rx_bd_base = (cbd_t *)&immap->im_cpm.cp_dpmem[i];

              i = m8xx_cpm_dpalloc(sizeof(cbd_t)); /* i points to an empty
space in
      dual port ram */
              sccxp->scc_genscc.scc_tbase = i;
              cep->tx_bd_base = (cbd_t *)&immap->im_cpm.cp_dpmem[i];


      /* 8. pg. 19-6 Write 0x0081 to CPCR to exe the INIT RX and TX params
      connand for SCC3 */
               /* pg. 19-6 */
              immap->im_cpm.cp_cpcr = 0x0081;


      /* 9. ?? Write RFCR with 0x10 and TFCR with 0x10 */
              /* Initialize function code registers for big-endian.
              */
          sccxp->scc_genscc.scc_rfcr  = 0x18;         /*
MPC8XX_PRAM_SCC_FCR_BO_BE;
      */          /* Rx Func Code   */
          sccxp->scc_genscc.scc_tfcr  = 0x18; /* MPC8XX_PRAM_SCC_FCR_BO_BE;
      */          /* Tx Func Code   */

      /* 10. ?? Wrt MRBLR with the max # of bytes per Rx buffer. assume 16
      bytes; MRBLR = 0x0010 */
          sccxp->scc_genscc.scc_mrblr = 1;
      /* Max Rx Buf Len */


      /* 11. Wrt MAX_IDL with 0x0000 in the param RAM to disable the max
      idle func */
              sccxp->scc_maxidl = 0;                  /* Maximum Idle
Caracters       */

      /* 12.  Set BRKCR to 0x0001 so STOP TRANSMIT cmds send only one break
      char */
          sccxp->scc_brkcr   = 1;                     /* Break Count
Register (transmit)      */

      /* 13. Clr  PAREC, FRMEC, NOSEC & BRKEC in param RAM */
          sccxp->scc_parec   = 0;                     /* Receive Parity
Error Counter         */
          sccxp->scc_frmec   = 0;                     /* Receive Framing
Error Counter        */
          sccxp->scc_nosec   = 0;                     /* Receive Noise
Counter                        */
          sccxp->scc_brkec   = 0;                     /* Receive Break
Condition Counter      */

      /* 14. Clr  UADDR1 & UADDR2. Not used */
          sccxp->scc_uaddr1  = 0;                     /* UART Address
Character 1*/
          sccxp->scc_uaddr2  = 0;                     /* UART Address
Character 2*/

      /* 15. Clr TOSEQ. Not used */
          sccxp->scc_toseq   = 0;                     /* X-mit
Out-of-Sequence Character      */

      /* 16. Wrt CHARACTER1-8 with 0x8000. Not used */
          sccxp->scc_char1   = 0x8000;                /* Control Character 1
*/
          sccxp->scc_char2   = 0x8000;                /* Control Character 2
*/
          sccxp->scc_char3   = 0x8000;                /* Control Character 3
*/
          sccxp->scc_char4   = 0x8000;                /* Control Character 4
*/
          sccxp->scc_char5   = 0x8000;                /* Control Character 5
*/
          sccxp->scc_char6   = 0x8000;                /* Control Character 6
*/
          sccxp->scc_char7   = 0x8000;                /* Control Character 7
*/
          sccxp->scc_char8   = 0x8000;                /* Control Character 8
*/


      /* 17. Wrt RCCM with 0x C0FF. Not used */
          sccxp->scc_rccm    = 0xC0FF;                /* Receive Control
Character Mask       */

      /* 18. ?? Init the RxBD. Assume the Rx buffer is at 0x0000_1000 in
      main mem.
              Wrt oxB000 to RxBD[Status and Control], 0x0000 to RxBD[Data
length]
      and 0x0000_10000 to RxBD[Buf Ptr] */
              /*
           * Rx Buffer Descriptor
           */
              bdp = cep->rx_bd_base;
              bdp->cbd_sc = 0xB000;
              bdp->cbd_datlen = 0;
              bdp->cbd_bufaddr = (uint) &uart_rx_buf;


      /* 19. Initialize the TxBD */
              bdp = cep->tx_bd_base;
              bdp->cbd_sc = 0x2000;
              bdp->cbd_datlen = 1;
              bdp->cbd_bufaddr = (uint) &uart_tx_buf;

      /* 20. Wrt 0xFFFF to SCCE3 to clr any previous events */
          immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_scce = 0xFFFF;

      /* 21. ?? Wrt 0x0003 to SCCM3 to allow the TX and RX interr */
          immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_sccm = 0x0003;

              /* Install our interrupt handler.*/
         cpm_install_handler(CPMVEC_SILITEK_KB, cpm_silitek_kb_interrupt,
      cep);


      /* 22. p.g. 35-9 Wrt 0x1000_0000 to CPM inter mask reg (CIMR) to allow
      SCC3 to generate a system interrupt. The CICR shud also be init. */
      /* NOTE: Not sure why this is not needed */
              immap->im_cpic.cpic_cimr |= 0x10000000;
              immap->im_cpic.cpic_cicr |= 0x00200000;

      /* 23. pg 22-3 Wrt 0x0000 0020 to GSMR_H3 to configure a small Rx FIFO
      width */
          immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_gsmrh = 0x00000020;


      /* 24. ?? Wrt 0x0002 8004 to GSMR_L3 to configure 16x sampling for tx
      & rx, CTS & CD to
      automatically control transmission and reception (DIAG bits) and the
      SCC for UART mode. Notice that the transmitter (ENT) & receiver (ENR)
      have not been enabled yet.  */
          /* General SCC Mode Register Low */
              immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_gsmrl = 0x00028004;

      /*  25. ?? pg.23-13 Set PSMR3 */
              immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_pmsr = 0x2010;  /* I
think
      it shud be PSMR. possibly typo in linux */

      /* 26. Wrt 0x0002 8034 to GSMR_L3 to enable the tmitter & Rxer. This
      ensures that ENT and ENR are enabled last. */
          /*
           * Enable the Transmitter and Receiver
           * Now that SCC3 is configured, Tx and Rx can be enabled.
           */
          /* General SCC Mode Register Low */

              /* And last, enable the transmit and receive processing.
              */
              immap->im_cpm.cp_scc[SCC3_SILITEK_KB].scc_gsmrl |= 0x00000030;
              return 0;
      }


      --------------end


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/





More information about the Linuxppc-embedded mailing list