This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3874: Page Mode only reading half of the data it is supposed to.

Part Number: AM3874

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? 

 

  • Hi Krzysztof,

    Can you please try reading with a 64-bit datatype?
            uint64_t pDst = (uint64_t)&pDstBuff;

    Alternately, use DMA to read 4 words (64-bits).

    Do you only need to read 4 words page mode? I expect asynchronous writes will not support page mode.

    Regards,
    Mark