792 lines
24 KiB
C++
792 lines
24 KiB
C++
#include <stdio.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/time.h>
|
||
#include <fcntl.h>
|
||
#include <errno.h>
|
||
#include <sys/ioctl.h>
|
||
#include <stdlib.h>
|
||
#include <linux/types.h>
|
||
#include <string.h>
|
||
#include <iostream>
|
||
#include <unistd.h>
|
||
#include <sys/mman.h>
|
||
#include <stdint.h>
|
||
#include <cstdio>
|
||
#include <cstdlib>
|
||
#include <cstdint>
|
||
#include <cstring>
|
||
#include <fstream>
|
||
#include <limits>
|
||
|
||
#include "rio_lib_api.h"
|
||
|
||
#include "dwl_fw.h"
|
||
|
||
#define WRITE_DELAY_US 100000
|
||
#define WAITFLASH_DELAY_US 100000
|
||
|
||
#define MAX_RETRY_READ 1000
|
||
|
||
int srio_id = -1;
|
||
|
||
#define MAX_BUFFER_SIZE (1024 * 1024) // 1MB
|
||
#define MAX_NUMBERS (MAX_BUFFER_SIZE / 9) // circa 9 byte per numero: 8 hex + separatore
|
||
|
||
constexpr size_t DWL_CHUNK_SIZE = 256;
|
||
constexpr size_t DWL_WORDS = DWL_CHUNK_SIZE / sizeof(unsigned int);
|
||
unsigned int dwl_buffer[DWL_WORDS];
|
||
|
||
unsigned int flashport;
|
||
|
||
constexpr size_t ERASE_BLOCK_SIZE = 65536;
|
||
|
||
int initSrio(int *srio_id)
|
||
{
|
||
const char* devFullPathName = "/dev/zynq_xmc_rio_0";
|
||
int openFlags = O_RDWR + O_NONBLOCK; // O_NONBLOCK makes the read operation not blocking when no data are available
|
||
//int deviceFile;
|
||
|
||
if (rio_ok != (rio_open(devFullPathName, srio_id)))
|
||
{ int err = errno;
|
||
char buf[256];
|
||
snprintf (buf, sizeof(buf), "open(\"%s\", %d) returns FAIL (%s)\n", devFullPathName, openFlags, strerror(err));
|
||
perror (buf);
|
||
exit(-err);
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
//rio_to_eth_mirror_set(1);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
bool parse_args(int argc, char** argv, uint16_t* endpoint, uint32_t* address, uint32_t* value) {
|
||
if (argc != 4) {
|
||
fprintf(stderr, "Uso: %s <endpoint hex> <address hex> <value>\n", argv[0]);
|
||
return false;
|
||
}
|
||
|
||
// Parsing dell'endpoint come uint16_t
|
||
char* endptr = nullptr;
|
||
unsigned long ep = strtoul(argv[1], &endptr, 0);
|
||
if (*endptr != '\0' || ep > 0xFFFF) {
|
||
fprintf(stderr, "Endpoint non valido: %s\n", argv[1]);
|
||
return false;
|
||
}
|
||
*endpoint = static_cast<uint16_t>(ep);
|
||
|
||
// Parsing dell'address come uint32_t
|
||
unsigned long addr = strtoul(argv[2], &endptr, 0);
|
||
if (*endptr != '\0' || addr > 0xFFFFFFFF) {
|
||
fprintf(stderr, "Address non valido: %s\n", argv[2]);
|
||
return false;
|
||
}
|
||
*address = static_cast<uint32_t>(addr);
|
||
|
||
// Parsing del valore come uint32_t
|
||
unsigned long val = strtoul(argv[3], &endptr, 0);
|
||
if (*endptr != '\0' || val > 0xFFFFFFFF) {
|
||
fprintf(stderr, "valore non valido: %s\n", argv[2]);
|
||
return false;
|
||
}
|
||
*value = static_cast<uint32_t>(val);
|
||
return true;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////// BASE FUNCTION //////////////////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
int srio_write_reg(uint16_t endpoint, uint32_t address, uint32_t value, int max_retry = 500, int timeout_us = 1000) //fatto
|
||
{
|
||
/*printf("Endpoint: 0x%04x\n", endpoint);
|
||
printf("Address: 0x%08x\n", address);
|
||
printf("Value: %d\n", value);*/
|
||
rio_result res;
|
||
|
||
uint32_t address_offset = address & 0x000000FF;
|
||
if (address_offset % 4)
|
||
{
|
||
printf("\nAddress 0x%08X non è multiplo di 4",address);
|
||
return INPUT_NOT_VALID;
|
||
}
|
||
|
||
uint32_t buffer_size = 256/sizeof(unsigned int);
|
||
|
||
unsigned int* buffer = (unsigned int*)malloc(256);
|
||
if (!buffer) {
|
||
perror("Errore nell'allocazione del buffer");
|
||
free(buffer);
|
||
return GENERIC_ERROR;
|
||
}
|
||
|
||
uint32_t address_aligned = address & 0xFFFFFF00;
|
||
|
||
res = rio_nread(srio_id, endpoint, address_aligned, buffer, buffer_size*4);
|
||
if (res != rio_ok) {
|
||
printf("\nErrore nella lettura da SRIO %d",res);
|
||
free(buffer);
|
||
return SRIO_READ_ERROR;
|
||
}
|
||
|
||
int i;
|
||
for ( i = 0; i < max_retry; i++)
|
||
{
|
||
buffer[address_offset/4] = value;
|
||
|
||
res = rio_nwrite( srio_id, //rio_id rid
|
||
endpoint, //uint16_t remote_endpoint_id
|
||
address_aligned, //void* remote_addr (the virtual machine is a 64bit operating system)
|
||
buffer, //void* sending_payload
|
||
buffer_size*4); //numCount*sizeof(uint32_t)); //size_t payload_size
|
||
if (res != rio_ok)
|
||
{
|
||
printf("\nError writing to srio res=%d",res);
|
||
free(buffer);
|
||
return SRIO_WRITE_ERROR;
|
||
}
|
||
|
||
if(address == TX_FIFO_REG) break;
|
||
|
||
res = rio_nread(srio_id, endpoint, address_aligned, buffer, buffer_size*4);
|
||
if (res != rio_ok) {
|
||
printf("\nErrore nella lettura da SRIO %d",res);
|
||
free(buffer);
|
||
return SRIO_READ_ERROR;
|
||
}
|
||
|
||
if(buffer[address_offset/4] == value) break;
|
||
|
||
usleep(timeout_us);
|
||
}
|
||
|
||
if(i == max_retry) printf("\nsrio_write_reg:: FAIL (max retry) address 0x%08X, value 0x%08X\n",address, value);
|
||
// Cleanup
|
||
free(buffer);
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
int srio_wait_reg( uint16_t endpoint, //fatto
|
||
uint32_t address,
|
||
uint32_t pos,
|
||
uint32_t value,
|
||
int max_retry = 500,
|
||
int timeout_us = 1000)
|
||
{
|
||
/*printf("Endpoint: 0x%04x\n", endpoint);
|
||
printf("Address: 0x%08x\n", address);
|
||
printf("Value: %d\n", value);*/
|
||
|
||
|
||
uint32_t address_offset = address & 0x000000FF;
|
||
if (address_offset % 4)
|
||
{
|
||
printf("\nAddress 0x%08X non è multiplo di 4",address);
|
||
return INPUT_NOT_VALID;
|
||
}
|
||
|
||
uint32_t buffer_size = 256/sizeof(unsigned int);
|
||
|
||
unsigned int* buffer = (unsigned int*)malloc(256);
|
||
if (!buffer) {
|
||
perror("Errore nell'allocazione del buffer");
|
||
free(buffer);
|
||
return GENERIC_ERROR;
|
||
}
|
||
|
||
uint32_t address_aligned = address & 0xFFFFFF00;
|
||
int i;
|
||
int res = NO_ERROR;
|
||
rio_result res_srio;
|
||
|
||
for ( i = 0; i < max_retry; i++)
|
||
{
|
||
res_srio = rio_nread(srio_id, endpoint, address_aligned, buffer, buffer_size*4);
|
||
if (res_srio != rio_ok) {
|
||
printf("\nErrore nella lettura da SRIO %d",res);
|
||
free(buffer);
|
||
return SRIO_READ_ERROR;
|
||
}
|
||
|
||
if (( (buffer[address_offset/4]) >> pos & 0x00000001 ) == value)
|
||
{
|
||
//printf("\nreg: 0x%08X, pos: %d, value: %d. (wait finish)\n",address, pos, value);
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
//printf("\nWarning: SRIO WAIT: reg: 0x%08X, pos: %d, value: %d\n",address, pos, value);
|
||
if ( address == STATUS_REG &&
|
||
pos == 12 &&
|
||
value == 0)
|
||
{
|
||
srio_write_reg(endpoint, CTRL_REG, 0x01);
|
||
}
|
||
|
||
|
||
res = SRIO_WAIT_ERROR;
|
||
}
|
||
|
||
usleep(timeout_us);
|
||
}
|
||
if (i == max_retry)
|
||
{
|
||
//printf("\nwait_flash exit: FAILED for max retry: %d\n",i);
|
||
if (address != RX_FIFO_REG)
|
||
{
|
||
printf("\nwait_flash exit: FAILED for max retry: %d\n",i);
|
||
printf("\nWarning: SRIO WAIT: reg: 0x%08X, pos: %d, value_expected: %d\n",address, pos, value);
|
||
printf("\nPROGRAM STOPPED !\n");
|
||
exit(1);
|
||
}
|
||
}
|
||
//else
|
||
//printf("\nwait_flash exit: retry: %d\n",i);
|
||
|
||
free(buffer);
|
||
return res;
|
||
|
||
}
|
||
|
||
|
||
int srio_write_data(uint16_t endpoint, uint32_t address, uint32_t *data, uint32_t byte) //fatto (per ora scrive una rampa ogni 256 byte)
|
||
{
|
||
/*printf("Endpoint: 0x%04x\n", endpoint);
|
||
printf("Address: 0x%08x\n", address);
|
||
printf("Value: %d\n", value);*/
|
||
rio_result res;
|
||
|
||
uint32_t address_offset = address & 0x000000FF;
|
||
if (address_offset)
|
||
{
|
||
printf("\nsrio_write_data: Address 0x%08X non è multiplo di 256 byte",address);
|
||
return INPUT_NOT_VALID;
|
||
}
|
||
|
||
uint32_t buffer_size = 256/sizeof(unsigned int);
|
||
|
||
unsigned int* buffer;
|
||
buffer = (unsigned int*)malloc(256);
|
||
if (!buffer) {
|
||
perror("Errore nell'allocazione del buffer");
|
||
free(buffer);
|
||
return GENERIC_ERROR;
|
||
}
|
||
|
||
if(data == NULL)
|
||
{
|
||
for (int i = 0; i < byte/4; i++)
|
||
{
|
||
buffer[i] = i;
|
||
}
|
||
//NWRITE_SRIO_TX
|
||
res = rio_nwrite( srio_id, //rio_id rid
|
||
endpoint, //uint16_t remote_endpoint_id
|
||
address, //void* remote_addr (the virtual machine is a 64bit operating system)
|
||
buffer, //void* sending_payload
|
||
buffer_size*4); //numCount*sizeof(uint32_t)); //size_t payload_size
|
||
}
|
||
else
|
||
{
|
||
res = rio_nwrite( srio_id, //rio_id rid
|
||
endpoint, //uint16_t remote_endpoint_id
|
||
address, //void* remote_addr (the virtual machine is a 64bit operating system)
|
||
data, //void* sending_payload
|
||
buffer_size*4); //numCount*sizeof(uint32_t)); //size_t payload_size
|
||
}
|
||
|
||
|
||
if (res != rio_ok)
|
||
{
|
||
printf("\nError writing to srio res=%d",res);
|
||
free(buffer);
|
||
return SRIO_WRITE_ERROR;
|
||
}
|
||
|
||
// Cleanup
|
||
free(buffer);
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
int srio_read_reg(uint16_t endpoint, uint32_t address, uint32_t byte) //fatto
|
||
{
|
||
/*printf("Endpoint: 0x%04x\n", endpoint);
|
||
printf("Address: 0x%08x\n", address);
|
||
printf("byte: %d\n", byte);*/
|
||
rio_result res;
|
||
|
||
uint32_t address_offset = address & 0x000000FF;
|
||
if (address_offset % 4)
|
||
{
|
||
printf("\nAddress 0x%08X non è multiplo di 4",address);
|
||
return INPUT_NOT_VALID;
|
||
}
|
||
|
||
uint32_t buffer_size = 256/sizeof(unsigned int);
|
||
|
||
unsigned int* buffer = (unsigned int*)malloc(256);
|
||
if (!buffer) {
|
||
perror("Errore nell'allocazione del buffer");
|
||
free(buffer);
|
||
return GENERIC_ERROR;
|
||
}
|
||
|
||
uint32_t address_aligned = address & 0xFFFFFF00;
|
||
|
||
res = rio_nread(srio_id, endpoint, address_aligned, buffer, buffer_size*4);
|
||
if (res != rio_ok) {
|
||
printf("\nErrore nella lettura da SRIO %d",res);
|
||
free(buffer);
|
||
return SRIO_READ_ERROR;
|
||
}
|
||
|
||
printf("\nRead Value: \n");
|
||
for (int i = 0; i < buffer_size; i=i+4)
|
||
{
|
||
printf("0x%08X 0x%08X 0x%08X 0x%08X \n", buffer[i], buffer[i+1], buffer[i+2], buffer[i+3]);
|
||
}
|
||
|
||
// Cleanup
|
||
free(buffer);
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////// MAIN MACRO ////////////////////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x01
|
||
# aspetta che il bit#11 di STATUS_REG va a 1
|
||
*/
|
||
int start_request(uint16_t endpoint){ //fatto
|
||
srio_write_reg(endpoint, CTRL_REG, 0x01);
|
||
srio_wait_reg(endpoint,STATUS_REG,11,1);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
# controlla che i bit #1 #4 #5 #6 #10 di STATUS_REG sono 0 altrimenti ferma tutto e riporta errore
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x00
|
||
# aspetta che il bit#11 di STATUS_REG va a 0
|
||
*/
|
||
int end_request(uint16_t endpoint){ //fatto
|
||
srio_wait_reg(endpoint,STATUS_REG,1,0);
|
||
srio_wait_reg(endpoint,STATUS_REG,4,0);
|
||
srio_wait_reg(endpoint,STATUS_REG,5,0);
|
||
srio_wait_reg(endpoint,STATUS_REG,6,0);
|
||
srio_wait_reg(endpoint,STATUS_REG,10,0);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x00);
|
||
srio_wait_reg(endpoint,STATUS_REG,11,0);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x03
|
||
# aspetta che il bit#12 di STATUS_REG va a 1
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x01
|
||
# aspetta che il bit#12 di STATUS_REG va a 0
|
||
END_REQUEST
|
||
*/
|
||
int write_data(uint16_t endpoint){ // fatto
|
||
srio_write_reg(endpoint, CTRL_REG, 0x03);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,1);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x01);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,0);
|
||
end_request(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
START_REQUEST
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x03
|
||
# aspetta che il bit#12 di STATUS_REG va a 1
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x01
|
||
# aspetta che il bit#12 di STATUS_REG va a 0
|
||
*/
|
||
int read_data(uint16_t endpoint){ //fatto
|
||
start_request(endpoint);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x03);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,1);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x01);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,0);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
START_REQUEST
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x03
|
||
# aspetta che il bit#12 di STATUS_REG va a 1
|
||
./SRIOwrite < SRIO ID > CTRL_REG 0x01
|
||
# aspetta che il bit#12 di STATUS_REG va a 0
|
||
END_REQUEST
|
||
*/
|
||
int send_request(uint16_t endpoint){ //fatto
|
||
start_request(endpoint);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x03);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,1);
|
||
srio_write_reg(endpoint, CTRL_REG, 0x01);
|
||
srio_wait_reg(endpoint,STATUS_REG,12,0);
|
||
end_request(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
///////////////////////////////////// GENERAL FUNCTIONS //////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x00
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x06
|
||
SEND_REQUEST
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x00
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x61
|
||
START_REQUEST
|
||
./SRIOwrite < SRIO ID > TX_FIFO_REG 0x6F
|
||
WRITE_DATA
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x02
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x06
|
||
SEND_REQUEST
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x02
|
||
./SRIOwrite < SRIO ID > CMD_REG 0xB7
|
||
*/
|
||
int op_init_qspi(uint16_t endpoint) //fatto
|
||
{
|
||
printf("\nop_init_qspi endpoint: 0x%04X\n", endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x00 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0x06);
|
||
send_request(endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x00 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0x61);
|
||
start_request(endpoint);
|
||
srio_write_reg(endpoint, TX_FIFO_REG, 0x6F);
|
||
write_data(endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x02 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0x06);
|
||
send_request(endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x02 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0xB7);
|
||
send_request(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x06
|
||
./SRIOwrite < SRIO ID > ADDR_REG < MEMORY ADDRESS >
|
||
./SRIOwrite < SRIO ID > NUM_BYTE_REG < NUM BYTE TO READ >
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x0B
|
||
READ_DATA
|
||
./SRIOread < SRIO ID > RX_FIFO_REG < DATA TO READ >
|
||
END_REQUEST
|
||
*/
|
||
int read_flash(uint16_t endpoint, uint32_t address, uint32_t byte) //fatto
|
||
{
|
||
printf("\nop_init_qspi endpoint: 0x%04X, address 0x%08X, byte: %d \n", endpoint, address, byte);
|
||
srio_write_reg(endpoint, MODE_REG, 0x06 + flashport);
|
||
srio_write_reg(endpoint, ADDR_REG, address);
|
||
srio_write_reg(endpoint, NUM_BYTE_REG, byte);
|
||
srio_write_reg(endpoint, CMD_REG, 0x0B);
|
||
read_data(endpoint);
|
||
srio_read_reg(endpoint, RX_FIFO_REG, byte);
|
||
end_request(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x06
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x05
|
||
READ_DATA
|
||
# aspetta che il bit#0 di RX_FIFO_REG va a 0
|
||
END_REQUEST
|
||
*/
|
||
int wait_flash(uint16_t endpoint) //fatto
|
||
{
|
||
int res = NO_ERROR;
|
||
|
||
//printf("\nwait_flash...\n");
|
||
res += srio_write_reg(endpoint, MODE_REG, 0x06 + flashport);
|
||
res += srio_write_reg(endpoint, CMD_REG, 0x05);
|
||
res += read_data(endpoint);
|
||
res += srio_wait_reg(endpoint,RX_FIFO_REG,0,0);
|
||
res += end_request(endpoint);
|
||
return res;
|
||
}
|
||
|
||
int wait_flash_with_retry(uint16_t endpoint,int max_retry, int timeout_us)
|
||
{
|
||
int res = NO_ERROR;
|
||
int i;
|
||
|
||
for ( i = 0; i < max_retry; i++)
|
||
{
|
||
res = wait_flash(endpoint);
|
||
if(res == NO_ERROR)
|
||
break;
|
||
usleep(timeout_us);
|
||
}
|
||
if (i == max_retry) printf("\nwait_flash exit: FAILED for max retry: %d\n",i);
|
||
//else printf("\nwait_flash exit: retry: %d\n",i);
|
||
|
||
return res;
|
||
}
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x02
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x06
|
||
SEND_REQUEST
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x06
|
||
./SRIOwrite < SRIO ID > ADDR_REG < MEMORY ADDRESS >
|
||
./SRIOwrite < SRIO ID > NUM_BYTE_REG < NUM BYTE TO WRITE >
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x02
|
||
START_REQUEST
|
||
./SRIOwrite < SRIO ID > TX_FIFO_REG < DATA TO WRITE >
|
||
# Per esempio:
|
||
# ./SRIOwrite < SRIO ID > TX_FIFO_REG 0x12345678 0xAABBCCDD 0x00112233 0x24681357 0x12345678 0xAABBCCDD 0x00112233 0x24681357
|
||
WRITE_DATA
|
||
*/
|
||
int write_flash(uint16_t endpoint, uint32_t address, uint32_t *data, uint32_t byte) //fatto
|
||
{
|
||
//printf("\nwrite_flash endpoint: 0x%04X, address 0x%08X, byte: %d \n", endpoint, address, byte);
|
||
srio_write_reg(endpoint, MODE_REG, 0x02 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0x06);
|
||
send_request(endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x06 + flashport);
|
||
srio_write_reg(endpoint, ADDR_REG, address);
|
||
srio_write_reg(endpoint, NUM_BYTE_REG, byte);
|
||
srio_write_reg(endpoint, CMD_REG, 0x02);
|
||
start_request(endpoint);
|
||
srio_write_data(endpoint, TX_FIFO_REG, data, 256);
|
||
write_data(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
/*
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x02
|
||
./SRIOwrite < SRIO ID > CMD_REG 0x06
|
||
SEND_REQUEST
|
||
./SRIOwrite < SRIO ID > MODE_REG 0x06
|
||
./SRIOwrite < SRIO ID > ADDR_REG < MEMORY ADDRESS >
|
||
./SRIOwrite < SRIO ID > NUM_BYTE_REG 0x00
|
||
./SRIOwrite < SRIO ID > CMD_REG 0xD8
|
||
SEND_REQUEST
|
||
*/
|
||
int erase_section(uint16_t endpoint, uint32_t address) //fatto
|
||
{
|
||
printf("\nerase_section endpoint: 0x%04X, address 0x%08X\n", endpoint, address);
|
||
srio_write_reg(endpoint, MODE_REG, 0x02 + flashport);
|
||
srio_write_reg(endpoint, CMD_REG, 0x06);
|
||
send_request(endpoint);
|
||
srio_write_reg(endpoint, MODE_REG, 0x06 + flashport);
|
||
srio_write_reg(endpoint, ADDR_REG, address);
|
||
srio_write_reg(endpoint, NUM_BYTE_REG, 0x00);
|
||
srio_write_reg(endpoint, CMD_REG, 0xD8);
|
||
send_request(endpoint);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
int main(int argc, char* argv[])
|
||
{
|
||
uint16_t endpoint;
|
||
uint32_t address;
|
||
uint32_t value;
|
||
rio_result res;
|
||
if (!parse_args(argc, argv, &endpoint, &address, &value)) {
|
||
return 1; // errore nei parametri
|
||
}
|
||
|
||
printf("Endpoint: 0x%04x\n", endpoint);
|
||
printf("Address: 0x%08x\n", address);
|
||
printf("Value: %d\n", value);
|
||
|
||
initSrio(&srio_id);
|
||
|
||
/*
|
||
erase_section(endpoint, 0x01F00000);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
erase_section(endpoint, 0x01F10000);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
erase_section(endpoint, 0x01F20000);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
|
||
write_flash(endpoint,0x01F00000,NULL,256);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
write_flash(endpoint,0x01F00100,NULL,256);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
write_flash(endpoint,0x01F00200,NULL,256);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
|
||
read_flash(endpoint, 0x01F00000, 256);
|
||
read_flash(endpoint, 0x01F00100, 256);
|
||
read_flash(endpoint, 0x01F00200, 256);
|
||
*/
|
||
|
||
std::cout << "insert download file: "<< std::endl;
|
||
|
||
std::string filename;
|
||
std::streamsize size = 0;
|
||
|
||
std::getline(std::cin, filename);
|
||
|
||
|
||
std::ifstream file(filename,std::ios::binary | std::ios::ate);
|
||
if (!file)
|
||
{
|
||
std::cerr <<"impossibile aprire il file\n";
|
||
close(srio_id);
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
size = file.tellg();
|
||
std::cout << "File Dimension: " << size << "bytes\n";
|
||
}
|
||
|
||
std::cout << "insert flash number ( primary : 0 , secondary : 1): ";
|
||
std::string line;
|
||
std::getline(std::cin,line);
|
||
try
|
||
{
|
||
flashport = std::stoul(line, nullptr,10);
|
||
if(flashport !=0 && flashport !=1)
|
||
{
|
||
std::cerr << "Flash number errato!" << '\n';
|
||
close(srio_id);
|
||
file.close();
|
||
exit(1);
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
std::cerr << "Numero non valido!" << '\n';
|
||
close(srio_id);
|
||
file.close();
|
||
}
|
||
|
||
if(flashport == 1) flashport = 8;
|
||
|
||
|
||
std::cout << "insert flash address (fomato esadecimale senza 0x): ";
|
||
//std::string line;
|
||
std::getline(std::cin,line);
|
||
|
||
unsigned int start_address_to_dwl;
|
||
try
|
||
{
|
||
start_address_to_dwl = std::stoul(line, nullptr,16);
|
||
}
|
||
catch(...)
|
||
{
|
||
std::cerr << "Numero esadecimale non valido!" << '\n';
|
||
close(srio_id);
|
||
file.close();
|
||
}
|
||
|
||
|
||
|
||
printf("\nIndirizzo inserito: 0x%08X\n",start_address_to_dwl);
|
||
std::cout << "Procediamo? (Ctrl+C per annullare)";
|
||
std::getline(std::cin,line);
|
||
|
||
|
||
|
||
op_init_qspi(endpoint);
|
||
op_init_qspi(endpoint);
|
||
read_flash(endpoint, address, 256);
|
||
|
||
std::cout << "Procediamo? (Ctrl+C per annullare)";
|
||
std::getline(std::cin,line);
|
||
|
||
|
||
//ERASE FULL SECTION
|
||
std::cout << "\nErasing memory...\n\n";
|
||
int i;
|
||
unsigned long start_address_to_erase = start_address_to_dwl;
|
||
for ( i = 0; i < size; i = i + ERASE_BLOCK_SIZE)
|
||
{
|
||
erase_section(endpoint, start_address_to_erase);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
|
||
start_address_to_erase += ERASE_BLOCK_SIZE;
|
||
if (start_address_to_erase > start_address_to_dwl+size)
|
||
start_address_to_erase = start_address_to_dwl+size;
|
||
std::cout << "\rErasing.. "
|
||
<< i << " / " << size
|
||
<< " byte"
|
||
<< std::flush;
|
||
}
|
||
|
||
|
||
std::cout << "Procediamo? (Ctrl+C per annullare)";
|
||
std::getline(std::cin,line);
|
||
|
||
//WRITE DATA
|
||
std::cout << "\nWriting memory...\n\n";
|
||
|
||
file.seekg(0, std::ios::beg); //puntiamo all'inizio del file
|
||
|
||
address = start_address_to_dwl;
|
||
std::streamsize bytes_read = 0;
|
||
std::streamsize bytes_written = 0;
|
||
while (file) {
|
||
file.read(reinterpret_cast<char*>(dwl_buffer), DWL_CHUNK_SIZE);
|
||
bytes_read = file.gcount();
|
||
|
||
if (bytes_read == 0)
|
||
break;
|
||
|
||
// Se l’ultimo blocco è < 256 byte, padding a zero
|
||
if (bytes_read < DWL_CHUNK_SIZE) {
|
||
std::memset(
|
||
reinterpret_cast<char*>(dwl_buffer) + bytes_read,
|
||
0,
|
||
DWL_CHUNK_SIZE - bytes_read
|
||
);
|
||
}
|
||
|
||
write_flash(endpoint, address, dwl_buffer, DWL_CHUNK_SIZE);
|
||
usleep(WRITE_DELAY_US*value);
|
||
wait_flash_with_retry(endpoint, MAX_RETRY_READ, 1000);
|
||
usleep(WAITFLASH_DELAY_US*value);
|
||
address += DWL_CHUNK_SIZE;
|
||
|
||
bytes_written += DWL_CHUNK_SIZE;
|
||
if (bytes_written > size)
|
||
bytes_written = size;
|
||
std::cout << "\rWriting "
|
||
<< bytes_written << " / " << size
|
||
<< " byte"
|
||
<< " address: " << std::hex << address
|
||
<< std::flush;
|
||
|
||
}
|
||
|
||
std::cout << std::endl;
|
||
|
||
|
||
file.close();
|
||
|
||
close(srio_id);
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
per tutte le altre "aspetta" bisogna rileggere lo stesso registro con nread, non rifacendo tutta la macro
|
||
mi devo fermare subito se non va mai al valore
|
||
|
||
nell'endrequest la "controlla" controlla solamente e se c'è qualche errore si blocca tutto
|
||
*/
|
||
|
||
|
||
|