Skocz do zawartości

LIN Breakout Board


H1M4W4R1

Pomocna odpowiedź

(edytowany)
1 godzinę temu, PiotrekEl napisał:

Jakbyś wiedział gdzie są dostępne, daj znać. Kupię cały karton😆

Osobiście mam jeszcze ze 20 sztuk 😛 Do tego też płytki (chyba, dawno nie grzebałem tak głęboko w szufladzie) 😉 

Konkretniej ten model: https://pl.mouser.com/ProductDetail/863-NCV7329D10R2G😉 

Edytowano przez H1M4W4R1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

5 godzin temu, arow napisał:

Cześć.

Czy mógłbyś pokazać przykład w ino, który obsługuje tą płytkę z Arduino?

Nie, pisałem w czystym C++ pod RPi Pico.

CPP:

#include <cstdio>
#include "lin.h"

#define LIN_BREAK_WIDTH 14
#define LIN_SYNC 0x55

uint baud;
uint txPin;
uint rxPin;

uint8_t lin_sync = LIN_SYNC;
uart_inst_t* uart;
bool freeHeader = false;
alarm_id_t alarmId;

uint64_t get_lin_time(){
    double micros_d = (double) 1000000 / baud;
    uint64_t micros = (uint64_t) micros_d;

    return micros;
}

void lin_initialize(uart_inst_t *uartInst, uint tx, uint rx, uint baudRate) {
    // Initialize GPIO
    gpio_init(tx);
    gpio_init(rx);
    gpio_set_dir(tx, true);
    gpio_set_dir(rx, false);
    gpio_pull_up(tx);
    gpio_pull_up(rx);
    gpio_put(tx, true);

    // As UART
    gpio_set_function(tx, GPIO_FUNC_UART);
    gpio_set_function(rx, GPIO_FUNC_SIO);

    // Set PIN values
    txPin = tx;
    rxPin = rx;

    // Store BAUD value
    baud = baudRate;

    // Init UART
    uart_init(uartInst, baudRate);
    uart_set_format(uartInst, 8, 1, UART_PARITY_NONE);

    uart = uartInst;
    // READY
}

uint8_t calculate_checksum(uint8_t id, uint8_t* data, uint8_t len, bool enhanced_checksum){
    uint16_t sum = 0;
    for(int q = 0; q < len; q++){
        sum += data[q];
    }

    // IF LIN2, then also consider ID
    if(enhanced_checksum) {
        sum += id;
    }

    // Subtract sum
    while(sum >= 256)
        sum -= 255;

    // Invert sum
    uint8_t sum8 = (uint8_t) sum;
    return ~sum8;
}

bool get_bit(uint8_t input, uint8_t n){
    return (input >> n) & 1;
}

uint8_t set_bit(uint8_t input, uint8_t n, bool value){
    if(value)
        input |= 1 << n;
    else
        input &= ~(1 << n);

    return input;
}

uint8_t lin_get_data_size(uint8_t pid){
    // Reset parity bits
    uint8_t id = set_bit(pid, 7, 0);
    id = set_bit(id, 6, 0);

    if(id <= 0x1F) return 2;
    if(id <= 0x2F) return 4;
    if(id <= 0x3F) return 8;

    return 0;
}

uint8_t lin_calculate_parity(uint8_t id){
    bool p0 = get_bit(id, 0) xor get_bit(id, 1) xor get_bit(id, 2) xor get_bit(id, 4);
    bool p1 = not (get_bit(id, 1) xor get_bit(id, 3) xor get_bit(id, 4) xor get_bit(id, 5));

    id = set_bit(id, 6, p0);
    id = set_bit(id, 7, p1);

    return id;
}


void lin_send_frame(lin_frame* frame)
{
    // Calculate settings
    uint64_t lin_delay = get_lin_time();
    uint8_t id = lin_calculate_parity(frame->id);

    // Break
    gpio_set_function(txPin, GPIO_FUNC_SIO);
    gpio_put(txPin, false); // Send 0 for 14 TLIN
    sleep_us(LIN_BREAK_WIDTH * lin_delay);

    gpio_put(txPin, true);
    sleep_us(lin_delay);

    uint8_t checksum = calculate_checksum(id, frame->data, frame->length, frame->enhanced_checksum);

    gpio_set_function(txPin, GPIO_FUNC_UART);

    // Prepare data array
    uint8_t data[12];
    data[0] = lin_sync;
    data[1] = id;
    for(int q = 2; q < 2 + frame->length; q++){
        data[q] = frame->data[q - 2];
    }
    data[2 + frame->length] = checksum;

    // Send
    uart_write_blocking(uart, data, frame->length + 3);
}

