// (Re)Initialize the specified mode.
// The mode parameter should be a value from enum DMXMode.
void ModifiedDMXSerialClass::init (int mode, uint8_t* data)
{
  stat = 0;
  #ifdef SCOPEDEBUG
  pinMode(DmxTriggerPin, OUTPUT);
  pinMode(DmxISRPin, OUTPUT);
  #endif
  _dmxData = data;
  // initialize global variables
  _dmxMode = DMXNone;
  _dmxRecvState= IDLE; // initial state
  _dmxChannel = 0;
  _gotLastPacket = millis(); // remember current (relative) time in msecs.

  // initialize the DMX buffer
  for (int n = 0; n < DMXSERIAL_MAX+1; n++)
  _dmxData[n] = 0;

  // now start
  _dmxMode = (DMXMode)mode;

  if (_dmxMode == DMXController) {
    // Setup external mode signal
    pinMode(DmxModePin, OUTPUT); // enables pin 2 for output to control data direction
    digitalWrite(DmxModePin, DmxModeOut); // data Out direction

    // Setup Hardware
    // Enable transmitter and interrupt
    UCSRnB = (1<<TXENn) | (1<<TXCIEn);

    // Start sending a BREAK and loop (forever) in UDRE ISR
    _DMXSerialBaud(Calcprescale(BREAKSPEED), BREAKFORMAT);
    _DMXSerialWriteByte((uint8_t)0);
    _dmxChannel = 0;

    } else if (_dmxMode == DMXReceiver) {
    // Setup external mode signal
    pinMode(DmxModePin, OUTPUT); // enables pin 2 for output to control data direction
    digitalWrite(DmxModePin, DmxModeIn); // data in direction

    // Setup Hardware
    // Enable receiver and Receive interrupt
    UCSRnB = (1<<RXENn) | (1<<RXCIEn);
    _DMXSerialBaud(Calcprescale(DMXSPEED), DMXFORMAT); // Enable serial reception with a 250k rate

    } else {
    // Enable receiver and transmitter and interrupts
    // UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn) | (1<<UDRIEn);

  } // if
} // init()
// (Re)Initialize the specified mode.
// The mode parameter should be a value from enum DMXMode.
void ModifiedDMXSerialClass::init(int mode)
{
	// Setup external mode signal
	//TODO Refactor to constant A0 is used as the RX/TX en pin on the RF1 Serial adapter
	pinMode(A0, OUTPUT); // enables pin 2 for output to control data direction
	digitalWrite(A0, LOW); //Set it low to put the RS485 chip in Receive mode

#ifdef SCOPEDEBUG
	//if in debug mode define some pins for watching the timing in the logic analyzer
	pinMode(rxStatusPin, OUTPUT); // enables pin 2 for output to control data direction
	pinMode(DmxTriggerPin, OUTPUT);
	pinMode(DmxISRPin, OUTPUT);
#endif

	// initialize global variables
	_dmxMode = DMXNone;
	_dmxRecvState = DMX_IDLE; // initial state
	_dmxChannel = 0;
	_gotLastPacket = millis(); // remember current (relative) time in msecs.

	// initialize the DMX buffer
	for (int n = 0; n < 18; n++){
		for (int in = 0; in < 32; in++)
			str[n][in] = 0;
	}

	// now start
	_dmxMode = (DMXMode)mode;

	// Setup Hardware
	// Enable receiver and Receive interrupt
	UCSRnB = (1 << RXENn) | (1 << RXCIEn);
	_DMXSerialBaud(Calcprescale(DMXSPEED), DMXFORMAT); // Enable serial reception with a 250k rate
} // init()
Esempio n. 3
0
// Initialize or reinitialize the DMX RDM mode.
// The other values are stored for later use with the specific commands.
void DMXSerialClass2::init(struct RDMINIT *initData, RDMCallbackFunction func, uint8_t modePin, uint8_t modeIn, uint8_t modeOut)
{
  // This structure is defined for mapping the values in the EEPROM
  struct EEPROMVALUES eeprom;

  // save the given initData for later use.
  _initData = initData;
  _rdmFunc = func;

  _dmxModePin = modePin;
  _dmxModeIn = modeIn;
  _dmxModeOut = modeOut;

  _baseInit();

  // now initialize RDM specific elements
  _isMute = false;
  _rdmAvailable = false;
  _identifyMode = false;
  _softwareLabel = "Arduino RDM 1.0";

  DeviceIDCpy(_devID, initData->deviceID);

  // read from EEPROM or set defaults
  for (unsigned int i = 0; i < sizeof(eeprom); i++)
    ((byte *)(&eeprom))[i] = EEPROM.read(i);

  // check if the EEEPROM values are from the RDM library
  if ((eeprom.sig1 == 0x6D) && (eeprom.sig2 == 0x68)) {
    _startAddress = eeprom.startAddress;
    strcpy (deviceLabel, eeprom.deviceLabel);
    DeviceIDCpy(_devID, eeprom.deviceID);
  } else {
    // set default values
    _startAddress = 1;
    strcpy (deviceLabel, "new");
    _devID[4] = random255(); // random(255);
    _devID[5] = random255(); // random(255);
  } // if 

  // setup the manufacturer adressing device-ID

  _devIDGroup[0] = _devID[0];
  _devIDGroup[1] = _devID[1];

  _saveEEPRom();

  // now start
  digitalWrite(_dmxModePin, _dmxModeIn); // data in direction

  _dmxSendBuffer = _rdm.buffer;
  // _dmxSendLen = ... will be set individually

  // Setup Hardware
  // Enable receiver and transmitter and interrupts
  UCSRnB = (1<<RXENn) | (1<<RXCIEn);
  _DMXSerialBaud(Calcprescale(DMXSPEED), DMXFORMAT); // Enable serial reception with a 250k rate
} // initRDM()
Esempio n. 4
0
// Handle RDM Requests and send response
// see http://www.opendmx.net/index.php/RDM_Discovery
// see http://www.enttec.com/docs/sniffer_manual.pdf
void DMXSerialClass2::tick(void)
{
  if ((_dmxState == IDLE) && (_rdmAvailable)) {
    // never process twice.
    _rdmAvailable = false;

    // respond to RDM commands now.
    bool8 packetIsForMe = false;
    bool8 packetIsForGroup = false;
    bool8 packetIsForAll = false;
    bool8 isHandled = false;

    struct RDMDATA *rdm = &_rdm.packet;
    
    byte     CmdClass  = rdm->CmdClass;  // command class
    uint16_t Parameter = rdm->Parameter; // parameter ID

    // in the ISR only some global conditions are checked: DestID
    if (DeviceIDCmp(rdm->DestID, _devIDAll) == 0) {
      packetIsForAll = true;
    } else if (DeviceIDCmp(rdm->DestID, _devIDGroup) == 0) {
      packetIsForGroup = true;
    } else if (DeviceIDCmp(rdm->DestID, _devID) == 0) {
      packetIsForMe = true;
    } // if

      if ((! packetIsForMe) && (! packetIsForGroup) && (! packetIsForAll)) {
        // ignore this packet

      } else if (CmdClass == E120_DISCOVERY_COMMAND) { // 0x10
        // handle all Discovery commands locally 
        if (Parameter == SWAPINT(E120_DISC_UNIQUE_BRANCH)) { // 0x0001
          // not tested here for pgm space reasons: rdm->Length must be 24+6+6 = 36
          // not tested here for pgm space reasons: rdm->_DataLength must be 6+6 = 12
          
          if (! _isMute) {
            // check if my _devID is in the discovery range
            if ((DeviceIDCmp(rdm->Data, _devID) <= 0) && (DeviceIDCmp(_devID, rdm->Data+6) <= 0)) {
              
              // respond a special discovery message !
              struct DISCOVERYMSG *disc = &_rdm.discovery;
              _rdmCheckSum = 6 * 0xFF;
              
              // fill in the _rdm.discovery response structure
              for (byte i = 0; i < 7; i++)
                disc->headerFE[i] = 0xFE;
              disc->headerAA = 0xAA;  
              for (byte i = 0; i < 6; i++) {
                disc->maskedDevID[i+i]   = _devID[i] | 0xAA;
                disc->maskedDevID[i+i+1] = _devID[i] | 0x55;
                _rdmCheckSum += _devID[i];
              }
              disc->checksum[0] = (_rdmCheckSum >> 8)   | 0xAA;
              disc->checksum[1] = (_rdmCheckSum >> 8)   | 0x55;
              disc->checksum[2] = (_rdmCheckSum & 0xFF) | 0xAA;
              disc->checksum[3] = (_rdmCheckSum & 0xFF) | 0x55;
            
              // disable all interrupt routines and send the _rdm.discovery packet 
              // now send out the _rdm.buffer without a starting BREAK.
              _DMXSerialBaud(Calcprescale(DMXSPEED), DMXFORMAT); 
              UCSRnB = (1<<TXENn); // no interrupts !
              
              // delayMicroseconds(50);  // ??? 180
              digitalWrite(_dmxModePin, _dmxModeOut); // data Out direction

              unsigned int _rdmBufferLen = sizeof(_rdm.discovery);
              for (unsigned int i = 0; i < _rdmBufferLen; i++) {
                UDRn = _rdm.buffer[i];
                UCSRnA= (1<<TXCn);
                loop_until_bit_is_set(UCSRnA, TXCn);
              } // for
            
              digitalWrite(_dmxModePin, _dmxModeIn); // data Out direction
            
              // Re-enable receiver and Receive interrupt
              _dmxState= IDLE; // initial state
              UCSRnB = (1<<RXENn) | (1<<RXCIEn);
              _DMXSerialBaud(Calcprescale(DMXSPEED), DMXFORMAT); // Enable serial reception with a 250k rate
            } // if
          } // if 

        } else if (Parameter == SWAPINT(E120_DISC_UN_MUTE)) { // 0x0003
          isHandled = true;
          if (packetIsForMe) { // 05.12.2013
            if (_rdm.packet.DataLength > 0) {
              // Unexpected data
              // Do nothing
            } else {
              _isMute = false;
              // Control field
              _rdm.packet.Data[0] = 0b00000000;
              _rdm.packet.Data[1] = 0b00000000;
              _rdm.packet.DataLength = 2;
              respondMessage(true); // 21.11.2013
            }
          }
          
        } else if (Parameter == SWAPINT(E120_DISC_MUTE)) { // 0x0002
          isHandled = true;
          if (packetIsForMe) { // 05.12.2013
            if (_rdm.packet.DataLength > 0) {
              // Unexpected data
              // Do nothing
            } else {
              _isMute = true;
              // Control field
              _rdm.packet.Data[0] = 0b00000000;
              _rdm.packet.Data[1] = 0b00000000;
              _rdm.packet.DataLength = 2;
              respondMessage(true); // 21.11.2013
            }
          }

        } // if

      } else {