This commit is contained in:
parent
0705564d6d
commit
f2027360a0
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
};
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
743
can/can.c
743
can/can.c
|
@ -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,376 +123,393 @@ 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 d;
|
unsigned char mcp_rx_status() {
|
||||||
spi_set_ss();
|
unsigned char d;
|
||||||
spi_data(RX_STATUS);
|
spi_set_ss();
|
||||||
d = spi_data(0);
|
spi_data(RX_STATUS);
|
||||||
spi_clear_ss();
|
d = spi_data(0);
|
||||||
return d;
|
spi_clear_ss();
|
||||||
}
|
return d;
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned char mcp_status(){
|
|
||||||
unsigned char d;
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(READ_STATUS);
|
|
||||||
d = spi_data(0);
|
|
||||||
spi_clear_ss();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val){
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(BIT_MODIFY);
|
|
||||||
spi_data(reg);
|
|
||||||
spi_data(mask);
|
|
||||||
spi_data(val);
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
|
|
||||||
//load a message to mcp2515 and start transmission
|
|
||||||
void message_load(can_message_x * msg){
|
|
||||||
unsigned char x;
|
|
||||||
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(WRITE);
|
|
||||||
spi_data(TXB0SIDH);
|
|
||||||
|
|
||||||
spi_data( ((unsigned char)(msg->msg.port_src << 2)) | (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_dst);
|
|
||||||
spi_data(msg->msg.dlc);
|
|
||||||
for(x=0;x<msg->msg.dlc;x++){
|
|
||||||
spi_data(msg->msg.data[x]);
|
|
||||||
}
|
}
|
||||||
spi_clear_ss();
|
*/
|
||||||
spi_set_ss();
|
|
||||||
spi_data(WRITE);
|
|
||||||
spi_data(TXB0CTRL);
|
|
||||||
spi_data( (1<<TXREQ) );
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
|
|
||||||
//get a message from mcp2515 and disable RX interrupt Condition
|
unsigned char mcp_status() {
|
||||||
void message_fetch(can_message_x * msg){
|
unsigned char d;
|
||||||
unsigned char tmp1, tmp2, tmp3;
|
spi_set_ss();
|
||||||
unsigned char x;
|
spi_data(READ_STATUS);
|
||||||
|
d = spi_data(0);
|
||||||
spi_set_ss();
|
spi_clear_ss();
|
||||||
spi_data(READ);
|
return d;
|
||||||
spi_data(RXB0SIDH);
|
|
||||||
tmp1 = spi_data(0);
|
|
||||||
msg->msg.port_src = tmp1 >> 2;
|
|
||||||
tmp2 = spi_data(0);
|
|
||||||
tmp3 = (unsigned char)((unsigned char)(tmp2 >> 3) & 0x0C);
|
|
||||||
msg->msg.port_dst = ((unsigned char)(tmp1 <<4 ) & 0x30) | tmp3 | (unsigned char)(tmp2 & 0x03);
|
|
||||||
msg->msg.addr_src = spi_data(0);
|
|
||||||
msg->msg.addr_dst = spi_data(0);
|
|
||||||
msg->msg.dlc = spi_data(0) & 0x0F;
|
|
||||||
for(x=0;x<msg->msg.dlc;x++){
|
|
||||||
msg->msg.data[x] = spi_data(0);
|
|
||||||
}
|
}
|
||||||
spi_clear_ss();
|
|
||||||
|
|
||||||
mcp_bitmod(CANINTF, (1<<RX0IF), 0x00);
|
void mcp_bitmod(unsigned char reg, unsigned char mask, unsigned char val) {
|
||||||
}
|
spi_set_ss();
|
||||||
#ifdef CAN_INTERRUPT
|
spi_data(BIT_MODIFY);
|
||||||
|
spi_data(reg);
|
||||||
|
spi_data(mask);
|
||||||
|
spi_data(val);
|
||||||
|
spi_clear_ss();
|
||||||
|
}
|
||||||
|
|
||||||
static can_message_x RX_BUFFER[CAN_RX_BUFFER_SIZE], TX_BUFFER[CAN_TX_BUFFER_SIZE];
|
//load a message to mcp2515 and start transmission
|
||||||
unsigned char RX_HEAD=0;volatile unsigned char RX_TAIL=0;
|
void message_load(can_message_x * msg) {
|
||||||
unsigned char TX_HEAD= 0;volatile unsigned char TX_TAIL=0;
|
unsigned char x;
|
||||||
static volatile unsigned char TX_INT;
|
|
||||||
|
|
||||||
ISR(INT0_vect) {
|
spi_set_ss();
|
||||||
unsigned char status = mcp_status();
|
spi_data(WRITE);
|
||||||
|
spi_data(TXB0SIDH);
|
||||||
|
|
||||||
|
spi_data(((unsigned char)(msg->msg.port_src << 2)) |
|
||||||
|
(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_dst);
|
||||||
|
spi_data(msg->msg.dlc);
|
||||||
|
for(x=0;x<msg->msg.dlc;x++) {
|
||||||
|
spi_data(msg->msg.data[x]);
|
||||||
|
}
|
||||||
|
spi_clear_ss();
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(WRITE);
|
||||||
|
spi_data(TXB0CTRL);
|
||||||
|
spi_data((1<<TXREQ));
|
||||||
|
spi_clear_ss();
|
||||||
|
}
|
||||||
|
|
||||||
|
//get a message from mcp2515 and disable RX interrupt Condition
|
||||||
|
void message_fetch(can_message_x * msg) {
|
||||||
|
unsigned char tmp1, tmp2, tmp3;
|
||||||
|
unsigned char x;
|
||||||
|
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(READ);
|
||||||
|
spi_data(RXB0SIDH);
|
||||||
|
tmp1 = spi_data(0);
|
||||||
|
msg->msg.port_src = tmp1 >> 2;
|
||||||
|
tmp2 = spi_data(0);
|
||||||
|
tmp3 = (unsigned char)((unsigned char)(tmp2 >> 3) & 0x0C);
|
||||||
|
msg->msg.port_dst = ((unsigned char)(tmp1 <<4 ) & 0x30) | tmp3 |
|
||||||
|
(unsigned char)(tmp2 & 0x03);
|
||||||
|
msg->msg.addr_src = spi_data(0);
|
||||||
|
msg->msg.addr_dst = spi_data(0);
|
||||||
|
msg->msg.dlc = spi_data(0) & 0x0F;
|
||||||
|
for(x=0;x<msg->msg.dlc;x++) {
|
||||||
|
msg->msg.data[x] = spi_data(0);
|
||||||
|
}
|
||||||
|
spi_clear_ss();
|
||||||
|
|
||||||
|
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];
|
||||||
|
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;
|
||||||
|
|
||||||
if ( status & 0x01 ) { // Message in RX0
|
ISR(INT0_vect) {
|
||||||
if ( !(((can_message_x*)&RX_BUFFER[RX_HEAD])->flags & 0x01) ) {
|
unsigned char status = mcp_status();
|
||||||
message_fetch(&RX_BUFFER[RX_HEAD]);
|
|
||||||
RX_BUFFER[RX_HEAD].flags |= 0x01;//mark buffer as used
|
|
||||||
if( ++RX_HEAD == CAN_RX_BUFFER_SIZE) RX_HEAD = 0;
|
|
||||||
}else{
|
|
||||||
//buffer overflow
|
|
||||||
//just clear the Interrupt condition, and lose the message
|
|
||||||
mcp_bitmod(CANINTF, (1<<RX0IF), 0x00);
|
|
||||||
}
|
|
||||||
} else if ( status & 0x08 ) { // TX1 empty
|
|
||||||
if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01) {
|
|
||||||
((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01;
|
|
||||||
TX_INT = 1;
|
|
||||||
message_load(&TX_BUFFER[TX_TAIL]);
|
|
||||||
if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0;
|
|
||||||
}else{
|
|
||||||
TX_INT = 0;
|
|
||||||
}
|
|
||||||
mcp_bitmod(CANINTF, (1<<TX0IF), 0x00);
|
|
||||||
} else {
|
|
||||||
#ifdef CAN_HANDLEERROR
|
|
||||||
status = mcp_read(EFLG);
|
|
||||||
|
|
||||||
if(status) { // we've got a error condition
|
if ( status & 0x01 ) { // Message in RX0
|
||||||
can_error = status;
|
if ( !(((can_message_x*)&RX_BUFFER[RX_HEAD])->flags & 0x01) ) {
|
||||||
|
message_fetch(&RX_BUFFER[RX_HEAD]);
|
||||||
|
RX_BUFFER[RX_HEAD].flags |= 0x01;//mark buffer as used
|
||||||
|
if( ++RX_HEAD == CAN_RX_BUFFER_SIZE) RX_HEAD = 0;
|
||||||
|
}else{
|
||||||
|
//buffer overflow
|
||||||
|
//just clear the Interrupt condition, and lose the message
|
||||||
|
mcp_bitmod(CANINTF, (1<<RX0IF), 0x00);
|
||||||
|
}
|
||||||
|
} else if ( status & 0x08 ) { // TX1 empty
|
||||||
|
if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01) {
|
||||||
|
((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01;
|
||||||
|
TX_INT = 1;
|
||||||
|
message_load(&TX_BUFFER[TX_TAIL]);
|
||||||
|
if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0;
|
||||||
|
}else{
|
||||||
|
TX_INT = 0;
|
||||||
|
}
|
||||||
|
mcp_bitmod(CANINTF, (1<<TX0IF), 0x00);
|
||||||
|
} else {
|
||||||
|
#ifdef CAN_HANDLEERROR
|
||||||
|
status = mcp_read(EFLG);
|
||||||
|
|
||||||
mcp_write(EFLG, 0);
|
if(status) { // we've got a error condition
|
||||||
|
can_error = status;
|
||||||
|
|
||||||
|
mcp_write(EFLG, 0);
|
||||||
|
}
|
||||||
|
#endif // CAN_HANDLEERROR
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // CAN_HANDLEERROR
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void mcp_reset() {
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(RESET);
|
||||||
|
spi_clear_ss();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void mcp_reset(){
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(RESET);
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mcp_write(unsigned char reg, unsigned char data){
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(WRITE);
|
|
||||||
spi_data(reg);
|
|
||||||
spi_data(data);
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void mcp_write_b(unsigned char reg, unsigned char *buf, unsigned char len){
|
|
||||||
unsigned char x;
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(WRITE);
|
|
||||||
spi_data(reg);
|
|
||||||
for(x=0;x<len;x++){
|
|
||||||
spi_data(buf[x]);
|
|
||||||
}
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned char mcp_read(unsigned char reg){
|
|
||||||
unsigned char d;
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(READ);
|
|
||||||
spi_data(reg);
|
|
||||||
d = spi_data(0);
|
|
||||||
spi_clear_ss();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void mcp_read_b(unsigned char reg, unsigned char *buf, unsigned char len){
|
|
||||||
unsigned char x;
|
|
||||||
spi_set_ss();
|
|
||||||
spi_data(READ);
|
|
||||||
spi_data(reg);
|
|
||||||
for(x=0;x<len;x++){
|
|
||||||
buf[x] = spi_data(0);
|
|
||||||
}
|
|
||||||
spi_clear_ss();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Management */
|
|
||||||
void can_setmode( can_mode_t mode ) {
|
|
||||||
unsigned char val = mode << 5;
|
|
||||||
val |= 0x04; // CLKEN
|
|
||||||
|
|
||||||
mcp_write( CANCTRL, val );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void can_setfilter() {
|
|
||||||
//RXM1 RXM0
|
|
||||||
// 0 0 receive matching filter
|
|
||||||
// 0 1 " only 11bit Identifier
|
|
||||||
// 1 0 " only 29bit Identifier
|
|
||||||
// 1 1 any
|
|
||||||
mcp_write(RXB0CTRL, (1<<RXM1) | (1<<RXM0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void can_setled(unsigned char led, unsigned char state){
|
|
||||||
mcp_bitmod(BFPCTRL, 0x10<<led, state?0xff:0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************/
|
|
||||||
void delayloop(){
|
|
||||||
unsigned char x;
|
|
||||||
for(x=0;x<255;x++){
|
|
||||||
asm ("nop");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void can_init(){
|
|
||||||
//set Slave select high
|
|
||||||
SPI_PORT |= (1<<SPI_PIN_SS);
|
|
||||||
|
|
||||||
#ifdef CAN_INTERRUPT
|
|
||||||
unsigned char x;
|
|
||||||
for(x=0;x<CAN_RX_BUFFER_SIZE;x++){
|
|
||||||
RX_BUFFER[x].flags = 0;
|
|
||||||
}
|
|
||||||
for(x=0;x<CAN_TX_BUFFER_SIZE;x++){
|
|
||||||
TX_BUFFER[x].flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CAN_HANDLEERROR
|
|
||||||
can_error = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mcp_reset();
|
|
||||||
|
|
||||||
delayloop();
|
|
||||||
|
|
||||||
mcp_write(BFPCTRL,0x0C);//RXBF Pins to Output
|
|
||||||
|
|
||||||
// 0x01 : 125kbit/8MHz
|
|
||||||
// 0x03 : 125kbit/16MHz
|
|
||||||
// 0x04 : 125kbit/20MHz
|
|
||||||
|
|
||||||
#if FREQ == 16000000
|
|
||||||
#define CNF1_T 0x03
|
|
||||||
#elif FREQ == 8000000
|
|
||||||
#define CNF1_T 0x01
|
|
||||||
#elif FREQ == 20000000
|
|
||||||
#define CNF1_T 0x04
|
|
||||||
#else
|
|
||||||
#error Can Baudrate is only defined for 8, 16 and 20 MHz
|
|
||||||
#endif
|
|
||||||
mcp_write( CNF1, 0x40 | CNF1_T );
|
|
||||||
mcp_write( CNF2, 0xf1 );
|
|
||||||
mcp_write( CNF3, 0x05 );
|
|
||||||
|
|
||||||
// configure IRQ
|
|
||||||
// this only configures the INT Output of the mcp2515, not the int on the Atmel
|
|
||||||
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
|
|
||||||
|
|
||||||
can_setfilter();
|
|
||||||
can_setmode(normal);
|
|
||||||
|
|
||||||
#ifdef CAN_INTERRUPT
|
|
||||||
|
|
||||||
// configure IRQ
|
|
||||||
// this only configures the INT Output of the mcp2515, not the int on the Atmel
|
|
||||||
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __C64__
|
|
||||||
#error not implemented yet
|
|
||||||
#elif ATMEGA
|
|
||||||
//this turns on INT0 on the Atmega
|
|
||||||
GICR |= (1<<INT0);
|
|
||||||
#else
|
|
||||||
//this turns on INT0 on the Atmel
|
|
||||||
MCUCR |= (1<<ISC01);
|
|
||||||
GIMSK |= (1<<INT0);
|
|
||||||
#endif //ATMEGA
|
|
||||||
|
|
||||||
#else //CAN_INTERRUPT
|
|
||||||
// configure IRQ
|
|
||||||
// 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
|
|
||||||
#endif //CAN_INTERRUPT
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CAN_INTERRUPT
|
|
||||||
//returns next can message in buffer, or 0 Pointer if buffer is empty
|
|
||||||
can_message * can_get_nb(){
|
|
||||||
can_message_x *p;
|
|
||||||
if(RX_HEAD == RX_TAIL){
|
|
||||||
return 0;
|
|
||||||
}else{
|
|
||||||
p = &RX_BUFFER[RX_TAIL];
|
|
||||||
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
|
|
||||||
return &(p->msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
can_message * can_get(){
|
|
||||||
can_message_x *p;
|
|
||||||
|
|
||||||
while(RX_HEAD == RX_TAIL) { };
|
|
||||||
|
|
||||||
p = &RX_BUFFER[RX_TAIL];
|
|
||||||
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
|
|
||||||
|
|
||||||
return &(p->msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//marks a receive buffer as unused again so it can be overwritten in Interrupt
|
|
||||||
void can_free(can_message * msg){
|
|
||||||
can_message_x * msg_x = (can_message_x *) msg;
|
|
||||||
msg_x->flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//returns pointer to the next can TX buffer
|
|
||||||
can_message * can_buffer_get(){
|
|
||||||
can_message_x *p;
|
|
||||||
p = &TX_BUFFER[TX_HEAD];
|
|
||||||
while (p->flags&0x01); //wait until buffer is free
|
|
||||||
if(++TX_HEAD == CAN_TX_BUFFER_SIZE) TX_HEAD = 0;
|
|
||||||
return &(p->msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//start transmitting can messages, and mark message msg as transmittable
|
|
||||||
void can_transmit(can_message* msg2){
|
|
||||||
can_message_x* msg=(can_message_x*) msg2;
|
|
||||||
if(msg){
|
|
||||||
msg->flags |= 0x01;
|
|
||||||
}
|
|
||||||
if(!TX_INT){
|
|
||||||
if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01){
|
|
||||||
((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01;
|
|
||||||
TX_INT = 1;
|
|
||||||
message_load(&TX_BUFFER[TX_TAIL]);
|
|
||||||
if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // NON INTERRUPT VERSION
|
|
||||||
|
|
||||||
can_message_x RX_MESSAGE, TX_MESSAGE;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}else{
|
|
||||||
//So the MCP Generates an RX Interrupt
|
|
||||||
message_fetch(&RX_MESSAGE);
|
|
||||||
return &(RX_MESSAGE.msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
can_message * can_get(){
|
|
||||||
//wait while the MCP doesn't generate an RX Interrupt
|
|
||||||
while(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) { };
|
|
||||||
|
|
||||||
message_fetch(&RX_MESSAGE);
|
|
||||||
return &(RX_MESSAGE.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
//only for compatibility with Interrupt driven Version
|
|
||||||
can_message * can_buffer_get(){
|
|
||||||
return &(TX_MESSAGE.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void can_transmit(can_message * msg){
|
|
||||||
message_load((can_message_x*)msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void can_free(can_message * msg){
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void mcp_write(unsigned char reg, unsigned char data) {
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(WRITE);
|
||||||
|
spi_data(reg);
|
||||||
|
spi_data(data);
|
||||||
|
spi_clear_ss();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void mcp_write_b(unsigned char reg, unsigned char *buf, unsigned char len) {
|
||||||
|
unsigned char x;
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(WRITE);
|
||||||
|
spi_data(reg);
|
||||||
|
for(x=0;x<len;x++) {
|
||||||
|
spi_data(buf[x]);
|
||||||
|
}
|
||||||
|
spi_clear_ss();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char mcp_read(unsigned char reg) {
|
||||||
|
unsigned char d;
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(READ);
|
||||||
|
spi_data(reg);
|
||||||
|
d = spi_data(0);
|
||||||
|
spi_clear_ss();
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void mcp_read_b(unsigned char reg, unsigned char *buf, unsigned char len) {
|
||||||
|
unsigned char x;
|
||||||
|
spi_set_ss();
|
||||||
|
spi_data(READ);
|
||||||
|
spi_data(reg);
|
||||||
|
for(x=0;x<len;x++) {
|
||||||
|
buf[x] = spi_data(0);
|
||||||
|
}
|
||||||
|
spi_clear_ss();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Management */
|
||||||
|
void can_setmode(can_mode_t mode) {
|
||||||
|
unsigned char val = mode << 5;
|
||||||
|
val |= 0x04; // CLKEN
|
||||||
|
|
||||||
|
mcp_write( CANCTRL, val );
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_setfilter() {
|
||||||
|
//RXM1 RXM0
|
||||||
|
// 0 0 receive matching filter
|
||||||
|
// 0 1 " only 11bit Identifier
|
||||||
|
// 1 0 " only 29bit Identifier
|
||||||
|
// 1 1 any
|
||||||
|
mcp_write(RXB0CTRL, (1<<RXM1) | (1<<RXM0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_setled(unsigned char led, unsigned char state) {
|
||||||
|
mcp_bitmod(BFPCTRL, 0x10<<led, state?0xff:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
void delayloop(){
|
||||||
|
unsigned char x;
|
||||||
|
for(x=0;x<255;x++){
|
||||||
|
asm ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_init(){
|
||||||
|
//set Slave select high
|
||||||
|
SPI_PORT |= (1<<SPI_PIN_SS);
|
||||||
|
|
||||||
|
#ifdef CAN_INTERRUPT
|
||||||
|
unsigned char x;
|
||||||
|
for(x=0;x<CAN_RX_BUFFER_SIZE;x++){
|
||||||
|
RX_BUFFER[x].flags = 0;
|
||||||
|
}
|
||||||
|
for(x=0;x<CAN_TX_BUFFER_SIZE;x++){
|
||||||
|
TX_BUFFER[x].flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CAN_HANDLEERROR
|
||||||
|
can_error = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mcp_reset();
|
||||||
|
|
||||||
|
delayloop();
|
||||||
|
|
||||||
|
mcp_write(BFPCTRL,0x0C);//RXBF Pins to Output
|
||||||
|
|
||||||
|
// 0x01 : 125kbit/8MHz
|
||||||
|
// 0x03 : 125kbit/16MHz
|
||||||
|
// 0x04 : 125kbit/20MHz
|
||||||
|
|
||||||
|
#if FREQ == 16000000
|
||||||
|
#define CNF1_T 0x03
|
||||||
|
#elif FREQ == 8000000
|
||||||
|
#define CNF1_T 0x01
|
||||||
|
#elif FREQ == 20000000
|
||||||
|
#define CNF1_T 0x04
|
||||||
|
#else
|
||||||
|
#error Can Baudrate is only defined for 8, 16 and 20 MHz
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mcp_write( CNF1, 0x40 | CNF1_T );
|
||||||
|
mcp_write( CNF2, 0xf1 );
|
||||||
|
mcp_write( CNF3, 0x05 );
|
||||||
|
|
||||||
|
// configure IRQ: this only configures the INT Output of the mcp2515, not
|
||||||
|
// the int on the Atmel
|
||||||
|
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
|
||||||
|
|
||||||
|
can_setfilter();
|
||||||
|
can_setmode(normal);
|
||||||
|
|
||||||
|
#ifdef CAN_INTERRUPT
|
||||||
|
|
||||||
|
// configure IRQ: this only configures the INT Output of the mcp2515,
|
||||||
|
// not the int on the Atmel
|
||||||
|
mcp_write( CANINTE, (1<<RX0IE) | (1<<TX0IE) );
|
||||||
|
|
||||||
|
#ifdef __C64__
|
||||||
|
#error not implemented yet
|
||||||
|
#elif ATMEGA
|
||||||
|
//this turns on INT0 on the Atmega
|
||||||
|
GICR |= (1<<INT0);
|
||||||
|
#else
|
||||||
|
//this turns on INT0 on the Atmel
|
||||||
|
MCUCR |= (1<<ISC01);
|
||||||
|
GIMSK |= (1<<INT0);
|
||||||
|
#endif //ATMEGA
|
||||||
|
#else //CAN_INTERRUPT
|
||||||
|
// configure IRQ: 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
|
||||||
|
#endif //CAN_INTERRUPT
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CAN_INTERRUPT
|
||||||
|
//returns next can message in buffer, or 0 Pointer if buffer is empty
|
||||||
|
can_message * can_get_nb() {
|
||||||
|
can_message_x *p;
|
||||||
|
if(RX_HEAD == RX_TAIL) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
p = &RX_BUFFER[RX_TAIL];
|
||||||
|
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
|
||||||
|
return &(p->msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
can_message * can_get() {
|
||||||
|
can_message_x *p;
|
||||||
|
|
||||||
|
while(RX_HEAD == RX_TAIL) {};
|
||||||
|
|
||||||
|
p = &RX_BUFFER[RX_TAIL];
|
||||||
|
if(++RX_TAIL == CAN_RX_BUFFER_SIZE) RX_TAIL = 0;
|
||||||
|
|
||||||
|
return &(p->msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//marks a receive buffer as unused again so it can be overwritten in Interrupt
|
||||||
|
void can_free(can_message * msg) {
|
||||||
|
can_message_x * msg_x = (can_message_x *) msg;
|
||||||
|
msg_x->flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns pointer to the next can TX buffer
|
||||||
|
can_message * can_buffer_get() {
|
||||||
|
can_message_x *p;
|
||||||
|
p = &TX_BUFFER[TX_HEAD];
|
||||||
|
while (p->flags&0x01); //wait until buffer is free
|
||||||
|
if(++TX_HEAD == CAN_TX_BUFFER_SIZE) TX_HEAD = 0;
|
||||||
|
return &(p->msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//start transmitting can messages, and mark message msg as transmittable
|
||||||
|
void can_transmit(can_message* msg2) {
|
||||||
|
can_message_x* msg=(can_message_x*) msg2;
|
||||||
|
if(msg) {
|
||||||
|
msg->flags |= 0x01;
|
||||||
|
}
|
||||||
|
if(!TX_INT) {
|
||||||
|
if(((can_message_x*)&TX_BUFFER[TX_TAIL])->flags & 0x01) {
|
||||||
|
((can_message_x*)&TX_BUFFER[TX_TAIL])->flags &= ~0x01;
|
||||||
|
TX_INT = 1;
|
||||||
|
message_load(&TX_BUFFER[TX_TAIL]);
|
||||||
|
if(++TX_TAIL == CAN_TX_BUFFER_SIZE) TX_TAIL = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else // NON INTERRUPT VERSION
|
||||||
|
can_message_x RX_MESSAGE, TX_MESSAGE;
|
||||||
|
|
||||||
|
can_message * can_get_nb() {
|
||||||
|
//check the pin, that the MCP's interrupt output connects to
|
||||||
|
if(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
//So the MCP Generates an RX Interrupt
|
||||||
|
message_fetch(&RX_MESSAGE);
|
||||||
|
return &(RX_MESSAGE.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
can_message * can_get() {
|
||||||
|
//wait while the MCP doesn't generate an RX Interrupt
|
||||||
|
while(SPI_REG_PIN_MCP_INT & (1<<SPI_PIN_MCP_INT)) {};
|
||||||
|
|
||||||
|
message_fetch(&RX_MESSAGE);
|
||||||
|
return &(RX_MESSAGE.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//only for compatibility with Interrupt driven Version
|
||||||
|
can_message * can_buffer_get() {
|
||||||
|
return &(TX_MESSAGE.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_transmit(can_message * msg) {
|
||||||
|
message_load((can_message_x*)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
|
||||||
|
|
79
can/can.h
79
can/can.h
|
@ -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>
|
|
||||||
|
|
||||||
typedef unsigned char can_addr;
|
#include <stdint.h>
|
||||||
typedef unsigned char can_port;
|
|
||||||
|
typedef unsigned char can_addr_t;
|
||||||
|
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
|
||||||
|
|
34
can/lap.c
34
can/lap.c
|
@ -9,46 +9,33 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 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;
|
||||||
msg->port_src = PORT_MGT;
|
msg->port_src = PORT_MGT;
|
||||||
msg->port_dst = PORT_MGT;
|
msg->port_dst = PORT_MGT;
|
||||||
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;
|
||||||
msg->port_src = PORT_MGT;
|
msg->port_src = PORT_MGT;
|
||||||
msg->port_dst = PORT_MGT;
|
msg->port_dst = PORT_MGT;
|
||||||
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
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
110
can/lap.h
110
can/lap.h
|
@ -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,42 +41,74 @@ 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 {
|
||||||
#define SDO_CMD_READ 0x20
|
FKT_MOOD_INFO = 0x00,
|
||||||
#define SDO_CMD_REPLY 0x21
|
FKT_MOOD_GET = 0x01,
|
||||||
#define SDO_CMD_INFO 0x22
|
FKT_MOOD_SET = 0x02,
|
||||||
#define SDO_CMD_READ_BLK 0x40
|
FKT_MOOD_ONOFF = 0x03
|
||||||
#define SDO_CMD_READ_BLK_ACK 0x41
|
} lap_mood_fkts;
|
||||||
#define SDO_CMD_WRITE_BLK 0x48
|
|
||||||
#define SDO_CMD_WRITE_BLK_ACK 0x49
|
|
||||||
|
|
||||||
|
#define SDO_CMD_READ 0x20
|
||||||
|
#define SDO_CMD_REPLY 0x21
|
||||||
|
#define SDO_CMD_INFO 0x22
|
||||||
|
#define SDO_CMD_READ_BLK 0x40
|
||||||
|
#define SDO_CMD_READ_BLK_ACK 0x41
|
||||||
|
#define SDO_CMD_WRITE_BLK 0x48
|
||||||
|
#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
|
||||||
#define SDO_TYPE_UINT8_RW 0x01
|
#define SDO_TYPE_UINT8_RW 0x01
|
||||||
#define SDO_TYPE_UINT16_RO 0x04
|
#define SDO_TYPE_UINT16_RO 0x04
|
||||||
#define SDO_TYPE_UINT16_RW 0x05
|
#define SDO_TYPE_UINT16_RW 0x05
|
||||||
#define SDO_TYPE_UINT32_RO 0x08
|
#define SDO_TYPE_UINT32_RO 0x08
|
||||||
#define SDO_TYPE_UINT32_RW 0x09
|
#define SDO_TYPE_UINT32_RW 0x09
|
||||||
#define SDO_TYPE_STRING_RO 0x80
|
#define SDO_TYPE_STRING_RO 0x80
|
||||||
#define SDO_TYPE_STRING_RW 0x81
|
#define SDO_TYPE_STRING_RW 0x81
|
||||||
#define SDO_TYPE_STRING_WO 0x82
|
#define SDO_TYPE_STRING_WO 0x82
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -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
|
||||||
|
|
35
can/spi.c
35
can/spi.c
|
@ -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
|
||||||
|
|
18
can/spi.h
18
can/spi.h
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue