Revision: 1329 Author: bvwelch Date: Tue Sep 15 20:25:48 2009 Log: serial line protocol for CAN, as per socket-CAN SLCAN API
http://code.google.com/p/jallib/source/detail?r=1329 Added: /trunk/include/protocol/can_ascii.jal ======================================= --- /dev/null +++ /trunk/include/protocol/can_ascii.jal Tue Sep 15 20:25:48 2009 @@ -0,0 +1,165 @@ +-- Title: ASCII encapsulation of CAN messages +-- Author: William Welch Copyright (c) 2009, all rights reserved. +-- Compiler: 2.4l +-- +-- This file is part of jallib (http://jallib.googlecode.com) +-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) +-- +-- Description: ASCII-to-CAN and CAN-to-ASCII routines. The intent is to be compatible with +-- the SLCAN API. These routines may be used, for example, to implement a RS232 to CAN adapter +-- +-- Sources: Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/ +-- also, the LAWICEL CAN-USB adapter. +-- +-- Excerpt cut/pasted from SLCAN.C: +-- +-- A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended +-- frame format) a data length code (can_dlc) which can be from 0 to 8 +-- and up to <can_dlc> data bytes as payload. +-- Additionally a CAN frame may become a remote transmission frame if the +-- RTR-bit is set. This causes another ECU to send a CAN frame with the +-- given can_id. +-- +-- The SLCAN ASCII representation of these different frame types is: +-- <type> <id> <dlc> <data>* +-- +-- Extended frames (29 bit) are defined by capital characters in the type. +-- RTR frames are defined as 'r' types - normal frames have 't' type: +-- t => 11 bit data frame +-- r => 11 bit RTR frame +-- T => 29 bit data frame +-- R => 29 bit RTR frame +-- +-- The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64). +-- The <dlc> is a one byte ASCII number ('0' - '8') +-- The <data> section has at much ASCII Hex bytes as defined by the <dlc> +-- +-- Examples: +-- +-- t1230 : can_id 0x123, can_dlc 0, no data +-- t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33 +-- T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55 +-- r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request +-- + +function _ascii2bin(byte in c) return byte is + pragma inline + + if c >= "a" then + return ( c - "a" + 10 ) + end if + + if (c >= "A") then + return ( c - "A" + 10 ) + end if + + return ( c - "0" ) +end function + +-- convert ASCII message to CAN message, as per socket-CAN SLCAN API +-- FIXME: poor method. +function ascii_to_can(byte in ascii_buf[32], dword out can_id, byte out can_data[8], byte out data_len) return bit is + var bit ext, rtr + var byte i, j + + if ascii_buf[0] == "t" then + rtr = 0 + ext = 0 + elsif ascii_buf[0] == "T" then + rtr = 0 + ext = 1 + elsif ascii_buf[0] == "r" then + rtr = 1 + ext = 0 + elsif ascii_buf[0] == "R" then + rtr = 1 + ext = 1 + else + return 0 + end if + + if ext then + i = 8 + else + i = 3 + end if + + can_id = 0 + for i using j loop + can_id = can_id << 4 + can_id = can_id | dword( _ascii2bin( ascii_buf[j+1] ) ) + end loop + i = i + 1 + + if ext then + can_encode_ext_id(can_id) + end if + + if rtr then + can_encode_rtr_id(can_id) + end if + + data_len = _ascii2bin( ascii_buf[i] ) + if data_len > 8 then + data_len = 8 + end if + i = i + 1 + + for data_len using j loop + var byte v + v = _ascii2bin( ascii_buf[i] ) << 4 + v = v | _ascii2bin( ascii_buf[i+1] ) + can_data[j] = v + i = i + 2 + end loop + + return 1 +end function + +-- convert CAN message to socket-CAN SLCAN API +-- FIXME: poor method. +function can_to_ascii(dword in can_id, byte in can_data[8], byte in data_len, byte out ascii_buf[32]) return byte is + var byte i, j + + if can_is_rtr_id(can_id) then + ascii_buf[0] = "R" + else + ascii_buf[0] = "T" + end if + if can_is_std_id(can_id) then + ascii_buf[0] = ascii_buf[0] | 0x20 -- make lower-case + ascii_buf[1] = nibble2hex[ byte(can_id >> 8) & 7 ] + ascii_buf[2] = nibble2hex[ byte(can_id >> 4) & 0xF ] + ascii_buf[3] = nibble2hex[ byte(can_id) & 0xF ] + i = 4 + else + ascii_buf[1] = nibble2hex[ byte(can_id >> 28) & 1 ] + ascii_buf[2] = nibble2hex[ byte(can_id >> 24) & 0xF ] + ascii_buf[3] = nibble2hex[ byte(can_id >> 20) & 0xF ] + ascii_buf[4] = nibble2hex[ byte(can_id >> 16) & 0xF ] + ascii_buf[5] = nibble2hex[ byte(can_id >> 12) & 0xF ] + ascii_buf[6] = nibble2hex[ byte(can_id >> 8) & 0xF ] + ascii_buf[7] = nibble2hex[ byte(can_id >> 4) & 0xF ] + ascii_buf[8] = nibble2hex[ byte(can_id ) & 0xF ] + i = 9 + end if + + -- bulletproofing + if data_len > 8 then + data_len = 8 + end if + + ascii_buf[i] = nibble2hex[ data_len & 0xF ] + i = i + 1 + + for data_len using j loop + ascii_buf[i] = nibble2hex[ can_data[j] >> 4 ] + ascii_buf[i+1] = nibble2hex[ can_data[j] & 0XF ] + i = i + 2 + end loop + + ascii_buf[i] = 13 + i = i + 1 + return i +end function + --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jallib" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jallib?hl=en -~----------~----~----~----~------~----~------~--~---
