Example #1
0
void DoSpiTx(char port, char *string)
{
  SPI_t *Port;

    switch(port)
    {
      case 'c':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPIC);
	    break;
      case 'd':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPID);
	    break;
      case 'e':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPIE);
	    break;
      default:
	    Error("Illegal port");
	    return; // if no valid port, return
    };

    while(*string != 0)
	{
		Port->DATA = *string++;
        	if(!(Port->STATUS&(1<<7)))
		while(!(Port->STATUS & (1<<7))); // wait for TX complete
  		Port->STATUS |= (1<<7);  // clear TX interrupt flag
	};
};
// -----------------------------------------------------------------------------
//                                                                 init_channels
// -----------------------------------------------------------------------------
inline void init_channels() {
  // hardcoded ports and pins
  // use _SFR_IO_ADDR(PORTA) + 32 for ports 
  // and ~(1<<pinnumber) for pins
  // servo.stop = base value - (x * 12MHz) / 22
  //    where x is the time you want added to 400us
  SET(PORTD, PD5);
  uint8_t i = 0;
  for (i = 0; i < 8; ++i) {
    servo_channels[i].servo.stopbytes[1] =  eeprom_read_byte(i<<1);
    servo_channels[i].servo.stopbytes[0] =  eeprom_read_byte((i<<1) + 1);
    // servo_channels[i].servo.stop = ((ASM1700HI<<8)|(ASM1700LO)) - MIDPULSE;
    servo_channels[i].port = _SFR_IO_ADDR(PORTA) + 32;
    servo_channels[i].pin = ~(1<<i);
  }
  for (i = 8; i < SERVO_AMOUNT; ++i) {
    servo_channels[i].servo.stopbytes[1] =  eeprom_read_byte(i<<1);
    servo_channels[i].servo.stopbytes[0] =  eeprom_read_byte((i<<1) + 1);
    // servo_channels[i].servo.stop = ((ASM1700HI<<8)|(ASM1700LO)) - MIDPULSE;
    servo_channels[i].port = _SFR_IO_ADDR(PORTC) + 32;
    servo_channels[i].pin = ~(1<<(i - 6));
  }
  DDRA = 0xFF;
  PORTA = 0x00;
  DDRC |= (1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5);
  PORTC &= ~((1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5));

  // servo_channels[0].servo.stop = ((ASM1700HI<<8)|(ASM1700LO)) - 328;
  CLR(PORTD, PD5);

  // TODO add offsets per pin based on their pos in cycle
}
Example #3
0
void DoSpiConfig(char port, unsigned int div)
{
  SPI_t *Port;

    switch(port)
    {
      case 'c':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPIC);
		PORTC.DIR |= (1<<4) | (1<<5) | (1<<7);
	    break;
      case 'd':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPID);
		PORTD.DIR |= (1<<4) | (1<<5)| (1<<7);
	    break;
      case 'e':
	    Port = (SPI_t*)_SFR_IO_ADDR(SPIE);
		PORTE.DIR |= (1<<4) | (1<<5)| (1<<7);
	    break;
      default:
	    Error("Illegal port");
	    return; // if no valid port, return
    };

	Port->CTRL = 0x50 | (div & 0x3);
};
Example #4
0
ISR (WDT_vect, ISR_NAKED){ //will occur after 4 seconds of displaying the current number.
  asm(
    "sbi  %0,%1 \n\t" //This operation won't affect SREG and will make a noticable change to the register
    "reti       \n\t" //return from interrupt
    : 
    : "I" (_SFR_IO_ADDR(watchdogTimeout)), "I" (watchdogFlagBit)
  );
}
Example #5
0
void servoTest(void)
{
	u08 pos;
	u08 channel;

	// do some examples
	// initialize RC servo system
	servoInit();
	// setup servo output channel-to-I/Opin mapping
	// format is servoSetChannelIO( CHANNEL#, PORT, PIN );
	servoSetChannelIO(0, _SFR_IO_ADDR(PORTC), PC0);
	servoSetChannelIO(1, _SFR_IO_ADDR(PORTC), PC1);
	servoSetChannelIO(2, _SFR_IO_ADDR(PORTC), PC2);
	servoSetChannelIO(3, _SFR_IO_ADDR(PORTC), PC3);

	// set port pins to output
	outb(DDRC, 0x0F);

	pos = 0;

#define SPEED_SERVO	1

	// spin servos sequentially back and forth between their limits
	while(1)
	{
		for(channel=0; channel<SERVO_NUM_CHANNELS; channel++)
		{
			for(pos=0; pos<SERVO_POSITION_MAX; pos++)
			{
				servoSetPosition(channel,pos);
				timerPause(SPEED_SERVO);
			}
		}

		for(channel=0; channel<SERVO_NUM_CHANNELS; channel++)
		{
			for(pos=SERVO_POSITION_MAX; pos>=1; pos--)
			{
				servoSetPosition(channel,pos);
				timerPause(SPEED_SERVO);
			}
		}
	}
}
Example #6
0
int DoOutput(char port, unsigned int pin, unsigned int val)
{
  PORT_t *Port;

  switch(port)
  {
    case 'a':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTA);
	  break;
    case 'b':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTB);
	  break;
    case 'c':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTC);
	  break;
    case 'd':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTD);
	  break;
    case 'e':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTE);
	  break;
    case 'f':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTF);
	  break;
    default:
	  return -1; // if no valid port, return
  };
};
Example #7
0
//! initializes software PWM system
void servoInit(void)
{
	u08 channel;
	// disble the timer1 output compare A interrupt
	cbi(TIMSK, OCIE1A);
	// set the prescaler for timer1
	timer1SetPrescaler(TIMER_CLK_DIV256);
	// attach the software PWM service routine to timer1 output compare A
	timerAttach(TIMER1OUTCOMPAREA_INT, servoService);
	// enable and clear channels
	for(channel=0; channel<SERVO_NUM_CHANNELS; channel++)
	{
		// set minimum position as default
		ServoChannels[channel].duty = SERVO_MIN;
		// set default port and pins assignments
		ServoChannels[channel].port = _SFR_IO_ADDR(SERVO_DEFAULT_PORT);
		//ServoChannels[channel].port = (unsigned char)&SERVO_DEFAULT_PORT;
		ServoChannels[channel].pin = (1<<channel);
		// set channel pin to output
		// THIS IS OBSOLETED BY THE DYNAMIC CHANNEL TO PORT,PIN ASSIGNMENTS
		//outb(SERVODDR, inb(SERVODDR) | (1<<channel));
	}
	// set PosTics
	ServoPosTics = 0;
	// set PeriodTics
	ServoPeriodTics = SERVO_MAX*9;
	// set initial interrupt time
	u16 OCValue;
	// read in current value of output compare register OCR1A
	OCValue =  inb(OCR1AL);		// read low byte of OCR1A
	OCValue += inb(OCR1AH)<<8;	// read high byte of OCR1A
	// increment OCR1A value by nextTics
	OCValue += ServoPeriodTics; 
	// set future output compare time to this new value
	outb(OCR1AH, (OCValue>>8));			// write high byte
	outb(OCR1AL, (OCValue & 0x00FF));	// write low byte
	// enable the timer1 output compare A interrupt
	sbi(TIMSK, OCIE1A);
}
Example #8
0
  int DoInput(char port, unsigned int pin)
{
  PORT_t *Port;

  switch(port)
  {
    case 'a':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTA);
	  break;
    case 'b':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTB);
	  break;
    case 'c':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTC);
	  break;
    case 'd':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTD);
	  break;
    case 'e':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTE);
	  break;
    case 'f':
	  Port = (PORT_t*)_SFR_IO_ADDR(PORTF);
	  break;
    default:
	  return -1; // if no valid port, return
  };

  if(pin > 7) { return -1; };

  Port->DIR &= ~(1<<pin);  // configure port as input
  if(Port->IN & (1<<pin))
    return 1;
  else
    return 0;

};
Example #9
0
void shiftDmxOut(int pin, int theByte)
{
  int port_to_output[] = {
    NOT_A_PORT,
    NOT_A_PORT,
    _SFR_IO_ADDR(PORTB),
    _SFR_IO_ADDR(PORTC),
    _SFR_IO_ADDR(PORTD)
    };

    int portNumber = port_to_output[digitalPinToPort(pin)];
  int pinMask = digitalPinToBitMask(pin);

  // the first thing we do is to write te pin to high
  // it will be the mark between bytes. It may be also
  // high from before
  _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
  delayMicroseconds(10);

  // disable interrupts, otherwise the timer 0 overflow interrupt that
  // tracks milliseconds will make us delay longer than we want.
  cli();

  // DMX starts with a start-bit that must always be zero
  _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask;

  // we need a delay of 4us (then one bit is transfered)
  // this seems more stable then using delayMicroseconds
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  for (int i = 0; i < 8; i++)
  {
    if (theByte & 01)
    {
      _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
    }
    else
    {
      _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask;
    }

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    theByte >>= 1;
  }

  // the last thing we do is to write the pin to high
  // it will be the mark between bytes. (this break is have to be between 8 us and 1 sec)
  _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;

  // reenable interrupts.
  sei();
}
Example #10
0
 constexpr RegisterConfig(volatile uint8_t &reg, const uint8_t value) :
      _u8RegNr{static_cast<uint8_t>(_SFR_IO_ADDR(reg))}, _u8RegValue{value} {}
