Browse Source

update

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 6 years ago
parent
commit
cbc62475d1
  1. 1
      Makefile
  2. 209
      lib/a3k.c
  3. 39
      lib/a3k.h
  4. 12
      lib/eeprom.c
  5. 39
      lib/serial.c
  6. 7
      lib/serial.h
  7. 74
      lib/utils.c
  8. 24
      lib/utils.h
  9. 3
      src/config.h
  10. 29
      src/iap.c
  11. 378
      src/main.c

1
Makefile

@ -145,6 +145,7 @@ lib_srcs += \
$(lib_dir)/a3k.c \
$(lib_dir)/serial.c \
$(lib_dir)/vrom.c \
$(lib_dir)/utils.c \
$(lib_dir)/sdram.c \
$(lib_dir)/is42s32800g.c \
$(lib_dir)/timer.c \

209
lib/a3k.c

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include "serial.h"
#include "a3kpacket.h"
#include "gpio.h"
@ -9,9 +10,9 @@
#define RATE_PINS (6)
struct fifo_tag {
volatile char *pnew; /* points to newest fifo element */
volatile char *pold; /* points to oldest fifo element */
volatile short nelem; // number of bytes currently in fifo
char *pnew; /* points to newest fifo element */
char *pold; /* points to oldest fifo element */
short nelem; // number of bytes currently in fifo
short blen;
char *bend;
char *b;
@ -65,20 +66,28 @@ static char *get_next_word( char *p, short *val )
return p;
}
static void fifo_putpacket(a3k_t a3k, char *p)
static void __send_all(a3k_t tag, const uint8_t *p, int len)
{
int n, len;
int n;
while (len > 0) {
n = serial_send_buffered(tag->uart, p, len);
p += n;
len -= 0;
}
}
static void fifo_putpacket(a3k_t tag, char *p)
{
int len;
len = (((short)p[1])<<8)|p[2];
len += 4;
while (len > 0) {
n = serial_send_buffered(a3k->uart, (void *)p, len);
p += n;
len -= n;
}
__send_all(tag, (void *)p, len);
}
#if 0
static char __getc(a3k_t a3k)
{
char c;
@ -87,23 +96,38 @@ static char __getc(a3k_t a3k)
;
return c;
}
#endif
static char __fifo_getc(FIFO *f)
{
if (f->nelem) {
char c;
c = *f->pold++;
if(f->pold == f->bend)
f->pold = f->b;
f->nelem -= 1;
return c;
} else
return 0;
}
static int __getpacket(a3k_t f, char *p)
static int __getpacket(a3k_t tag, char *p)
{
short len;
short i;
uint8_t *p_save = (uint8_t *)p;
FIFO *f = &tag->rx;
p[0] = __getc( f ); //get the header
p[1] = __getc( f ); //get the len (msb)
p[2] = __getc( f ); //get the len (lsb)
p[3] = __getc( f ); //get the type
p[0] = __fifo_getc(f); //get the header
p[1] = __fifo_getc(f); //get the len (msb)
p[2] = __fifo_getc(f); //get the len (lsb)
p[3] = __fifo_getc(f); //get the type
len = p[1];
len <<= 8;
len |= (p[2] & 0x00ff);
p += 4;
for ( i = 0; i < len; i++ ) {
*p++ = __getc(f);
*p++ = __fifo_getc(f);
}
printf("\r\n");
@ -112,7 +136,7 @@ static int __getpacket(a3k_t f, char *p)
}
printf("\r\n");
return len+4;
return len + 4;
}
static void put_packet(a3k_t a3k, char *packet, char *end, char type, char parity)
@ -153,19 +177,77 @@ static void put_packet(a3k_t a3k, char *packet, char *end, char type, char parit
fifo_putpacket(a3k, packet);
}
/*
* This function gets the next character from a fifo. It is assumed
* that the fifo contains at leas one character. If it does not the
* function returns a null character.
*/
static void __fifo_waitpacket(a3k_t tag)
{
int n, len;
char *old;
FIFO *f = &tag->rx;
restart:
/* try to receive from serial */
while (f->blen != f->nelem) {
len = f->bend - f->pnew;
n = serial_recv_buffered(tag->uart, (void *)f->pnew, len);
if (n > 0) {
f->pnew += n;
if (f->pnew == f->bend) {
f->pnew = f->b;
}
f->nelem += n;
} else {
break;
}
}
while ((f->nelem > 0) && (*f->pold != PKT_HEADER)) {
__fifo_getc(f);
}
if (*f->pold != PKT_HEADER)
goto restart;
if (f->nelem < 3)
goto restart;
old = f->pold + 1;
if (old == f->bend) {
old = f->b;
}
len = *old++;
len <<= 8;
if (old == f->bend) {
old = f->b;
}
len |= *old++;
if (f->nelem < (len + 4)) {
goto restart;
}
}
static int get_packet(a3k_t a3k, char *packet)
{
#if 0
return __getpacket(a3k, packet);
#else
__fifo_waitpacket(a3k);
return __getpacket(a3k, packet);
#endif
}
static int wait_a3k_ready(a3k_t interface)
static int wait_a3k_ready(a3k_t tag)
{
char packet[30];
short i;
for (i = 0;i < 30; i++)
packet[i] = 0xFF;
get_packet(interface, packet);
get_packet(tag, packet);
if (packet[0] != 0x61)
return (1);
@ -549,23 +631,6 @@ static void __fifo_init(FIFO *f, short blen, char *b)
f->nelem = 0;
}
/*
* This function gets the next character from a fifo. It is assumed
* that the fifo contains at leas one character. If it does not the
* function returns a null character.
*/
static char __fifo_getc(FIFO *f)
{
if (f->nelem) {
char c;
c = *f->pold++;
if(f->pold == f->bend)
f->pold = f->b;
f->nelem -= 1;
return c;
} else
return 0;
}
/*
* This function does not take anything out of the fifo. It assumes
* that there is a complete packet in the fifo (or at least the
@ -635,29 +700,46 @@ int a3k_getpacket(a3k_t tag, uint8_t *buf, int size)
len |= (c & 0xff);
++len; // dont forget the type byte
for (x = 0; x < len; ++x) {
for (x = 0; x < len && x < (size - 4); ++x) {
buf[i++] = __fifo_getc(f);
}
while (x < len) { /* drop */
__fifo_getc(f);
++x;
}
return (len + 3);
}
int a3k_putpacket(a3k_t tag, const void *_ptr, int len)
int a3k_get_rawpacket(a3k_t tag, uint8_t *buf, int size)
{
#if 1
const uint8_t *ptr = _ptr, *ptr_save = _ptr;
int n;
uint8_t c;
int n = 0, len;
FIFO *f = &tag->rx;
__fifo_getc(f); /* drop 0x61 */
c = __fifo_getc(f); /*len (MSB) */
len = (c << 8) | (__fifo_getc(f) & 0xff); /* len (LSB) */
__fifo_getc(f); /* drop type */
c = __fifo_getc(f); /* drop CHAND field */
assert(c == 1);
c = __fifo_getc(f); /* CHANAD bits */
c /= 8; /* to bytes */
for (n = 0; n < c && n < size; ++n) {
buf[n] = __fifo_getc(f);
}
len -= n;
while (len > 0) { /* drop 0x2f, parity, etc ... */
__fifo_getc(f);
}
return (n);
}
while (len > 0) {
n = serial_send_buffered(tag->uart, ptr, len);
ptr += n;
len -= n;
}
return (ptr - ptr_save);
#else
serial_send_blocking(tag->uart, _ptr, len);
return (len);
#endif
int a3k_putpacket(a3k_t tag, const void *_ptr, int len)
{
__send_all(tag, _ptr, len);
return (len);
}
/*
@ -669,7 +751,7 @@ int a3k_checkfullpacket(a3k_t tag)
{
FIFO *f = &tag->rx;
int len, n;
volatile char *old;
char *old;
start:
/* try to receive from serial */
@ -761,6 +843,10 @@ int a3k_setup(a3k_t tag, int baudrate)
__fifo_init(&tag->rx, FORMAT3KBLEN, (void *)tag->_buf);
if (baudrate < 0) {
baudrate = A3K_UART_BAUDRATE;
}
serial_setup(tag->uart, baudrate, 8, SERIAL_STOPBITS_1);
if (tag->pseudo) {
@ -817,6 +903,7 @@ void a3k_close(a3k_t tag)
serial_close(tag->uart);
}
#ifdef TARGET_HAS_A3K_0
struct a3k_tag a3k0 = {
.uart = &serial1,
.rst = PF10,
@ -829,7 +916,9 @@ struct a3k_tag a3k0 = {
.ns = PJ15,
.es = PG12,
};
#endif
#ifdef TARGET_HAS_A3K_1
struct a3k_tag a3k1 = {
.uart = &serial2,
.rst = PI14,
@ -842,24 +931,16 @@ struct a3k_tag a3k1 = {
.ns = PJ12,
.es = PH4,
};
#endif
#if 1
#ifdef TARGET_HAS_A3K_2
struct a3k_tag a3k2 = {
.uart = &serial3,
.pseudo = 1,
};
#endif
struct a3k_tag a3k3 = {
.uart = &serial5,
.pseudo = 1,
};
#else
struct a3k_tag a3k2 = {
.uart = &serial4,
.pseudo = 1,
};
#ifdef TARGET_HAS_A3K_3
struct a3k_tag a3k3 = {
.uart = &serial5,
.pseudo = 1,

39
lib/a3k.h

@ -1,17 +1,17 @@
#ifndef __A3K_H___
#define __A3K_H___
/*
* XXX define to reset board.
*/
#define PKT_CMD_REBOOT 5
#ifdef __cplusplus
extern "C" {
#endif
#define UART_BAUDRATE (460800)
#define RS422_BAUDRATE (115200)
#include "a3kpacket.h"
#define FORMAT3KBLEN (350)
#include "config.h"
extern struct a3k_tag a3k0, a3k1, a3k2, a3k3;
#define A3K_UART_BAUDRATE (460800)
#define FORMAT3KBLEN (350)
typedef struct a3k_tag *a3k_t;
@ -23,11 +23,34 @@ int a3k_checkfullpacket(a3k_t tag);
int a3k_peekpackettype(a3k_t tag);
/* push only channel data into buf */
int a3k_get_rawpacket(a3k_t tag, uint8_t *buf, int size);
int a3k_getpacket(a3k_t tag, uint8_t *buf, int size);
int a3k_putpacket(a3k_t tag, const void *_ptr, int len);
void a3k_discardpacket(a3k_t tag);
#ifdef TARGET_HAS_A3K_0
extern struct a3k_tag a3k0;
#endif
#ifdef TARGET_HAS_A3K_1
extern struct a3k_tag a3k1;
#endif
#ifdef TARGET_HAS_A3K_2
extern struct a3k_tag a3k2;
#endif
#ifdef TARGET_HAS_A3K_3
extern struct a3k_tag a3k3;
#endif
#ifdef __cplusplus
}
#endif
#endif

12
lib/eeprom.c

@ -7,12 +7,12 @@
enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256,M24512};
#define EEPROM_TYPE M24512
#define EEPROM_TYPE M24256
int eeprom_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as I2C1SDA and I2C1SCL
I2C_InitTypeDef I2C_InitStruct; // this is for the I2C1 initilization
I2C_InitTypeDef I2C_InitStruct; // this is for the I2C1 initilization
/* enable APB1 peripheral clock for I2C1*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
@ -64,7 +64,7 @@ int eeprom_write(uint16_t addr, uint8_t data)
lower_addr = (uint8_t)((0x00FF)&addr);
if(EEPROM_TYPE == M24512) {
if((EEPROM_TYPE == M24512) || (EEPROM_TYPE == M24256)) {
addr = addr << 8;
upper_addr = (uint8_t)((0x00FF)&addr);
}
@ -90,7 +90,7 @@ int eeprom_write(uint16_t addr, uint8_t data)
return -2;
}
if (EEPROM_TYPE == M24512) {
if ((EEPROM_TYPE == M24512) || (EEPROM_TYPE == M24256)) {
/* Send I2C1 location address LSB */
I2C_SendData(I2C1, upper_addr);
@ -138,7 +138,7 @@ uint8_t eeprom_read(uint16_t addr)
lower_addr = (uint8_t)((0x00FF)&addr);
if(EEPROM_TYPE == M24512) {
if((EEPROM_TYPE == M24512) || (EEPROM_TYPE == M24256)) {
addr = addr << 8;
upper_addr = (uint8_t)((0x00FF)&addr);
}
@ -163,7 +163,7 @@ uint8_t eeprom_read(uint16_t addr)
return 0xFF;
}
if(EEPROM_TYPE == M24512) {
if((EEPROM_TYPE == M24512) || (EEPROM_TYPE == M24256)) {
/* Send I2C1 location address LSB */
I2C_SendData(I2C1,upper_addr);

39
lib/serial.c

@ -42,18 +42,14 @@ struct serial {
uint16_t rx_head;
};
void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
void serial_reconfigure(struct serial *uart, int baudrate, int databits, int stopbits, int parity)
{
USART_InitTypeDef uart_conf;
DMA_InitTypeDef dma_conf;
NVIC_InitTypeDef irq_conf;
/* setup pins */
uart->setup(uart);
RCC_AHB1PeriphClockCmd(uart->dma_rcc, ENABLE);
USART_Cmd(uart->uart, DISABLE);
/* Set up USART/UART parameters using the libopencm3 helper functions */
USART_DeInit(uart->uart);
/* Set up USART/UART using default parameters */
USART_StructInit(&uart_conf);
switch (databits) {
@ -66,13 +62,30 @@ void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
}
uart_conf.USART_BaudRate = baudrate;
uart_conf.USART_StopBits = stopbits;
uart_conf.USART_Parity = parity ;
uart_conf.USART_Parity = USART_Parity_No ;
uart_conf.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
uart_conf.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(uart->uart, &uart_conf);
// Configure RX DMA ...
USART_Cmd(uart->uart, ENABLE);
}
void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
{
DMA_InitTypeDef dma_conf;
NVIC_InitTypeDef irq_conf;
/* setup pins */
uart->setup(uart);
RCC_AHB1PeriphClockCmd(uart->dma_rcc, ENABLE);
serial_reconfigure(uart, baudrate, databits, stopbits, SERIAL_PARITY_NO);
USART_Cmd(uart->uart, DISABLE);
/* Configure RX DMA ... */
DMA_DeInit(uart->rx_dma_stream);
DMA_StructInit(&dma_conf);
dma_conf.DMA_Channel = uart->rx_dma_channel;
@ -87,7 +100,7 @@ void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
dma_conf.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_Init(uart->rx_dma_stream, &dma_conf);
// Configure TX DMA ...
/* Configure TX DMA ... */
DMA_DeInit(uart->tx_dma_stream);
DMA_StructInit(&dma_conf);
dma_conf.DMA_Channel = uart->tx_dma_channel;
@ -127,7 +140,7 @@ void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
USART_ITConfig(uart->uart, USART_IT_PE | USART_IT_ERR | USART_IT_NE | USART_IT_FE, ENABLE);
}
// Enable the UART with the new settings
/* Enable the UART with the new settings */
USART_Cmd(uart->uart, ENABLE);
}
@ -803,6 +816,6 @@ void UART7_IRQHandler(void)
{
__eie_isr(&serial6);
}
#endif

7
lib/serial.h

@ -18,7 +18,14 @@ struct serial;
#define SERIAL_STOPBITS_2 (0x2000)
#define SERIAL_STOPBITS_1_5 (0x3000)
#define SERIAL_PARITY_NO (0x0000)
#define SERIAL_PARITY_EVEN (0x0400)
#define SERIAL_PARITY_ODD (0x0600)
void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits);
void serial_reconfigure(struct serial *uart, int baudrate, int databits, int stopbits, int parity);
void serial_close(struct serial *uart);
size_t serial_send_buffered(struct serial *uart, const uint8_t* data, size_t num_bytes);

74
lib/utils.c

@ -0,0 +1,74 @@
#include <stdint.h>
#include "stm32f4xx.h"
#include "utils.h"
#ifdef CRC8_TABLE
/* CRC-8 x8+x2+x+1 */
unsigned char crc8(const unsigned char *p, int n)
{
unsigned char crc8 = 0;
static unsigned char crc_array[256] = {
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
};
while (n > 0) {
crc8 = crc_array[crc8^*p]; /* lookup table */
p++;
--n;
}
return crc8;
}
#else
/* CRC-8 x8+x2+x+1 */
unsigned char crc8(const unsigned char *data, int len)
{
unsigned crc = 0;
int i, j;
for (j = len; j; j--, data++) {
crc ^= (*data << 8);
for (i = 8; i; i--) {
if (crc & 0x8000)
crc ^= (0x1070 << 3);
crc <<= 1;
}
}
return (unsigned char)(crc >> 8);
}
#endif
int go(unsigned long vect)
{
volatile unsigned int *ptr = (volatile unsigned int *)vect;
register unsigned int stack = ptr[0];
register unsigned int addr = ptr[1];
if (((*(volatile uint32_t*)vect) & 0x2FFE0000 ) == 0x20000000) {
SCB->VTOR = vect;
__set_MSP(stack);
__set_PSP(stack);
/* Memory barriers for good measure. */
__ISB();
__DSB();
((void (*)(void))addr)();
}
return -1;
}

24
lib/utils.h

@ -0,0 +1,24 @@
#ifndef __UTILS_H_____
#define __UTILS_H_____
#ifdef __cplusplus
extern "C" {
#endif
#define CRC8_TABLE 1
/*
* jump to address `vect'.
* if success, don't return. failed, return -1.
*/
int go(unsigned long vect);
/* CRC-8 x8+x2+x+1 */
unsigned char crc8(const unsigned char *data, int len);
#ifdef __cplusplus
}
#endif
#endif

3
src/config.h

@ -29,6 +29,9 @@
#define TARGET_USART7_RX_BUFFER_SIZE (2048)
#define TARGET_USART7_TX_BUFFER_SIZE (2048)
#define TARGET_HAS_A3K_0 1
#define TARGET_HAS_A3K_1 1
#define TARGET_HAS_TIM1 1
#define TARGET_HAS_TIM3 1

29
src/iap.c

@ -3,9 +3,10 @@
#include "stm32f4xx.h"
#include "serial.h"
#include "ymodem.h"
#include "utils.h"
#include "config.h"
#define SERIRALX (&serial0)
#define UART (&serial0)
struct fileinfo {
char name[256];
@ -13,22 +14,6 @@ struct fileinfo {
unsigned int received;
};
static uint32_t jump_address;
static int go()
{
if (((*(__IO uint32_t*)APP_ADDRESS) & 0x2FFE0000 ) == 0x20000000) {
/* Jump to user application */
jump_address = *(__IO uint32_t*) (APP_ADDRESS + 4);
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APP_ADDRESS);
__DSB();
__ISB();
__asm__ volatile ("bx %[address]\n\t": : [address] "r" (jump_address));
}
return -1;
}
static int on_info(void *ud, const char *name, unsigned int size)
{
struct fileinfo *fi = ud;
@ -50,12 +35,12 @@ static int do_upgrade()
{
struct fileinfo fi;
serial_setup(SERIRALX, 115200, 8, 1);
serial_setup(UART, 115200, 8, 1);
memset(&fi, 0, sizeof fi);
ymodem_recv(SERIRALX, &fi, on_info, on_data);
serial_close(SERIRALX);
ymodem_recv(UART, &fi, on_info, on_data);
serial_close(UART);
go();
go(APP_ADDRESS);
return 0;
}
@ -66,7 +51,7 @@ int main()
return do_upgrade();
}
go();
go(APP_ADDRESS);
return 0;
}

378
src/main.c

@ -10,6 +10,7 @@
#include "tick.h"
#include "timer.h"
#include "iwdg.h"
#include "utils.h"
#define LED_D3 (PI13)
#define LED_D4 (PK5)
@ -19,6 +20,34 @@
#define PKT_LEN (64)
#define PKT_NLEMS (128) /* must power of 2 */
#define SEND_PKT_HDR (0x61)
#define SEND_PKT_TAL (0x2f)
#define SEND_PKT_TYPE_DATA (0x01)
#define SEND_PKT_TYPE_CMD (0x02)
#define SEND_PKT_LEN (40)
#define RAW_PKT_LEN (18)
#define RAW_PKT_OFF (6)
#define BIT0 (0x01)
#define BIT1 (0x02)
#define RS422_BAUDRATE (115200)
/* UART 4 */
#define RS422_0 (&serial3)
/* USART 6 */
#define RS422_1 (&serial5)
#define TIM_40MS (&timer2)
struct tag_fifo {
char *pnew; /* points to newest fifo element */
char *pold; /* points to oldest fifo element */
short nelem; // number of bytes currently in fifo
short blen;
char *bend;
char *b;
};
struct ringbuf {
int size;
int len;
@ -29,12 +58,32 @@ struct frames {
struct ringbuf slices[PKT_NLEMS];
uint32_t head;
uint32_t tail;
struct tag_fifo f;
};
static struct frames rx0, rx1;
static volatile int to_play = 0;
static struct frames rx[2], tx[2];
static uint8_t __rxbuf[2][PKT_LEN * 2];
static volatile unsigned int to_decode = 0;
static volatile unsigned int to_send = 0;
static void init_frames(struct frames *f)
static void wait_to_reset()
{
ticks_close();
timer_close(TIM_40MS);
serial_close(&serial0);
serial_close(RS422_0);
serial_close(RS422_1);
a3k_close(&a3k0);
a3k_close(&a3k1);
for (;;)
;
}
static void init_frames(struct frames *f, void *b, int blen)
{
int i;
struct ringbuf *rb;
@ -44,8 +93,82 @@ static void init_frames(struct frames *f)
rb = &f->slices[i];
rb->size = PKT_LEN;
}
f->f.pnew = f->f.pold = b;
f->f.blen = blen;
f->f.bend = b + blen;
f->f.b = b;
f->f.nelem = 0;
}
static void encode_packet(a3k_t from, struct frames *f)
{
struct ringbuf *rb;
int pos;
if (a3k_checkfullpacket(from)) {
if (a3k_peekpackettype(from) == PKT_CHANNEL) { /* only cache the channel packet */
pos = f->tail & (PKT_NLEMS - 1);
++f->tail;
rb = &f->slices[pos];
rb->len = a3k_getpacket(from, rb->rb, rb->size);
} else {
a3k_discardpacket(from);
}
}
}
static void __send_all(struct serial *to, const uint8_t *ptr, int len)
{
int n;
while (len > 0) {
n = serial_send_buffered(to, ptr, len);
if (n > 0) {
ptr += n;
len -= n;
}
}
}
static int send_packet(struct serial *to, struct frames *f, uint32_t led)
{
struct ringbuf *rb0, *rb1;
uint8_t buffer[SEND_PKT_LEN];
int i = 0, x;
uint8_t p = 0;
/*
* packet tx buffer as:
*
* 0x61 [type] d0 d1 .... d39 0x2f parity
* *****-------------------------- [compute parity]
*/
if ((f->tail - f->head) >= 2) {
rb0 = &f->slices[(f->head & (PKT_NLEMS - 1))];
rb1 = &f->slices[((f->head + 1) & (PKT_NLEMS - 1))];
f->head += 2;
buffer[i++] = SEND_PKT_HDR;
buffer[i++] = SEND_PKT_TYPE_DATA;
memcpy(buffer + i, rb0->rb + RAW_PKT_OFF, RAW_PKT_LEN);
i += RAW_PKT_LEN;
memcpy(buffer + i, rb1->rb + RAW_PKT_OFF, RAW_PKT_LEN);
i += RAW_PKT_LEN;
buffer[i++] = SEND_PKT_TAL;
for (x = 0; x < SEND_PKT_LEN - 2; ++x) {
p ^= buffer[x];
}
buffer[i++] = p;
__send_all(to, buffer, SEND_PKT_LEN);
gpio_toggle(led);
return 0;
}
return -1;
}
#if 0
static void forward_packet(a3k_t from, a3k_t to, uint32_t led)
{
uint8_t buf[FORMAT3KBLEN];
@ -57,38 +180,151 @@ static void forward_packet(a3k_t from, a3k_t to, uint32_t led)
gpio_toggle(led);
}
}
#endif
static void wait_to_reset()
static char __fifo_getc(struct tag_fifo *f)
{
ticks_close();
serial_close(&serial0);
a3k_close(&a3k0);
a3k_close(&a3k1);
a3k_close(&a3k2);
a3k_close(&a3k3);
if (f->nelem) {
char c;
c = *f->pold++;
if(f->pold == f->bend)
f->pold = f->b;
f->nelem -= 1;
return c;
} else
return 0;
}
for (;;)
;
static int check_rxpacket(struct serial *uart, struct frames *tag)
{
struct tag_fifo *f = &tag->f;
int len, n;
char *old;
uint8_t parity = 0;
start:
/* try to receive from serial */
while (f->blen != f->nelem) {
len = f->bend - f->pnew;
n = serial_recv_buffered(uart, (void *)f->pnew, len);
if (n > 0) {
f->pnew += n;
if (f->pnew == f->bend) {
f->pnew = f->b;
}
f->nelem += n;
} else {
break;
}
}
/*
* if there is a character in the fifo and it is not
* a header byte then discard it. Keep going as
* long as there are still bytes in the fifo. if a packet
* with bad parity is received it is discarded.
*/
while ((f->nelem > 0) && ( *f->pold != SEND_PKT_HDR)) {
__fifo_getc(f);
}
/*
* now we are either out of characters in the fifo
* or the first character is a header byte. If we
* dont have at least the header byte and the two
* len bytes yet, then just return.
*/
if (f->nelem < SEND_PKT_LEN)
return 0;
old = f->pold + 1;
/*
* we now have received a full packet. We will
* check its parity. if the parity is bad then
* we will discard the packet, and return 0.
* If the packet is good then we will return 1.
*/
if (old == f->bend)
old = f->b;
for(n = 0; n < SEND_PKT_LEN - 1; n++) {
parity ^= *old++;
if (old == f->bend)
old = f->b;
}
if (parity == 0)
return 1; //we have a full packet with good parity check
else {
__fifo_getc(f); /* research header */
goto start;
}
return 0;
}
static void recv_packet(a3k_t from, struct frames *f, uint32_t led)
static void __drop_bytes(struct tag_fifo *f, int len)
{
uint32_t pos;
struct ringbuf *rb;
int i;
for (i = 0; i < len; ++i) {
__fifo_getc(f);
}
}
if (a3k_checkfullpacket(from)) {
if (a3k_peekpackettype(from) == PKT_CMD_REBOOT) {
return wait_to_reset();
}
pos = f->tail & (PKT_NLEMS - 1);
++f->tail;
rb = &f->slices[pos];
rb->len = a3k_getpacket(from, rb->rb, rb->size);
gpio_toggle(led);
}
static void __get_packet(struct ringbuf *rb, struct tag_fifo *f)
{
int x, i = 0;
uint8_t p = 0;
rb->rb[i++] = 0x61;
rb->rb[i++] = 0x00;
rb->rb[i++] = (RAW_PKT_LEN + 6); /* 22 bytes */
rb->rb[i++] = PKT_CHANNEL;
rb->rb[i++] = 0x01;
rb->rb[i++] = RAW_PKT_LEN * 8;
while (i < (RAW_PKT_LEN + 6)) {
rb->rb[i++] = __fifo_getc(f);
}
rb->rb[i++] = 0x2f;
for (x = 0; x < i; ++x) {
p ^= rb->rb[i];
}
rb->rb[i++] = p;
rb->len = i;
}
static void recv_packet(struct serial *from, struct frames *f, uint32_t led)
{
uint8_t c;
struct ringbuf *rb0, *rb1;
if (check_rxpacket(from, f)) {
__fifo_getc(&f->f); /* drop 0x61 */
c = __fifo_getc(&f->f); /* get type */
switch (c) {
case SEND_PKT_TYPE_DATA:
break;
case SEND_PKT_TYPE_CMD: /* reset command */
return wait_to_reset();
default:
__drop_bytes(&f->f, SEND_PKT_LEN - 2);
return;
}
rb0 = &f->slices[f->tail & (PKT_NLEMS - 1)];
rb1 = &f->slices[(f->tail + 1) & (PKT_NLEMS - 1)];
f->tail += 2;
__get_packet(rb0, &f->f);
__get_packet(rb1, &f->f);
__fifo_getc(&f->f); /* drop 0x2f */
__fifo_getc(&f->f); /* drop parity */
gpio_toggle(led);
}
}
static void decode_packet(a3k_t to, struct frames *f)
static int decode_packet(a3k_t to, struct frames *f)
{
uint32_t pos;
struct ringbuf *rb;
@ -101,14 +337,14 @@ static void decode_packet(a3k_t to, struct frames *f)
a3k_putpacket(to, rb->rb, rb->len);
rb->len = 0;
}
} else {
a3k_discardpacket(to);
return 0;
}
return -1;
}
static void __ticker(int ms)
static void __on_20ms(int ms)
{
to_play = 1;
to_decode = (BIT0 | BIT1);
// gpio_toggle(PK6);
}
@ -160,6 +396,7 @@ static void __attribute__((unused)) loopback()
static int __on_40ms(struct timer *tm, void *user)
{
to_send = (BIT0 | BIT1);
// gpio_toggle(LED_D6);
return 0;
}
@ -170,51 +407,80 @@ int main()
cmd_init();
/* debug console */
serial_setup(&serial0, 115200, 8, SERIAL_STOPBITS_1);
/* RS422 */
serial_setup(RS422_0, RS422_BAUDRATE, 8, SERIAL_STOPBITS_1);
serial_setup(RS422_1, RS422_BAUDRATE, 8, SERIAL_STOPBITS_1);
/* eeprom */
eeprom_init();
gpio_init(LED_D4 | LED_D5 | LED_D6, GPIO_OUTPUT);
gpio_write(LED_D4 | LED_D5| LED_D6, 1);
gpio_write(LED_D4 | LED_D5 | LED_D6, 1);
gpio_init(LED_D3, GPIO_OUTPUT);
gpio_write(LED_D3, 1);
init_frames(&rx0);
init_frames(&rx1);
init_frames(&rx[0], __rxbuf[0], PKT_LEN);
init_frames(&rx[1], __rxbuf[1], PKT_LEN);
init_frames(&tx[0], NULL, 0);
init_frames(&tx[1], NULL, 0);
printf("\n");
a3k_setup(&a3k0, UART_BAUDRATE);
a3k_setup(&a3k1, UART_BAUDRATE);
/*
* recovery from bad image.
*/
iwdg_set_period_ms(1000);
iwdg_start();
a3k_setup(&a3k2, RS422_BAUDRATE);
a3k_setup(&a3k3, RS422_BAUDRATE);
a3k_setup(&a3k0, -1);
a3k_setup(&a3k1, -1);
ticks_set_callback(__ticker);
ticks_set_callback(__on_20ms);
ticks_init(20);
timer_setup(&timer2, 40, __on_40ms, &timer2);
timer_start(&timer2);
timer_setup(TIM_40MS, 40, __on_40ms, NULL);
timer_start(TIM_40MS);
printf("\nrunning\n> ");
/*
* recovery from bad image.
*/
iwdg_set_period_ms(1000);
iwdg_start();
while (1) {
iwdg_reset();
cmd_loop();
forward_packet(&a3k0, &a3k2, LED_D4); /* D4: UART4 tx */
forward_packet(&a3k1, &a3k3, LED_D6); /* D6: USART6 tx */
recv_packet(&a3k2, &rx0, LED_D3); /* D3: UART4 rx */
recv_packet(&a3k3, &rx1, LED_D5); /* D5: USART6 rx */
if (to_play) {
to_play = 0;
decode_packet(&a3k0, &rx0);
decode_packet(&a3k1, &rx1);
}
iwdg_reset();
encode_packet(&a3k0, &tx[0]);
encode_packet(&a3k1, &tx[1]);
if (to_send & BIT0) {
if (!send_packet(RS422_0, &tx[0], LED_D4)) { /* D4: UART4 TX */
to_send &= ~BIT0;
}
}
if (to_send & BIT1) {
if (!send_packet(RS422_1, &tx[1], LED_D6)) { /* D6: USART6 TX */
to_send &= ~BIT1;
}
}
//forward_packet(&a3k0, &a3k2, LED_D4); /* D4: UART4 tx */
//forward_packet(&a3k1, &a3k3, LED_D6); /* D6: USART6 tx */
recv_packet(RS422_0, &rx[0], LED_D3); /* D3: UART4 rx */
recv_packet(RS422_1, &rx[1], LED_D5); /* D5: USART6 rx */
if (to_decode & BIT0) {
if (!decode_packet(&a3k0, &rx[0])) {
to_decode &= ~(BIT0);
}
}
if (to_decode & BIT1) {
if (!decode_packet(&a3k1, &rx[1])) {
to_decode &= ~(BIT1);
}
}
}
return 0;
}

Loading…
Cancel
Save