void MatrixDriver::init() { // set all decoder lines as output and set them to LOW DEC_DDR |= _BV(DEC_A0) | _BV(DEC_A1) | _BV(DEC_A2) | _BV(DEC_E3); DEC_PORT &=~ (_BV(DEC_A0) | _BV(DEC_A1) | _BV(DEC_A2) | _BV(DEC_E3)); // set all driver lines as output and set them to LOW MY9221_DDR |= _BV(MY9221_DI) | _BV(MY9221_DCKI); MY9221_PORT &=~ (_BV(MY9221_DI) | _BV(MY9221_DCKI)); // init the line counter m_currentLine = 0; // use timer1 to create a task which gets called every 100us cli();//stop interrupts // Register | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 //----------+--------+--------+--------+--------+--------+--------+--------+------ // TCCR1A | COM1A1 | COM1A0 | COM1B1 | COM1B0 | - | - | WGM11 | WGM10 // | 0 | 0 | 0 | 0 | - | - | 0 | 0 // TCCR1B | ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 // | - | - | - | 0 | 1 | 0 | 0 | 1 // All COM registers are set to 0, because we don't want a pwm output on a pin // CTC, TOP = OCR1A // >> WGM 13, 12, 11, 10: 0, 1, 0, 0 // ICNC1 and ICES1 can be ignored, because no external clock source is used // No Prescaling // CS 12, 11, 10: 0, 0, 1 // For more details see chapter 20.14 of Atmega328 datasheet _SFR_BYTE(TCCR1A) = 0; _SFR_BYTE(TCCR1B) = _BV(WGM12) | _BV(CS10); _SFR_BYTE(TIMSK1) |= _BV(OCIE1A); OCR1A = 20000; sei();//allow interrupts }
void xbox_init(bool watchdog) { uchar i; // disable timer 0 overflow interrupt (enabled by Arduino's init() function). // PS3 was having difficulties detecting the adapter if that's enabled. // WARNING: This will mess up with micros(), millis() and delay() Arduino functions! // Use alternate timer functions instead! #if defined(TIMSK) && defined(TOIE0) (_SFR_BYTE(TIMSK) &= ~_BV(TOIE0)); #elif defined(TIMSK0) && defined(TOIE0) (_SFR_BYTE(TIMSK0) &= ~_BV(TOIE0)); #endif xbox_reset_pad_status(); if(watchdog) { wdt_enable(WDTO_2S); } else { wdt_disable(); } /* Even if you don't use the watchdog, turn it off here. On newer devices, * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! */ /* RESET status: all port bits are inputs without pull-up. * That's the way we need D+ and D-. Therefore we don't need any * additional hardware initialization. */ usbInit(); usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ i = 0; while (--i) { /* fake USB disconnect for > 250 ms */ wdt_reset(); _delay_ms(1); } usbDeviceConnect(); sei(); }
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(); }