Example #11
0
void DoUsartTx(char port, unsigned int num, char *string)
{
  USART_t *Port;

  if(num==0)
  {
    switch(port)
    {
      case 'c':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTC0);
		PORTC.DIR |= (1<<3);
	    break;
      case 'd':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTD0);
		PORTD.DIR |= (1<<3);
	    break;
      case 'e':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTE0);
		PORTE.DIR |= (1<<3);
	    break;
      case 'f':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTF0);
		PORTF.DIR |= (1<<3);
	    break;
      default:
	    Error("Illegal port");
	    return; // if no valid port, return
    };
  }
  else if(num==1)
  {
    switch(port)
    {
      case 'c':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTC1);
		PORTC.DIR |= (1<<7);
	    break;
      case 'd':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTD1);
		PORTD.DIR |= (1<<7);
	    break;
      case 'e':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTE1);
		PORTE.DIR |= (1<<7);
	    break;
      case 'f':
	    Port = (USART_t*)_SFR_IO_ADDR(USARTF1);
		PORTF.DIR |= (1<<7);
	    break;
      default:
	    Error("Illegal port");
	    return; // if no valid port, return
    };
  }
  else
  {
    Error("Illegal port num");
    return;
  };

    while(*string != 0)
	{
		Port->DATA = *string++;
        	if(!(Port->STATUS&USART_DREIF_bm))
		while(!(Port->STATUS & USART_TXCIF_bm)); // wait for TX complete
  		Port->STATUS |= USART_TXCIF_bm;  // clear TX interrupt flag
	};

};
Example #12
0
// PD6 12|    |17  PB3
// PD7 13|    |16  PB2
// PB0 14|    |15  PB1
//       +----+

#define NUM_PINS 28
#define NUM_PORTS 4

#define PB 2
#define PC 3
#define PD 4

int port_to_mode[NUM_PORTS + 1] = {
	NOT_A_PORT,
	NOT_A_PORT,
	_SFR_IO_ADDR(DDRB),
	_SFR_IO_ADDR(DDRC),
	_SFR_IO_ADDR(DDRD),
};

int port_to_output[NUM_PORTS + 1] = {
	NOT_A_PORT,
	NOT_A_PORT,
	_SFR_IO_ADDR(PORTB),
	_SFR_IO_ADDR(PORTC),
	_SFR_IO_ADDR(PORTD),
};

int port_to_input[NUM_PORTS + 1] = {
	NOT_A_PORT,
	NOT_A_PORT,