/* Updated by Kurt English 12/5/12 changes: Added can_dump_if2 function. dumps receive buffer registers Added can_send_rtr function. transmits remote frames Altered can_send_tx_buf function. line added to ensure data frame tranmission Removed #include "uart0.h", #include "uart0.c", and #include "sysinit.h" These files were incomplete. Code intended for them was put in the main function. Added #include "putget.h". Not sure why #include was but not that Some debug printout lines are now commented thoughts: can_set_buffer_data function should be altered to set data in the opposite order. The function currently accepts pointers, but pointers cannot be directly passed to the function because the function reverses the byte ordering ex. 0x12EF becomes 0xEF12. The CAN_BUFFER data type is never used for anything special. Usually it isn't used at all. It probably was intended for accessing the C8051's Can Controller's memory, but this was never implemented. The can_get_tx_buf function is worthless. It was likely for accessing the Can Controller memory too. */ #include #include "can.h" #include #include "ccanregs.h" #include "putget.h" // Necessary for printf static unsigned short can_read_register(unsigned char addr) { unsigned short ret; char save = SFRPAGE; SFRPAGE = CAN0_PAGE; CAN0ADR = addr; ret = (CAN0DATH << 8) | CAN0DATL; SFRPAGE = save; return ret; } static void can_write_register(unsigned char addr, unsigned short dat) { char save = SFRPAGE; SFRPAGE = CAN0_PAGE; CAN0ADR = addr; CAN0DATH = dat >> 8; CAN0DATL = dat; SFRPAGE = save; } static void can_setup_baud_rate( ) { // configure CAN baud rate // this should result in ~500kbps with a 22.1184MHz clock can_write_register(BITREG, 0x2641); } void can_init( ) { char SFRPAGE_SAVE = SFRPAGE; // enable CAN configuration SFRPAGE = CAN0_PAGE; CAN0CN = 0x41; // Set the CAN baud rate can_setup_baud_rate( ); // Set the CAN module to basic mode CAN0CN = 0xc1; SFRPAGE = UART0_PAGE; printf("CANTSTR=%02x\r\n", can_read_register(CANTSTR)); can_write_register(CANTSTR, 0x0004); printf("CANTSTR=%02x\r\n", can_read_register(CANTSTR)); SFRPAGE = CAN0_PAGE; // initialize the receive buffer can_write_register(IF2CMDMSK, 0x0073/*0x00b8*/); can_write_register(IF2ARB1, 0x0000); can_write_register(IF2ARB2, 0x8000); can_write_register(IF2MSGC, /*0x0488*/0x0000); // return to normal operation (leave test mode enabled) CAN0CN = 0x0080; SFRPAGE = SFRPAGE_SAVE; } static void can_dump_if1( ) { printf("IF1MASK1=0x%04x\r\n", can_read_register(IF1MSK1)); printf("IF1MASK2=0x%04x\r\n", can_read_register(IF1MSK2)); printf("IF1ARB1=0x%04x\r\n", can_read_register(IF1ARB1)); printf("IF1ARB2=0x%04x\r\n", can_read_register(IF1ARB2)); printf("IF1MSGCON=0x%04x\r\n", can_read_register(IF1MSGC)); printf("IF1DATA1=0x%04x\r\n", can_read_register(IF1DATA1)); printf("IF1DATA2=0x%04x\r\n", can_read_register(IF1DATA2)); printf("IF1DATB1=0x%04x\r\n", can_read_register(IF1DATB1)); printf("IF1DATB2=0x%04x\r\n", can_read_register(IF1DATB2)); printf("IF1CMDMSK=0x%04x\r\n", can_read_register(IF1CMDMSK)); printf("IF1CMDRQST=0x%04x\r\n", can_read_register(IF1CMDRQST)); } static void can_dump_if2( ) { // function added 12/5/12 printf("IF2MASK1=0x%04x\r\n", can_read_register(IF2MSK1)); printf("IF2MASK2=0x%04x\r\n", can_read_register(IF2MSK2)); printf("IF2ARB1=0x%04x\r\n", can_read_register(IF2ARB1)); printf("IF2ARB2=0x%04x\r\n", can_read_register(IF2ARB2)); printf("IF2MSGCON=0x%04x\r\n", can_read_register(IF2MSGC)); printf("IF2DATA1=0x%04x\r\n", can_read_register(IF2DATA1)); printf("IF2DATA2=0x%04x\r\n", can_read_register(IF2DATA2)); printf("IF2DATB1=0x%04x\r\n", can_read_register(IF2DATB1)); printf("IF2DATB2=0x%04x\r\n", can_read_register(IF2DATB2)); printf("IF2CMDMSK=0x%04x\r\n", can_read_register(IF2CMDMSK)); printf("IF2CMDRQST=0x%04x\r\n", can_read_register(IF2CMDRQST)); } unsigned long can_get_address(CAN_BUFFER buf) { unsigned long ret; unsigned short arb1, arb2; arb1 = can_read_register(IF2ARB1); arb2 = can_read_register(IF2ARB2); //printf("arb1=0x%04x arb2=0x%04x\r\n", arb1, arb2); if (arb2 & 0x4000) { // if message has an extended ID ret = arb2 & 0x1fff; ret <<= 16; ret |= arb1; } else { // only 11 bit ID present arb1 &= 0x07ff; ret = arb1; //arb1 = (arb1 & 0x07ff) //return arb1; } return ret; } void can_set_address_std(CAN_BUFFER buf, unsigned long addr) { can_write_register(IF1ARB1, 0x0000); can_write_register(IF1ARB2, 0xa000 | ((addr & 0x7ff) << 2)); } void can_set_address_ext(CAN_BUFFER buf, unsigned long addr) { can_write_register(IF1ARB1, addr); can_write_register(IF1ARB2, 0xe000 | (addr >> 16)); } void can_set_buffer_data( CAN_BUFFER buf, unsigned char *data_in, unsigned char length ) { can_write_register(IF1DATA1, data_in[0] | (data_in[1] << 8)); can_write_register(IF1DATA2, data_in[2] | (data_in[3] << 8)); can_write_register(IF1DATB1, data_in[4] | (data_in[5] << 8)); can_write_register(IF1DATB2, data_in[6] | (data_in[7] << 8)); can_write_register(IF1MSGC, 0x8080 | length); } void can_send_tx_buf(CAN_BUFFER buf) { //can_dump_if1( ); can_write_register(IF1ARB2, (can_read_register(IF1ARB2) | 0x2000)); // set dir = 1. line added can_write_register(IF1CMDMSK, 0x00ff); // unmask everything can_write_register(IF1CMDRQST, 0x8001); // initiate transmit while (can_read_register(IF1CMDRQST) & 0x8000) { // wait for completion //can_dump_if1( ); } } void can_send_rtr(CAN_BUFFER buf) { // function added 12/5/12 //can_dump_if1( ); can_write_register(IF1ARB2, (can_read_register(IF1ARB2) & 0xDFFF)); // set dir = 0 can_write_register(IF1CMDMSK, (can_read_register(IF1CMDMSK) | 0x0004)); // set txrqst = 1 can_write_register(IF1CMDRQST, 0x8001); // initiate transmit while (can_read_register(IF1CMDRQST) & 0x8000) { // wait for completion //can_dump_if1( ); } } // wait for a CAN buffer to be free and then return it CAN_BUFFER can_get_tx_buf( ) { return (CAN_BUFFER) 1; // only 1 buffer to use } // get the next full CAN receive buffer (or 0 if no messages ready) CAN_BUFFER can_get_rx_msg( ) { //printf("IF2MSGC=0x%04x\r\n", can_read_register(IF2MSGC)); if (can_read_register(IF2MSGC) & 0x8000) { //printf("IF2ARB1=0x%04x\r\n", can_read_register(IF2ARB1)); //printf("IF2ARB2=0x%04x\r\n", can_read_register(IF2ARB2)); //printf("IF2MSGC=0x%04x\r\n", can_read_register(IF2MSGC)); return 1; } else { return 0; } } // Free the received message buffer for another message off the bus void can_free_rx_buf(CAN_BUFFER buf) { can_write_register(IF2MSGC, 0x0000); } unsigned char can_get_dlc(CAN_BUFFER buf) { return can_read_register(IF2MSGC) & 0x0f; } unsigned char can_get_data_byte(CAN_BUFFER buf, unsigned char index) { switch (index) { case 0: return can_read_register(IF2DATA1) & 0xff; case 1: return can_read_register(IF2DATA1) >> 8; case 2: return can_read_register(IF2DATA2) & 0xff; case 3: return can_read_register(IF2DATA2) >> 8; case 4: return can_read_register(IF2DATB1) & 0xff; case 5: return can_read_register(IF2DATB1) >> 8; case 6: return can_read_register(IF2DATB2) & 0xff; case 7: return can_read_register(IF2DATB2) >> 8; default: return 0; } }