/** * Request a few bytes from two wire slave device. Make slave device * NACK his address. Test if TwoWirePlus_bytesToReceive is set to 0 and no bytes are * received. */ static void TwoWirePlus_BaseTest_MasterReceiver_TC2(void) { TwoWirePlus_BaseTest_resetBuffer(); /* Start reading from address 0x42 four bytes */ Wire.beginReception(0x42); Wire.requestBytes(4); /* Test if address SLA+R was written to txRingBuffer and that START was requested in TWCR */ TEST_ASSERT_EQUAL_INT(TWOWIREPLUS_LASTOPERATION_WRITE, TwoWirePlus_txRingBuffer.lastOperation); TEST_ASSERT_EQUAL_INT(((0x42 << 1) | 0x01), TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_BaseTest_previousElement(TwoWirePlus_txRingBuffer.head)]); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_TWCR_START), TWCR); /* Emulate START was generated */ TWSR = TW_START; TWI_vect(); /* Check if global TwoWirePlus_status was set correctly to START */ TEST_ASSERT_EQUAL_INT((TW_START), TwoWirePlus_status); /* Preset TwoWirePlus_status register to emulate ACK for address from two wire slave device */ TWSR = TW_MR_SLA_NACK; TWI_vect(); /* Test if TwoWirePlus_status is set correctly and SLA+R was read from txRingBuffer and written to tw data register */ TEST_ASSERT_EQUAL_INT((TW_MR_SLA_NACK), TwoWirePlus_status); TEST_ASSERT_EQUAL_INT(TWOWIREPLUS_LASTOPERATION_READ, TwoWirePlus_txRingBuffer.lastOperation); TEST_ASSERT_EQUAL_INT(((0x42 << 1) | 0x01), TWDR); /* Test if txRingBuffer is empty now because address was sent. */ TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); /* NACK was sent for address by two wire slave device, so no data to be received */ TEST_ASSERT_EQUAL_INT(0x0, TwoWirePlus_bytesToReceive); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWEA), TWCR); /* Wire.endReception can't be tested. A bit is set in this function and function will wait until bit is cleared in ISR */ }
/** * When ISR is called TwoWirePlus_status shall reflect the latest status of two * wire bus. Status is stored in bit 3 to 7 of TWSR. * Set different status values and test if status is copied to TwoWirePlus_status * and if only bit 3 to 7 are used. */ static void TwoWirePlus_BaseTest_ISR_TC1(void) { TWSR = 0xaa; TWI_vect(); TEST_ASSERT_EQUAL_INT((0xaa & 0xf8), TwoWirePlus_status); TWSR = 0x55; TWI_vect(); TEST_ASSERT_EQUAL_INT((0x55 & 0xf8), TwoWirePlus_status); }
/** * In case TW_MR_SLA_NACK was received fro m two wire slave device for SLA+R * no more bytes shall be received and therefore TwoWirePlus_bytesToReceive shall * be set to 0. * Set TwoWirePlus_bytesToReceive to some value and test if set to 0 in case of * TW_MR_SLA_NACK */ static void TwoWirePlus_BaseTest_ISR_TC2(void) { TWSR = TW_MR_SLA_NACK; TwoWirePlus_bytesToReceive = 0xaa; TWI_vect(); TEST_ASSERT_EQUAL_INT(0, TwoWirePlus_bytesToReceive); }
/** * In case of TW_MR_SLA_NACK, TW_MT_SLA_ACK, TW_MR_SLA_ACK, TW_MT_SLA_NACK, TW_MT_DATA_NACK * or TW_MT_DATA_ACK a byte was sent to two wire slave device earlier and therefore ring * buffer tail must be increased accordingly. * Set above mentioned two wire status, put one byte in txRingBuffer, call ISR and test if * byte was consumed in ISR. */ static void TwoWirePlus_BaseTest_ISR_TC3(void) { TwoWirePlus_BaseTest_resetBuffer(); TWSR = TW_MR_SLA_NACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0xaa; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); TwoWirePlus_BaseTest_resetBuffer(); TWSR = TW_MT_SLA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0xaa; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); TwoWirePlus_BaseTest_resetBuffer(); TWSR = TW_MR_SLA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0xaa; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); TwoWirePlus_BaseTest_resetBuffer(); TWSR = TW_MT_SLA_NACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0xaa; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); TwoWirePlus_BaseTest_resetBuffer(); TWSR = TW_MT_DATA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0xaa; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); }
/** * Request a few bytes from two wire slave device. Make slave device * ACK his address. This test tests a typical two wire slave device * read. */ static void TwoWirePlus_BaseTest_MasterReceiver_TC1(void) { TwoWirePlus_BaseTest_resetBuffer(); /* Start reading from address 0x42 four bytes */ Wire.beginReception(0x42); /* Test if address SLA+R was written to txRingBuffer and that START was requested in TWCR */ TEST_ASSERT_EQUAL_INT(TWOWIREPLUS_LASTOPERATION_WRITE, TwoWirePlus_txRingBuffer.lastOperation); TEST_ASSERT_EQUAL_INT(((0x42 << 1) | 0x01), TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_BaseTest_previousElement(TwoWirePlus_txRingBuffer.head)]); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_TWCR_START), TWCR); /* Request four bytes and see if they are requested */ Wire.requestBytes(4); TEST_ASSERT_EQUAL_INT(0x4, TwoWirePlus_bytesToReceive); /* Emulate START was generated */ TWSR = TW_START; TWI_vect(); /* Check if global TwoWirePlus_status was set correctly to START */ TEST_ASSERT_EQUAL_INT((TW_START), TwoWirePlus_status); /* Preset TwoWirePlus_status register to emulate ACK for address from two wire slave device */ TWSR = TW_MR_SLA_ACK; TWI_vect(); /* Test if TwoWirePlus_status is set correctly and SLA+R was read from txRingBuffer and written to tw data register */ TEST_ASSERT_EQUAL_INT((TW_MR_SLA_ACK), TwoWirePlus_status); TEST_ASSERT_EQUAL_INT(TWOWIREPLUS_LASTOPERATION_READ, TwoWirePlus_txRingBuffer.lastOperation); TEST_ASSERT_EQUAL_INT(((0x42 << 1) | 0x01), TWDR); /* Test if txRingBuffer is empty now because address was sent. */ TEST_ASSERT(TwoWirePlus_RingBufferEmpty(TwoWirePlus_txRingBuffer)); /* Check if TWIE, TWEN, TWEA and TWINT were set in ISR. */ TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWEA | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); /* Now signal three bytes to be received from two wire slave device. Test if TWCR is set * correctly to make sure ACK and not NACK was sent. */ TWSR = TW_MR_DATA_ACK; TWDR = 0xa1; TWI_vect(); TEST_ASSERT_EQUAL_INT((TW_MR_DATA_ACK), TwoWirePlus_status); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWEA | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TWDR = 0xa2; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWEA | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TWDR = 0xa3; TWI_vect(); /* For the very last by a NACK shall be sent TWEA = 0 */ TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); /* Signal last byte and test if NACH (TWEA not set) is returned to two wire slave device */ TWDR = 0xa4; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWEA ), TWCR); /* Test if we really received four bytes and if the values match */ TEST_ASSERT_EQUAL_INT(4, Wire.available()); TEST_ASSERT_EQUAL_INT(0xa1, Wire.read()); TEST_ASSERT_EQUAL_INT(3, Wire.available()); TEST_ASSERT_EQUAL_INT(0xa2, Wire.read()); TEST_ASSERT_EQUAL_INT(2, Wire.available()); TEST_ASSERT_EQUAL_INT(0xa3, Wire.read()); TEST_ASSERT_EQUAL_INT(1, Wire.available()); TEST_ASSERT_EQUAL_INT(0xa4, Wire.read()); TEST_ASSERT_EQUAL_INT(0, Wire.available()); /* Wire.endReception can't be tested. A bit is set in this function and function will wait until bit is cleared in ISR */ }
/** * In case of TW_MT_SLA_ACK, TW_MR_SLA_ACK, TW_MT_SLA_NACK, TW_MT_DATA_NACK, * TW_MT_DATA_ACK, TW_START or TW_REP_START and no data available in txRingBuffer but * TwoWirePlus_bytesToReceive is 1, so only one more byte to sent, TW_INT shall be cleared and NACH * requested to signal that last byte is now about to be received. For TW_MR_SLA_NACK * TwoWirePlus_bytesToReceive will be set to 0 in ISR (see following tests). * Set above mentioned two wire status, set TwoWirePlus_bytesToReceive to 2, call ISR and * test if TW_INT is set correctly in TWSR.For TW_MR_SLA_NACK, TW_MT_SLA_ACK, TW_MR_SLA_ACK, * TW_MT_SLA_NACK, TW_MT_DATA_NACK and TW_MT_DATA_ACK one byte must be present in txRingBuffer * (see previous test) */ static void TwoWirePlus_BaseTest_ISR_TC6(void) { TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_MT_SLA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0x55; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_MR_SLA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0x55; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_MT_SLA_NACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0x55; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_MT_DATA_ACK; TwoWirePlus_txRingBuffer.buffer[TwoWirePlus_txRingBuffer.head] = 0x55; TwoWirePlus_incrementIndex(TwoWirePlus_txRingBuffer.head); TwoWirePlus_txRingBuffer.lastOperation = TWOWIREPLUS_LASTOPERATION_WRITE; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_START; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); TwoWirePlus_BaseTest_resetBuffer(); TwoWirePlus_bytesToReceive = 1; TWSR = TW_REP_START; TWI_vect(); TEST_ASSERT_EQUAL_INT((TWOWIREPLUS_BASETEST_TWCR_TWIE | TWOWIREPLUS_BASETEST_TWCR_TWEN | TWOWIREPLUS_BASETEST_TWCR_TWINT), TWCR); }
void sim_check_interrupts() { unsigned int ticks = SDL_GetTicks(); int tickDiff = ticks - prevTicks; prevTicks = ticks; if (!(SREG & _BV(SREG_I))) return; #ifdef ENABLE_ULTILCD2 if ((TWCR & _BV(TWEN)) && (TWCR & _BV(TWINT)) && (TWCR & _BV(TWIE))) { //Relay the TWI interrupt by 25ms one time till it gets disabled again. This fakes the LCD refresh rate. if (twiIntStart == 0) twiIntStart = SDL_GetTicks(); if (SDL_GetTicks() - twiIntStart > 25) { cli(); TWI_vect(); _sei(); } } if (!(TWCR & _BV(TWEN)) || !(TWCR & _BV(TWIE))) { twiIntStart = 0; } #endif //if (tickDiff > 1) // printf("Ticks slow! %i\n", tickDiff); if (tickDiff > 0) { ms_callback(); cli(); for(int n=0;n<tickDiff;n++) { if (TIMSK0 & _BV(OCIE0B)) TIMER0_COMPB_vect(); if (TIMSK0 & _BV(TOIE0)) TIMER0_OVF_vect(); } //Timer1 runs at 16Mhz / 8 ticks per second. unsigned int waveformMode = ((TCCR1B & (_BV(WGM13) | _BV(WGM12))) >> 1) | (TCCR1A & (_BV(WGM11) | _BV(WGM10))); unsigned int clockSource = TCCR1B & (_BV(CS12) | _BV(CS11) | _BV(CS10)); unsigned int tickCount = F_CPU * tickDiff / 1000; unsigned int ticks = TCNT1; switch(clockSource) { case 0: tickCount = 0; break; case 1: break; case 2: tickCount /= 8; break; case 3: tickCount /= 64; break; case 4: tickCount /= 256; break; case 5: tickCount /= 1024; break; case 6: tickCount = 0; break; case 7: tickCount = 0; break; } tickCount *= 4;//For some reason the stepper speed is to slow, so cheat the timer routine. if (tickCount > 0 && OCR1A > 0) { ticks += tickCount; while(ticks > int(OCR1A)) { ticks -= int(OCR1A); if (TIMSK1 & _BV(OCIE1A)) TIMER1_COMPA_vect(); } TCNT1 = ticks; } _sei(); }