This commit is contained in:
Christian Kroll 2012-05-06 18:45:43 +00:00
parent 0705564d6d
commit f2027360a0
8 changed files with 547 additions and 523 deletions

View File

@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <avr/pgmspace.h> #include "../compat/pgmspace.h"
#include "../config.h" #include "../config.h"
#include "../can/can.h" #include "../can/can.h"
#include "../can/lap.h" #include "../can/lap.h"
@ -21,7 +21,7 @@
#endif #endif
//hackhack //hackhack
extern can_addr myaddr; extern can_addr_t myaddr;
//send a time request packet via can //send a time request packet via can
void time_request(void) void time_request(void)

View File

@ -4,13 +4,19 @@
#include "spi.h" #include "spi.h"
#include "../borg_hw/borg_hw.h" #include "../borg_hw/borg_hw.h"
#include <avr/pgmspace.h>
#include <setjmp.h> #include <setjmp.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h> #ifdef __AVR__
# include <avr/pgmspace.h>
# include <avr/interrupt.h>
# include <avr/eeprom.h>
#else
# include "../compat/eeprom.h"
#endif
#include <string.h> #include <string.h>
can_addr myaddr; can_addr_t myaddr;
extern jmp_buf newmode_jmpbuf; extern jmp_buf newmode_jmpbuf;
#ifdef LAP_TIME_EXTENSION #ifdef LAP_TIME_EXTENSION
@ -45,9 +51,11 @@ void process_mgt_msg(pdo_message *msg)
switch(msg->cmd) { switch(msg->cmd) {
case FKT_MGT_RESET: case FKT_MGT_RESET:
#ifdef __AVR__
timer0_off(); timer0_off();
cli(); cli();
while(1); while(1);
#endif
break; break;
case FKT_MGT_PING: case FKT_MGT_PING:
rmsg = (pdo_message *)can_buffer_get(); rmsg = (pdo_message *)can_buffer_get();
@ -75,26 +83,27 @@ void process_borg_msg(pdo_message *msg)
{ {
unsigned char i, j; unsigned char i, j;
switch(msg->cmd) { switch (msg->cmd) {
case FKT_BORG_MODE: case FKT_BORG_MODE:
longjmp(newmode_jmpbuf, msg->data[0]); longjmp(newmode_jmpbuf, msg->data[0]);
break; break;
case FKT_BORG_SCROLLTEXT_RESET: case FKT_BORG_SCROLLTEXT_RESET:
for(i=0; i < msg->dlc-1; i++) { for (i = 0; i < msg->dlc - 1; i++) {
scrolltext_text[i] = msg->data[i]; scrolltext_text[i] = msg->data[i];
} }
scrolltext_text[i] = 0; scrolltext_text[i] = 0;
break; break;
case FKT_BORG_SCROLLTEXT_APPEND: case FKT_BORG_SCROLLTEXT_APPEND:
j=0; j = 0;
while(scrolltext_text[j]) j++; while (scrolltext_text[j])
j++;
for(i=0; i < msg->dlc-1; i++) { for (i = 0; i < msg->dlc - 1; i++) {
scrolltext_text[i+j] = msg->data[i]; scrolltext_text[i + j] = msg->data[i];
} }
scrolltext_text[i+j] = 0; scrolltext_text[i + j] = 0;
break; break;
#ifdef Hansi_hat_gelernt_Werte_vorher_zu_definieren #ifdef Hansi_hat_gelernt_Werte_vorher_zu_definieren
@ -129,21 +138,19 @@ void process_borg_msg(pdo_message *msg)
} }
} }
void bcan_process_messages() void bcan_process_messages() {
{
pdo_message *msg = (pdo_message*) can_get_nb(); pdo_message *msg = (pdo_message*) can_get_nb();
while(msg) { while (msg) {
if (!msg) if (!msg)
return; return;
if(msg->addr_dst == myaddr && msg->port_dst == PORT_MGT) if (msg->addr_dst == myaddr && msg->port_dst == PORT_MGT)
process_mgt_msg(msg); process_mgt_msg(msg);
if(msg->addr_dst == myaddr && msg->port_dst == PORT_BORG) if (msg->addr_dst == myaddr && msg->port_dst == PORT_BORG)
process_borg_msg(msg); process_borg_msg(msg);
msg = (pdo_message*) can_get_nb(); msg = (pdo_message*) can_get_nb();
}; }
} }

287
can/can.c
View File

@ -1,7 +1,9 @@
#ifndef __C64__ #ifndef __C64__
#include <avr/io.h> #ifdef __AVR__
#include <avr/interrupt.h> #include <avr/io.h>
#include <avr/interrupt.h>
#endif
#define asm asm volatile #define asm asm volatile
#endif #endif
@ -121,62 +123,65 @@ void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val);
unsigned char mcp_status(); unsigned char mcp_status();
//unsigned char mcp_rx_status(); //unsigned char mcp_rx_status();
// Functions #ifdef __AVR__
/* // Functions
unsigned char mcp_rx_status(){ /*
unsigned char mcp_rx_status() {
unsigned char d; unsigned char d;
spi_set_ss(); spi_set_ss();
spi_data(RX_STATUS); spi_data(RX_STATUS);
d = spi_data(0); d = spi_data(0);
spi_clear_ss(); spi_clear_ss();
return d; return d;
} }
*/ */
unsigned char mcp_status(){ unsigned char mcp_status() {
unsigned char d; unsigned char d;
spi_set_ss(); spi_set_ss();
spi_data(READ_STATUS); spi_data(READ_STATUS);
d = spi_data(0); d = spi_data(0);
spi_clear_ss(); spi_clear_ss();
return d; return d;
} }
void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val){ void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val) {
spi_set_ss(); spi_set_ss();
spi_data(BIT_MODIFY); spi_data(BIT_MODIFY);
spi_data(reg); spi_data(reg);
spi_data(mask); spi_data(mask);
spi_data(val); spi_data(val);
spi_clear_ss(); spi_clear_ss();
} }
//load a message to mcp2515 and start transmission //load a message to mcp2515 and start transmission
void message_load(can_message_x * msg){ void message_load(can_message_x * msg) {
unsigned char x; unsigned char x;
spi_set_ss(); spi_set_ss();
spi_data(WRITE); spi_data(WRITE);
spi_data(TXB0SIDH); spi_data(TXB0SIDH);
spi_data( ((unsigned char)(msg->msg.port_src << 2)) | (msg->msg.port_dst >> 4 ) ); spi_data(((unsigned char)(msg->msg.port_src << 2)) |
spi_data( (unsigned char)((msg->msg.port_dst & 0x0C) << 3) | (1<<EXIDE) | (msg->msg.port_dst & 0x03) ); (msg->msg.port_dst >> 4));
spi_data((unsigned char)((msg->msg.port_dst & 0x0C) << 3) |
(1<<EXIDE) | (msg->msg.port_dst & 0x03));
spi_data(msg->msg.addr_src); spi_data(msg->msg.addr_src);
spi_data(msg->msg.addr_dst); spi_data(msg->msg.addr_dst);
spi_data(msg->msg.dlc); spi_data(msg->msg.dlc);
for(x=0;x<msg->msg.dlc;x++){ for(x=0;x<msg->msg.dlc;x++) {
spi_data(msg->msg.data[x]); spi_data(msg->msg.data[x]);
} }
spi_clear_ss(); spi_clear_ss();
spi_set_ss(); spi_set_ss();
spi_data(WRITE); spi_data(WRITE);
spi_data(TXB0CTRL); spi_data(TXB0CTRL);
spi_data( (1<<TXREQ) ); spi_data((1<<TXREQ));
spi_clear_ss(); spi_clear_ss();
} }
//get a message from mcp2515 and disable RX interrupt Condition //get a message from mcp2515 and disable RX interrupt Condition
void message_fetch(can_message_x * msg){ void message_fetch(can_message_x * msg) {
unsigned char tmp1, tmp2, tmp3; unsigned char tmp1, tmp2, tmp3;
unsigned char x; unsigned char x;
@ -187,25 +192,27 @@ void message_fetch(can_message_x * msg){
msg->msg.port_src = tmp1 >> 2; msg->msg.port_src = tmp1 >> 2;
tmp2 = spi_data(0); tmp2 = spi_data(0);
tmp3 = (unsigned char)((unsigned char)(tmp2 >> 3) & 0x0C); tmp3 = (unsigned char)((unsigned char)(tmp2 >> 3) & 0x0C);
msg->msg.port_dst = ((unsigned char)(tmp1 <<4 ) & 0x30) | tmp3 | (unsigned char)(tmp2 & 0x03); msg->msg.port_dst = ((unsigned char)(tmp1 <<4 ) & 0x30) | tmp3 |
(unsigned char)(tmp2 & 0x03);
msg->msg.addr_src = spi_data(0); msg->msg.addr_src = spi_data(0);
msg->msg.addr_dst = spi_data(0); msg->msg.addr_dst = spi_data(0);
msg->msg.dlc = spi_data(0) & 0x0F; msg->msg.dlc = spi_data(0) & 0x0F;
for(x=0;x<msg->msg.dlc;x++){ for(x=0;x<msg->msg.dlc;x++) {
msg->msg.data[x] = spi_data(0); msg->msg.data[x] = spi_data(0);
} }
spi_clear_ss(); spi_clear_ss();
mcp_bitmod(CANINTF, (1<<RX0IF), 0x00); mcp_bitmod(CANINTF, (1<<RX0IF), 0x00);
} }
#ifdef CAN_INTERRUPT
static can_message_x RX_BUFFER[CAN_RX_BUFFER_SIZE], TX_BUFFER[CAN_TX_BUFFER_SIZE]; #ifdef CAN_INTERRUPT
unsigned char RX_HEAD=0;volatile unsigned char RX_TAIL=0; static can_message_x RX_BUFFER[CAN_RX_BUFFER_SIZE],
unsigned char TX_HEAD= 0;volatile unsigned char TX_TAIL=0; TX_BUFFER[CAN_TX_BUFFER_SIZE];
static volatile unsigned char TX_INT; unsigned char RX_HEAD=0;volatile unsigned char RX_TAIL=0;
unsigned char TX_HEAD= 0;volatile unsigned char TX_TAIL=0;
static volatile unsigned char TX_INT;
ISR(INT0_vect) { ISR(INT0_vect) {
unsigned char status = mcp_status(); unsigned char status = mcp_status();
if ( status & 0x01 ) { // Message in RX0 if ( status & 0x01 ) { // Message in RX0
@ -229,7 +236,7 @@ ISR(INT0_vect) {
} }
mcp_bitmod(CANINTF, (1<<TX0IF), 0x00); mcp_bitmod(CANINTF, (1<<TX0IF), 0x00);
} else { } else {
#ifdef CAN_HANDLEERROR #ifdef CAN_HANDLEERROR
status = mcp_read(EFLG); status = mcp_read(EFLG);
if(status) { // we've got a error condition if(status) { // we've got a error condition
@ -237,41 +244,40 @@ ISR(INT0_vect) {
mcp_write(EFLG, 0); mcp_write(EFLG, 0);
} }
#endif // CAN_HANDLEERROR #endif // CAN_HANDLEERROR
} }
} }
#endif
#endif
void mcp_reset(){ void mcp_reset() {
spi_set_ss(); spi_set_ss();
spi_data(RESET); spi_data(RESET);
spi_clear_ss(); spi_clear_ss();
} }
void mcp_write(unsigned char reg, unsigned char data){ void mcp_write(unsigned char reg, unsigned char data) {
spi_set_ss(); spi_set_ss();
spi_data(WRITE); spi_data(WRITE);
spi_data(reg); spi_data(reg);
spi_data(data); spi_data(data);
spi_clear_ss(); spi_clear_ss();
} }
/* /*
void mcp_write_b(unsigned char reg, unsigned char *buf, unsigned char len){ void mcp_write_b(unsigned char reg, unsigned char *buf, unsigned char len) {
unsigned char x; unsigned char x;
spi_set_ss(); spi_set_ss();
spi_data(WRITE); spi_data(WRITE);
spi_data(reg); spi_data(reg);
for(x=0;x<len;x++){ for(x=0;x<len;x++) {
spi_data(buf[x]); spi_data(buf[x]);
} }
spi_clear_ss(); spi_clear_ss();
} }
*/ */
unsigned char mcp_read(unsigned char reg){ unsigned char mcp_read(unsigned char reg) {
unsigned char d; unsigned char d;
spi_set_ss(); spi_set_ss();
spi_data(READ); spi_data(READ);
@ -279,58 +285,57 @@ unsigned char mcp_read(unsigned char reg){
d = spi_data(0); d = spi_data(0);
spi_clear_ss(); spi_clear_ss();
return d; return d;
} }
/* /*
void mcp_read_b(unsigned char reg, unsigned char *buf, unsigned char len){ void mcp_read_b(unsigned char reg, unsigned char *buf, unsigned char len) {
unsigned char x; unsigned char x;
spi_set_ss(); spi_set_ss();
spi_data(READ); spi_data(READ);
spi_data(reg); spi_data(reg);
for(x=0;x<len;x++){ for(x=0;x<len;x++) {
buf[x] = spi_data(0); buf[x] = spi_data(0);
} }
spi_clear_ss(); spi_clear_ss();
} }
*/ */
/* Management */ /* Management */
void can_setmode( can_mode_t mode ) { void can_setmode(can_mode_t mode) {
unsigned char val = mode << 5; unsigned char val = mode << 5;
val |= 0x04; // CLKEN val |= 0x04; // CLKEN
mcp_write( CANCTRL, val ); mcp_write( CANCTRL, val );
} }
void can_setfilter() {
void can_setfilter() {
//RXM1 RXM0 //RXM1 RXM0
// 0 0 receive matching filter // 0 0 receive matching filter
// 0 1 " only 11bit Identifier // 0 1 " only 11bit Identifier
// 1 0 " only 29bit Identifier // 1 0 " only 29bit Identifier
// 1 1 any // 1 1 any
mcp_write(RXB0CTRL, (1<<RXM1) | (1<<RXM0)); mcp_write(RXB0CTRL, (1<<RXM1) | (1<<RXM0));
} }
void can_setled(unsigned char led, unsigned char state){ void can_setled(unsigned char led, unsigned char state) {
mcp_bitmod(BFPCTRL, 0x10<<led, state?0xff:0); mcp_bitmod(BFPCTRL, 0x10<<led, state?0xff:0);
} }
/*******************************************************************/ /*******************************************************************/
void delayloop(){ void delayloop(){
unsigned char x; unsigned char x;
for(x=0;x<255;x++){ for(x=0;x<255;x++){
asm ("nop"); asm ("nop");
} }
} }
void can_init(){ void can_init(){
//set Slave select high //set Slave select high
SPI_PORT |= (1<<SPI_PIN_SS); SPI_PORT |= (1<<SPI_PIN_SS);
#ifdef CAN_INTERRUPT #ifdef CAN_INTERRUPT
unsigned char x; unsigned char x;
for(x=0;x<CAN_RX_BUFFER_SIZE;x++){ for(x=0;x<CAN_RX_BUFFER_SIZE;x++){
RX_BUFFER[x].flags = 0; RX_BUFFER[x].flags = 0;
@ -339,11 +344,11 @@ void can_init(){
TX_BUFFER[x].flags = 0; TX_BUFFER[x].flags = 0;
} }
#endif #endif
#ifdef CAN_HANDLEERROR #ifdef CAN_HANDLEERROR
can_error = 0; can_error = 0;
#endif #endif
mcp_reset(); mcp_reset();
@ -355,142 +360,156 @@ void can_init(){
// 0x03 : 125kbit/16MHz // 0x03 : 125kbit/16MHz
// 0x04 : 125kbit/20MHz // 0x04 : 125kbit/20MHz
#if FREQ == 16000000 #if FREQ == 16000000
#define CNF1_T 0x03 #define CNF1_T 0x03
#elif FREQ == 8000000 #elif FREQ == 8000000
#define CNF1_T 0x01 #define CNF1_T 0x01
#elif FREQ == 20000000 #elif FREQ == 20000000
#define CNF1_T 0x04 #define CNF1_T 0x04
#else #else
#error Can Baudrate is only defined for 8, 16 and 20 MHz #error Can Baudrate is only defined for 8, 16 and 20 MHz
#endif #endif
mcp_write( CNF1, 0x40 | CNF1_T ); mcp_write( CNF1, 0x40 | CNF1_T );
mcp_write( CNF2, 0xf1 ); mcp_write( CNF2, 0xf1 );
mcp_write( CNF3, 0x05 ); mcp_write( CNF3, 0x05 );
// configure IRQ // configure IRQ: this only configures the INT Output of the mcp2515, not
// this only configures the INT Output of the mcp2515, not the int on the Atmel // the int on the Atmel
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) ); mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
can_setfilter(); can_setfilter();
can_setmode(normal); can_setmode(normal);
#ifdef CAN_INTERRUPT #ifdef CAN_INTERRUPT
// configure IRQ // configure IRQ: this only configures the INT Output of the mcp2515,
// this only configures the INT Output of the mcp2515, not the int on the Atmel // not the int on the Atmel
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) ); mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
#ifdef __C64__
#ifdef __C64__
#error not implemented yet #error not implemented yet
#elif ATMEGA #elif ATMEGA
//this turns on INT0 on the Atmega //this turns on INT0 on the Atmega
GICR |= (1<<INT0); GICR |= (1<<INT0);
#else #else
//this turns on INT0 on the Atmel //this turns on INT0 on the Atmel
MCUCR |= (1<<ISC01); MCUCR |= (1<<ISC01);
GIMSK |= (1<<INT0); GIMSK |= (1<<INT0);
#endif //ATMEGA #endif //ATMEGA
#else //CAN_INTERRUPT
#else //CAN_INTERRUPT // configure IRQ: this only configures the INT Output of the mcp2515,
// configure IRQ // not the int on the Atmel
// this only configures the INT Output of the mcp2515, not the int on the Atmel
mcp_write( CANINTE, (1<<RX0IE) ); //only turn RX int on mcp_write( CANINTE, (1<<RX0IE) ); //only turn RX int on
#endif //CAN_INTERRUPT #endif //CAN_INTERRUPT
} }
#ifdef CAN_INTERRUPT #ifdef CAN_INTERRUPT
//returns next can message in buffer, or 0 Pointer if buffer is empty //returns next can message in buffer, or 0 Pointer if buffer is empty
can_message * can_get_nb(){ can_message * can_get_nb() {
can_message_x *p; can_message_x *p;
if(RX_HEAD == RX_TAIL){ if(RX_HEAD == RX_TAIL) {
return 0; return 0;
}else{ } else {
p = &RX_BUFFER[RX_TAIL]; p = &RX_BUFFER[RX_TAIL];
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0; if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
return &(p->msg); return &(p->msg);
} }
} }
can_message * can_get(){ can_message * can_get() {
can_message_x *p; can_message_x *p;
while(RX_HEAD == RX_TAIL) { }; while(RX_HEAD == RX_TAIL) {};
p = &RX_BUFFER[RX_TAIL]; p = &RX_BUFFER[RX_TAIL];
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0; if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
return &(p->msg); return &(p->msg);
} }
//marks a receive buffer as unused again so it can be overwritten in Interrupt
//marks a receive buffer as unused again so it can be overwritten in Interrupt void can_free(can_message * msg) {
void can_free(can_message * msg){
can_message_x * msg_x = (can_message_x *) msg; can_message_x * msg_x = (can_message_x *) msg;
msg_x->flags = 0; msg_x->flags = 0;
} }
//returns pointer to the next can TX buffer
//returns pointer to the next can TX buffer can_message * can_buffer_get() {
can_message * can_buffer_get(){
can_message_x *p; can_message_x *p;
p = &TX_BUFFER[TX_HEAD]; p = &TX_BUFFER[TX_HEAD];
while (p->flags&0x01); //wait until buffer is free while (p->flags&0x01); //wait until buffer is free
if(++TX_HEAD == CAN_TX_BUFFER_SIZE) TX_HEAD = 0; if(++TX_HEAD == CAN_TX_BUFFER_SIZE) TX_HEAD = 0;
return &(p->msg); return &(p->msg);
} }
//start transmitting can messages, and mark message msg as transmittable
//start transmitting can messages, and mark message msg as transmittable void can_transmit(can_message* msg2) {
void can_transmit(can_message* msg2){
can_message_x* msg=(can_message_x*) msg2; can_message_x* msg=(can_message_x*) msg2;
if(msg){ if(msg) {
msg->flags |= 0x01; msg->flags |= 0x01;
} }
if(!TX_INT){ if(!TX_INT) {
if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01){ if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01) {
((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01; ((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01;
TX_INT = 1; TX_INT = 1;
message_load(&TX_BUFFER[TX_TAIL]); message_load(&TX_BUFFER[TX_TAIL]);
if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0; if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0;
} }
} }
} }
#else // NON INTERRUPT VERSION
can_message_x RX_MESSAGE, TX_MESSAGE;
#else // NON INTERRUPT VERSION can_message * can_get_nb() {
//check the pin, that the MCP's interrupt output connects to
can_message_x RX_MESSAGE, TX_MESSAGE; if(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) {
can_message * can_get_nb(){
//check the pin, that the MCP's Interrup output connects to
if(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)){
return 0; return 0;
}else{ } else {
//So the MCP Generates an RX Interrupt //So the MCP Generates an RX Interrupt
message_fetch(&RX_MESSAGE); message_fetch(&RX_MESSAGE);
return &(RX_MESSAGE.msg); return &(RX_MESSAGE.msg);
} }
} }
can_message * can_get(){ can_message * can_get() {
//wait while the MCP doesn't generate an RX Interrupt //wait while the MCP doesn't generate an RX Interrupt
while(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) { }; while(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) {};
message_fetch(&RX_MESSAGE); message_fetch(&RX_MESSAGE);
return &(RX_MESSAGE.msg); return &(RX_MESSAGE.msg);
} }
//only for compatibility with Interrupt driven Version //only for compatibility with Interrupt driven Version
can_message * can_buffer_get(){ can_message * can_buffer_get() {
return &(TX_MESSAGE.msg); return &(TX_MESSAGE.msg);
} }
void can_transmit(can_message * msg){ void can_transmit(can_message * msg) {
message_load((can_message_x*)msg); message_load((can_message_x*)msg);
} }
void can_free(can_message * msg){
}
void can_free(can_message * msg) {
}
#endif /* CAN_INTERRUPT */
#else /* ifdef __AVR__ */
/* stubs for simulator */
static can_message null_msg = {0};
unsigned char mcp_status() {return 0;}
void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val){}
void message_load(can_message_x * msg){}
void message_fetch(can_message_x * msg){}
void mcp_reset(){}
void mcp_write(unsigned char reg, unsigned char data){}
unsigned char mcp_read(unsigned char reg){return 0;}
void can_setmode(can_mode_t mode) {}
void can_setfilter() {}
void can_setled(unsigned char led, unsigned char state){}
void delayloop(){}
void can_init(){}
can_message * can_get_nb(){return &null_msg;}
can_message * can_get(){return &null_msg;}
can_message * can_buffer_get(){return &null_msg;}
void can_transmit(can_message * msg){}
void can_free(can_message * msg){}
#endif #endif

