I'm trying to access a 16 bit fully multiplexed 64k CPLD which is hooked up to the external bus interface on chip select 0. I am using the TWR-K60F120M and MQX 4.1. The following code runs in a standard task.
#define A2D_CPLD_START_ADDRESS (*(volatile unsigned char*)(0xA0000000))
void flexbus_init(void) {
SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK; // Enable the clock to the FlexBus
SIM_CLKDIV1 |= SIM_CLKDIV1_OUTDIV3(0); // no divisor
// Set the GPIO ports clocks
SIM_SCGC5 = SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK;
// 16 bit multiplexing - so set 16 bit address, latch, then those 16 bits become data lines
PORTB_PCR18 = PORT_PCR_MUX(5); // fb_ad[15]
PORTC_PCR0 = PORT_PCR_MUX(5); // fb_ad[14]
PORTC_PCR1 = PORT_PCR_MUX(5); // fb_ad[13]
PORTC_PCR2 = PORT_PCR_MUX(5); // fb_ad[12]
PORTC_PCR4 = PORT_PCR_MUX(5); // fb_ad[11]
PORTC_PCR5 = PORT_PCR_MUX(5); // fb_ad[10]
PORTC_PCR6 = PORT_PCR_MUX(5); // fb_ad[9]
PORTC_PCR7 = PORT_PCR_MUX(5); // fb_ad[8]
PORTC_PCR8 = PORT_PCR_MUX(5); // fb_ad[7]
PORTC_PCR9 = PORT_PCR_MUX(5); // fb_ad[6]
PORTC_PCR10 = PORT_PCR_MUX(5); // fb_ad[5]
PORTD_PCR2 = PORT_PCR_MUX(5); // fb_ad[4]
PORTD_PCR3 = PORT_PCR_MUX(5); // fb_ad[3]
PORTD_PCR4 = PORT_PCR_MUX(5); // fb_ad[2]
PORTD_PCR5 = PORT_PCR_MUX(5); // fb_ad[1]
PORTD_PCR6 = PORT_PCR_MUX(5); // fb_ad[0]
// Other lines - Output Enable, Read/Write, ChipSelect0, Address Latch Enable
PORTB_PCR19 = PORT_PCR_MUX(5); // fb_oe_b [nEBI_OE]
PORTC_PCR11 = PORT_PCR_MUX(5); // fb_rw_b [EBI_R/W]
PORTD_PCR1 = PORT_PCR_MUX(5); // fb_cs0_b [nEBI_CSO]
PORTD_PCR0 = PORT_PCR_MUX(5); // fb_ale [EBI_ALE/nEBI_CSI]
// Setup the chip select 1 control register (see K60P144M150SF3RM.pdf, section 33.3.3)
FB_CSCR0 = FB_CSCR_PS(0x2) // 16-bit port
//| FB_CSCR_BLS_MASK // data is right shifted, i.e. appears on bits 0-15
| FB_CSCR_EXTS_MASK
| FB_CSCR_AA_MASK // auto-acknowledge...
| FB_CSCR_WS(0x2) // ...after 2 wait states
| FB_CSCR_ASET(2) // assert chip select on 2nd clock edge after address
;
// Chip select mask register
FB_CSMR0 = FB_CSMR_BAM(0x0) //Set base address mask for 64K address space
| FB_CSMR_V_MASK
;
// Chip select address register
FB_CSAR0 = (unsigned int)&A2D_CPLD_START_ADDRESS; //Set Base address
}
void flexbus_read_card_info() {
volatile uint16_t raw_ID;
_dcache_disable(); // see https://community.freescale.com/thread/306380
raw_ID = (*(uint16_t*)(&A2D_CPLD_START_ADDRESS));
printf("Raw ID: %d\n", raw_ID);
}
The task runs flexbus_init, then flexbus_read_card_info. Whatever I do, raw_ID seems to come out as 40960, i.e. 0xa000. The value should actually be 0x81 (which is stored in the CPLD).
I also noticed in the bsp_twrk60f120m code, in init_hw.c it calls a function _bsp_flexbus_mram_setup which also sets up chip select 0; I have tried commenting out this function call but it makes no difference.