#include #include "tss463aa.h" #include "tss463aa_ll.h" #define XTAL1_PIN 9 #define TSS463AA_INT_PIN 3 #define TSS463AA_SS_PIN 13 /* time unit */ #define XTAL 100 /* μs */ /* Note: XTAL = μs for an 1 MHz oscillator (for 62.5 kTS/s on the VAN bus) */ extern "C" void LLtransceive(int fd, byte regno, byte controlvalue, const void* inputv, void* outputv, size_t bothsz) { const byte* input = (const byte*) inputv; byte* output = (byte*) outputv; size_t i; digitalWrite(TSS463AA_SS_PIN, LOW); delayMicroseconds(4*XTAL); byte r = SPI.transfer(regno); /* TODO check AA */ delayMicroseconds(8*XTAL); byte r2 = SPI.transfer(controlvalue); /* TODO check 55 */ delayMicroseconds(15*XTAL); if (input && bothsz) { for (i = 0U; i < bothsz; ++i) { byte r3 = SPI.transfer(input[i]); delayMicroseconds(12*XTAL); if (output) output[i] = r3; } } else if (output) { for (i = 0U; i < bothsz; ++i) { byte r3 = SPI.transfer(0xFFU); delayMicroseconds(12*XTAL); output[i] = r3; } } digitalWrite(TSS463AA_SS_PIN, HIGH); } static struct tss463aachannel* channels[2]; static FILE uartout = {}; static int uart_putchar(char c, FILE* stream) { Serial.write(c); return 0; } void setup() { int fd = 1; Serial.begin(115200); fdev_setup_stream(&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); Serial.print("Press any key: "); pinMode(TSS463AA_INT_PIN, INPUT); pinMode(TSS463AA_SS_PIN, OUTPUT); digitalWrite(TSS463AA_SS_PIN, 1); analogWrite(XTAL1_PIN, 128); /* approx. 490 Hz or 980 Hz depending on model. Duty cycle in percent on. */ //attachInterrupt(digitalPinToInterrupt(TSS463AA_INT_PIN), ISR, LOW /* or FALLING? RISING? */); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE3); SPI.setClockDivider(SPI_CLOCK_DIV2); SPI.begin(); tss463aa_init(fd); channels[0U] = (struct tss463aachannel*) malloc(tss463aachannel_get_size()); tss463aachannel_init(channels[0U], /*tag*/0U, /*mask*/0U, /*rnw*/0U, /*rtr*/1U, /*msgptr*/0U, 31U/*FIXME test */); /* set up for receiving messages. ID doesn't matter. */ tss463aa_set_channel_up(fd, 0U, channels[0U]); //LLtransceive(fd, 0, 0, NULL, NULL, 0U); tss463aa_enable_interrupts(fd); tss463aa_activate(fd); } #define MAX_PAYLOADLEN 64 /* FIXME check */ void hexdump(const unsigned char* buf, size_t sz) { size_t i; for(i = 0; buf[i] != 0U; ++i) { printf("%02X ", (unsigned) *buf); } printf("\n"); for(i = 0; buf[i] != 0U; ++i) { unsigned char c = *buf; printf("%c", (c >= 32 && c < 128) ? c : '?'); } } void loop() { int fd = 1; tss463aa_accept_msg(fd, 0U, channels[0U]); while (true) { uint8_t status = tss463aa_read_interrupt_status(fd); if (status & 7U) /* FIXME be nicer */ break; } tss463aa_clear_interrupt_status(fd); tss463aa_read_channel(fd, 0U, channels[0U]); if (tss463aachannel_get_error(channels[0U]) > 0U) { printf("warning: channel 0 raised error.\n"); /* TODO check error, hmm accept again (FIXME I think it already does accept) */ } /* note: on error, this isn't set. */ if (tss463aachannel_is_unread_incoming_msg_present(channels[0U])) { /* something appeared */ printf("info: message received.\n"); unsigned payloadlen = tss463aachannel_get_payloadlen(channels[0U]); /* checkable fields in msgheader: RAK, RNW, RTR, PAYLOADLEN */ if (payloadlen > 0U && payloadlen <= MAX_PAYLOADLEN) { unsigned char msgbody[MAX_PAYLOADLEN]; tss463aa_read_channel_msgbody(fd, 0U, channels[0U], msgbody); printf("Payload: "); hexdump(msgbody, payloadlen); printf("\n"); } else if (payloadlen == 0U) { printf("... message with no payload ignored\n"); } else { printf("... message with too long payload ignored\n"); } } else { printf("error: huh? Nothing is there\n"); } }