Esempio n. 1
3
//__attribute__ ((section (".irq")))
//__attribute__ ((interrupt("IRQ"))) 
void isr(void)
{
	uint32_t pending;

	nirqpass = 0;

	while ((pending = *NIPEND)) {
		if(bit_is_set(pending, INT_NUM_TMR)) { 
			/* dispatch to individual timer isrs if they exist */
			/* timer isrs are responsible for determining if they
			 * caused an interrupt */
			/* and clearing their own interrupt flags */
			if (tmr_isr_funcs[0] != 0) { (tmr_isr_funcs[0])(); }
			if (tmr_isr_funcs[1] != 0) { (tmr_isr_funcs[1])(); }
			if (tmr_isr_funcs[2] != 0) { (tmr_isr_funcs[2])(); }
			if (tmr_isr_funcs[3] != 0) { (tmr_isr_funcs[3])(); }
		}

		if(bit_is_set(pending, INT_NUM_MACA)) {
	 		if(maca_isr != 0) { maca_isr(); } 
		}
		if(bit_is_set(pending, INT_NUM_UART1)) {
			if (ttyInterrupt != 0) { ttyInterrupt(); }
		}
		if(bit_is_set(pending, INT_NUM_UART2)) {
	 		if(uart2_isr != 0) { uart2_isr(); } 
		}
		if(bit_is_set(pending, INT_NUM_CRM)) {
			if(rtc_wu_evt() && (rtc_isr != 0)) { rtc_isr(); }
			if(kbi_evnt(4) && (kbi4_isr != 0)) { kbi4_isr(); }
			if(kbi_evnt(5) && (kbi5_isr != 0)) { kbi5_isr(); }
			if(kbi_evnt(6) && (kbi6_isr != 0)) { kbi6_isr(); }
			if(kbi_evnt(7) && (kbi7_isr != 0)) { kbi7_isr(); }

			if (CRM->STATUSbits.CAL_DONE && CRM->CAL_CNTLbits.CAL_IEN && cal_isr)
			{
				CRM->STATUSbits.CAL_DONE = 0;
				cal_isr();
			}
		}
		if(bit_is_set(pending, INT_NUM_ASM)) {
			if(asm_isr != 0) { asm_isr(); }
		}
		if (bit_is_set(pending, INT_NUM_I2C)) {
			if (i2c_isr != 0) { i2c_isr(); }
		}

		*INTFRC = 0; /* stop forcing interrupts */
		nirqpass++;
	}
}
void HALT_Until_Event(HALT_EVENT halt_event)
{
	BOOLEAN cont;
	cont = true;
	
	while(cont)
	{
		lp_setHaltMode();
		// process during waiting
		i2c_isr(0);
		i2c_isr(1);
		switch(halt_event)
		{
		case HALT_I2C1_END:
			if(i2c_get_status(1) <= I2C_MODE_ERROR)
				cont = false;
			break;
		case HALT_I2C0_END:
			if(i2c_get_status(0) <= I2C_MODE_ERROR)
				cont = false;
			break;
		default:
			cont = false;
			break;
		}
		wdt_clear();
	}
	return;
}
Esempio n. 3
0
void i2c_update(void) {
    // TODO: Multiple ports
    if (I2C_2.state == IDLE) {
        // If there is data to send
        if (I2C_2.frameToSend == True) {
            I2C_2.state = START;

            i2c_isr(I2C2);
        }
    }
}
Esempio n. 4
0
void __attribute__((interrupt, auto_psv)) _MI2C1Interrupt(void)
{
    IFS1bits.MI2C1IF = 0;  //Clear flag
    i2c_isr();
}
Esempio n. 5
0
void i2c_isr(uint8_t p) {
    I2CModule_t * mod;

    // Get a reference to the module structure
    switch (p) {
        case I2C2:
            mod = &I2C_2;
            break;
            
        default:
            return;
    }

    switch (mod->state) {
        case IDLE:
            break;

        case START:
            I2CStart(mod->moduleName);
            mod->state = ADDRESS;
            I2C_2.dataDirection = WRITING;
            break;

        case ADDRESS:
            switch (mod->dataDirection) {
                case READING:
                    I2CSendByte(mod->moduleName, mod->frame->address + 1);
                    mod->state = CHECK_ACK;
                    break;

                case WRITING:
                    I2CSendByte(mod->moduleName, mod->frame->address);
                    mod->state = CHECK_ACK;
                    break;
            }

            break;

        case CHECK_ACK:
            if (I2CByteWasAcknowledged(mod->moduleName) == True) {
                switch (mod->dataDirection) {
                    case READING:
                        mod->state = READ;
                        break;

                    case WRITING:
                        mod->state = WRITE;
                        break;
                }
            } else {
                mod->frame->success = False;
                mod->state = STOP;
            }

            i2c_isr(mod->moduleName);
            
            break;

        case RESTART:
            I2CRepeatStart(mod->moduleName);
            mod->dataDirection = READING;
            mod->state = ADDRESS;
            break;

        case READ_START:
            I2CReceiverEnable(mod->moduleName, TRUE);
            mod->state = READ;
            break;

        case READ:
            mod->frame->rx_buf[mod->frame->rx_buf_index++] = I2CGetByte(mod->moduleName);
                
            // If we need to read more bytes send an ACK
            if (mod->frame->rx_buf_index <= mod->frame->bytesToRead) {
                I2CAcknowledgeByte(mod->moduleName, True); // Send an ACK
                mod->state = READ_START; // Prepare for the next byte
            } else {
                I2CAcknowledgeByte(mod->moduleName, False); // Send a NACK
                mod->frame->success = True;
                mod->state = STOP; // Prepare for a stop condition
            }

            break;

        case WRITE:
            // If there are still bytes to send
            if (mod->frame->tx_buf_index < mod->frame->tx_buf_size) {
                I2CSendByte(mod->moduleName, mod->frame->tx_buf[mod->frame->tx_buf_index++]);
            } else {
                // If we need to read some bytes
                if (mod->frame->bytesToRead > 0) {
                    mod->state = RESTART; // Send a restart condition
                } else {
                    mod->frame->success = True;
                    mod->state = STOP; // Send a stop condition
                }

                i2c_isr(mod->moduleName); // Re-run this function to call stop/restart
                // TODO: Perhaps there is a better way to do this..!
            }
            break;

        case STOP:
            I2CStop(mod->moduleName);
            mod->frameToSend = False;
            mod->state = IDLE;

            // Tell the owner of the frame that it has complete or failed
            if (mod->frame->success == True) {
                mod->frame->callback();
            } else {
                mod->frame->error();
            }

            break;

        case BUSERROR:
            led12 = 1;
            // TODO: Something..!
            while(1); // Don't know what to do here yet..!
            break;
    }
}
Esempio n. 6
0
void TWI1_Handler()
{
	i2c_isr( 1 );
}
Esempio n. 7
0
void TWI0_Handler()
{
	i2c_isr( 0 );
}
Esempio n. 8
0
void i2c1_isr()
{
	i2c_isr( 1 );
}
Esempio n. 9
0
void i2c0_isr()
{
	i2c_isr( 0 );
}
Esempio n. 10
0
int32_t i2c_send_sequence(
	uint8_t ch,
	uint16_t *sequence,
	uint32_t sequence_length,
	uint8_t *received_data,
	void ( *callback_fn )( void* ),
	void *user_data
) {
	int32_t result = 0;

	volatile I2C_Channel *channel = &( i2c_channels[ch - ISSI_I2C_FirstBus_define] );
	uint8_t address;

#if defined(_kinetis_)
	uint8_t status;
	volatile uint8_t *I2C_C1  = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
	volatile uint8_t *I2C_S   = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
	volatile uint8_t *I2C_D   = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
#elif defined(_sam_)
	Twi *twi_dev = twi_devs[ch];
#endif

	if ( channel->status == I2C_BUSY )
	{
		return -1;
	}

	// Check if there are back-to-back errors
	// in succession
	if ( channel->last_error > 5 )
	{
		warn_msg("I2C Bus Error: ");
		printInt8( ch );
		print(" errors: ");
		printInt32( channel->error_count );
		print( NL );
	}

	// Debug
	/*
	for ( uint8_t c = 0; c < sequence_length; c++ )
	{
		printHex( sequence[c] );
		print(" ");
	}
	print(NL);
	*/

	channel->sequence = sequence;
	channel->sequence_end = sequence + sequence_length;
	channel->received_data = received_data;
	channel->status = I2C_BUSY;
	channel->txrx = I2C_WRITING;
	channel->callback_fn = callback_fn;
	channel->user_data = user_data;

	// reads_ahead does not need to be initialized

#if defined(_kinetis_)
	// Acknowledge the interrupt request, just in case
	*I2C_S |= I2C_S_IICIF;
	*I2C_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE );

	// Generate a start condition and prepare for transmitting.
	*I2C_C1 |= ( I2C_C1_MST | I2C_C1_TX );

	status = *I2C_S;
	if ( status & I2C_S_ARBL )
	{
		warn_print("Arbitration lost");
		result = -1;
		goto i2c_send_sequence_cleanup;
	}

	// Write the first (address) byte.
	address = *channel->sequence++;
	*I2C_D = address;

	// Everything is OK.
	return result;

i2c_send_sequence_cleanup:
	// Record error, and reset last error counter
	channel->error_count++;
	channel->last_error++;

	// Generate STOP and disable further interrupts.
	*I2C_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX );
	channel->status = I2C_ERROR;

#elif defined(_sam_)
	// Convert 8 bit address to 7bit + RW
	address = *channel->sequence++;
	//print("Address: ");
	//printHex( address );
	//print( NL );

	uint8_t mread = address & 1;
	address >>= 1;

	// Set slave address
	twi_dev->TWI_MMR = TWI_MMR_DADR(address) | (mread ? TWI_MMR_MREAD : 0);

	// Enable interrupts
	twi_dev->TWI_IER = TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_ARBLST;
	//twi_dev->TWI_IDR = 0xFFFFFFFF;

	// Generate a start condition
	twi_dev->TWI_CR |= TWI_CR_START;

	// Fire off the first read or write.
	// The first (address) byte is automatically trasmitted before any data
	// Arbitration errors will be handled in the isr
	i2c_isr(ch);

	// Everything is OK.
	return result;
#endif

	return result;
}