View File

@ -4,78 +4,73 @@
/***************************************************************************** /*****************************************************************************
* Simple CAN Library * Simple CAN Library
* *
* #define CAN_INTERRUPT 1 //set this to enable interrupt driven * #define CAN_INTERRUPT 1 // set this to enable interrupt driven
* and buffering version * // and buffering version
* #define CAN_RX_BUFFER_SIZE 2 //only used for Interrupt * #define CAN_RX_BUFFER_SIZE 2 // only used for Interrupt
* #define CAN_TX_BUFFER_SIZE 2 //only used for Interrupt * #define CAN_TX_BUFFER_SIZE 2 // only used for Interrupt
*/ */
/***************************************************************************** /*****************************************************************************
* Types * Types
*/ */
#include <stdint.h> #include <stdint.h>
typedef unsigned char can_addr; typedef unsigned char can_addr_t;
typedef unsigned char can_port; typedef unsigned char can_port_t;
typedef uint16_t can_channel_t; typedef uint16_t can_channel_t;
typedef uint8_t can_subchannel_t; typedef uint8_t can_subchannel_t;
typedef struct typedef struct {
{
uint32_t id; uint32_t id;
uint8_t dlc; uint8_t dlc;
uint8_t data[8]; uint8_t data[8];
} can_message_raw; } can_message_raw;
typedef struct{ typedef struct {
can_addr addr_src; can_addr_t addr_src;
can_addr addr_dst; can_addr_t addr_dst;
can_port port_src; can_port_t port_src;
can_port port_dst; can_port_t port_dst;
unsigned char dlc; unsigned char dlc;
unsigned char data[8]; unsigned char data[8];
}can_message; } can_message;
typedef struct typedef struct {
{
can_channel_t channel; can_channel_t channel;
can_subchannel_t subchannel; can_subchannel_t subchannel;
can_addr addr_src; can_addr_t addr_src;
can_addr addr_dst; can_addr_t addr_dst;
uint8_t dlc; uint8_t dlc;
uint8_t data[8]; uint8_t data[8];
} can_message_v2; } can_message_v2;
typedef enum {
typedef enum { normal, mode_sleep, loopback, listenonly, config } can_mode_t ; normal, mode_sleep, loopback, listenonly, config
} can_mode_t;
/***************************************************************************** /*****************************************************************************
* Global variables * Global variables
*/ */
#ifdef CAN_HANDLEERROR #ifdef CAN_HANDLEERROR
extern unsigned char can_error; extern unsigned char can_error;
#endif #endif
/***************************************************************************** /*****************************************************************************
* Management * Management
*/ */
void can_init(); void can_init();
void can_setfilter(); void can_setfilter();
void can_setmode(can_mode_t); void can_setmode( can_mode_t);
void can_setled(unsigned char led, unsigned char state); void can_setled(unsigned char led, unsigned char state);
/***************************************************************************** /*****************************************************************************
* Sending * Sending
*/ */
can_message * can_buffer_get(); can_message * can_buffer_get();
void can_transmit( can_message *msg ); void can_transmit(can_message *msg);
/***************************************************************************** /*****************************************************************************
* Receiving * Receiving
@ -87,19 +82,17 @@ can_message *can_get_nb();
// this is only needed for Interrupt driven Version // this is only needed for Interrupt driven Version
#ifndef CAN_INTERRUPT #ifndef CAN_INTERRUPT
// # define can_free(m) // # define can_free(m)
void can_free(can_message * msg); void can_free(can_message * msg);
#else #else
void can_free(can_message * msg); void can_free(can_message * msg);
#endif #endif
/***************************************************************************** /*****************************************************************************
* Sending * Sending
*/ */
can_message_raw * can_buffer_get_raw(); can_message_raw * can_buffer_get_raw();
void can_transmit_raw( can_message_raw *msg ); void can_transmit_raw(can_message_raw *msg);
/***************************************************************************** /*****************************************************************************
* Receiving * Receiving
@ -111,20 +104,16 @@ can_message_raw *can_get_raw_nb();
// this is only needed for Interrupt driven Version // this is only needed for Interrupt driven Version
#ifndef CAN_INTERRUPT #ifndef CAN_INTERRUPT
// # define can_free(m) // # define can_free(m)
void can_free_raw(can_message_raw * msg); void can_free_raw(can_message_raw * msg);
#else #else
void can_free_raw(can_message_raw * msg); void can_free_raw(can_message_raw * msg);
#endif #endif
/***************************************************************************** /*****************************************************************************
* Sending * Sending
*/ */
void can_transmit_v2( can_message_v2 *msg ); void can_transmit_v2(can_message_v2 *msg);
/***************************************************************************** /*****************************************************************************
* Receiving * Receiving
@ -134,6 +123,4 @@ can_message_v2 *can_get_v2_nb();
void can_free_v2(can_message_v2 *msg); void can_free_v2(can_message_v2 *msg);
#endif #endif

View File

@ -9,9 +9,8 @@
*/ */
// send ping to dst // send ping to dst
void lap_ping( can_addr dst ) void lap_ping(can_addr_t dst) {
{ pdo_message *msg = (pdo_message *) can_buffer_get();
pdo_message *msg = (pdo_message *)can_buffer_get();
msg->addr_src = 0; msg->addr_src = 0;
msg->addr_dst = dst; msg->addr_dst = dst;
@ -20,13 +19,12 @@ void lap_ping( can_addr dst )
msg->dlc = 1; msg->dlc = 1;
msg->cmd = FKT_MGT_PING; msg->cmd = FKT_MGT_PING;
can_transmit( (can_message *)msg ); can_transmit((can_message *) msg);
} }
// send reset request to dst // send reset request to dst
void lap_reset( can_addr dst ) void lap_reset(can_addr_t dst) {
{ pdo_message *msg = (pdo_message *) can_buffer_get();
pdo_message *msg = (pdo_message *)can_buffer_get();
msg->addr_src = 0; msg->addr_src = 0;
msg->addr_dst = dst; msg->addr_dst = dst;
@ -35,20 +33,9 @@ void lap_reset( can_addr dst )
msg->dlc = 1; msg->dlc = 1;
msg->cmd = FKT_MGT_RESET; msg->cmd = FKT_MGT_RESET;
can_transmit( (can_message *)msg ); can_transmit((can_message *) msg);
} }
/* /*
char *sdo_readbuf(lap_message *first_msg, char *sdo_readbuf(lap_message *first_msg,
unsigned char int length, unsigned char &reallength) unsigned char int length, unsigned char &reallength)
@ -118,6 +105,5 @@ unsigned char sdo_sendbuf_nb(lap_message *fst_msg, unsigned char *buf, unsigned
can_transmit(); can_transmit();
} }
// XXX wait for ACK // XXX wait for ACK
} }
*/ */

