95 lines
5.5 KiB
C
95 lines
5.5 KiB
C
/* Production CAN adapter, fake hardware, wide C28x wire octets. */
|
|
#define EEPROM_M95M02 1
|
|
#ifndef F28335_BOOT_LOADER
|
|
#define F28335_BOOT_LOADER 1
|
|
#endif
|
|
#define F28335_CAN_BOOT_FIRMWARE_VERSION 0x12345678UL
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
void ServiceDog(void);
|
|
#include "../ports/tms320f28335/f28335_can_boot.c"
|
|
static unsigned char memory[0x40000];
|
|
static unsigned int running=255,resets,reset_arg,dog_feeds;
|
|
static int fail_write;
|
|
void ServiceDog(void) { ++dog_feeds; }
|
|
bool F28335Boot_Read(void *u,uint32_t a,pcan_boot_byte_t *p,unsigned int n)
|
|
{ unsigned i; (void)u; assert(a+n<=sizeof(memory)); for(i=0;i<n;++i)p[i]=memory[a+i]; return true; }
|
|
bool F28335Boot_Write(void *u,uint32_t a,const pcan_boot_byte_t *p,unsigned int n)
|
|
{ unsigned i; (void)u; assert(a+n<=0x3FE00); if(fail_write)return false;
|
|
for(i=0;i<n;++i)memory[a+i]=(unsigned char)p[i]; return true; }
|
|
uint32_t F28335Boot_Now(void) { return CpuTimer1.InterruptCount; }
|
|
unsigned int F28335Boot_RunningSlot(void) { return running; }
|
|
void F28335Boot_Reset(unsigned int session) { ++resets;reset_arg=session;reset_requested=0; }
|
|
static void command(unsigned cmd,const pcan_boot_byte_t *d,unsigned n)
|
|
{ tx_busy=0; assert(pcan_boot_process(&boot,pcan_boot_make_id(1,0,3,7,9,0x100|cmd),d,n)); }
|
|
static void put32(pcan_boot_byte_t *p,uint32_t v)
|
|
{ unsigned i;for(i=0;i<4;++i)p[i]=(v>>(i*8))&255; }
|
|
int main(void)
|
|
{
|
|
pcan_boot_byte_t image[40]={0xAA,8},meta[8],compat[8]={0x33,0x28,1,1,2,0,1,1};
|
|
unsigned i,slot; pcan_boot_manifest_t m;
|
|
memset(memory,0xA5,sizeof(memory)); image[21]=0x80; image[22]=5; image[27]=0x80;
|
|
F28335CanBoot_Init(); assert(boot.config.max_image_size==130560 && boot.config.slot_count==2);
|
|
if(!F28335_BOOT_LOADER) {
|
|
/* SPI-ROM application without Flash-loader handoff cannot erase anything. */
|
|
command(2,0,0); assert(boot.last_status==PCAN_BOOT_STATUS_INVALID_STATE && !reset_requested);
|
|
memset(&m,0,sizeof(m));m.image_size=40;m.image_crc32=f28335_boot_crc(0,image,40);
|
|
m.product_type=0x2833;m.hardware_revision_min=m.hardware_revision_max=1;
|
|
assert(f28335_boot_prepare(&store,0));
|
|
for(i=0;i<40;i+=8)assert(f28335_boot_write(&store,0,i,image+i,8));
|
|
assert(f28335_boot_commit(&store,0,&m)); assert(f28335_boot_select(&store,&slot));
|
|
running=0; F28335CanBoot_Init();
|
|
assert(!F28335CanBoot_WatchdogAllowed());
|
|
command(8,0,0);assert(boot.last_status==PCAN_BOOT_STATUS_INVALID_STATE);
|
|
F28335CanBoot_Ready();
|
|
for(i=0;i<100;++i) F28335CanBoot_Service();
|
|
assert(!confirmed && store.pending==0);
|
|
CpuTimer1.InterruptCount=5000; F28335CanBoot_Service();
|
|
assert(confirmed && store.active==0 && dog_feeds);
|
|
command(2,0,0); assert(reset_requested && reset_session==1 && boot.state==PCAN_BOOT_STATE_IDLE);
|
|
F28335CanBoot_Service();assert(resets==1 && reset_arg==1);
|
|
command(1,0,0);assert(ECanaMboxes.MBOX4.MDH.all==0x12345678UL);
|
|
} else {
|
|
command(2,0,0); put32(meta,40);put32(meta+4,f28335_boot_crc(0,image,40));
|
|
command(3,meta,8);command(4,compat,8);assert(boot.target_slot==0);
|
|
command(5,0,0);
|
|
for(i=0;i<5;++i) { tx_busy=0; assert(pcan_boot_process(&boot,
|
|
pcan_boot_make_id(1,0,3,7,10,i),image+i*8,8)); }
|
|
command(6,0,0);assert(boot.state==PCAN_BOOT_STATE_VERIFIED);
|
|
command(7,0,0);assert(store.pending==0 && boot.state==PCAN_BOOT_STATE_COMMITTED);
|
|
command(7,0,0);assert(boot.last_status==0);
|
|
command(8,0,0);assert(boot.last_status==PCAN_BOOT_STATUS_INVALID_STATE);
|
|
command(9,0,0);assert(reset_requested);tx_busy=0;
|
|
F28335CanBoot_Service();assert(resets==1 && reset_arg==0);
|
|
command(10,0,0);command(2,0,0);command(3,meta,8);command(4,compat,8);
|
|
command(5,0,0);assert(boot.last_status==PCAN_BOOT_STATUS_FLASH_ERROR); /* Pending is protected. */
|
|
}
|
|
command(12,0,0); assert((ECanaMboxes.MBOX4.MSGID.all&65535)==12);
|
|
command(13,0,0); assert(ECanaMboxes.MBOX4.MDH.all==130560);
|
|
meta[0]=0;command(14,meta,1); assert(ECanaMboxes.MBOX4.MDL.all==0x33383246UL); /* F283 */
|
|
meta[0]=3;command(15,meta,1);assert(ECanaMboxes.MBOX4.MDL.all==0x3FEFCUL);
|
|
assert(!pcan_boot_process(&boot,pcan_boot_make_id(1,0,3,6,9,0x102),0,0));
|
|
tx_busy=0;
|
|
assert(pcan_boot_process(&boot,pcan_boot_make_id(1,0,7,15,13,0),0,0));
|
|
assert(boot.discovery_pending); pcan_boot_poll(&boot,boot.discovery_at);
|
|
assert(!boot.discovery_pending && (ECanaMboxes.MBOX4.MSGID.all&65535)==1);
|
|
assert(!pcan_boot_process(&boot,pcan_boot_make_id(1,0,7,15,9,0x102),0,0));
|
|
head=tail=0; ECanaRegs.CANRMP.all=8;
|
|
ECanaMboxes.MBOX3.MSGID.all=0x80000000UL|pcan_boot_make_id(1,0,3,7,9,12);
|
|
ECanaMboxes.MBOX3.MSGCTRL.bit.DLC=0;
|
|
F28335CanBoot_RxISR(); assert(head==1 && tail==0);
|
|
tx_busy=0; F28335CanBoot_Service(); assert(tail==1);
|
|
ECanaMboxes.MBOX3.MSGCTRL.bit.RTR=1; F28335CanBoot_RxISR(); assert(head==1);
|
|
ECanaMboxes.MBOX3.MSGCTRL.bit.RTR=0;
|
|
overflow=1;tx_busy=0;F28335CanBoot_Service();assert(boot.state==PCAN_BOOT_STATE_IDLE);
|
|
/* An ACK arriving after cancellation must never execute a queued reset. */
|
|
tx_busy=1;tx_canceling=0;reset_requested=1;sent_at=0;
|
|
CpuTimer1.InterruptCount=300;ECanaRegs.CANTA.all=0;ECanaRegs.CANAA.all=0;
|
|
F28335CanBoot_Service();assert(!reset_requested && tx_canceling);
|
|
ECanaRegs.CANTA.all=16; F28335CanBoot_Service();assert(!tx_busy && resets==1);
|
|
for(i=0x3FE00;i<0x40000;++i)assert(memory[i]==0xA5);
|
|
puts(F28335_BOOT_LOADER?"F28335 loader CAN services: OK":"F28335 application handoff/confirmation: OK");
|
|
return 0;
|
|
}
|