gonzui


Format: Advanced Search

mtkernel_3/device/adc/sysdepend/rx231/adc_rx231.cbare sourcepermlink (0.03 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_RX231
   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_rx231.c
   23:  *      A/D converter device driver
   24:  *      System dependent processing for RX231
   25:  */
   26: 
   27: /*----------------------------------------------------------------------
   28:  * Device control data
   29: */
   30: LOCAL struct {
   31:         ID     wait_tskid;
   32: } ll_devcb;
   33: 
   34: 
   35: /*----------------------------------------------------------------------
   36:  * Interrupt handler
   37:  */
   38: void adc_inthdr( UINT intno)
   39: {
   40:         ClearInt(intno);
   41:         tk_wup_tsk(ll_devcb.wait_tskid);
   42: }
   43: 
   44: /*----------------------------------------------------------------------
   45:  * A/D convert
   46:  */
   47: LOCAL UW adc_convert( INT start, INT size, UW *buf )
   48: {
   49:         INT    ch, end;
   50:         ER     err;
   51: 
   52:         ll_devcb.wait_tskid = tk_get_tid();
   53:         tk_can_wup(TSK_SELF);
   54: 
   55:         if((start > 7 && start <16) || start > 31) return E_PAR;
   56:         if( start >= 16) start -= 8;
   57:         end = start + size -1;
   58:         if( end > 31) return (UW)E_PAR;
   59: 
   60:         /* Set target channel */
   61:         for(ch = start; ch <= end; ch++) {
   62:                 if(ch <= 7) {
   63:                         *(UH*)(ADANSA0) |= (1<<ch);
   64:                 } else {
   65:                         *(UH*)(ADANSA1) |= (1<<(ch-8));
   66:                 }
   67:         }
   68: 
   69:         out_h(ADCSR, ADCSR_ADST | ADCSR_ADIE); // Start Covert
   70: 
   71:         err = tk_slp_tsk(DEVCNF_ADC_TMOSCAN);
   72:         if(err != E_OK) return (UW)err;
   73: 
   74:         for(ch = start; ch <= end; ch++) {     /* Read data */
   75:                 if(ch <= 7) {
   76:                         *buf++ = (UW)in_h(ADDR(ch));
   77:                 } else {
   78:                         *buf++ = (UW)in_h(ADDR(ch+8));
   79:                 }
   80:         }
   81:         return (UW)size;
   82: }
   83: 
   84: 
   85: /*----------------------------------------------------------------------
   86:  * Low level device control
   87:  */
   88: EXPORT W dev_adc_llctl( UW unit, INT cmd, UW p1, UW p2, UW *pp)
   89: {
   90:         UW     rtn = (UW)E_OK;
   91: 
   92:         switch(cmd) {
   93:         case LLD_ADC_OPEN:     /* Open A/DC */
   94:                 out_h(ADANSA0,0);
   95:                 out_h(ADANSA1,0);
   96:                 EnableInt(INTNO_S10ADI0, DEVCNF_ADC_INTPRI);
   97:                 break;
   98: 
   99:         case LLD_ADC_CLOSE:    /* Close A/DC */
  100:                 DisableInt(INTNO_S10ADI0);
  101:                 break;
  102:         
  103:         case LLD_ADC_READ:     /* Read A/DC data */
  104:                 rtn = adc_convert(p1, p2, pp);
  105:                 break;
  106:         
  107:         case LLD_ADC_RSIZE:    /* Get read data size */
  108:                 if((p1 > 7 && p1 <16) || p1 > 31) return (UW)E_PAR;
  109:                 rtn = ADC_CH_NUM - (p1<=7?p1:p1-8);
  110:                 if(rtn < 0 ) rtn = 0;
  111:                 break;
  112: 
  113:         }
  114:         
  115:         return rtn;
  116: }
  117: 
  118: /*----------------------------------------------------------------------
  119:  * Device initialization
  120:  */
  121: EXPORT ER dev_adc_llinit( T_ADC_DCB *p_dcb)
  122: {
  123:         const T_DINT   dint = {
  124:                 .intatr       = TA_HLNG,
  125:                 .inthdr       = adc_inthdr,
  126:         };
  127:         ER     err;
  128: 
  129: #if DEVCONF_ADC_INIT_MSTP               // Initialize module stop
  130:         UINT   sts;
  131: 
  132:         if(in_w(MSTPCRA) & (1<<17)) {
  133:                 DI(sts);
  134:                 out_h(SYSTEM_PRCR, 0xA502);   /* Disable Register Protect */
  135:                 *(UW*)(MSTPCRA) &= ~(1<<17);  /* Release module stop */
  136:                 out_h(SYSTEM_PRCR, 0xA500);   /* Enable Register protect */
  137:                 EI(sts);
  138:         }
  139: #endif  /* DEVCONF_ADC_INIT_MSTP */
  140: 
  141: #if DEVCONF_ADC_INIT_PIN                // Initialize I/O pin
  142:         INT    i;
  143:         UB     cnf;
  144: 
  145:         out_b(MPC_PWPR, 0);                            // PWPR.B0WI = 0
  146:         out_b(MPC_PWPR, MPC_PWMR_PFSWE);               // PWPR.PFSWE = 1
  147: 
  148:         /* P40-P47 = AN00-AN07 */
  149:         cnf = DEVCONF_ENA_AN00_07;
  150:         *(UB*)PORT4_PDR &= ~cnf;               // Set input port
  151:         *(UB*)PORT4_PMR &= ~cnf;               // Set General-purpose i/o port
  152:         for( i = 0; i < 8; i++, cnf<<=1) {
  153:                 if(cnf & 1) {
  154:                         out_b(MPC_P4nPFS(i), MPC_PFS_ASEL);
  155:                 }
  156:         }
  157: 
  158:         /* PE0-PE7 = AN16-AN23 */
  159:         cnf = DEVCONF_ENA_AN16_23;
  160:         *(UB*)PORTE_PDR &= ~cnf;               // Set input port
  161:         *(UB*)PORTE_PMR &= ~cnf;               // Set General-purpose i/o port
  162:         for( i = 0; i < 8; i++, cnf<<=1) {
  163:                 if(cnf & 1) {
  164:                         out_b(MPC_PEnPFS(i), MPC_PFS_ASEL);
  165:                 }
  166:         }
  167: 
  168:         /* PD0-PD7 = AN24-AN31 */
  169:         cnf = DEVCONF_ENA_AN24_31;
  170:         *(UB*)PORTD_PDR &= ~cnf;               // Set input port
  171:         *(UB*)PORTD_PMR &= ~cnf;               // Set General-purpose i/o port
  172:         for( i = 0; i < 8; i++, cnf<<=1) {
  173:                 if(cnf & 1) {
  174:                         out_b(MPC_PDnPFS(i), MPC_PFS_ASEL);
  175:                 }
  176:         }
  177: 
  178:         out_b(MPC_PWPR, MPC_PWMR_B0WI);                // PWPR.PFSWE = 0, PWPR.B0WI = 1
  179: #endif          /* DEVCONF_ADC_INIT_PIN */
  180: 
  181:         /* ADC device initialize */
  182:         out_h(ADCER, ADCER_INI);
  183: 
  184:         out_h(ADSSTR(0), DEVCNF_ADSSTR0_INI);  // Set sampling rate
  185:         out_h(ADSSTR(1), DEVCNF_ADSSTR1_INI);
  186:         out_h(ADSSTR(2), DEVCNF_ADSSTR2_INI);
  187:         out_h(ADSSTR(3), DEVCNF_ADSSTR3_INI);
  188:         out_h(ADSSTR(4), DEVCNF_ADSSTR4_INI);
  189:         out_h(ADSSTR(5), DEVCNF_ADSSTR5_INI);
  190:         out_h(ADSSTR(6), DEVCNF_ADSSTR6_INI);
  191:         out_h(ADSSTR(7), DEVCNF_ADSSTR7_INI);
  192:         out_h(ADSSTRL, DEVCNF_ADSSTRL_INI);
  193: 
  194:         /* Interrupt handler definition */
  195:         err = tk_def_int(INTNO_S10ADI0, &dint);
  196: 
  197:         return err;
  198: }
  199: 
  200: #endif          /* DEV_ADC_ENABLE */
  201: #endif          /* CPU_RX231 */