Пример #1
0
/**
 * pinMode
 * 
 * Config pin mode
 * 
 * @param pin pin number
 * @param mode pin mode
 */
void pinMode(uint8_t pin, uint8_t mode) 
{
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);

	volatile uint8_t *dir = portDirRegister(port);
	volatile uint8_t *ren = portRenRegister(port);
	volatile uint8_t *out = portOutputRegister(port);
	volatile uint8_t *sel = portSelRegister(port);

  *sel &= ~bit;     // Unselect alternate function
   
  switch(mode)
  {
    case INPUT:
      *dir &= ~bit;
      break;
    case INPUT_PULLUP:
      *dir &= ~bit;
      *out |= bit;
      *ren |= bit;
      break;
    case INPUT_PULLDOWN:
      *dir &= ~bit;
      *out &= ~bit;
      *ren |= bit;
      break;
    case OUTPUT:
      *dir |= bit;
      break;
    default:
      break;
  }
}
Пример #2
0
void pwm::pinSetting(uint8_t pin){
    uint8_t bit = digitalPinToBitMask(pin); // get pin bit
    uint8_t port = digitalPinToPort(pin);   // get pin port
    volatile uint8_t *sel;

    if (port == NOT_A_PORT) return; // pin on timer?

    sel = portSelRegister(port); // get the port function select register address
    *sel |= bit;                 // set bit in pin function select register
    /// set pin in output mode
    pinMode(pin, OUTPUT);

}
Пример #3
0
  TouchPin::TouchPin(uint8_t pin, int16_t threshold ){                 // select given pin as a capacitive touch pin
  	_bit  = digitalPinToBitMask(pin);
	_port = digitalPinToPort(pin);
	volatile uint16_t *reg = portSelRegister(_port);
	*reg  &= ~_bit; //reset portselect bit
	reg = portSel2Register(_port);
	*reg  &= ~_bit; //reset portselect2 bit
	

  	reg = portDirRegister(_port);
	*reg  &= ~_bit; //set port as input 
  	reg = portRenRegister(_port);
	*reg  |= _bit; //enable pullup register when port is input 

	_threshold = threshold;
  }
