Add C28x RS boot ports for F2812 and F28335
This commit is contained in:
@@ -6,7 +6,9 @@
|
||||
|
||||
Ядро не обращается к регистрам МК. Проект передаёт ему принятые байты через
|
||||
`rs485_boot_feed()` и реализует callbacks Flash/передачи из `rs485_boot_port_t`.
|
||||
Готовые bare-metal порты находятся в `ports/stm32f103` и `ports/stm32g474vet`.
|
||||
Готовые порты находятся в `ports/stm32f103`, `ports/stm32g474vet`,
|
||||
`ports/tms320f2812` и `ports/tms320f28335`. TI-порты используют общее ядро
|
||||
`ports/c28x` для ABI C28x с 16-битным `char` и умеют зеркалировать Flash в RAM.
|
||||
|
||||
Важно: линии A/B должны иметь терминацию и fail-safe bias. Порт держит DE
|
||||
активным до флага физического завершения передачи TC, затем возвращается в RX.
|
||||
|
||||
130
c/rs485-boot/ports/c28x/rs_boot_transport.c
Normal file
130
c/rs485-boot/ports/c28x/rs_boot_transport.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "rs_boot_transport.h"
|
||||
|
||||
#define SOF0 0xA5U
|
||||
#define SOF1 0x5AU
|
||||
#define VERSION 1U
|
||||
#define HEADER 8U
|
||||
#define CRC_SIZE 4U
|
||||
#define MSG_BEGIN 0x0BU
|
||||
#define MSG_DATA 0x0CU
|
||||
#define MSG_END 0x0DU
|
||||
#define MSG_ABORT 0x0EU
|
||||
#define MSG_STATUS 0x0FU
|
||||
#define MSG_NACK 0x80U
|
||||
|
||||
static rsbt_u16_t u16(const rsbt_byte_t *p)
|
||||
{ return (p[0] & 0xFFU) | ((p[1] & 0xFFU) << 8); }
|
||||
|
||||
static rsbt_u32_t u32(const rsbt_byte_t *p)
|
||||
{
|
||||
return (rsbt_u32_t)(p[0] & 0xFFU) |
|
||||
((rsbt_u32_t)(p[1] & 0xFFU) << 8) |
|
||||
((rsbt_u32_t)(p[2] & 0xFFU) << 16) |
|
||||
((rsbt_u32_t)(p[3] & 0xFFU) << 24);
|
||||
}
|
||||
|
||||
static void put32(rsbt_byte_t *p, rsbt_u32_t v)
|
||||
{
|
||||
p[0] = (rsbt_byte_t)(v & 0xFFU); p[1] = (rsbt_byte_t)((v >> 8) & 0xFFU);
|
||||
p[2] = (rsbt_byte_t)((v >> 16) & 0xFFU); p[3] = (rsbt_byte_t)((v >> 24) & 0xFFU);
|
||||
}
|
||||
|
||||
rsbt_u32_t rsbt_crc32(const rsbt_byte_t *p, rsbt_u16_t n)
|
||||
{
|
||||
rsbt_u32_t crc = 0xFFFFFFFFUL;
|
||||
rsbt_u16_t i, bit;
|
||||
for (i = 0U; i < n; ++i) {
|
||||
crc ^= (rsbt_u32_t)(p[i] & 0xFFU);
|
||||
for (bit = 0U; bit < 8U; ++bit)
|
||||
crc = (crc >> 1) ^ ((crc & 1U) ? 0xEDB88320UL : 0U);
|
||||
}
|
||||
return crc ^ 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
void rsbt_abort(rsbt_t *b)
|
||||
{
|
||||
if (!b) return;
|
||||
b->state = RSBT_IDLE; b->image_size = 0UL; b->flags = 0U;
|
||||
b->image_crc = 0UL; b->next_offset = 0UL;
|
||||
}
|
||||
|
||||
int rsbt_init(rsbt_t *b, const rsbt_config_t *c, const rsbt_port_t *p, void *u)
|
||||
{
|
||||
rsbt_u16_t i;
|
||||
if (!b || !c || !p || !c->app_size || !p->transmit || !p->erase || !p->write || !p->read) return 0;
|
||||
for (i = 0U; i < RSBT_MAX_FRAME; ++i) { b->parser[i] = 0U; b->tx[i] = 0U; }
|
||||
b->config = *c; b->port = *p; b->user = u; b->parser_length = 0U; b->crc_errors = 0UL;
|
||||
if (!b->config.max_block || b->config.max_block > RSBT_MAX_BLOCK) b->config.max_block = RSBT_MAX_BLOCK;
|
||||
rsbt_abort(b); return 1;
|
||||
}
|
||||
|
||||
static int send_frame(rsbt_t *b, rsbt_byte_t type, rsbt_u16_t seq,
|
||||
const rsbt_byte_t *payload, rsbt_u16_t size)
|
||||
{
|
||||
rsbt_u16_t i, total; rsbt_u32_t crc;
|
||||
if (size > RSBT_MAX_PAYLOAD) return 0;
|
||||
total = HEADER + size + CRC_SIZE;
|
||||
b->tx[0]=SOF0; b->tx[1]=SOF1; b->tx[2]=VERSION; b->tx[3]=type;
|
||||
b->tx[4]=(seq>>8)&0xFFU; b->tx[5]=seq&0xFFU;
|
||||
b->tx[6]=(size>>8)&0xFFU; b->tx[7]=size&0xFFU;
|
||||
for(i=0U;i<size;++i) b->tx[HEADER+i]=payload[i]&0xFFU;
|
||||
crc=rsbt_crc32(&b->tx[2],6U+size); put32(&b->tx[HEADER+size],crc);
|
||||
return b->port.transmit(b->user,b->tx,total);
|
||||
}
|
||||
|
||||
static void nack(rsbt_t *b, rsbt_byte_t req, rsbt_u16_t seq, rsbt_u16_t result)
|
||||
{
|
||||
rsbt_byte_t p[3]; p[0]=result&0xFFU; p[1]=(result>>8)&0xFFU; p[2]=req;
|
||||
(void)send_frame(b,MSG_NACK,seq,p,3U);
|
||||
}
|
||||
|
||||
static int matches(rsbt_t *b, rsbt_u32_t off, const rsbt_byte_t *p, rsbt_u16_t n)
|
||||
{
|
||||
rsbt_u16_t done=0U,i,take;
|
||||
while(done<n){take=n-done;if(take>32U)take=32U;
|
||||
if(!b->port.read(b->user,off+done,b->scratch,take))return 0;
|
||||
for(i=0U;i<take;++i)if((b->scratch[i]&0xFFU)!=(p[done+i]&0xFFU))return 0;
|
||||
done+=take;} return 1;
|
||||
}
|
||||
|
||||
static void process(rsbt_t *b, rsbt_byte_t type, rsbt_u16_t seq,
|
||||
const rsbt_byte_t *p, rsbt_u16_t size)
|
||||
{
|
||||
rsbt_u32_t off,base; rsbt_u16_t n,sum,i;
|
||||
if(type==MSG_BEGIN){if(size!=16U){nack(b,type,seq,2U);return;}
|
||||
b->image_size=u32(p);b->image_crc=u32(&p[4]);b->flags=p[8]&RSBT_FLAG_MIRROR_RAM;base=u32(&p[12]);
|
||||
if((b->flags&RSBT_FLAG_MIRROR_RAM)&&!b->port.write_ram){nack(b,type,seq,0x11U);return;}
|
||||
if(!b->image_size||b->image_size>b->config.app_size||(base&&base!=b->config.app_address)){nack(b,type,seq,1U);return;}
|
||||
b->next_offset=0UL;b->state=RSBT_RECEIVING;
|
||||
if(!b->port.erase(b->user,b->image_size)){b->state=RSBT_FAILED;nack(b,type,seq,7U);return;}
|
||||
put32(b->scratch,0UL);(void)send_frame(b,type,seq,b->scratch,4U);return;}
|
||||
if(type==MSG_DATA){if(b->state!=RSBT_RECEIVING||size<8U){nack(b,type,seq,5U);return;}
|
||||
off=u32(p);n=u16(&p[4]);sum=0U;for(i=0U;i<n&&8U+i<size;++i)sum=(sum+(p[8U+i]&0xFFU))&0xFFFFU;
|
||||
if(!n||n>b->config.max_block||size!=8U+n||off>b->image_size||n>b->image_size-off){nack(b,type,seq,2U);return;}
|
||||
if(sum!=u16(&p[6])){nack(b,type,seq,1U);return;}
|
||||
if(off<b->next_offset){if(off+n>b->next_offset||!matches(b,off,&p[8],n)){nack(b,type,seq,1U);return;}}
|
||||
else {if(off!=b->next_offset||!b->port.write(b->user,off,&p[8],n)||
|
||||
((b->flags&RSBT_FLAG_MIRROR_RAM)&&!b->port.write_ram(b->user,off,&p[8],n))){b->state=RSBT_FAILED;nack(b,type,seq,7U);return;}b->next_offset+=n;}
|
||||
put32(b->scratch,b->next_offset);(void)send_frame(b,type,seq,b->scratch,4U);return;}
|
||||
if(type==MSG_END){if(b->state!=RSBT_RECEIVING||size!=8U||u32(p)!=b->image_size||u32(&p[4])!=b->image_crc||b->next_offset!=b->image_size||(b->port.image_valid&&!b->port.image_valid(b->user,b->image_size,b->image_crc))){b->state=RSBT_FAILED;nack(b,type,seq,1U);return;}
|
||||
b->state=RSBT_READY;(void)send_frame(b,type,seq,0,0U);if(b->port.reboot)b->port.reboot(b->user);return;}
|
||||
if(type==MSG_ABORT){rsbt_abort(b);(void)send_frame(b,type,seq,0,0U);return;}
|
||||
if(type==MSG_STATUS){b->scratch[0]=b->state;put32(&b->scratch[1],b->next_offset);b->scratch[5]=b->flags;(void)send_frame(b,type,seq,b->scratch,6U);return;}
|
||||
nack(b,type,seq,0x11U);
|
||||
}
|
||||
|
||||
static void discard(rsbt_t *b, rsbt_u16_t n)
|
||||
{ rsbt_u16_t i;if(n>=b->parser_length){b->parser_length=0U;return;}for(i=n;i<b->parser_length;++i)b->parser[i-n]=b->parser[i];b->parser_length-=n; }
|
||||
|
||||
void rsbt_feed(rsbt_t *b, rsbt_byte_t byte)
|
||||
{
|
||||
rsbt_u16_t payload,total,seq; rsbt_u32_t got;
|
||||
if(!b)return;if(b->parser_length==RSBT_MAX_FRAME)b->parser_length=0U;
|
||||
b->parser[b->parser_length++]=byte&0xFFU;
|
||||
for(;;){while(b->parser_length>=2U&&(b->parser[0]!=SOF0||b->parser[1]!=SOF1))discard(b,1U);
|
||||
if(b->parser_length<HEADER)return;if(b->parser[2]!=VERSION){discard(b,1U);continue;}
|
||||
payload=((b->parser[6]&0xFFU)<<8)|(b->parser[7]&0xFFU);if(payload>RSBT_MAX_PAYLOAD){discard(b,1U);continue;}
|
||||
total=HEADER+payload+CRC_SIZE;if(b->parser_length<total)return;got=u32(&b->parser[HEADER+payload]);
|
||||
if(got!=rsbt_crc32(&b->parser[2],6U+payload)){++b->crc_errors;discard(b,1U);continue;}
|
||||
seq=((b->parser[4]&0xFFU)<<8)|(b->parser[5]&0xFFU);process(b,b->parser[3],seq,&b->parser[HEADER],payload);discard(b,total);}
|
||||
}
|
||||
62
c/rs485-boot/ports/c28x/rs_boot_transport.h
Normal file
62
c/rs485-boot/ports/c28x/rs_boot_transport.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef RS_BOOT_TRANSPORT_H
|
||||
#define RS_BOOT_TRANSPORT_H
|
||||
|
||||
/*
|
||||
* ProtoCAN RS boot transport for TI C28x.
|
||||
* A C28x char is 16 bits, therefore every wire byte is stored in the low
|
||||
* eight bits of rsbt_byte_t. Never use sizeof() as a wire-byte count.
|
||||
*/
|
||||
typedef unsigned int rsbt_byte_t;
|
||||
typedef unsigned int rsbt_u16_t;
|
||||
typedef unsigned long rsbt_u32_t;
|
||||
|
||||
#define RSBT_MAX_PAYLOAD 512U
|
||||
#define RSBT_MAX_FRAME (8U + RSBT_MAX_PAYLOAD + 4U)
|
||||
#define RSBT_MAX_BLOCK (RSBT_MAX_PAYLOAD - 8U)
|
||||
#define RSBT_FLAG_MIRROR_RAM 0x01U
|
||||
|
||||
typedef enum {
|
||||
RSBT_IDLE = 0U,
|
||||
RSBT_RECEIVING = 1U,
|
||||
RSBT_READY = 2U,
|
||||
RSBT_FAILED = 3U
|
||||
} rsbt_state_t;
|
||||
|
||||
typedef struct {
|
||||
int (*transmit)(void *, const rsbt_byte_t *, rsbt_u16_t);
|
||||
int (*erase)(void *, rsbt_u32_t);
|
||||
int (*write)(void *, rsbt_u32_t, const rsbt_byte_t *, rsbt_u16_t);
|
||||
int (*read)(void *, rsbt_u32_t, rsbt_byte_t *, rsbt_u16_t);
|
||||
int (*write_ram)(void *, rsbt_u32_t, const rsbt_byte_t *, rsbt_u16_t);
|
||||
int (*image_valid)(void *, rsbt_u32_t, rsbt_u32_t);
|
||||
void (*reboot)(void *);
|
||||
} rsbt_port_t;
|
||||
|
||||
typedef struct {
|
||||
rsbt_u32_t app_address;
|
||||
rsbt_u32_t app_size;
|
||||
rsbt_u16_t max_block;
|
||||
} rsbt_config_t;
|
||||
|
||||
typedef struct {
|
||||
rsbt_config_t config;
|
||||
rsbt_port_t port;
|
||||
void *user;
|
||||
rsbt_byte_t parser[RSBT_MAX_FRAME];
|
||||
rsbt_byte_t tx[RSBT_MAX_FRAME];
|
||||
rsbt_byte_t scratch[32];
|
||||
rsbt_u16_t parser_length;
|
||||
rsbt_u32_t image_size;
|
||||
rsbt_u32_t image_crc;
|
||||
rsbt_u32_t next_offset;
|
||||
rsbt_u32_t crc_errors;
|
||||
rsbt_byte_t flags;
|
||||
rsbt_state_t state;
|
||||
} rsbt_t;
|
||||
|
||||
int rsbt_init(rsbt_t *, const rsbt_config_t *, const rsbt_port_t *, void *);
|
||||
void rsbt_feed(rsbt_t *, rsbt_byte_t);
|
||||
void rsbt_abort(rsbt_t *);
|
||||
rsbt_u32_t rsbt_crc32(const rsbt_byte_t *, rsbt_u16_t);
|
||||
|
||||
#endif
|
||||
4
c/rs485-boot/ports/tms320f2812/README.md
Normal file
4
c/rs485-boot/ports/tms320f2812/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# TMS320F2812
|
||||
BALZAM adapter using the common C28x transport, existing `RS485` helpers and
|
||||
`flash_tools`. BEGIN byte 8 bit 0 mirrors blocks to RAM while Flash remains the
|
||||
persistent recovery source.
|
||||
99
c/rs485-boot/ports/tms320f2812/rs_boot_port_f2812.c
Normal file
99
c/rs485-boot/ports/tms320f2812/rs_boot_port_f2812.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "DSP281x_Device.h"
|
||||
#include "RS485.h"
|
||||
#include "flash_tools.h"
|
||||
#include "rs_boot_port_f2812.h"
|
||||
|
||||
static rsbt_t boot;
|
||||
|
||||
/* Sector sizes of the external flash, in 16-bit words. */
|
||||
static const unsigned long sectors[] = {
|
||||
0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,
|
||||
0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,0x8000UL,
|
||||
0x4000UL,0x1000UL,0x1000UL,0x2000UL
|
||||
};
|
||||
|
||||
static int port_tx(void *user, const rsbt_byte_t *data, rsbt_u16_t length)
|
||||
{
|
||||
rsbt_u16_t i; (void)user;
|
||||
RS_Line_to_send(COM_1); RS_SetBitMode(&rs_a,8);
|
||||
for(i=0U;i<length;++i){SCIa_Wait4OK();SCIa_send(data[i]&0xFFU);}
|
||||
SCIa_Wait4OK(); RS_SetBitMode(&rs_a,9); RS_Line_to_receive(COM_1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int port_erase(void *user, rsbt_u32_t image_size)
|
||||
{
|
||||
unsigned int i; unsigned long at=0UL, words=(image_size+1UL)/2UL;
|
||||
(void)user;
|
||||
if(!image_size || words>F2812_BOOT_FLASH_WORDS)return 0;
|
||||
for(i=0U;i<(sizeof(sectors)/sizeof(sectors[0])) && at<words;++i){
|
||||
if(flash_erase_sector(at))return 0; /* legacy API: zero means success */
|
||||
at+=sectors[i];
|
||||
}
|
||||
return at>=words;
|
||||
}
|
||||
|
||||
static int port_write(void *user, rsbt_u32_t offset,
|
||||
const rsbt_byte_t *data, rsbt_u16_t length)
|
||||
{
|
||||
rsbt_u16_t i=0U,word; unsigned long address;
|
||||
(void)user;
|
||||
if(offset+length>F2812_BOOT_APP_BYTES)return 0;
|
||||
address=offset/2UL;
|
||||
if(offset&1UL){
|
||||
word=flash_read_word(address);word=(word&0xFF00U)|(data[0]&0xFFU);
|
||||
if(!flash_write_word(address,word))return 0;++address;++i;
|
||||
}
|
||||
while(i<length){
|
||||
word=(data[i]&0xFFU)<<8;
|
||||
if(i+1U<length)word|=data[i+1U]&0xFFU;else word|=0x00FFU;
|
||||
if(!flash_write_word(address++,word))return 0;i+=2U;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int port_read(void *user, rsbt_u32_t offset,
|
||||
rsbt_byte_t *data, rsbt_u16_t length)
|
||||
{
|
||||
rsbt_u16_t i,word; (void)user;
|
||||
if(offset+length>F2812_BOOT_APP_BYTES)return 0;
|
||||
for(i=0U;i<length;++i){word=flash_read_word((offset+i)/2UL);
|
||||
data[i]=((offset+i)&1UL)?(word&0xFFU):((word>>8)&0xFFU);}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int port_write_ram(void *user, rsbt_u32_t offset,
|
||||
const rsbt_byte_t *data, rsbt_u16_t length)
|
||||
{
|
||||
rsbt_u16_t i,word; volatile unsigned int *ram;
|
||||
(void)user;
|
||||
if(offset+length>F2812_BOOT_RAM_WORDS*2UL)return 0;
|
||||
ram=(volatile unsigned int *)(F2812_BOOT_RAM_ADDRESS+offset/2UL);
|
||||
if(offset&1UL){word=*ram;*ram++=(word&0xFF00U)|(data[0]&0xFFU);i=1U;}else i=0U;
|
||||
while(i<length){word=(data[i]&0xFFU)<<8;
|
||||
if(i+1U<length)word|=data[i+1U]&0xFFU;else word|=0x00FFU;
|
||||
*ram++=word;i+=2U;}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int port_valid(void *user, rsbt_u32_t size, rsbt_u32_t expected)
|
||||
{
|
||||
rsbt_byte_t block[32]; rsbt_u32_t crc=0xFFFFFFFFUL,off; rsbt_u16_t i,n,bit;
|
||||
(void)user;
|
||||
for(off=0UL;off<size;off+=32UL){n=(rsbt_u16_t)(size-off);if(n>32U)n=32U;
|
||||
if(!port_read(0,off,block,n))return 0;
|
||||
for(i=0U;i<n;++i){crc^=block[i]&0xFFU;for(bit=0U;bit<8U;++bit)crc=(crc>>1)^((crc&1U)?0xEDB88320UL:0U);}}
|
||||
return (crc^0xFFFFFFFFUL)==expected;
|
||||
}
|
||||
|
||||
void BalzamBoot_Init(void)
|
||||
{
|
||||
rsbt_config_t c; rsbt_port_t p;
|
||||
c.app_address=F2812_BOOT_APP_ADDRESS;c.app_size=F2812_BOOT_APP_BYTES;c.max_block=RSBT_MAX_BLOCK;
|
||||
p.transmit=port_tx;p.erase=port_erase;p.write=port_write;p.read=port_read;
|
||||
p.write_ram=port_write_ram;p.image_valid=port_valid;p.reboot=0;
|
||||
init_flash();(void)rsbt_init(&boot,&c,&p,0);
|
||||
}
|
||||
|
||||
void BalzamBoot_FeedByte(unsigned int wire_byte){rsbt_feed(&boot,wire_byte&0xFFU);}
|
||||
rsbt_state_t BalzamBoot_State(void){return boot.state;}
|
||||
17
c/rs485-boot/ports/tms320f2812/rs_boot_port_f2812.h
Normal file
17
c/rs485-boot/ports/tms320f2812/rs_boot_port_f2812.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef RS_BOOT_PORT_F2812_H
|
||||
#define RS_BOOT_PORT_F2812_H
|
||||
|
||||
#include "rs_boot_transport.h"
|
||||
|
||||
/* External AM29-style flash is word-addressed by flash_tools.c. */
|
||||
#define F2812_BOOT_APP_ADDRESS 0x00100000UL
|
||||
#define F2812_BOOT_FLASH_WORDS 0x00078000UL
|
||||
#define F2812_BOOT_APP_BYTES (F2812_BOOT_FLASH_WORDS * 2UL)
|
||||
#define F2812_BOOT_RAM_ADDRESS 0x00080000UL
|
||||
#define F2812_BOOT_RAM_WORDS 0x00078000UL
|
||||
|
||||
void BalzamBoot_Init(void);
|
||||
void BalzamBoot_FeedByte(unsigned int wire_byte);
|
||||
rsbt_state_t BalzamBoot_State(void);
|
||||
|
||||
#endif
|
||||
5
c/rs485-boot/ports/tms320f28335/README.md
Normal file
5
c/rs485-boot/ports/tms320f28335/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# TMS320F28335
|
||||
Uses `../c28x` to preserve 8-bit wire bytes on the 16-bit-byte C28x ABI.
|
||||
Copy the config template, provide the board external-Flash functions and RS485
|
||||
direction macros. BEGIN byte 8 bit 0 enables Flash + RAM mirroring; Flash is
|
||||
always retained and used for final CRC/recovery after reset.
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef RS_BOOT_PORT_CONFIG_H
|
||||
#define RS_BOOT_PORT_CONFIG_H
|
||||
#include "DSP2833x_Device.h"
|
||||
/* C28x addresses and sizes are in 16-bit words. */
|
||||
#define F28335_BOOT_FLASH_BASE 0x00100000UL
|
||||
#define F28335_BOOT_FLASH_WORDS 0x00078000UL
|
||||
#define F28335_BOOT_RAM_BASE 0x00080000UL
|
||||
#define F28335_BOOT_RAM_WORDS 0x00078000UL
|
||||
#define F28335_BOOT_USE_SCIB 0
|
||||
#define F28335_BOOT_RS485_TX() do { } while (0)
|
||||
#define F28335_BOOT_RS485_RX() do { } while (0)
|
||||
#define F28335_BOOT_REBOOT() do { } while (0)
|
||||
/* Supply board Flash driver. word_offset is relative to FLASH_BASE. */
|
||||
int F28335_BOOT_FLASH_ERASE(unsigned long first_word,unsigned long word_count);
|
||||
int F28335_BOOT_FLASH_PROGRAM(unsigned long word_offset,unsigned int value);
|
||||
unsigned int F28335_BOOT_FLASH_READ(unsigned long word_offset);
|
||||
#endif
|
||||
24
c/rs485-boot/ports/tms320f28335/rs_boot_port_f28335.c
Normal file
24
c/rs485-boot/ports/tms320f28335/rs_boot_port_f28335.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "rs_boot_port_config.h"
|
||||
#include "rs_boot_port_f28335.h"
|
||||
static rsbt_t boot;
|
||||
static int tx(void*u,const rsbt_byte_t*d,rsbt_u16_t n){rsbt_u16_t i;(void)u;F28335_BOOT_RS485_TX();for(i=0U;i<n;++i){
|
||||
#if F28335_BOOT_USE_SCIB
|
||||
while(!ScibRegs.SCICTL2.bit.TXRDY){}ScibRegs.SCITXBUF=d[i]&0xFFU;
|
||||
#else
|
||||
while(!SciaRegs.SCICTL2.bit.TXRDY){}SciaRegs.SCITXBUF=d[i]&0xFFU;
|
||||
#endif
|
||||
}
|
||||
#if F28335_BOOT_USE_SCIB
|
||||
while(!ScibRegs.SCICTL2.bit.TXEMPTY){}
|
||||
#else
|
||||
while(!SciaRegs.SCICTL2.bit.TXEMPTY){}
|
||||
#endif
|
||||
F28335_BOOT_RS485_RX();return 1;}
|
||||
static int erase(void*u,rsbt_u32_t n){(void)u;if(!n||n>F28335_BOOT_FLASH_WORDS*2UL)return 0;return F28335_BOOT_FLASH_ERASE(0UL,(n+1UL)/2UL);}
|
||||
static int wr(void*u,rsbt_u32_t o,const rsbt_byte_t*d,rsbt_u16_t n){rsbt_u16_t i=0U,w;unsigned long a=o/2UL;(void)u;if(o+n>F28335_BOOT_FLASH_WORDS*2UL)return 0;if(o&1UL){w=F28335_BOOT_FLASH_READ(a);w=(w&0xFF00U)|(d[0]&0xFFU);if(!F28335_BOOT_FLASH_PROGRAM(a++,w))return 0;i=1U;}while(i<n){w=(d[i]&0xFFU)<<8;w|=(i+1U<n)?(d[i+1U]&0xFFU):0xFFU;if(!F28335_BOOT_FLASH_PROGRAM(a++,w))return 0;i+=2U;}return 1;}
|
||||
static int rd(void*u,rsbt_u32_t o,rsbt_byte_t*d,rsbt_u16_t n){rsbt_u16_t i,w;(void)u;if(o+n>F28335_BOOT_FLASH_WORDS*2UL)return 0;for(i=0U;i<n;++i){w=F28335_BOOT_FLASH_READ((o+i)/2UL);d[i]=((o+i)&1UL)?(w&0xFFU):(w>>8);}return 1;}
|
||||
static int ram(void*u,rsbt_u32_t o,const rsbt_byte_t*d,rsbt_u16_t n){rsbt_u16_t i=0U,w;volatile unsigned int*p;(void)u;if(o+n>F28335_BOOT_RAM_WORDS*2UL)return 0;p=(volatile unsigned int*)(F28335_BOOT_RAM_BASE+o/2UL);if(o&1UL){w=*p;*p++=(w&0xFF00U)|(d[0]&0xFFU);i=1U;}while(i<n){w=(d[i]&0xFFU)<<8;w|=(i+1U<n)?(d[i+1U]&0xFFU):0xFFU;*p++=w;i+=2U;}return 1;}
|
||||
static int valid(void*u,rsbt_u32_t size,rsbt_u32_t expected){rsbt_byte_t b[32];rsbt_u32_t crc=0xFFFFFFFFUL,o;rsbt_u16_t i,n,bit;(void)u;for(o=0UL;o<size;o+=32UL){n=(rsbt_u16_t)(size-o);if(n>32U)n=32U;if(!rd(0,o,b,n))return 0;for(i=0U;i<n;++i){crc^=b[i]&0xFFU;for(bit=0U;bit<8U;++bit)crc=(crc>>1)^((crc&1U)?0xEDB88320UL:0U);}}return(crc^0xFFFFFFFFUL)==expected;}
|
||||
static void reboot(void*u){(void)u;F28335_BOOT_REBOOT();}
|
||||
void F28335Boot_Init(void){rsbt_config_t c;rsbt_port_t p;c.app_address=F28335_BOOT_FLASH_BASE;c.app_size=F28335_BOOT_FLASH_WORDS*2UL;c.max_block=RSBT_MAX_BLOCK;p.transmit=tx;p.erase=erase;p.write=wr;p.read=rd;p.write_ram=ram;p.image_valid=valid;p.reboot=reboot;(void)rsbt_init(&boot,&c,&p,0);}
|
||||
void F28335Boot_FeedByte(unsigned int b){rsbt_feed(&boot,b&0xFFU);}rsbt_state_t F28335Boot_State(void){return boot.state;}
|
||||
7
c/rs485-boot/ports/tms320f28335/rs_boot_port_f28335.h
Normal file
7
c/rs485-boot/ports/tms320f28335/rs_boot_port_f28335.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef RS_BOOT_PORT_F28335_H
|
||||
#define RS_BOOT_PORT_F28335_H
|
||||
#include "rs_boot_transport.h"
|
||||
void F28335Boot_Init(void);
|
||||
void F28335Boot_FeedByte(unsigned int wire_byte);
|
||||
rsbt_state_t F28335Boot_State(void);
|
||||
#endif
|
||||
Reference in New Issue
Block a user