kopia lustrzana https://github.com/cariboulabs/cariboulite
smi interface work in progress
rodzic
8861797758
commit
c7224f421a
|
@ -1,4 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(cariboulite)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
|
||||
#Bring the headers, such as Student.h into the project
|
||||
|
@ -8,13 +9,13 @@ include_directories(${SUPER_DIR})
|
|||
|
||||
#However, the file(GLOB...) allows for wildcard additions:
|
||||
set(SOURCES_LIB caribou_smi.c)
|
||||
set(SOURCES ${SOURCES_LIB} test_caribou_smi.c)
|
||||
set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a)
|
||||
|
||||
#Generate the static library from the sources
|
||||
add_library(caribou_smi STATIC ${SOURCES_LIB})
|
||||
target_include_directories(caribou_smi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_executable(test_caribou_smi test_caribou_smi.c)
|
||||
target_link_libraries(test_caribou_smi caribou_smi rt)
|
||||
add_executable(test_caribou_smi ${SOURCES})
|
||||
target_include_directories(test_caribou_smi rt pthread ${EXTERN_LIBS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
#Set the location for library installation -- i.e., /usr/lib in this case
|
||||
# not really necessary in this example. Use "sudo make install" to apply
|
||||
|
|
|
@ -1,9 +1,105 @@
|
|||
#include <stdio.h>
|
||||
#include "caribou_smi.h"
|
||||
|
||||
//=====================================================================
|
||||
void caribou_smi_map_devices(caribou_smi_st* dev)
|
||||
{
|
||||
// map_periph(&dev->gpio_regs, (void *)GPIO_BASE, PAGE_SIZE);
|
||||
map_periph(&dev->dma_regs, (void *)DMA_BASE, PAGE_SIZE);
|
||||
map_periph(&dev->clk_regs, (void *)CLK_BASE, PAGE_SIZE);
|
||||
map_periph(&dev->smi_regs, (void *)SMI_BASE, PAGE_SIZE);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
// Free memory segments and exit
|
||||
void caribou_smi_unmap_devices(caribou_smi_st* dev)
|
||||
{
|
||||
unmap_periph_mem(&dev->vc_mem);
|
||||
unmap_periph_mem(&dev->smi_regs);
|
||||
unmap_periph_mem(&dev->dma_regs);
|
||||
//unmap_periph_mem(&dev->gpio_regs);
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Initialise SMI, given data width, time step, and setup/hold/strobe counts
|
||||
// Step value is in nanoseconds: even numbers, 2 to 30
|
||||
void init_smi(caribou_smi_st* dev,
|
||||
int width,
|
||||
int ns,
|
||||
int setup,
|
||||
int strobe,
|
||||
int hold)
|
||||
{
|
||||
int divi = ns / 2;
|
||||
|
||||
dev->smi_cs = (SMI_CS_REG *) REG32(dev->smi_regs, SMI_CS);
|
||||
dev->smi_l = (SMI_L_REG *) REG32(dev->smi_regs, SMI_L);
|
||||
dev->smi_a = (SMI_A_REG *) REG32(dev->smi_regs, SMI_A);
|
||||
dev->smi_d = (SMI_D_REG *) REG32(dev->smi_regs, SMI_D);
|
||||
dev->smi_dmc = (SMI_DMC_REG *)REG32(dev->smi_regs, SMI_DMC);
|
||||
dev->smi_dsr = (SMI_DSR_REG *)REG32(dev->smi_regs, SMI_DSR0);
|
||||
dev->smi_dsw = (SMI_DSW_REG *)REG32(dev->smi_regs, SMI_DSW0);
|
||||
dev->smi_dcs = (SMI_DCS_REG *)REG32(dev->smi_regs, SMI_DCS);
|
||||
dev->smi_dca = (SMI_DCA_REG *)REG32(dev->smi_regs, SMI_DCA);
|
||||
dev->smi_dcd = (SMI_DCD_REG *)REG32(dev->smi_regs, SMI_DCD);
|
||||
dev->smi_cs->value = dev->smi_l->value = dev->smi_a->value = 0;
|
||||
dev->smi_dsr->value = dev->smi_dsw->value = dev->smi_dcs->value = dev->smi_dca->value = 0;
|
||||
if (*REG32(dev->clk_regs, CLK_SMI_DIV) != divi << 12)
|
||||
{
|
||||
*REG32(dev->clk_regs, CLK_SMI_CTL) = CLK_PASSWD | (1 << 5);
|
||||
usleep(10);
|
||||
while (*REG32(dev->clk_regs, CLK_SMI_CTL) & (1 << 7)) ;
|
||||
usleep(10);
|
||||
*REG32(dev->clk_regs, CLK_SMI_DIV) = CLK_PASSWD | (divi << 12);
|
||||
usleep(10);
|
||||
*REG32(dev->clk_regs, CLK_SMI_CTL) = CLK_PASSWD | 6 | (1 << 4);
|
||||
usleep(10);
|
||||
while ((*REG32(dev->clk_regs, CLK_SMI_CTL) & (1 << 7)) == 0) ;
|
||||
usleep(100);
|
||||
}
|
||||
if (dev->smi_cs->seterr)
|
||||
{
|
||||
dev->smi_cs->seterr = 1;
|
||||
}
|
||||
dev->smi_dsr->rsetup = dev->smi_dsw->wsetup = setup;
|
||||
dev->smi_dsr->rstrobe = dev->smi_dsw->wstrobe = strobe;
|
||||
dev->smi_dsr->rhold = dev->smi_dsw->whold = hold;
|
||||
dev->smi_dmc->panicr = dev->smi_dmc->panicw = 8;
|
||||
dev->smi_dmc->reqr = dev->smi_dmc->reqw = REQUEST_THRESH;
|
||||
dev->smi_dsr->rwidth = dev->smi_dsw->wwidth = width;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
int caribou_smi_init(caribou_smi_st* dev)
|
||||
{
|
||||
for (int i=0; i<ADC_NPINS; i++)
|
||||
{
|
||||
gpio_mode(ADC_D0_PIN+i, GPIO_IN);
|
||||
}
|
||||
gpio_mode(SMI_SOE_PIN, GPIO_ALT1);
|
||||
|
||||
init_smi(SMI_NUM_BITS, SMI_TIMING);
|
||||
|
||||
map_uncached_mem(&vc_mem, VC_MEM_SIZE(NSAMPLES+PRE_SAMP));
|
||||
dev->smi_dmc->dmaen = 1;
|
||||
dev->smi_cs->enable = 1;
|
||||
dev->smi_cs->clear = 1;
|
||||
|
||||
rxbuff = adc_dma_start(&vc_mem, NSAMPLES);
|
||||
smi_start(dev, NSAMPLES, 1);
|
||||
|
||||
while (dma_active(DMA_CHAN_A)) ;
|
||||
|
||||
adc_dma_end(dev, rxbuff, sample_data, NSAMPLES);
|
||||
|
||||
disp_reg_fields(smi_cs_regstrs, "CS", *REG32(dev->smi_regs, SMI_CS));
|
||||
dev->smi_cs->enable = dev->smi_dcs->enable = 0;
|
||||
for (int i=0; i<NSAMPLES; i++)
|
||||
{
|
||||
printf("%1.3f\n", val_volts(sample_data[i]));
|
||||
}
|
||||
|
||||
dev->initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,5 +113,149 @@ int caribou_smi_close(caribou_smi_st* dev)
|
|||
}
|
||||
|
||||
dev->initialized = 0;
|
||||
|
||||
if (dev->gpio_regs.virt)
|
||||
{
|
||||
for (int i=0; i<ADC_NPINS; i++)
|
||||
{
|
||||
gpio_mode(ADC_D0_PIN+i, GPIO_IN);
|
||||
}
|
||||
}
|
||||
if (dev->smi_regs.virt)
|
||||
{
|
||||
*REG32(dev->smi_regs, SMI_CS) = 0;
|
||||
}
|
||||
stop_dma(DMA_CHAN_A);
|
||||
caribou_smi_unmap_devices(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Start SMI, given number of samples, optionally pack bytes into words
|
||||
void caribou_smi_start(caribou_smi_st* dev, int nsamples, int pre_samp, int packed)
|
||||
{
|
||||
dev->smi_l->len = nsamples + pre_samp;
|
||||
dev->smi_cs->pxldat = (packed != 0);
|
||||
dev->smi_cs->enable = 1;
|
||||
dev->smi_cs->clear = 1;
|
||||
dev->smi_cs->start = 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Start DMA for SMI ADC, return Rx data buffer
|
||||
uint32_t *adc_dma_start(caribou_smi_mem_map_st *mp, int nsamp)
|
||||
{
|
||||
DMA_CB *cbs=mp->virt;
|
||||
uint32_t *data=(uint32_t *)(cbs+4), *pindata=data+8, *modes=data+0x10;
|
||||
uint32_t *modep1=data+0x18, *modep2=modep1+1, *rxdata=data+0x20, i;
|
||||
|
||||
// Get current mode register values
|
||||
for (i=0; i<3; i++)
|
||||
modes[i] = modes[i+3] = *REG32(gpio_regs, GPIO_MODE0 + i*4);
|
||||
// Get mode values with ADC pins set to SMI
|
||||
for (i=ADC_D0_PIN; i<ADC_D0_PIN+ADC_NPINS; i++)
|
||||
mode_word(&modes[i/10], i%10, GPIO_ALT1);
|
||||
// Copy mode values into 32-bit words
|
||||
*modep1 = modes[1];
|
||||
*modep2 = modes[2];
|
||||
*pindata = 1 << TEST_PIN;
|
||||
enable_dma(DMA_CHAN_A);
|
||||
// Control blocks 0 and 1: enable SMI I/P pins
|
||||
cbs[0].ti = DMA_SRCE_DREQ | (DMA_SMI_DREQ << 16) | DMA_WAIT_RESP;
|
||||
#if USE_TEST_PIN
|
||||
cbs[0].tfr_len = 4;
|
||||
cbs[0].srce_ad = MEM_BUS_ADDR(mp, pindata);
|
||||
cbs[0].dest_ad = REG_BUS_ADDR(gpio_regs, GPIO_SET0);
|
||||
cbs[0].next_cb = MEM_BUS_ADDR(mp, &cbs[2]);
|
||||
#else
|
||||
cbs[0].tfr_len = 4;
|
||||
cbs[0].srce_ad = MEM_BUS_ADDR(mp, modep1);
|
||||
cbs[0].dest_ad = REG_BUS_ADDR(gpio_regs, GPIO_MODE0+4);
|
||||
cbs[0].next_cb = MEM_BUS_ADDR(mp, &cbs[1]);
|
||||
#endif
|
||||
cbs[1].tfr_len = 4;
|
||||
cbs[1].srce_ad = MEM_BUS_ADDR(mp, modep2);
|
||||
cbs[1].dest_ad = REG_BUS_ADDR(gpio_regs, GPIO_MODE0+8);
|
||||
cbs[1].next_cb = MEM_BUS_ADDR(mp, &cbs[2]);
|
||||
// Control block 2: read data
|
||||
cbs[2].ti = DMA_SRCE_DREQ | (DMA_SMI_DREQ << 16) | DMA_CB_DEST_INC;
|
||||
cbs[2].tfr_len = (nsamp + PRE_SAMP) * SAMPLE_SIZE;
|
||||
cbs[2].srce_ad = REG_BUS_ADDR(smi_regs, SMI_D);
|
||||
cbs[2].dest_ad = MEM_BUS_ADDR(mp, rxdata);
|
||||
cbs[2].next_cb = MEM_BUS_ADDR(mp, &cbs[3]);
|
||||
// Control block 3: disable SMI I/P pins
|
||||
cbs[3].ti = DMA_CB_SRCE_INC | DMA_CB_DEST_INC;
|
||||
#if USE_TEST_PIN
|
||||
cbs[3].tfr_len = 4;
|
||||
cbs[3].srce_ad = MEM_BUS_ADDR(mp, pindata);
|
||||
cbs[3].dest_ad = REG_BUS_ADDR(gpio_regs, GPIO_CLR0);
|
||||
#else
|
||||
cbs[3].tfr_len = 3 * 4;
|
||||
cbs[3].srce_ad = MEM_BUS_ADDR(mp, &modes[3]);
|
||||
cbs[3].dest_ad = REG_BUS_ADDR(gpio_regs, GPIO_MODE0);
|
||||
#endif
|
||||
start_dma(mp, DMA_CHAN_A, &cbs[0], 0);
|
||||
return(rxdata);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// ADC DMA is complete, get data
|
||||
int adc_dma_end(void *buff, uint16_t *data, int nsamp)
|
||||
{
|
||||
uint16_t *bp = (uint16_t *)buff;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nsamp+PRE_SAMP; i++)
|
||||
{
|
||||
if (i >= PRE_SAMP)
|
||||
*data++ = bp[i] >> 4;
|
||||
}
|
||||
return(nsamp);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Display bit values in register
|
||||
void caribou_smi_disp_reg_fields(char *regstrs, char *name, uint32_t val)
|
||||
{
|
||||
char *p=regstrs, *q, *r=regstrs;
|
||||
uint32_t nbits, v;
|
||||
|
||||
printf("%s %08X", name, val);
|
||||
while ((q = strchr(p, ':')) != 0)
|
||||
{
|
||||
p = q + 1;
|
||||
nbits = 0;
|
||||
while (*p>='0' && *p<='9')
|
||||
nbits = nbits * 10 + *p++ - '0';
|
||||
v = val & ((1 << nbits) - 1);
|
||||
val >>= nbits;
|
||||
if (v && *r!='_')
|
||||
printf(" %.*s=%X", q-r, r, v);
|
||||
while (*p==',' || *p==' ')
|
||||
p = r = p + 1;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Display SMI registers
|
||||
// SMI register names for diagnostic print
|
||||
static char *smi_regstrs[] = {
|
||||
"CS","LEN","A","D","DSR0","DSW0","DSR1","DSW1",
|
||||
"DSR2","DSW2","DSR3","DSW3","DMC","DCS","DCA","DCD",""
|
||||
};
|
||||
|
||||
void caribou_smi_disp_smi(caribou_smi_st* dev)
|
||||
{
|
||||
volatile uint32_t *p=REG32(dev->smi_regs, SMI_CS);
|
||||
int i=0;
|
||||
|
||||
while (smi_regstrs[i][0])
|
||||
{
|
||||
printf("%4s=%08X ", smi_regstrs[i++], *p++);
|
||||
if (i%8==0 || smi_regstrs[i][0]==0)
|
||||
printf("\n");
|
||||
}
|
||||
}
|
|
@ -1,10 +1,40 @@
|
|||
#ifndef __CARIBOU_SMI_H__
|
||||
#define __CARIBOU_SMI_H__
|
||||
|
||||
#include "caribou_smi_defs.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd; // File descriptor
|
||||
int h; // Memory handle
|
||||
int size; // Memory size
|
||||
void *bus; // Bus address
|
||||
void *virt; // Virtual address
|
||||
void *phys; // Physical address
|
||||
} caribou_smi_mem_map_st;
|
||||
|
||||
#define REG32(m, x) ((volatile uint32_t *)((uint32_t)(m.virt)+(uint32_t)(x)))
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int initialized;
|
||||
|
||||
extern caribou_smi_mem_map_st gpio_regs, dma_regs;
|
||||
caribou_smi_mem_map_st vc_mem, clk_regs, smi_regs;
|
||||
|
||||
volatile SMI_CS_REG *smi_cs;
|
||||
volatile SMI_L_REG *smi_l;
|
||||
volatile SMI_A_REG *smi_a;
|
||||
volatile SMI_D_REG *smi_d;
|
||||
volatile SMI_DMC_REG *smi_dmc;
|
||||
volatile SMI_DSR_REG *smi_dsr;
|
||||
volatile SMI_DSW_REG *smi_dsw;
|
||||
volatile SMI_DCS_REG *smi_dcs;
|
||||
volatile SMI_DCA_REG *smi_dca;
|
||||
volatile SMI_DCD_REG *smi_dcd;
|
||||
|
||||
} caribou_smi_st;
|
||||
|
||||
int caribou_smi_init(caribou_smi_st* dev);
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
#ifndef __CARIBOU_SMI_DEFS_H__
|
||||
#define __CARIBOU_SMI_DEFS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// Location of peripheral registers in physical memory
|
||||
//#define PHYS_REG_BASE 0x20000000 // Pi Zero or 1
|
||||
//#define PHYS_REG_BASE 0x3F000000 // Pi 2 or 3
|
||||
#define PHYS_REG_BASE 0xFE000000 // Pi 4
|
||||
|
||||
// Location of peripheral registers in bus memory
|
||||
#define BUS_REG_BASE 0x7E000000
|
||||
|
||||
|
||||
//==========================================================
|
||||
// SMI
|
||||
//==========================================================
|
||||
|
||||
// Register definitions
|
||||
#define SMI_BASE (PHYS_REG_BASE + 0x600000)
|
||||
#define SMI_CS 0x00 // Control & status
|
||||
#define SMI_L 0x04 // Transfer length
|
||||
#define SMI_A 0x08 // Address
|
||||
#define SMI_D 0x0c // Data
|
||||
#define SMI_DSR0 0x10 // Read settings device 0
|
||||
#define SMI_DSW0 0x14 // Write settings device 0
|
||||
#define SMI_DSR1 0x18 // Read settings device 1
|
||||
#define SMI_DSW1 0x1c // Write settings device 1
|
||||
#define SMI_DSR2 0x20 // Read settings device 2
|
||||
#define SMI_DSW2 0x24 // Write settings device 2
|
||||
#define SMI_DSR3 0x28 // Read settings device 3
|
||||
#define SMI_DSW3 0x2c // Write settings device 3
|
||||
#define SMI_DMC 0x30 // DMA control
|
||||
#define SMI_DCS 0x34 // Direct control/status
|
||||
#define SMI_DCA 0x38 // Direct address
|
||||
#define SMI_DCD 0x3c // Direct data
|
||||
#define SMI_FD 0x40 // FIFO debug
|
||||
#define SMI_REGLEN (SMI_FD * 4)
|
||||
|
||||
// Data widths
|
||||
#define SMI_8_BITS 0
|
||||
#define SMI_16_BITS 1
|
||||
#define SMI_18_BITS 2
|
||||
#define SMI_9_BITS 3
|
||||
|
||||
// DMA request
|
||||
#define DMA_SMI_DREQ 4
|
||||
|
||||
// Union of 32-bit value with register bitfields
|
||||
#define REG_DEF(name, fields) typedef union {struct {volatile uint32_t fields;}; volatile uint32_t value;} name
|
||||
|
||||
// Control and status register
|
||||
#define SMI_CS_FIELDS \
|
||||
enable:1, done:1, active:1, start:1, clear:1, write:1, _x1:2,\
|
||||
teen:1, intd:1, intt:1, intr:1, pvmode:1, seterr:1, pxldat:1, edreq:1,\
|
||||
_x2:8, _x3:1, aferr:1, txw:1, rxr:1, txd:1, rxd:1, txe:1, rxf:1
|
||||
REG_DEF(SMI_CS_REG, SMI_CS_FIELDS);
|
||||
|
||||
// Data length register
|
||||
#define SMI_L_FIELDS \
|
||||
len:32
|
||||
REG_DEF(SMI_L_REG, SMI_L_FIELDS);
|
||||
|
||||
// Address & device number
|
||||
#define SMI_A_FIELDS \
|
||||
addr:6, _x1:2, dev:2
|
||||
REG_DEF(SMI_A_REG, SMI_A_FIELDS);
|
||||
|
||||
// Data FIFO
|
||||
#define SMI_D_FIELDS \
|
||||
data:32
|
||||
REG_DEF(SMI_D_REG, SMI_D_FIELDS);
|
||||
|
||||
// DMA control register
|
||||
#define SMI_DMC_FIELDS \
|
||||
reqw:6, reqr:6, panicw:6, panicr:6, dmap:1, _x1:3, dmaen:1
|
||||
REG_DEF(SMI_DMC_REG, SMI_DMC_FIELDS);
|
||||
|
||||
// Device settings: read (1 of 4)
|
||||
#define SMI_DSR_FIELDS \
|
||||
rstrobe:7, rdreq:1, rpace:7, rpaceall:1, \
|
||||
rhold:6, fsetup:1, mode68:1, rsetup:6, rwidth:2
|
||||
REG_DEF(SMI_DSR_REG, SMI_DSR_FIELDS);
|
||||
|
||||
// Device settings: write (1 of 4)
|
||||
#define SMI_DSW_FIELDS \
|
||||
wstrobe:7, wdreq:1, wpace:7, wpaceall:1, \
|
||||
whold:6, wswap:1, wformat:1, wsetup:6, wwidth:2
|
||||
REG_DEF(SMI_DSW_REG, SMI_DSW_FIELDS);
|
||||
|
||||
// Direct control register
|
||||
#define SMI_DCS_FIELDS \
|
||||
enable:1, start:1, done:1, write:1
|
||||
REG_DEF(SMI_DCS_REG, SMI_DCS_FIELDS);
|
||||
|
||||
// Direct control address & device number
|
||||
#define SMI_DCA_FIELDS \
|
||||
addr:6, _x1:2, dev:2
|
||||
REG_DEF(SMI_DCA_REG, SMI_DCA_FIELDS);
|
||||
|
||||
// Direct control data
|
||||
#define SMI_DCD_FIELDS \
|
||||
data:32
|
||||
REG_DEF(SMI_DCD_REG, SMI_DCD_FIELDS);
|
||||
|
||||
// Debug register
|
||||
#define SMI_FLVL_FIELDS \
|
||||
fcnt:6, _x1:2, flvl:6
|
||||
REG_DEF(SMI_FLVL_REG, SMI_FLVL_FIELDS);
|
||||
|
||||
#define CLK_SMI_CTL 0xb0
|
||||
#define CLK_SMI_DIV 0xb4
|
||||
|
||||
|
||||
//==========================================================
|
||||
// DMA
|
||||
//==========================================================
|
||||
// DMA channels and data requests
|
||||
#define DMA_CHAN_A 10
|
||||
#define DMA_CHAN_B 11
|
||||
#define DMA_PWM_DREQ 5
|
||||
#define DMA_SPI_TX_DREQ 6
|
||||
#define DMA_SPI_RX_DREQ 7
|
||||
#define DMA_BASE (PHYS_REG_BASE + 0x007000)
|
||||
|
||||
// DMA register addresses offset by 0x100 * chan_num
|
||||
#define DMA_CS 0x00
|
||||
#define DMA_CONBLK_AD 0x04
|
||||
#define DMA_TI 0x08
|
||||
#define DMA_SRCE_AD 0x0c
|
||||
#define DMA_DEST_AD 0x10
|
||||
#define DMA_TXFR_LEN 0x14
|
||||
#define DMA_STRIDE 0x18
|
||||
#define DMA_NEXTCONBK 0x1c
|
||||
#define DMA_DEBUG 0x20
|
||||
#define DMA_REG(ch, r) ((r)==DMA_ENABLE ? DMA_ENABLE : (ch)*0x100+(r))
|
||||
#define DMA_ENABLE 0xff0
|
||||
|
||||
// DMA register values
|
||||
#define DMA_WAIT_RESP (1 << 3)
|
||||
#define DMA_CB_DEST_INC (1 << 4)
|
||||
#define DMA_DEST_DREQ (1 << 6)
|
||||
#define DMA_CB_SRCE_INC (1 << 8)
|
||||
#define DMA_SRCE_DREQ (1 << 10)
|
||||
#define DMA_PRIORITY(n) ((n) << 16)
|
||||
|
||||
// Size of memory page
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
// Round up to nearest page
|
||||
#define PAGE_ROUNDUP(n) ((n)%PAGE_SIZE==0 ? (n) : ((n)+PAGE_SIZE)&~(PAGE_SIZE-1))
|
||||
|
||||
//==========================================================
|
||||
// CLOCK
|
||||
//==========================================================
|
||||
// Clock registers and values
|
||||
#define CLK_BASE (PHYS_REG_BASE + 0x101000)
|
||||
#define CLK_PWM_CTL 0xa0
|
||||
#define CLK_PWM_DIV 0xa4
|
||||
#define CLK_PASSWD 0x5a000000
|
||||
#define PWM_CLOCK_ID 0xa
|
||||
|
||||
#endif // __CARIBOU_SMI_DEFS_H__
|
Ładowanie…
Reference in New Issue