Пример #4
0
void pinMode(uint8_t pin, uint8_t mode)
{

	volatile uint32_t *dir;
	volatile uint8_t *sel;
	volatile uint32_t *out;
	volatile uint32_t *pud;
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	dir = portDirRegister(port);
	sel = portSelRegister(port);
	out = portOutputRegister(port);
	pud = portPullupRegister(port);

	if (port == NOT_A_PORT) return;

	if(pin > 31){
		pin -= 32;
	}

	EALLOW;
	//Turn off peripheral function
	if(port == PORT_A_2){
		*sel &= ~((uint32_t)0x03 << ((pin-16) * 2));
	}else{
		*sel &= ~((uint32_t)0x03 << (pin * 2));
	}
	*dir &= ~((uint32_t)1 << pin);
	*dir |= ((uint32_t)(mode & 0x01) << pin);

	if(mode == INPUT_PULLUP){
		*pud &= ~((uint32_t)1 << pin);
	}else{
		*pud |= ((uint32_t)1 << pin);
	}

	EDIS;

}
Пример #5
0
void analogWrite(uint8_t pin, int val)
{
        pinMode(pin, OUTPUT); // pin as output

 	if (val == 0)
	{
		digitalWrite(pin, LOW); // set pin to LOW when duty cycle is 0
                                        // digitalWrite will take care of invalid pins
	}
	else if (val == 255)
	{
		digitalWrite(pin, HIGH); // set pin HIGH when duty cycle is 255
                                         // digitalWrite will take care of invalid pins
	}
	else
	{

	        uint8_t bit = digitalPinToBitMask(pin); // get pin bit
	        uint8_t port = digitalPinToPort(pin);   // get pin port
	        volatile uint16_t *sel;
	        volatile uint16_t *sel2;
                
                if (port == NOT_A_PORT) return; // pin on timer?
               
	        sel = portSelRegister(port); // get the port function select register address
		*sel |= bit;                 // set bit in pin function select register  
                
                //TODO: Firgure out a better way to determine if SEL2 needs to be set
	        if(bit == BV(4) && port == P1) {
                        sel2 = portSel2Register(port); // get the port function select register address
                        *sel2 |= bit;
                }
                switch(digitalPinToTimer(pin)) {                // which timer and CCR?
 			//case: T0A0                            // CCR0 used as period register
			case T0A1:                              // Timer0 / CCR1
                                TA0CCR0 = PWM_PERIOD;           // PWM Period
                                TA0CCTL1 = OUTMOD_7;            // reset/set
                                TA0CCR1 = PWM_DUTY(val);       // PWM duty cycle
                                TA0CTL = TASSEL_2 + MC_1 + analog_div;       // SMCLK, up mode
                                break;
#if defined(__MSP430_HAS_TA3__) 
 			case T0A2:                              // Timer0 / CCR1
                                TA0CCR0 = PWM_PERIOD;           // PWM Period
                                TA0CCTL2 = OUTMOD_7;            // reset/set
                                TA0CCR2 = PWM_DUTY(val);       // PWM duty cycle
                                TA0CTL = TASSEL_2 + MC_1+ analog_div;       // SMCLK, up mode
                                break;
#endif
#if defined(__MSP430_HAS_T1A3__) 
 			//case: T1A0                            // CCR0 used as period register
			case T1A1:                              // Timer0 / CCR1
                                TA1CCR0 = PWM_PERIOD;           // PWM Period
                                TA1CCTL1 = OUTMOD_7;            // reset/set
                                TA1CCR1 = PWM_DUTY(val);       // PWM duty cycle
                                TA1CTL = TASSEL_2 + MC_1+ analog_div;       // SMCLK, up mode
                                break;
 			case T1A2:                              // Timer0 / CCR1
                                TA1CCR0 = PWM_PERIOD;           // PWM Period
                                TA1CCTL2 = OUTMOD_7;            // reset/set
                                TA1CCR2 = PWM_DUTY(val);       // PWM duty cycle
                                TA1CTL = TASSEL_2 + MC_1+ analog_div;       // SMCLK, up mode
                                break;
#endif
#if defined(__MSP430_HAS_T2A3__)  
 			//case: T2A0                            // CCR0 used as period register
			case T2A1:                              // Timer0 / CCR1
                                TA2CCR0 = PWM_PERIOD;           // PWM Period
                                TA2CCTL1 = OUTMOD_7;            // reset/set
                                TA2CCR1 = PWM_DUTY(val);       // PWM duty cycle
                                TA2CTL = TASSEL_2 + MC_1+ analog_div;       // SMCLK, up mode
                                break;
 			case T2A2:                              // Timer0 / CCR1
                                TA2CCR0 = PWM_PERIOD;           // PWM Period
                                TA2CCTL2 = OUTMOD_7;            // reset/set
                                TA2CCR2 = PWM_DUTY(val);       // PWM duty cycle
                                TA2CTL = TASSEL_2 + MC_1+ analog_div;       // SMCLK, up mode
                                break;
#endif
                        case NOT_ON_TIMER:                      // not on a timer output pin
			default:                                // or TxA0 pin
				if (val < 128) {
					digitalWrite(pin, LOW); // 
				} else {
					digitalWrite(pin, HIGH);
				}
                }
        }
}
Пример #6
0
void pinMode(uint8_t pin, uint8_t mode)
{

    if(pin & 0x8000)
    {

    	EALLOW;
        //Analog Pins
        pin &= 0x7FFF;

        if(mode == HARDWARE)
        {
            //Turn on normal analog functionality
            GpioCtrlRegs.AIOMUX1.all |= 3UL << (pin * 2);
        }
        else
        {
            //Turn on AIO functionality
            GpioCtrlRegs.AIOMUX1.all &= ~( 3UL << (pin * 2));

            if(mode == INPUT)
            {
                GpioCtrlRegs.AIODIR.all &= ~(1UL << pin);
            }
            else if(mode == OUTPUT)
            {
                GpioCtrlRegs.AIODIR.all |= (1UL << pin);
            }

        }
        EDIS;

    }
    else
    {
        //Digital Pins
	    volatile uint32_t *dir;
	    volatile uint32_t *sel;
	    volatile uint32_t *pud;
	    uint8_t port = digitalPinToPort(pin);
	    dir = portDirRegister(port);
	    sel = portSelRegister(port);
    	pud = portPullupRegister(port);

	    if (port == NOT_A_PORT) return;

    	if(pin > 31){
    		pin -= 32;
    	}

    	EALLOW;
    	//Turn off peripheral function
    	if(port == PORT_A_2){
    		*sel &= ~((uint32_t)0x03 << ((pin-16) * 2));
    	}else{
    		*sel &= ~((uint32_t)0x03 << (pin * 2));
    	}
    	*dir &= ~((uint32_t)1 << pin);
    	*dir |= ((uint32_t)(mode & 0x01) << pin);

    	if(mode == INPUT_PULLUP){
    		*pud &= ~((uint32_t)1 << pin);
    	}else{
    		*pud |= ((uint32_t)1 << pin);
    	}

    	EDIS;
    }

}
Пример #7
0
void pinMode(uint8_t pin, uint8_t mode)
{
    uint16_t gpio_number = pin_mapping[pin];

    if(gpio_number & 0x8000)
    {

    	EALLOW;
        //Analog Pins
#ifdef TMS320F28377S
    	AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    	AdcaRegs.ADCCTL2.bit.SIGNALMODE = 0; //single-ended
    	AdcaRegs.ADCCTL2.bit.RESOLUTION = 0; //12-bit
    	AdcaRegs.ADCSOC0CTL.bit.CHSEL = gpio_number & 0xF;
#else
        gpio_number &= 0x7FFF;

        if(mode == HARDWARE)
        {
            //Turn on normal analog functionality
            GpioCtrlRegs.AIOMUX1.all |= 3UL << (gpio_number * 2);
        }
        else
        {
            //Turn on AIO functionality
            GpioCtrlRegs.AIOMUX1.all &= ~( 3UL << (gpio_number * 2));

            if(mode == INPUT)
            {
                GpioCtrlRegs.AIODIR.all &= ~(1UL << gpio_number);
            }
            else if(mode == OUTPUT)
            {
                GpioCtrlRegs.AIODIR.all |= (1UL << gpio_number);
            }

        }
#endif
        EDIS;

    }
    else
    {
        //Digital Pins
	    volatile uint32_t *dir;
	    volatile uint32_t *sel;
	    volatile uint32_t *pud;
	    uint8_t port = digitalPinToPort(gpio_number);
	    dir = portDirRegister(port);
	    sel = portSelRegister(port);
    	pud = portPullupRegister(port);

	    if (port == NOT_A_PORT) return;

	    gpio_number %= 32; //limits gpio_number to 32 bits

    	EALLOW;
    	//Turn off peripheral function
    	if(port == PORT_A_2)
    	{
    		*sel &= ~((uint32_t)0x03 << ((gpio_number-16) * 2));
    	}
    	else
    	{
    		*sel &= ~((uint32_t)0x03 << (gpio_number * 2));
    	}
    	*dir &= ~((uint32_t)1 << gpio_number);
    	*dir |= ((uint32_t)(mode & 0x01) << gpio_number);

    	if(mode == INPUT_PULLUP)
    	{
    		*pud &= ~((uint32_t)1 << gpio_number);
    	}
    	else
    	{
    		*pud |= ((uint32_t)1 << gpio_number);
    	}

    	EDIS;
    }

}
Пример #8
0
/**
 * analogRead
 *
 * read ADC value
 *
 * @param pin pn number
 * 
 * @return ADC value
 */
