gonzui


Format: Advanced Search

mtkernel_3/device/adc/sysdepend/tx03_m367/adc_m367.cbare sourcepermlink (0.02 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 "../../adc.h"
   19: #include "../../../include/dev_def.h"
   20: #if DEV_ADC_ENABLE
   21: /*
   22:  *      dev_adc_m367.c
   23:  *      A/D converter device driver
   24:  *      System dependent processing for TX03_M367
   25:  */
   26: 
   27: /*----------------------------------------------------------------------
   28:  * Device register base address
   29: */
   30: const LOCAL UW ba[DEV_ADC_UNITNM] = { ADA_BASE, ADB_BASE };
   31: 
   32: /*----------------------------------------------------------------------
   33:  * Device control data
   34: */
   35: LOCAL struct {
   36:         ID     wait_tskid;
   37: } ll_devcb[DEV_ADC_UNITNM];
   38: 
   39: 
   40: /*----------------------------------------------------------------------
   41:  * Interrupt handler
   42:  */
   43: void adc_inthdr( UINT intno)
   44: {
   45:         INT            unit;
   46: 
   47:         unit = (intno == INTNO_INTADA? DEV_ADC_UNIT0: DEV_ADC_UNIT1);
   48:         tk_wup_tsk(ll_devcb[unit].wait_tskid);
   49: }
   50: 
   51: /*----------------------------------------------------------------------
   52:  * A/D convert
   53:  */
   54: LOCAL UW adc_convert( UINT unit, INT ch, INT size, UW *buf )
   55: {
   56:         UW     addr, rtn;
   57: 
   58:         if(ch < 0 || ch >= ADC_CH_NUM) return E_PAR;
   59: 
   60:         ll_devcb[unit].wait_tskid = tk_get_tid();
   61: 
   62:         if( size == 1) {
   63:                 /* channel fixed single convert */
   64:                 out_w( ba[unit] + ADxMOD3, ADMD_CHFIX_SINGLE);        // Ch.Fixed Single mode
   65:                 out_w( ba[unit] + ADxMOD2, ch);                       // MOD2.ADCH = Channel
   66:                 
   67:         } else  if(( ch + size ) <= ADC_CH_NUM ) {
   68:                 /* channel scan single convert */
   69:                 out_w( ba[unit] + ADxMOD3, ADMD_CHSCAN_SINGLE);       // Ch.Fixed scan mode
   70:                 out_w( ba[unit] + ADxMOD4, ch | ((size-1)<<4));       // MOD4.SCANSTA = ch, .SCANAREA = size-1
   71: 
   72:         } else {
   73:                 return (UW)E_PAR;
   74:         }
   75: 
   76:         tk_can_wup(TSK_SELF);
   77:         out_w( ba[unit] + ADxMOD0, ADxMOD0_ADS);       // MOD0.ADS = 1  Start Covert
   78: 
   79:         rtn = (UW)tk_slp_tsk(unit?DEVCNF_ADCB_INTPRI:DEVCNF_ADCA_TMOSCAN);
   80:         if(rtn == E_OK) {
   81:                 addr = ba[unit] + ADxREG00 + (ch<<2);
   82:                 rtn = size;
   83:                 while( size-- > 0) {
   84:                         *buf++ = in_w( addr) & 0x0000FFF;
   85:                         addr += 4;
   86:                 }
   87:                 in_w( ba[unit] + ADxMOD5);    // clear MOD5.EOCF
   88:         }
   89: 
   90:         return rtn;
   91: }
   92: 
   93: 
   94: /*----------------------------------------------------------------------
   95:  * Low level device control
   96:  */
   97: EXPORT W dev_adc_llctl( UW unit, INT cmd, UW p1, UW p2, UW *pp)
   98: {
   99:         W      rtn  = (W)E_OK;
  100: 
  101:         switch(cmd) {
  102:         case LLD_ADC_OPEN:     /* Open A/DC */
  103:                 if(unit == DEV_ADC_UNIT0) {
  104:                         out_w(ba[unit] + ADxCLK, DEVCNF_ADCA_CLK);   // Clock setting
  105:                         EnableInt(INTNO_INTADA, DEVCNF_ADCA_INTPRI);
  106:                 } else {
  107:                         out_w(ba[unit] + ADxCLK, DEVCNF_ADCB_CLK);   // Clock setting
  108:                         EnableInt(INTNO_INTADB, DEVCNF_ADCB_INTPRI);
  109:                 }
  110:                 out_w(ba[unit] + ADxMOD1, ADxMOD1_DACON);             // MOD1.DACON = 1
  111:                 break;
  112: 
  113:         case LLD_ADC_CLOSE:    /* Close A/DC */
  114:                 DisableInt((unit?INTNO_INTADB:INTNO_INTADA));
  115:                 out_w(ba[unit] + ADxMOD1, 0);         // MOD1.DACON = 0
  116:                 break;
  117:         
  118:         case LLD_ADC_READ:     /* Read A/DC data */
  119:                 rtn = adc_convert(unit, p1, p2, pp);
  120:                 break;
  121:         
  122:         case LLD_ADC_RSIZE:    /* Get read data size */
  123:                 rtn = ADC_CH_NUM - p1;
  124:                 if(rtn < 0 ) rtn = 0;
  125:                 break;
  126: 
  127:         }
  128:         
  129:         return rtn;
  130: }
  131: 
  132: /*----------------------------------------------------------------------
  133:  * Device initialization
  134:  */
  135: EXPORT ER dev_adc_llinit( T_ADC_DCB *p_dcb)
  136: {
  137:         const T_DINT   dint = {
  138:                 .intatr       = TA_HLNG,
  139:                 .inthdr       = adc_inthdr,
  140:         };
  141:         ER     err;
  142: 
  143:         /* Interrupt handler definition */
  144:         err = tk_def_int((p_dcb->unit?INTNO_INTADB:INTNO_INTADA), &dint);
  145: 
  146:         return err;
  147: }
  148: 
  149: #endif          /* DEV_ADC_ENABLE */
  150: #endif          /* CPU_TMPM367FDFG */