TS-4800 MUXBUS Access
From embeddedTS Manuals
On this board the MUXBUS memory window is available at 0xb0017000. The first 64KB of memwindow space are for using the external bus in 16 bit mode. The next 64KB are for the external bus in 8 bit mode.
Offset | Bits | Access | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0 | 15:0 | Read/Write | Address bits 26-11 | ||||||||||
0x2 | 15:14 | Read/Write |
| ||||||||||
13:12 | Read/Write |
| |||||||||||
11 | Read/Write | Auto increment enable [3] | |||||||||||
10:0 | Read/Write | Address bits 10-0 | |||||||||||
0x4 | 15:0 | Read/Write | Data register 1 [4] | ||||||||||
0x6 | 15:0 | Read/Write | Data register 2[4] |
- ↑ Write 1 16 bit data register to write 2x 8bit cycles.
- ↑ Write 2 16 bit values to perform 1 32 bit cycle.
- ↑ When accessing data register 2 the auto increment will step the address by the number of bytes written each time, otherwise writing multiple times will go to the same address.
- ↑ 4.0 4.1 Data register 1 and 2 both read/write to the same address, but data register 2 can auto increment the address from the number of bytes after each read/write cycle. Data register 1 will ignore 0x2 and will not increment the address.
Within this memory window there are two sets of addresses for 16-bit or 8-bit accesses.
Memory Window Address | Bit width |
---|---|
0x0000-0xFFFF | 16-bit |
0x10000-0x1FFFF | 8-bit |
At either the 16-bit 0x0000 or 8-bit 0x10000, these start at offset 0 on the bus and access the same address range. The below C example can access 8 and 16 bit registers on the muxbus:
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
static volatile uint16_t *mwin;
void mwinen()
{
int mem;
volatile uint16_t *syscon;
mem = open("/dev/mem", O_RDWR|O_SYNC);
syscon = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, mem, 0xb0010000);
mwin = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, mem, 0xb0017000);
assert(syscon != NULL);
assert(mwin != NULL);
// Set up muxbus timing register.
syscon[0x12/2] = 0x321;
close(mem);
}
uint16_t mwinpeek16(uint32_t addr)
{
mwin[0x0] = addr >> 11; // This register contains the upper bits of address
// Sets the remaining address bits, and requests a 16 bit bus cycle
mwin[0x2/2] = (addr & 0x7ff) | 0x8000;
return mwin[0x4/2];
}
void mwinpoke16(uint32_t addr, uint16_t value)
{
mwin[0x0] = addr >> 11;
mwin[0x2/2] = (addr & 0x7ff) | 0x8000;
mwin[0x4/2] = value;
}
uint8_t mwinpeek8(uint32_t addr)
{
// 8-bit addr starts 64k into the memory window
addr = 0x10000 | addr;
mwin[0x0] = addr >> 11;
// Similar to the 16 bit transactions, but requests 8 bit bus cycles
mwin[0x2/2] = (addr & 0x7ff) | 0xc000;
return mwin[0x4/2];
}
void mwinpoke8(uint32_t addr, uint8_t value)
{
// 8-bit addr starts 64k into the memory window
addr = 0x10000 | addr;
mwin[0x0] = addr >> 11;
mwin[0x2/2] = (addr & 0x7ff) | 0xc000;
mwin[0x4/2] = value;
}
int main(int argc, char **argv)
{
mwinen();
printf("16-bit read 0x0: 0x%x\n", mwinpeek16(0x0));
printf("8-bit read 0x0: 0x%x\n", mwinpeek8(0x0));
return 0;
}
Note that baseboards may use different offsets for 8-bit and 16-bit off-board peripherals such as PC104 devices.