uint16_t analogRead(uint8_t pin)
{
  uint8_t port, bit=0;
  volatile uint8_t *dir=NULL;
  
  uint16_t refGain = 0;
   
  uint8_t channel;
  
  // Disable ADC
  ADC12CTL0 &= ~ADC12ENC;
   
  // Special analog channel?
  if (pin >= 128)
  {
    channel = pin - 128;
    
    if (pin == A10)
      REFCTL0 &= ~REFTCOFF; // Temp sensor enabled
  }

  // Check if pin is an analog input
	else if ((channel = digitalPinToADCIn(pin)) == NOT_ON_ADC)
		return 0;
  else
  {
    bit = digitalPinToBitMask(pin);
    port = digitalPinToPort(pin);

    // Map pin as analog input
    volatile uint8_t *map = digitalPinToPortMap(pin);
    PMAPPWD = 0x02D52;
    PMAPCTL |= PMAPRECFG; // Leave Pin mapping open
    *map = PM_ANALOG;
    PMAPPWD = 0;
    
    // Select alternate function
    volatile uint8_t *sel = portSelRegister(port);
    *sel |= bit;
    
    dir = portDirRegister(port);
    *dir &= ~bit; // Configure pin as input
  }

  // Set ADC reference  
  if (analogRef == ADCREF_VCC)
      ADC12MCTL0 = ADC12SREF_0;  // Vr+=Vcc and Vr-=AVss
  else
  {
    // Enable shared reference
    REFCTL0 |= REFMSTR + analogRef + REFON;   
    ADC12MCTL0 = ADC12SREF_1;    // Vr+=Vref+ and Vr-=AVss
    
    // Select REF calibration gain
    switch(analogRef)
    {
      case ADCREF_1V5:
        refGain = CALIB_1V5REF_GAIN;
        break;
      case ADCREF_2V0:
        refGain = CALIB_2V0REF_GAIN;
        break;
      case ADCREF_2V5:
        refGain = CALIB_2V5REF_GAIN;
        break;
     }
  }

  ADC12IFG = 0;                                   // Clear flags
  ADC12CTL0 = ADC12SHT02 + ADC12ON;               // Sampling time=64 cycles, ADC12 on
  ADC12CTL1 = ADC12SHP;                           // Use sampling timer
  ADC12MCTL0 |= channel;                          // Select channel
  ADC12IE = 0;                                    // Disable interrupt
  
  __delay_cycles(1100);

  ADC12CTL0 |= ADC12ENC | ADC12SC;                // Enable ADC and start conversion

  while (!(ADC12IFG & BIT0));                     // Wait until ADC is completed

  ADC12IFG = 0;

  // POWER: Turn ADC and reference voltage off to conserve power
  ADC12CTL0 &= ~ADC12ENC;
  ADC12CTL0 &= ~ADC12ON;
  ADC12CTL0 &= ~ADC12REFON;
  REFCTL0 &= ~REFON;
  REFCTL0 |= REFTCOFF;  // Temp sensor disabled

  uint64_t result = ADC12MEM0;

  if (refGain)
    result *= refGain;

  result *= CALIB_ADC_GAIN;
  result /= 0x8000;
  
  if (refGain)
    result /= 0x8000;
    
  result += CALIB_ADC_OFFSET;

  return (uint16_t) result;
}
Пример #9
0
/**
 * analogWrite
 *
 * set PWM output level
 *
 * @param pin pin number
 * @param val duty cycle
 */