int64_t lin_not_received(alarm_id_t id, void *user_data)
{
    if(alarmId == id) {
        // Free header
        freeHeader = true;

        return 0x0;
    }
    else{
        return 0x1;
    }
}

void lin_send_header(lin_frame* frame)
{
    freeHeader = false;

    uint64_t lin_delay = get_lin_time();
    uint8_t id = lin_calculate_parity(frame->id);

    // Break
    gpio_set_function(txPin, GPIO_FUNC_SIO);
    gpio_put(txPin, false); // Send 0 for 14 TLIN
    sleep_us(LIN_BREAK_WIDTH * lin_delay);
    gpio_put(txPin, true);
    sleep_us(lin_delay);

    // Frame
    gpio_set_function(txPin, GPIO_FUNC_UART);

    // Prepare data
    uint8_t data[2] = {lin_sync, id};

    // Send
    uart_write_blocking(uart, data,2);

    // Check if is readable
    alarmId = add_alarm_in_us(get_lin_time() * 512, lin_not_received, nullptr, false);

    // Try to read frame
    if(!lin_read_frame_blocking(frame))
    {
        for(uint8_t q = 0; q < lin_get_data_size(id); q++)
            frame->data[q] = 0x0;
    }

    // Cancel alarm
    cancel_alarm(alarmId);
}

void lin_send_response(lin_frame* frame)
{
    // Calculate PID
    uint8_t id = lin_calculate_parity(frame->id);

    // Update settings
    gpio_set_function(txPin, GPIO_FUNC_UART);
    uint8_t checksum = calculate_checksum(id, frame->data, frame->length, frame->enhanced_checksum);

    uint8_t data_size = lin_get_data_size(id);

    // Build
    uint8_t data[9];
    for(int q = 0; q < data_size; q++)
        data[q] = frame->data[q];
    data[data_size] = checksum;

    // Send response
    uart_write_blocking(uart, data, frame->length + 1);
}

bool lin_read_frame_blocking(lin_frame *frame) {
    // Get timing
    uint64_t lin_delay = get_lin_time();
    gpio_set_function(rxPin, GPIO_FUNC_UART);
    uint8_t sync;
    uint8_t id;

    // Check if can be freed
    while(!uart_is_readable(uart)){
        if(freeHeader)
            return false;
    }

    // Break catcher
    uart_read_blocking(uart, &sync, 1);
    if(sync == 0x55){
        goto skip_sync;
    }

    if(sync != 0x0){
        gpio_set_function(rxPin, GPIO_FUNC_SIO);
        return false;
    }

    // Check if can be freed
    while(!uart_is_readable(uart)){
        if(freeHeader)
            return false;
    }

    // Invalid SYNC
    uart_read_blocking(uart, &sync, 1);
    if (sync != 0x55){
        gpio_set_function(rxPin, GPIO_FUNC_SIO);
        return false;
    }

    skip_sync:

    // Check if can be freed
    while(!uart_is_readable(uart)){
        if(freeHeader)
            return false;
    }

    uart_read_blocking(uart, &id, 1);

    frame->id = id;

    // Read data (if sent proper frame)
    if(uart_is_readable_within_us(uart, 16 * lin_delay))
    {
        uart_read_blocking(uart, frame->data, lin_get_data_size(id));
        uart_read_blocking(uart, &frame->checksum, 1);
    }

    gpio_set_function(rxPin, GPIO_FUNC_SIO);

    return true;

}

H:

#ifndef PICOUARTLIN_LIN_H
#define PICOUARTLIN_LIN_H

#include "pico/stdlib.h"
#include <hardware/uart.h>

struct lin_frame{
    uint8_t id;
    uint8_t* data;
    uint8_t length;
    bool enhanced_checksum;

    // Checksum only in received frames
    uint8_t checksum;
};

void lin_initialize(uart_inst_t* uartInst, uint tx, uint rx, uint baudRate);
void lin_send_frame(lin_frame* frame);
void lin_send_response(lin_frame* response);
bool lin_read_frame_blocking(lin_frame* frame);
void lin_send_header(lin_frame* frame);
uint8_t lin_get_data_size(uint8_t pid);
uint8_t lin_calculate_parity(uint8_t id);

#endif //PICOUARTLIN_LIN_H

 

Link do komentarza
Share on other sites

1 godzinę temu, arow napisał:

Szkoda 🙂 Walczę z tym LIN BUS od 5 miesięcy i żadnego postępu :(. Cały czas odczytuje ale nic nie jestem w stanie wysłać. 

Możesz przejrzeć wcześniej podesłany kod. Wysyłanie działało bardzo dobrze, gorzej z odbiorem, bo czasem potrafił się przywiesić. Przepisanie tego na Arduino nie powinno być dużym problemem.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.