View File

@ -15,10 +15,10 @@
// "inherits" from can_message // "inherits" from can_message
typedef struct { typedef struct {
can_addr addr_src; can_addr_t addr_src;
can_addr addr_dst; can_addr_t addr_dst;
can_port port_src; can_port_t port_src;
can_port port_dst; can_port_t port_dst;
unsigned char dlc; unsigned char dlc;
unsigned char cmd; unsigned char cmd;
uint16_t index; uint16_t index;
@ -27,11 +27,11 @@ typedef struct {
} sdo_message; } sdo_message;
// "inherits" from can_message // "inherits" from can_message
typedef struct{ typedef struct {
can_addr addr_src; can_addr_t addr_src;
can_addr addr_dst; can_addr_t addr_dst;
can_port port_src; can_port_t port_src;
can_port port_dst; can_port_t port_dst;
unsigned char dlc; unsigned char dlc;
unsigned char cmd; unsigned char cmd;
unsigned char data[7]; unsigned char data[7];
@ -41,22 +41,55 @@ typedef struct{
* Known ports and services * Known ports and services
*/ */
typedef enum { PORT_MGT=0x30, PORT_LAMPE=0x20, PORT_SDO=0x15, PORT_SDO_DATA=0x16, PORT_LAPD=0x18, typedef enum {
PORT_BORG=0x23, PORT_MOOD=0x17, PORT_REMOTE=0x21, PORT_GATE=0x22, PORT_CHUCK=0x26 } ports; PORT_MGT = 0x30,
PORT_LAMPE = 0x20,
PORT_SDO = 0x15,
PORT_SDO_DATA = 0x16,
PORT_LAPD = 0x18,
PORT_BORG = 0x23,
PORT_MOOD = 0x17,
PORT_REMOTE = 0x21,
PORT_GATE = 0x22,
PORT_CHUCK = 0x26
} ports;
typedef enum { FKT_MGT_PING=0x00, FKT_MGT_PONG=0x01, typedef enum {
FKT_MGT_RESET=0x02, FKT_MGT_AWAKE=0x03, FKT_MGT_TIMEREQUEST=0x04, FKT_MGT_TIMEREPLY=0x05 } lap_mgt_fkts; FKT_MGT_PING = 0x00,
FKT_MGT_PONG = 0x01,
FKT_MGT_RESET = 0x02,
FKT_MGT_AWAKE = 0x03,
FKT_MGT_TIMEREQUEST = 0x04,
FKT_MGT_TIMEREPLY = 0x05
} lap_mgt_fkts;
typedef enum { FKT_LAMPE_SET=0x00, FKT_LAMPE_SETMASK=0x01, typedef enum {
FKT_LAMPE_SETDELAY=0x02, FKT_LAMPE_ADD=0x03 } lap_lampe_fkts; FKT_LAMPE_SET = 0x00,
FKT_LAMPE_SETMASK = 0x01,
FKT_LAMPE_SETDELAY = 0x02,
FKT_LAMPE_ADD = 0x03
} lap_lampe_fkts;
typedef enum { FKT_BORG_INFO=0x00, FKT_BORG_MODE=0x01, FKT_BORG_SCROLLTEXT_RESET=0x02, typedef enum {
FKT_BORG_SCROLLTEXT_APPEND=0x03 } lap_borg_fkts; FKT_BORG_INFO = 0x00,
FKT_BORG_MODE = 0x01,
FKT_BORG_SCROLLTEXT_RESET = 0x02,
FKT_BORG_SCROLLTEXT_APPEND = 0x03
} lap_borg_fkts;
typedef enum { FKT_ONOFF_INFO=0, FKT_ONOFF_SET=1, FKT_ONOFF_GET=2, typedef enum {
} lap_lapd_fkts; FKT_ONOFF_INFO = 0,
FKT_ONOFF_SET = 1,
FKT_ONOFF_GET = 2
} lap_lapd_fkts;
typedef enum {
FKT_MOOD_INFO = 0x00,
FKT_MOOD_GET = 0x01,
FKT_MOOD_SET = 0x02,
FKT_MOOD_ONOFF = 0x03
} lap_mood_fkts;
typedef enum { FKT_MOOD_INFO=0x00, FKT_MOOD_GET=0x01, FKT_MOOD_SET=0x02, FKT_MOOD_ONOFF=0x03} lap_mood_fkts;
#define SDO_CMD_READ 0x20 #define SDO_CMD_READ 0x20
#define SDO_CMD_REPLY 0x21 #define SDO_CMD_REPLY 0x21
#define SDO_CMD_INFO 0x22 #define SDO_CMD_INFO 0x22
@ -65,7 +98,6 @@ typedef enum { FKT_MOOD_INFO=0x00, FKT_MOOD_GET=0x01, FKT_MOOD_SET=0x02, FKT_MOO
#define SDO_CMD_WRITE_BLK 0x48 #define SDO_CMD_WRITE_BLK 0x48
#define SDO_CMD_WRITE_BLK_ACK 0x49 #define SDO_CMD_WRITE_BLK_ACK 0x49
#define SDO_CMD_ERROR_INDEX 0x80 #define SDO_CMD_ERROR_INDEX 0x80
#define SDO_TYPE_UINT8_RO 0x00 #define SDO_TYPE_UINT8_RO 0x00
@ -84,10 +116,10 @@ typedef enum { FKT_MOOD_INFO=0x00, FKT_MOOD_GET=0x01, FKT_MOOD_SET=0x02, FKT_MOO
*/ */
// send ping to dst // send ping to dst
void lap_ping( can_addr dst ); void lap_ping(can_addr_t dst);
// send reset request to dst // send reset request to dst
void lap_reset( can_addr dst ); void lap_reset(can_addr_t dst);
#ifdef LAP_TIME_EXTENSION #ifdef LAP_TIME_EXTENSION
//variables to save the last received hours and minutes //variables to save the last received hours and minutes

View File

@ -1,6 +1,10 @@
#ifdef __AVR__
#include <avr/io.h> #include <avr/io.h>
#endif
#include "spi.h" #include "spi.h"
#ifdef __AVR__
void spi_init(){ void spi_init(){
//set output SPI pins to output //set output SPI pins to output
@ -27,21 +31,21 @@ void spi_init(){
} }
#ifndef SPI_HARDWARE #ifndef SPI_HARDWARE
unsigned char spi_data(unsigned char c){ unsigned char spi_data(unsigned char c) {
unsigned char x, d=d; unsigned char x, d=d;
for(x=0;x<8;x++){ for(x = 0; x < 8; x++) {
if(c & 0x80){ if(c & 0x80) {
SPI_PORT |= (1<<SPI_PIN_MOSI); SPI_PORT |= (1 << SPI_PIN_MOSI);
}else{ } else {
SPI_PORT &= ~(1<<SPI_PIN_MOSI); SPI_PORT &= ~(1 << SPI_PIN_MOSI);
} }
SPI_PORT |= (1<<SPI_PIN_SCK); SPI_PORT |= (1 << SPI_PIN_SCK);
d<<=1; d <<= 1;
if(SPI_PIN & (1<<SPI_PIN_MISO)){ if(SPI_PIN & (1 << SPI_PIN_MISO)) {
d|=1; d |= 1;
} }
SPI_PORT &= ~(1<<SPI_PIN_SCK); SPI_PORT &= ~(1 << SPI_PIN_SCK);
c<<=1; c <<= 1;
} }
return d; return d;
} }
@ -53,3 +57,10 @@ unsigned char spi_data(unsigned char c) {
return (c); return (c);
} }
#endif #endif
#else
void spi_init(){}
unsigned char spi_data(unsigned char c){return 0;}
#endif

View File

@ -3,26 +3,8 @@
#include "../config.h" #include "../config.h"
/**
* this enables the use of Hardware SPI on ATMEGA
*
* #define SPI_HARDWARE 1
* #define SPI_PORT PORTB
* #define SPI_PIN PINB
* #define SPI_DDR DDRB
*
* #define SPI_PIN_MOSI PB5
* #define SPI_PIN_MISO PB6
* #define SPI_PIN_SCK PB7
* #define SPI_PIN_SS PB4
*
*/
void spi_init(); void spi_init();
unsigned char spi_data(unsigned char c); unsigned char spi_data(unsigned char c);
#endif #endif