void analogWrite(uint8_t pin, uint16_t val)
{     
  if (val == 0)
  {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
  }
  else
  {
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);

    volatile uint8_t *dir = portDirRegister(port);
    volatile uint8_t *sel = portSelRegister(port);
    volatile uint8_t *map = digitalPinToPortMap(pin);
     
    *dir |= bit;                               // Config pin as an output
    *sel |= bit;                               // Select alternate function
    
    // Set PWM period
    TA0CCR0 = analogPeriod;
    TA1CCR0 = analogPeriod;
    
    uint8_t timer = digitalPinToTimer(pin);

    PMAPPWD = 0x02D52;                         // Get write-access to port mapping regs 
    PMAPCTL |= PMAPRECFG;                      // Leave Pin mapping open
        
    switch(timer)
    {
      case T0A1:
        *map = PM_TA0CCR1A;
        TA0CCTL1 = OUTMOD_7;                    // CCR1 reset/set
        TA0CCR1 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      case T0A2:
        *map = PM_TA0CCR2A;
        TA0CCTL2 = OUTMOD_7;                    // CCR1 reset/set
        TA0CCR2 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      case T0A3:
        *map = PM_TA0CCR3A;
        TA0CCTL3 = OUTMOD_7;                    // CCR1 reset/set
        TA0CCR3 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      case T0A4:
        *map = PM_TA0CCR4A;
        TA0CCTL4 = OUTMOD_7;                    // CCR1 reset/set
        TA0CCR4 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      case T1A1:
        *map = PM_TA1CCR1A;
        TA1CCTL1 = OUTMOD_7;                    // CCR1 reset/set
        TA1CCR1 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      case T1A2:
        *map = PM_TA1CCR2A;
        TA1CCTL2 = OUTMOD_7;                    // CCR1 reset/set
        TA1CCR2 = PWM_DUTY(val);                // CCR1 PWM duty cycle
        break;
      default:
        break;
    }

    PMAPPWD = 0;                               // Lock port mapping registers 
  
    if (timer < T1A1)
    {
      if (val == TA0CCR0)                     // duty cycle = period?
      {
        pinMode(pin, OUTPUT);
        digitalWrite(pin, HIGH);
      }
      else
        TA0CTL = TASSEL_2 + MC_1 + TACLR;     // SMCLK, up mode, clear TAR
    }
    else
    {
      if (val == TA1CCR0)                     // duty cycle = period?
      {
        pinMode(pin, OUTPUT);
        digitalWrite(pin, HIGH);
      }
      else
        TA1CTL = TASSEL_2 + MC_1 + TACLR;     // SMCLK, up mode, clear TAR
    }
  }
}