252 lines
4.8 KiB
C
252 lines
4.8 KiB
C
/*
|
|
* SPI_Bridge.c
|
|
*
|
|
* Created on: Jun 13, 2020
|
|
* Author: matth
|
|
*/
|
|
|
|
#include "SPI_Bridge.h"
|
|
#include <string.h>
|
|
|
|
void SPI_Bridge_init(SPI_Bridge_t *b, SPI_DEV_t *hdev,
|
|
osMutexId pack_mutex) {
|
|
b->hdev = hdev;
|
|
b->pack_mutex_id = pack_mutex;
|
|
b->queue_in_hdr = 0;
|
|
b->queue_in_tail = 0;
|
|
b->queue_out_hdr = 0;
|
|
b->queue_out_tail = 0;
|
|
|
|
b->stage = 0;
|
|
|
|
b->error_cnt = 0;
|
|
b->count_in = 0;
|
|
b->count_out = 0;
|
|
b->pkg_in = 0;
|
|
b->pkg_out = 0;
|
|
b->dia_in = 0; /* diagram in */
|
|
b->dia_out = 0; /* diagram out */
|
|
b->Bps_in = 0;
|
|
b->Pps_in = 0;
|
|
b->Dps_in = 0;
|
|
b->Bps_out = 0;
|
|
b->Pps_out = 0;
|
|
b->Dps_out = 0;
|
|
}
|
|
|
|
void SPI_Bridge_pack(SPI_Bridge_t *b, uint8_t id, uint8_t cmd[], size_t len,
|
|
uint32_t millisec) {
|
|
size_t i;
|
|
uint8_t sum;
|
|
|
|
if (osMutexWait(b->pack_mutex_id, millisec) == osOK) {
|
|
b->queue_out[b->queue_out_hdr++] = 0xEF;
|
|
if (b->queue_out_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_hdr = 0;
|
|
sum = (id << 3) + ((len & 0x0700) >> 8);
|
|
b->queue_out[b->queue_out_hdr++] = sum;
|
|
if (b->queue_out_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_hdr = 0;
|
|
|
|
sum = (len & 0xFF);
|
|
b->queue_out[b->queue_out_hdr++] = sum;
|
|
if (b->queue_out_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_hdr = 0;
|
|
|
|
sum = 0;
|
|
for (i = 0; i < len; ++i) {
|
|
b->queue_out[b->queue_out_hdr++] = cmd[i];
|
|
if (b->queue_out_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_hdr = 0;
|
|
|
|
sum ^= cmd[i];
|
|
}
|
|
|
|
b->queue_out[b->queue_out_hdr++] = sum;
|
|
if (b->queue_out_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_hdr = 0;
|
|
|
|
b->count_out += len;
|
|
b->pkg_out += 1;
|
|
osMutexRelease(b->pack_mutex_id);
|
|
}
|
|
}
|
|
|
|
int SPI_Bridge_unpack(SPI_Bridge_t *b) {
|
|
uint8_t c;
|
|
int ret;
|
|
|
|
ret = -1;
|
|
|
|
if (b->queue_in_hdr != b->queue_in_tail) {
|
|
c = b->queue_in[b->queue_in_tail++];
|
|
if (b->queue_in_tail >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_in_tail = 0;
|
|
switch (b->stage) {
|
|
case 0:
|
|
if (c == 0xEF) {
|
|
++b->stage;
|
|
}
|
|
break;
|
|
case 1:
|
|
b->id = c >> 3;
|
|
b->len = (c & 0x7) * 256;
|
|
++b->stage;
|
|
break;
|
|
case 2:
|
|
b->len += c;
|
|
b->sum = 0;
|
|
b->idx = 0;
|
|
if (b->len > SPI_Bridge_UNPACK_LEN) {
|
|
b->stage = 0;
|
|
b->error_cnt++;
|
|
} else {
|
|
++b->stage;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (b->idx < b->len) {
|
|
b->data[b->idx] = c;
|
|
b->sum ^= c;
|
|
++b->idx;
|
|
} else {
|
|
if (b->sum == c) {
|
|
ret = b->id;
|
|
b->count_in += b->len;
|
|
b->pkg_in += 1;
|
|
}
|
|
else
|
|
{
|
|
b->error_cnt++;
|
|
}
|
|
b->stage = 0;
|
|
}
|
|
break;
|
|
default:
|
|
b->stage = 0;
|
|
}
|
|
} else {
|
|
ret = -2;
|
|
}
|
|
return ret;
|
|
|
|
}
|
|
|
|
void SPI_Bridge_Slave_TransmitReceive(SPI_Bridge_t *b, uint32_t millisec, uint32_t millisec_trans) {
|
|
int i;
|
|
|
|
if (!SPI_DEV_begin(b->hdev, millisec))
|
|
{
|
|
b->error_cnt++;
|
|
return;
|
|
}
|
|
|
|
b->buff[0] = 0xEB;
|
|
b->buff[1] = 0x90;
|
|
for (i = 2; i < SPI_Bridge_BLOCK_LEN; ++i) {
|
|
|
|
if (b->queue_out_hdr != b->queue_out_tail) {
|
|
b->buff[i] = b->queue_out[b->queue_out_tail++];
|
|
if (b->queue_out_tail >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_tail = 0;
|
|
} else {
|
|
b->buff[i] = 0xFE;
|
|
}
|
|
}
|
|
b->dia_out++;
|
|
|
|
if (SPI_DEV_transfer(b->hdev, b->buff, SPI_Bridge_BLOCK_LEN,
|
|
b->buff_in, SPI_Bridge_BLOCK_LEN, millisec_trans))
|
|
{
|
|
if (b->buff_in[0] == 0xEB && b->buff_in[1] == 0x90) {
|
|
for (i = 2; i < SPI_Bridge_BLOCK_LEN; ++i) {
|
|
b->queue_in[b->queue_in_hdr++] = b->buff_in[i];
|
|
if (b->queue_in_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_in_hdr = 0;
|
|
}
|
|
b->dia_in++;
|
|
}
|
|
else
|
|
{
|
|
b->error_cnt++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
b->error_cnt++;
|
|
}
|
|
|
|
SPI_DEV_end(b->hdev);
|
|
}
|
|
|
|
|
|
void SPI_Bridge_Master_TransmitReceive(SPI_Bridge_t *b, uint32_t millisec, uint32_t millisec_wait, uint32_t millisec_trans) {
|
|
int i;
|
|
|
|
if (!SPI_DEV_begin(b->hdev, millisec))
|
|
{
|
|
b->error_cnt++;
|
|
return;
|
|
}
|
|
|
|
SPI_DEV_select(b->hdev);
|
|
|
|
b->buff[0] = 0xEB;
|
|
b->buff[1] = 0x90;
|
|
for (i = 2; i < SPI_Bridge_BLOCK_LEN; ++i) {
|
|
|
|
if (b->queue_out_hdr != b->queue_out_tail) {
|
|
b->buff[i] = b->queue_out[b->queue_out_tail++];
|
|
if (b->queue_out_tail >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_out_tail = 0;
|
|
} else {
|
|
b->buff[i] = 0xFE;
|
|
}
|
|
}
|
|
b->dia_out++;
|
|
|
|
osDelay(millisec_wait);
|
|
|
|
if (SPI_DEV_transfer(b->hdev, b->buff, SPI_Bridge_BLOCK_LEN,
|
|
b->buff_in, SPI_Bridge_BLOCK_LEN,millisec_trans))
|
|
{
|
|
if (b->buff_in[0] == 0xEB && b->buff_in[1] == 0x90) {
|
|
for (i = 2; i < SPI_Bridge_BLOCK_LEN; ++i) {
|
|
b->queue_in[b->queue_in_hdr++] = b->buff_in[i];
|
|
if (b->queue_in_hdr >= SPI_Bridge_QUEUE_LEN)
|
|
b->queue_in_hdr = 0;
|
|
}
|
|
b->dia_in++;
|
|
}
|
|
else
|
|
{
|
|
b->error_cnt++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
b->error_cnt++;
|
|
}
|
|
|
|
SPI_DEV_unselect(b->hdev);
|
|
|
|
SPI_DEV_end(b->hdev);
|
|
}
|
|
|
|
void SPI_Bridge_stats(SPI_Bridge_t *b)
|
|
{
|
|
b->Bps_in = b->count_in;
|
|
b->Pps_in = b->pkg_in;
|
|
b->Dps_in = b->dia_in;
|
|
b->Bps_out = b->count_out;
|
|
b->Pps_out = b->pkg_out;
|
|
b->Dps_out = b->dia_out;
|
|
|
|
b->count_in = 0;
|
|
b->count_out = 0;
|
|
b->pkg_in = 0;
|
|
b->pkg_out = 0;
|
|
b->dia_in = 0; /* diagram in */
|
|
b->dia_out = 0; /* diagram out */
|
|
}
|