gonzui


Format: Advanced Search

mtkernel_3/device/adc/sysdepend/rza2m/adc_rza2m.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_RZA2M
   16: 
   17: #include <tk/tkernel.h>
   18: #include "../../adc.h"
   19: #include "../../../include/dev_def.h"
   20: #if DEV_ADC_ENABLE
   21: 
   22: /*
   23:  *      dev_adc_rza2m.c
   24:  *      A/D converter device driver
   25:  *      System dependent processing for RZ/A2M
   26:  */
   27: 
   28: /*----------------------------------------------------------------------
   29:  * Device control data
   30: */
   31: LOCAL struct {
   32:         ID     wait_tskid;
   33: } ll_devcb;
   34: 
   35: 
   36: /*----------------------------------------------------------------------
   37:  * Interrupt handler
   38:  */
   39: void adc_inthdr( UINT intno)
   40: {
   41:         ClearInt(intno);
   42:         tk_wup_tsk(ll_devcb.wait_tskid);
   43:         EndOfInt(intno);
   44: }
   45: 
   46: /*----------------------------------------------------------------------
   47:  * A/D convert
   48:  */
   49: LOCAL UW adc_convert( INT start, INT size, UW *buf )
   50: {
   51:         UH     chset = 0;
   52:         INT    end, ch;
   53:         ER     err;
   54: 
   55:         ll_devcb.wait_tskid = tk_get_tid();
   56:         tk_can_wup(TSK_SELF);
   57: 
   58:         if(start >= ADC_CH_NUM) return E_PAR;
   59:         end = start + size -1;
   60:         if( end >= ADC_CH_NUM) return E_PAR;
   61: 
   62:         /* Set target channel */
   63:         for(INT ch = start; ch <= end; ch++) {
   64:                 chset |= (1<<ch);
   65:         }
   66:         out_h(ADANSA0, chset);
   67: 
   68:         out_h(ADCSR, ADCSR_ADST | ADCSR_ADIE);         // Start Covert
   69: 
   70:         err = tk_slp_tsk(DEVCNF_ADC_TMOSCAN);
   71:         if(err != E_OK) return (UW)err;
   72: 
   73:         for(ch = start; ch <= end; ch++) {     /* Read data */
   74:                 *buf++ = (UW)in_h(ADDR(ch));
   75:         }
   76:         return (UW)size;
   77: }
   78: 
   79: 
   80: /*----------------------------------------------------------------------
   81:  * Low level device control
   82:  */
   83: EXPORT W dev_adc_llctl( UW unit, INT cmd, UW p1, UW p2, UW *pp)
   84: {
   85:         UW     rtn = (UW)E_OK;
   86: 
   87:         switch(cmd) {
   88:         case LLD_ADC_OPEN:     /* Open A/DC */
   89:                 EnableInt(INTNO_S12ADI0, DEVCNF_ADC_INTPRI);
   90:                 break;
   91: 
   92:         case LLD_ADC_CLOSE:    /* Close A/DC */
   93:                 DisableInt(INTNO_S12ADI0);
   94:                 break;
   95:         
   96:         case LLD_ADC_READ:     /* Read A/DC data */
   97:                 rtn = adc_convert(p1, p2, pp);
   98:                 break;
   99:         
  100:         case LLD_ADC_RSIZE:    /* Get read data size */
  101:                 if(p1  >= ADC_CH_NUM) return (UW)E_PAR;
  102:                 rtn = ADC_CH_NUM - p1;
  103:                 break;
  104: 
  105:         }
  106:         
  107:         return rtn;
  108: }
  109: 
  110: /*----------------------------------------------------------------------
  111:  * Device initialization
  112:  */
  113: EXPORT ER dev_adc_llinit( T_ADC_DCB *p_dcb)
  114: {
  115:         const T_DINT   dint = {
  116:                 .intatr       = TA_HLNG,
  117:                 .inthdr       = adc_inthdr,
  118:         };
  119:         ER     err;
  120: 
  121: #if DEVCONF_ADC_INIT_MSTP               // Initialize module stop
  122:         UB     stbc;
  123: 
  124:         stbc = in_b(CPG_STBCR5);
  125:         out_b(CPG_STBCR5, stbc & 0x7F);
  126:         stbc = in_b(CPG_STBCR5);       // dummy read
  127:         
  128: #endif  /* DEVCONF_ADC_INIT_MSTP */
  129: 
  130: #if DEVCONF_ADC_INIT_PIN                // Initialize I/O pin
  131:         UH     pdr;
  132:         UB     cnf;
  133: 
  134:         /* Pin function selection */
  135:         out_b(PORT_PWPR, 0);
  136:         out_b(PORT_PWPR, PORT_PWPR_PFSWE);             /* Allow writing to PFS */
  137: 
  138:         cnf = DEVCONF_ENA_AN00_07;
  139:         pdr = in_h(PORT5_PDR);
  140:         for(INT i = 0; i < 8; i++, cnf<<=1) {
  141:                 if(cnf & 1) {
  142:                         pdr &= ~(0x03<<(i*2));
  143:                         out_b(PORT5n_PFS(i), PORT_PFS_PSEL(1));
  144:                 }
  145:         }
  146: 
  147:         out_b(PORT_PWPR, PORT_PWPR_B0WI);              /* Prohibit writing to PFS */
  148: 
  149:         out_h(PORT5_PDR, pdr);
  150:         *(UB*)PORT5_PMR |= cnf;
  151: 
  152: #endif          /* DEVCONF_ADC_INIT_PIN */
  153: 
  154:         /* ADC device initialize */
  155:         out_h(ADCSR, 0);               // ADC stop, Single scan mode
  156: 
  157:         // Set sampling rate
  158:         out_b(ADSSTR(0), DEVCNF_ADSSTR0_INI);
  159:         out_b(ADSSTR(1), DEVCNF_ADSSTR1_INI);
  160:         out_b(ADSSTR(2), DEVCNF_ADSSTR2_INI);
  161:         out_b(ADSSTR(3), DEVCNF_ADSSTR3_INI);
  162:         out_b(ADSSTR(4), DEVCNF_ADSSTR4_INI);
  163:         out_b(ADSSTR(5), DEVCNF_ADSSTR5_INI);
  164:         out_b(ADSSTR(6), DEVCNF_ADSSTR6_INI);
  165:         out_b(ADSSTR(7), DEVCNF_ADSSTR7_INI);
  166: 
  167:         /* Interrupt handler definition */
  168:         err = tk_def_int(INTNO_S12ADI0, &dint);
  169: 
  170:         return err;
  171: }
  172: 
  173: #endif          /* DEV_ADC_ENABLE */
  174: #endif          /* CPU_RZA2M */