Rose-Hulman Robotics Team

Changeset 571 for trunk/electronics/avr

Show
Ignore:
Timestamp:
10/15/09 16:58:25 (2 years ago)
Author:
auchtemm
Message:

added code for defining responses to messages. this *really* does not belong in a usb-can bridge, but it's the only can device i've got lying around so it's convenient for testing... be sure to break this out.

Location:
trunk/electronics/avr/can-bridge
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/electronics/avr/can-bridge/main.c

    r566 r571  
    128128} 
    129129 
     130void repeat_last_octet(canmsg_t *msg, can_handler_t *r) 
     131{ 
     132   canmsg_t new = RTR_RESPONSE_FROM_REQUEST(msg); 
     133   new.data[0] = msg->addr[3]; 
     134   can_send_message(&new); 
     135} 
     136 
     137void ever_increasing_response(canmsg_t *msg, can_handler_t *r) 
     138{ 
     139   static uint8_t i; 
     140   canmsg_t new = RTR_RESPONSE_FROM_REQUEST(msg); 
     141   new.data[0] = i++; 
     142   can_send_message(&new); 
     143} 
     144 
     145void unknown_message(canmsg_t *msg, can_handler_t *r) 
     146{ 
     147   usart_print("UNHANDLED MESSAGE!!!\n"); 
     148} 
     149 
     150const can_handler_t handlers[] = { 
     151   RTR_HANDLER(0x00000000UL, ever_increasing_response), 
     152   RTR_HANDLER_WITH_MASK(0x1DEADC00UL, 0xFFFFFF00UL, repeat_last_octet), 
     153   CAN_HANDLER_WITH_MASK(0x00000000UL, 0x00000000UL, unknown_message), 
     154   CAN_HANDLER_LIST_END, 
     155}; 
    130156 
    131157int main(void) 
     
    139165   usart_init(19200); 
    140166        spi_init(); 
    141         mcp_init(); 
     167        mcp_init(handlers); 
    142168 
    143169        sei(); 
    144170   can_bridge_fsm(); 
     171 
    145172 
    146173        return 0; 
  • trunk/electronics/avr/can-bridge/mcp.c

    r570 r571  
    1616static canmsg_t rx_queue[kRXQueueLength]; 
    1717static canmsg_t tx_queue[kTXQueueLength]; 
     18 
     19static can_handler_t *handler_list = NULL; 
     20 
     21int can_handler(canmsg_t *msg, can_handler_t handler_list[]) 
     22{ 
     23   can_handler_t *h; 
     24   int i; 
     25   if (!handler_list) return -1; 
     26 
     27   h = handler_list; 
     28   // 0xFF is an invalid value for the first address byte; use this as sentinel. 
     29   while (h->addr[0] != 0xFF) { 
     30      for (i = 0; i < 4; i++) { 
     31         if ((h->addr[i] & h->mask[i]) != (msg->addr[i] & h->mask[i])) 
     32            goto next_filter; 
     33      } 
     34      if (CANMSG_TST_FLAG(msg, mCANMSG_RTR) == h->is_rtr)  
     35         if (h->handler) h->handler(msg, h); 
     36      return 0; 
     37next_filter: 
     38      h++; 
     39   } 
     40 
     41   return -1; 
     42} 
    1843 
    1944 
     
    6691} 
    6792 
    68 void mcp_init(void) 
     93void mcp_init(can_handler_t handlers[]) 
    6994{ 
    7095   mcp_reset(); 
     96   handler_list = handlers; 
    7197 
    7298   mcp_set_mode(kModeConfig); 
     
    79105 
    80106   mcp_set_mode(kModeLoopback); 
     107 
    81108} 
    82109 
     
    284311   mcp_read_rx_buffer(rxbuf, &tmp); 
    285312   can_print(&tmp); 
     313   // Remove this line for pure CAN-USB: 
     314   can_handler(&tmp, handler_list); 
    286315} 
    287316 
  • trunk/electronics/avr/can-bridge/mcp.h

    r570 r571  
    1 void mcp_reset(void); 
    2 void mcp_read(uint8_t addr, uint8_t len, uint8_t *buf); 
    3 void mcp_write_byte(uint8_t addr, uint8_t data); 
    4 void mcp_read_rxbuf(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
    5 void mcp_write(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
    6 void mcp_load_txbuf(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
    7 uint8_t mcp_read_status(void); 
    8 uint8_t mcp_rx_stat(void); 
    9 void mcp_rts(uint8_t bufs); 
    10 void mcp_bit_mod(uint8_t addr, uint8_t mask, uint8_t data); 
    11 void mcp_init(void); 
     1 
    122 
    133 
     
    8070#define mRXBSIDL_SRR (1<<4) 
    8171 
    82 /* 
    83 typedef struct { 
    84    uint32_t eid :18; 
    85    uint32_t rtr :1; 
    86    uint32_t exide :1; 
    87    uint32_t sid :11; 
    88    uint8_t dlc; 
    89    uint8_t data[8]; 
    90 } canmsg_t; 
    91 */ 
    92  
    9372typedef struct { 
    9473   uint8_t addr[4]; 
     
    10382#define CANMSG_SET_FLAG(msg, flag_mask) (msg)->flags |= (flag_mask) 
    10483#define CANMSG_CLR_FLAG(msg, flag_mask) (msg)->flags &= (flag_mask) 
    105 #define CANMSG_TST_FLAG(msg, flag_mask) ((msg)->flags & (flag_mask)) 
     84#define CANMSG_TST_FLAG(msg, flag_mask) (!!((msg)->flags & (flag_mask))) 
    10685 
    10786#define CANMSG_ZERO(msg) do { \ 
     
    121100   (msg)->flags = 0; \ 
    122101} while (0); 
     102 
     103 
     104typedef struct can_handler_st can_handler_t; 
     105typedef void (*can_handler_func)(canmsg_t *, can_handler_t *); 
     106 
     107struct can_handler_st { 
     108   uint8_t addr[4]; 
     109   uint8_t mask[4]; 
     110   uint8_t is_rtr; 
     111   can_handler_func handler; 
     112}; 
     113 
     114int can_handler(canmsg_t *msg, can_handler_t handler_list[]); 
     115 
     116#define _32BIT_TO_ARRAY(x) {  (x) >> 030, \ 
     117                             ((x) >> 020) & 0xFF, \ 
     118                             ((x) >> 010) & 0xFF, \ 
     119                              (x) & 0xFF\ 
     120} 
     121 
     122#define HANDLER_WITH_MASK(_addr, _mask, _is_rtr, _rspdr) { \ 
     123   .addr = _32BIT_TO_ARRAY(_addr), \ 
     124   .mask = _32BIT_TO_ARRAY(_mask), \ 
     125   .is_rtr = _is_rtr, \ 
     126   .handler = _rspdr \ 
     127} 
     128 
     129#define RTR_HANDLER_WITH_MASK(_addr, _mask, _rspdr) HANDLER_WITH_MASK(_addr, _mask, 1, _rspdr) 
     130 
     131#define RTR_HANDLER(_addr, _rspdr) RTR_HANDLER_WITH_MASK(_addr, 0xFFFFFFFFUL, _rspdr) 
     132 
     133#define CAN_HANDLER_WITH_MASK(_addr, _mask, _rspdr) HANDLER_WITH_MASK(_addr, _mask, 0, _rspdr) 
     134 
     135#define CAN_HANDLER(_addr, _rspdr) CAN_HANDLER_WITH_MASK(_addr, 0xFFFFFFFFUL, _rspdr) 
     136 
     137#define CAN_HANDLER_LIST_END CAN_HANDLER (0xFFFFFFFFUL, 0) 
     138 
     139#define RTR_RESPONSE_FROM_REQUEST(req) { \ 
     140   .addr = {(req)->addr[0], (req)->addr[1], (req)->addr[2], (req)->addr[3]}, \ 
     141   .dlc = (req)->dlc, \ 
     142   .flags = (req)->flags &~ mCANMSG_RTR,\ 
     143} 
     144 
     145 
     146 
     147 
     148void mcp_init(can_handler_t handlers[]); 
     149void mcp_reset(void); 
     150void mcp_read(uint8_t addr, uint8_t len, uint8_t *buf); 
     151void mcp_write_byte(uint8_t addr, uint8_t data); 
     152void mcp_read_rxbuf(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
     153void mcp_write(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
     154void mcp_load_txbuf(uint8_t addr, uint8_t *buf, uint8_t nbuf); 
     155uint8_t mcp_read_status(void); 
     156uint8_t mcp_rx_stat(void); 
     157void mcp_rts(uint8_t bufs); 
     158void mcp_bit_mod(uint8_t addr, uint8_t mask, uint8_t data); 
     159 
  • trunk/electronics/avr/can-bridge/mkfile

    r564 r571  
    99        usart.o \ 
    1010 
     11 
    1112<$RHRTELEC/avr/mkcommon