gonzui


Format: Advanced Search

mtkernel_3/device/ser/sysdepend/tx03_m367/ser_m367.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    Device Driver for micro T-Kernel for μT-Kernel 3.0
    4:  *
    5:  *    Copyright (C) 2020-2021 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.2.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2021/08.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: #include <sys/machine.h>
   15: #ifdef CPU_TMPM367FDFG
   16: 
   17: #include <tk/tkernel.h>
   18: #include "../../ser.h"
   19: #include "../../../include/dev_def.h"
   20: #if DEV_SER_ENABLE
   21: /*
   22:  *      ser_m367.c
   23:  *      Serial communication device driver
   24:  *      System dependent processing for TX03_M367
   25:  */
   26: 
   27: /*----------------------------------------------------------------------
   28:  * Device register base address
   29:  */
   30: const LOCAL UW ba[DEV_SER_UNITNM] = { UART4_BASE, UART5_BASE};
   31: 
   32: /*----------------------------------------------------------------------
   33:  * Device low-level control data
   34: */
   35: typedef struct {
   36:         UW     mode;               // Serial mode
   37:         UW     speed;              // Spped (bit rate)
   38: } T_DEV_SER_LLDEVCB;
   39: 
   40: LOCAL T_DEV_SER_LLDEVCB         ll_devcb[DEV_SER_UNITNM];
   41: 
   42: /*----------------------------------------------------------------------
   43:  * Interrupt handler
   44:  */
   45: void uart_inthdr( UINT intno)
   46: {
   47:         UW     data, err;
   48:         W      unit;
   49: 
   50:         unit = intno -INTNO_UART0;
   51:         
   52:         /* Clear Interrupt */
   53:         out_w( ba[unit] + UARTxICR, UARTxINT_ALL);
   54: 
   55:         /* Reception processing */
   56:         while( (in_w( ba[unit] + UARTxFR) & UARTxFR_RXFE) == 0) {
   57:                 data  = in_w(ba[unit] + UARTxDR);
   58:                 err   = data >> 8;
   59:                 
   60:                 if (err) {
   61:                         dev_ser_notify_err(unit, err);       /* Notify the main process of the communication error. */
   62:                         out_w( ba[unit] + UARTxECR, 0);      /* Clear error */
   63:                         data &= 0x000000FF;
   64:                 }
   65:                 dev_ser_notify_rcv(unit, data);       /* Notify the main process of data reception. */
   66:         }
   67: 
   68:         /* Transmission process */
   69:         while( (in_w( ba[unit] + UARTxFR) & UARTxFR_TXFF) == 0 ) {
   70:                 if( !dev_ser_get_snddat(unit, &data))  break;
   71:                 out_w( ba[unit] + UARTxDR, data);
   72:         }
   73: }
   74: 
   75: /*----------------------------------------------------------------------
   76:  * Set mode & Start communication
   77:  */
   78: LOCAL void start_com(UW unit, UW mode, UW speed)
   79: {
   80:         /* Set communication Speed */
   81:         out_w( ba[unit] + UARTxIBDR, speed >> 6);
   82:         out_w( ba[unit] + UARTxFBDR, speed & 0x3f);            
   83: 
   84:         /* Set communication mode */
   85:         out_w( ba[unit] + UARTxLCR_H, (mode & (UARTxLCR_H_SPS|UARTxLCR_H_WLEN(8)| UARTxLCR_H_STP2| UARTxLCR_H_EPS|UARTxLCR_H_PEN)) |UARTxLCR_H_FEN);
   86:         *(UW*)(ba[unit] + UARTxCR) |= mode & (UARTxCR_CTSEN | UARTxCR_RTSEN);
   87: 
   88:         /* Start communication */
   89:         *(UW*)(ba[unit] + UARTxCR) |= (UARTxCR_TXE | UARTxCR_RXE | UARTxCR_UARTEN);
   90: }
   91: 
   92: /*----------------------------------------------------------------------
   93:  * Stop communication
   94:  */
   95: LOCAL void stop_com(UW unit)
   96: {
   97:         if(unit != DEVCNF_SER_DBGUN) {
   98:                 out_w( ba[unit] + UARTxCR, 0);
   99:         } else {       /* Used by T-Monitor */
  100:                 out_w( ba[unit] + UARTxCR, UARTxCR_UARTEN | UARTxCR_TXE | UARTxCR_RXE);
  101:         }
  102: }
  103: 
  104: /*----------------------------------------------------------------------
  105:  * Low level device control
  106:  */
  107: EXPORT ER dev_ser_llctl( UW unit, INT cmd, UW parm)
  108: {
  109:         ER     err = E_OK;
  110: 
  111:         switch(cmd) {
  112:         case LLD_SER_MODE:     /* Set Communication mode */
  113:                 ll_devcb[unit].mode = parm;
  114:                 break;
  115:         
  116:         case LLD_SER_SPEED:    /* Set Communication Speed */
  117:                 ll_devcb[unit].speed = ((CLOCK_fsys * (64*2 / 16) / parm) + 1) >> 1;
  118:                 break;
  119:         
  120:         case LLD_SER_START:    /* Start communication */
  121:                 out_w(ba[unit] + UARTxICR, UARTxINT_ALL);     // Clear interrupt
  122:                 out_w(ba[unit] + UARTxIMSC, UARTxINT_COM);    // Unmask all interrupts
  123:                 EnableInt(unit?INTNO_UART1:INTNO_UART0, DEVCNF_SER_INTPRI);   // Enable Interrupt
  124:                 start_com( unit, ll_devcb[unit].mode, ll_devcb[unit].speed);
  125:                 break;
  126:         
  127:         case LLD_SER_STOP:
  128:                 DisableInt(unit?INTNO_UART1:INTNO_UART0);
  129:                 stop_com(unit);
  130:                 break;
  131: 
  132:         case LLD_SER_SEND:
  133:                 if((in_w( ba[unit] + UARTxFR) & UARTxFR_TXFF) == 0) {
  134:                         out_w(ba[unit] + UARTxDR, parm);
  135:                         err = E_OK;
  136:                 } else {
  137:                         err = E_BUSY;
  138:                 }
  139:                 break;
  140: 
  141:         case LLD_SER_BREAK:    /* Send Break */
  142:                 if(parm) {
  143:                         *(UW*)(ba[unit] + UARTxLCR_H) |= UARTxLCR_H_BRK;
  144:                 } else {
  145:                         *(UW*)(ba[unit] + UARTxLCR_H) &= ~UARTxLCR_H_BRK;
  146:                 }
  147:                 break;
  148:         }
  149: 
  150:         return err;
  151: }
  152: 
  153: /*----------------------------------------------------------------------
  154:  * Device initialization
  155:  */
  156: EXPORT ER dev_ser_llinit( T_SER_DCB *p_dcb)
  157: {
  158:         const T_DINT   dint = {
  159:                 .intatr       = TA_HLNG,
  160:                 .inthdr       = uart_inthdr,
  161:         };
  162:         UW     unit;
  163:         ER     err;
  164: 
  165:         unit = p_dcb->unit;
  166: 
  167:         out_w( ba[unit] + UARTxCR, 0);
  168: 
  169:         /* UART device initialize */
  170:         out_w(ba[unit] + UARTxIMSC, 0);                        // Mask all interrupt
  171:         out_w(ba[unit] + UARTxECR, 0);                 // Clear error
  172:         out_w(ba[unit] + UARTxIFLS,                    // Set FIFO level
  173:                         UARTxIFLS_RXIFLSEL(UARTxIFLS_RXINI) |
  174:                         UARTxIFLS_TXIFLSEL(UARTxIFLS_TXINI));
  175:         out_w(ba[unit] + UARTxICR, 0x000007FF);                // Clear interrupt
  176:         out_w(ba[unit] + UARTxDMACR, 0);               // Stop DMA
  177: 
  178:         /* Device Control block Initizlize */
  179:         p_dcb->intno_rcv = p_dcb->intno_snd = INTNO_UART0 + unit;
  180: 
  181:         /* Interrupt handler definition */
  182:         err = tk_def_int((INTNO_UART0 + unit), &dint);
  183: 
  184:         stop_com(unit);
  185: 
  186:         return err;
  187: }
  188: 
  189: #endif          /* DEV_SER_ENABLE */
  190: #endif          /* CPU_TMPM367FDFG */