#include "periph28335.h" #include #include "balsam167_eeprom_block.h" #include static void response(uint8_t *out, unsigned high, unsigned low) { /* Reply is low data byte, high data byte, then an unrelated timer. * Nonzero timer detects accidentally copying four memory bytes per PEEK. */ uint8_t payload[] = {16,56,0,0,0xef,0xbe}; payload[2]=(uint8_t)low; payload[3]=(uint8_t)high; assert(periph28335_append_crc(payload,6,out,10)==8); out[8]=out[9]=0; } static void blocks(void) { periph28335_eeprom_reader r; uint8_t req[8], reply[245], out[240]; unsigned start, transactions, n, a, i, old; int got; assert(!balsam167_eeprom_block_valid(6,0x8000,1)); assert(!balsam167_eeprom_block_valid(3,0xbfff,2)); assert(!balsam167_eeprom_block_valid(3,0xffff,120)); assert(!balsam167_eeprom_block_valid(3,0x8000,121)); assert(!balsam167_eeprom_block_valid(3,0x8000,0)); assert(balsam167_eeprom_block_valid(3,0xbfff,1)); for(start=0;start<2;start++) { assert(!periph28335_eeprom_begin(&r,16,start,32768-start)); transactions=0; while(r.received0); for(i=0;i<(unsigned)got;i++) assert(out[i]==(uint8_t)(start+old+i)); transactions++; } assert(transactions==137); assert(!periph28335_eeprom_block_request(&r,req,8)); } } static void profiles(void) { periph28335_eeprom_reader r; uint8_t req[18], reply[245], out[240]; unsigned n, i, q, a, bankmask=0; uint32_t pos, before; assert(periph28335_eeprom_capacity_profile(0)==32768); assert(periph28335_eeprom_capacity_profile(1)==262144); assert(periph28335_eeprom_capacity_profile(2)==0); assert(periph28335_eeprom_begin_profile(&r,16,262143,2,1)<0); assert(periph28335_eeprom_begin_profile(&r,16,0,2,2)<0); assert(!balsam167_eeprom_block_valid_profile(3,0xffff,0x8078,1)); assert(!balsam167_eeprom_block_valid_profile(3,0x8000,0x8401,1)); assert(!balsam167_eeprom_block_valid_profile(3,0x8000,0x8001,0)); assert(!balsam167_eeprom_block_valid_profile(3,0x8000,1,1)); assert(balsam167_eeprom_block_valid_profile(3,0xffff,0x8301,1)); /* Full 256-KiB dump from an odd start exercises every bank transition, * first/last byte trimming, CRC failure and exact physical byte order. */ assert(!periph28335_eeprom_begin_profile(&r,16,1,262143,1)); while(r.received>8)&3U); assert(periph28335_eeprom_block_expected_profile(&r,1)==5+2*n); reply[0]=5; reply[1]=3; reply[2]=(uint8_t)(n*2); for(i=0;i>16)); periph28335_append_crc(reply,3+n*2,reply,sizeof(reply)); before=r.received; reply[4]^=1; assert(periph28335_eeprom_block_accept_profile(&r,reply,5+2*n,out,240,1)==PERIPH28335_ERROR_CRC); assert(r.received==before); reply[4]^=1; assert(periph28335_eeprom_block_accept_profile(&r,reply,5+2*n,out,240,1)>0); for(i=0;i>16))); } } assert(bankmask==15); assert(!periph28335_eeprom_block_request_profile(&r,req,8,1)); assert(periph28335_eeprom_write_profile(5,0,0x200000,33514,0,req,18)==0); assert(periph28335_eeprom_write_profile(5,0,0x200000,33514,1,req,18)==18); assert(req[14]==0x44 && req[15]==0 && !periph28335_crc16_modbus(req,18)); assert(!periph28335_eeprom_write_profile(5,0x1ff7e,0,2,1,req,18)); assert(!periph28335_eeprom_write_profile(5,0xffffffff,0,2,1,req,18)); assert(periph28335_eeprom_write_profile(5,0,0,32438,0,req,18)==18 && req[14]==4); } int main(void) { periph28335_eeprom_reader reader; blocks(); profiles(); uint8_t request[8], reply[10], data[2]; unsigned i; assert(sizeof(reader)==16); assert(periph28335_eeprom_begin(&reader,16,0,0)==PERIPH28335_ERROR_RANGE); assert(periph28335_eeprom_begin(&reader,0,0,2)==PERIPH28335_ERROR_RANGE); assert(periph28335_eeprom_begin(&reader,16,0x8000,1)==PERIPH28335_ERROR_RANGE); assert(periph28335_eeprom_begin(&reader,16,0x7fff,2)==PERIPH28335_ERROR_RANGE); assert(periph28335_eeprom_begin(&reader,16,1,0xffffffffUL)==PERIPH28335_ERROR_RANGE); assert(periph28335_eeprom_request(&reader,request,8)==0); assert(periph28335_eeprom_begin(&reader,16,1,3)==0); assert(periph28335_eeprom_request(&reader,request,7)==0); assert(periph28335_eeprom_request(&reader,request,8)==8); assert(memcmp(request,"\x10\x38\0\0\0\0",6)==0); response(reply,0x12,0x34); assert(periph28335_eeprom_accept(&reader,reply,8,data,2)==1 && data[0]==0x34); assert(reader.received==1); assert(periph28335_eeprom_request(&reader,request,8)==8 && request[2]==1); reply[2]^=1; assert(periph28335_eeprom_accept(&reader,reply,8,data,2)==PERIPH28335_ERROR_CRC); assert(reader.received==1); response(reply,0x56,0x78); assert(periph28335_eeprom_accept(&reader,reply,8,data,1)==PERIPH28335_ERROR_CAPACITY); assert(reader.received==1); assert(periph28335_eeprom_accept(&reader,reply,10,data,2)==2); assert(data[0]==0x56 && data[1]==0x78 && reader.received==3); assert(periph28335_eeprom_request(&reader,request,8)==0); /* Every requested word of a complete dump remains in the EEPROM window. * In particular, neither the RAM route nor selector 0x10000000 is used. */ assert(periph28335_eeprom_begin(&reader,16,0,32768)==0); for (i=0;i<16384;i++) { assert(periph28335_eeprom_request(&reader,request,8)==8); assert(request[1]==56 && request[4]==0 && request[5]==0); assert(((unsigned)request[3]*256+request[2])==i); assert(periph28335_crc16_modbus(request,8)==0); response(reply,i>>8,i); assert(periph28335_eeprom_accept(&reader,reply,8,data,2)==2); assert(data[0]==(i>>8) && data[1]==(i&255)); } assert(reader.received==32768 && periph28335_eeprom_request(&reader,request,8)==0); assert(periph28335_eeprom_begin(&reader,16,0x7fff,1)==0); assert(periph28335_eeprom_request(&reader,request,8)==8); assert(request[2]==0xff && request[3]==0x3f); response(reply,0x9a,0xbc); assert(periph28335_eeprom_accept(&reader,reply,8,data,2)==1 && data[0]==0xbc); return 0; }