Firstly, a quote from the Manual regarding Page Mode:
"Figure 11-26 shows an asynchronous multiple read operation on a Nonmultiplexed Device, in which two word32 host read accesses to the GPMC are split into one multiple (page mode of 4 word 16) read access to the attached device."
link: https://www.ti.com/lit/ug/sprugz7e/sprugz7e.pdf?ts=1655806231947&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FAM3874 (chapter 11.2.4.10.3.3)
The problem summary:
When we turn on Page mode on Asynchronous Multiple Read for Non-multiplexed device we receive two 16bit words instead of four. We can’t read the last two.
Our Registers are set like this:
GPMC_CS_CONFIG1: GPMC_CONFIG1_READMULTIPLE_SUPP | GPMC_CONFIG1_DEVICETYPE_NOR | GPMC_CONFIG1_DEVICESIZE_16
GPMC_CS_CONFIG2: GPMC_CFG2_CSWROFFTIME(5) | GPMC_CFG2_CSRDOFFTIME(5) | GPMC_CFG2_CSONTIME(0)
GPMC_CS_CONFIG3: zeros
GPMC_CS_CONFIG4: GPMC_CFG4_WEOFFTIME(5) | GPMC_CFG4_WEONTIME(0) | GPMC_CFG4_OEOFFTIME(5) | GPMC_CFG4_OEONTIME(0)
GPMC_CS_CONFIG5: GPMC_CFG5_PAGEBURSTACCESSTIME(1) | GPMC_CFG5_RDACCESSTIME(4) | GPMC_CFG5_WRCYCLETIME(5) | GPMC_CFG5_RDCYCLETIME(5)
GPMC_CS_CONFIG6: GPMC_CFG6_WRACCESSTIME(5) | GPMC_CFG6_CYCLE2CYCLEDELAY(5) | GPMC_CFG6_CYCLE2CYCLESAMECSEN | GPMC_CFG6_CYCLE2CYCLEDIFFCSEN | GPMC_CFG6_BUSTURNAROUND(5)
From FPGA side of the project:
signal test_data : std_logic_vector(15 downto 0 ) := x"1137";
...
if (sig_gpmc_ncs = '0' and sig_gpmc_nre = '0' AND sig_gpmc_nwe = '1' and sig_gmpc_a(7 downto 0) = DOUBLE_WORD_REG) then
sig_state <= ST_READ_DOUBLE_WORD_REG;
sig_control_reg <= sig_control_reg;
sig_gpmc_d_in <= test_data_mod;
test_data_mod <= std_logic_vector(to_unsigned(to_integer(unsigned( test_data_mod )) + 1, 16));
So, basically register DOUBLE_WORD_REG has incremented value with every clk cycle, starting from 1137.
Our reader in C:
#define GPMC 0x1000000
#define GPMC_SIZE 0x1F000000
#define ITERATIONS 1000000
...
//all registers
struct mainboard_fpga_t {
uint32_t revision_reg;
uint32_t control_status_reg;
uint32_t gtp_rxstatus_reg;
uint32_t gtp_rxfifo_empty_reg;
uint32_t gtp_rxfifo_full_reg;
uint32_t gtp_txstatus_reg;
uint32_t gtp_txfifo_empty_reg;
uint32_t gtp_txfifo_full_reg;
uint32_t gtp_rxfifo_count_regs[8];
uint32_t gtp_fifo_data_regs[8];
uint32_t gtp_broadcast_data_reg;
uint32_t test_reg; <-thats DOUBLE_WORD_REG
uint32_t test_reg2;
uint32_t test_reg3;
uint32_t test_reg4;
uint32_t test_reg5;
};
…
int main(int argc, char **argv) {
int fd;
volatile uint32_t *gpmc_ptr;
volatile struct mainboard_fpga_t *s;
fd = open("/dev/mem", O_RDWR | O_SYNC);
...
gpmc_ptr = (volatile uint32_t*) mmap(0, GPMC_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPMC);
...
s= (volatile struct mainboard_fpga_t*)gpmc_ptr;
...
printf("0x%08x\n",s->test_reg);
printf("0x%08x\n",s->gtp_broadcast_data_reg);
printf("0x%08x\n",s->test_reg2);
printf("0x%08x\n",s->test_reg3);
Results:
11381137
00000000
00000000
00000000
Question: On oscilloscope we have 6 cycles read, which means that we are reading two words. How can we read four? How to call two 32-bit readings in C to force a reading of 4 words?