int main(void)
{
	uart_init ();
	stdout = &uart_stdout;
	printf ("Initializing...\n");

	can_init (0x10);
	uint8_t count = 0;
	sei();
		
	printf ("Initialized\n");

	while(1) {
		can_frame_t frame;
		frame.identifier = 0x00;
		frame.size = count%8;
		for(uint8_t i = 0; i < frame.size; i++) {
			frame.data[i] = ~(128-i)+count;
		}
		uint8_t s = can_send_frame(&frame);
		printf("Sent data %d %s\r",count, (s?"SUCCESS":"FAIL"));
		
		can_frame_t recieved;
		
		_delay_ms(100);
		uint8_t status = mcp2515_read_status();
		printf("  Status = 0x%x\r", status);
		s = can_recieve_frame(&recieved);
		printf("  Receieved data: L1: %d L2: %d %s\r", frame.size, recieved.size, (s?"SUCCESS":"FAIL"));
		
		_delay_ms(100);
		if(frame.size == recieved.size) {
			printf("  Identical length\r");
			uint8_t passed = 1;
			for(uint8_t i = 0; i < recieved.size; i++) {
				if(frame.data[i] != recieved.data[i]) {
					passed = 0;
					continue;
				}
			}
			if(passed) {
				printf("    AND identical data\r");
			}
			else {
				printf("    FAIL! NOT identical data\r");
				
			}
		} else {
			printf("  FAIL! NOT identical length\r");
		}
		status = mcp2515_read_status();
		printf("  Status = 0x%x\r", status);
		_delay_ms(500);
		
		count++;
	}
}
예제 #2
0
bool mcp2515_check_free_buffer(void)
{
	uint8_t status = mcp2515_read_status(SPI_READ_STATUS);
	
	if ((status & 0x54) == 0x54)
		return false;		// all buffers used
	else
		return true;
}
예제 #3
0
// ----------------------------------------------------------------------------
uint8_t mcp2515_get_message(tCAN *message)
{
	// read status
	uint8_t status = mcp2515_read_status(SPI_RX_STATUS);
	uint8_t addr;
	uint8_t t;
	if (bit_is_set(status,6)) {
		// message in buffer 0
		addr = SPI_READ_RX;
	}
	else if (bit_is_set(status,7)) {
		// message in buffer 1
		addr = SPI_READ_RX | 0x04;
	}
	else {
		// Error: no message available
		return 0;
	}

	RESET(MCP2515_CS);
	spi_putc(addr);
	
	// read id
	message->raw_data[0] = spi_putc(0xff);
	message->raw_data[1] = spi_putc(0xff);
	message->raw_data[2] = spi_putc(0xff);
	message->raw_data[3] = spi_putc(0xff);
	message->raw_data[4] = spi_putc(0xff);

	message->id = (uint16_t)message->raw_data[0] << 3;
	message->id |= message->raw_data[1] >> 5;
	
	// read DLC
	uint8_t length = message->raw_data[4] & 0x0f;
	
	message->header.length = length;
	message->header.rtr = (bit_is_set(status, 3)) ? 1 : 0;
	
	// read data
	for (t=0;t<length;t++) {
		message->data[t] = spi_putc(0xff);
		message->raw_data[t + 5] = message->data[t];
	}
	SET(MCP2515_CS);
	
	// clear interrupt flag
	if (bit_is_set(status, 6)) {
		mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0);
	}
	else {
		mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0);
	}
	
	return (status & 0x07) + 1;
}
예제 #4
0
파일: MCP2515.c 프로젝트: eirikpre/byggern
void mcp2515_init(){
	char status;
	spi_init();
	mcp2515_reset();
	
	status = mcp2515_read_status();
	if ((status & MODE_MASK) != MODE_CONFIG)
	{
		printf("MCP2515 is not in config mode!\n");
	}
	
	
}
예제 #5
0
bool mcp2515_check_message(void)
{
	#if defined(MCP2515_INT)
		return ((!IS_SET(MCP2515_INT)) ? true : false);
	#else
		#ifdef RXnBF_FUNKTION
			if (!IS_SET(MCP2515_RX0BF) || !IS_SET(MCP2515_RX1BF))
				return true;
			else
				return false;
		#else
			return ((mcp2515_read_status(SPI_RX_STATUS) & 0xC0) ? true : false);
		#endif
	#endif
}
예제 #6
0
파일: can.c 프로젝트: Ketilgrav/Byggern
//Returns 1 if message was sedt, otherwise 0
uint8_t CAN_message_send(CAN_message const * const msg){
	//Finds an available register
	
	//reg0, 0x30: status bit nr 2 
	//reg1, 0x40: status bit nr 4 
	//reg2, 0x50: status bit nr 6
	
	uint8_t status = mcp2515_read_status();
	if(status | (1 << 2)){
		CAN_message_send_to_reg(msg, MCP_TXB0CTRL);
	}
	else if(status | (1<<4)){
		CAN_message_send_to_reg(msg, MCP_TXB1CTRL);
	}
	else if(status | (1<<6)){
		CAN_message_send_to_reg(msg, MCP_TXB2CTRL);
	}
	else{
		return 0;
	}
	return 1;
}
예제 #7
0
파일: mcp2515.c 프로젝트: BaconShaker/raspy
// ----------------------------------------------------------------------------
uint8_t mcp2515_send_message(tCAN *message)
{
	uint8_t status = mcp2515_read_status(SPI_READ_STATUS);
	
	/* Statusbyte:
	 *
	 * Bit	Function
	 *  2	TXB0CNTRL.TXREQ
	 *  4	TXB1CNTRL.TXREQ
	 *  6	TXB2CNTRL.TXREQ
	 */
	uint8_t address;
	uint8_t t;
//	SET(LED2_HIGH);
	if (bit_is_clear(status, 2)) {
		address = 0x00;
	}
	else if (bit_is_clear(status, 4)) {
		address = 0x02;
	} 
	else if (bit_is_clear(status, 6)) {
		address = 0x04;
	}
	else {
		// all buffer used => could not send message
		return 0;
	}
	
	RESET(MCP2515_CS);
	spi_putc(SPI_WRITE_TX | address);
	
	spi_putc(message->id >> 3);
    spi_putc(message->id << 5);
	
	spi_putc(0);
	spi_putc(0);
	
	uint8_t length = message->header.length & 0x0f;
	
	if (message->header.rtr) {
		// a rtr-frame has a length, but contains no data
		spi_putc((1<<RTR) | length);
	}
	else {
		// set message length
		spi_putc(length);
		
		// data
		for (t=0;t<length;t++) {
			spi_putc(message->data[t]);
		}
	}
	SET(MCP2515_CS);
	
	_delay_us(1);
	
	// send message
	RESET(MCP2515_CS);
	address = (address == 0) ? 1 : address;
	spi_putc(SPI_RTS | address);
	SET(MCP2515_CS);
	
	return address;
}
예제 #8
0
uint8_t mcp2515_buffers_status(void)
{
	return mcp2515_read_status(SPI_READ_STATUS);
}
// ----------------------------------------------------------------------------
uint8_t mcp2515_send_message(const can_t *msg)
{
	// Status des MCP2515 auslesen
	uint8_t status = mcp2515_read_status(SPI_READ_STATUS);
	
	/* Statusbyte:
	 *
	 * Bit	Funktion
	 *  2	TXB0CNTRL.TXREQ
	 *  4	TXB1CNTRL.TXREQ
	 *  6	TXB2CNTRL.TXREQ
	 */
	uint8_t address;
	if (_bit_is_clear(status, 2)) {
		address = 0x00;
	}
	else {
		// Alle Puffer sind belegt,
		// Nachricht kann nicht verschickt werden
		return 0;
	}
	
	RESET(MCP2515_CS);
	spi_putc(SPI_WRITE_TX | address);
	#if SUPPORT_EXTENDED_CANID
		mcp2515_write_id(&msg->id, msg->flags.extended);
	#else
		mcp2515_write_id(&msg->id);
	#endif
	uint8_t length = msg->length & 0x0f;
	
	// Ist die Nachricht ein "Remote Transmit Request" ?
	if (msg->flags.rtr)
	{
		// Ein RTR hat zwar eine Laenge,
		// enthaelt aber keine Daten
		
		// Nachrichten Laenge + RTR einstellen
		spi_putc((1<<RTR) | length);
	}
	else
	{
		// Nachrichten Laenge einstellen
		spi_putc(length);
		
		// Daten
		for (uint8_t i=0;i<length;i++) {
			spi_putc(msg->data[i]);
		}
	}
	SET(MCP2515_CS);
	
	_delay_us(1);
	
	// CAN Nachricht verschicken
	// die letzten drei Bit im RTS Kommando geben an welcher
	// Puffer gesendet werden soll.
	RESET(MCP2515_CS);
	address = (address == 0) ? 1 : address;
	spi_putc(SPI_RTS | address);
	SET(MCP2515_CS);
	
	CAN_INDICATE_TX_TRAFFIC_FUNCTION;
	
	return address;
}
예제 #10
0
uint8_t mcp2515_get_message(can_t *msg)
{
    uint8_t addr;

    #ifdef  RXnBF_FUNKTION
        if (!IS_SET(MCP2515_RX0BF))
            addr = SPI_READ_RX;
        else if (!IS_SET(MCP2515_RX1BF))
            addr = SPI_READ_RX | 0x04;
        else
            return 0;
    #else
        // read status
        uint8_t status = mcp2515_read_status(SPI_RX_STATUS);

        if (_bit_is_set(status,6)) {
            // message in buffer 0
            addr = SPI_READ_RX;
        }
        else if (_bit_is_set(status,7)) {
            // message in buffer 1
            addr = SPI_READ_RX | 0x04;
        }
        else {
            // Error: no message available
            return 0;
        }
    #endif

    RESET(MCP2515_CS);
    spi_putc(addr);

    // CAN ID auslesen und ueberpruefen
    uint8_t tmp = mcp2515_read_id(&msg->id);
    #if SUPPORT_EXTENDED_CANID
        msg->flags.extended = tmp & 0x01;
    #else
        if (tmp & 0x01) {
            // Nachrichten mit extended ID verwerfen
            SET(MCP2515_CS);
            #ifdef  RXnBF_FUNKTION
            if (!IS_SET(MCP2515_RX0BF))
            #else
            if (_bit_is_set(status, 6))
            #endif
                mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0);
            else
                mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0);

            return 0;
        }
    #endif

    // read DLC
    uint8_t length = spi_putc(0xff);
    #ifdef RXnBF_FUNKTION
        if (!(tmp & 0x01))
            msg->flags.rtr = (tmp & 0x02) ? 1 : 0;
        else
            msg->flags.rtr = (length & (1<<RTR)) ? 1 : 0;
    #else
        msg->flags.rtr = (_bit_is_set(status, 3)) ? 1 : 0;
    #endif

    length &= 0x0f;
    msg->length = length;
    // read data
    for (uint8_t i=0;i<length;i++) {
        msg->data[i] = spi_putc(0xff);
    }
    SET(MCP2515_CS);

    // clear interrupt flag
    #ifdef RXnBF_FUNKTION
    if (!IS_SET(MCP2515_RX0BF))
    #else
    if (_bit_is_set(status, 6))
    #endif
        mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0);
    else
        mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0);

    CAN_INDICATE_RX_TRAFFIC_FUNCTION;

    #ifdef RXnBF_FUNKTION
        return 1;
    #else
        return (status & 0x07) + 1;
    #endif
}