Commit 0f612e39 authored by Lucas Russo's avatar Lucas Russo

Merge branch 'emb-sw-devel' into wb-fmc516-devel

parents 9e46e4ab ccc7d66e
......@@ -9,6 +9,8 @@ CONFIG_PPRINTF =? 1
#endif
CONFIG_ETHERBONE =? 1
CONFIG_FMC150 ?= 1
CONFIG_FMC516 ?= 1
# and don't touch the rest unless you know what you're doing.
CROSS_COMPILE ?= lm32-elf-
......@@ -26,6 +28,8 @@ OBJS_DBE = dbe_main.o
INCLUDE_DIRS = -Iinclude \
-Iinclude/memmgr \
-Iinclude/fmc/fmc150 \
-Iinclude/fmc/fmc516 \
-I$(CURDIR)/pp_printf \
-I$(CURDIR)/lib \
-I$(CURDIR)/lib/ethmac
......@@ -49,6 +53,7 @@ include lib/lib.mk
include dev/dev.mk
include pp_printf/printf.mk
include boards/boards.mk
include fmc/fmc.mk
CFLAGS += $(CFLAGS_PLATFORM) $(CFLAGS_EB) $(INCLUDE_DIRS) \
$(CFLAGS_MEMMGR) $(CFLAGS_DEBUG) -ffunction-sections -fdata-sections \
......@@ -59,7 +64,7 @@ LDFLAGS = $(LDFLAGS_PLATFORM) \
OBJS = $(OBJS_PLATFORM) $(OBJS_DBE) \
$(OBJS_SHELL) $(OBJS_TESTS) $(OBJS_LIB) \
$(OBJS_DEV) $(OBJS_BOARD)
$(OBJS_DEV) $(OBJS_BOARD) $(OBJS_FMC)
OUTPUT = dbe
#OUTPUT = dbe_test
......
......@@ -16,7 +16,7 @@
// dynamic defined through SDB
//#define ETH0_BASE 0x30015000U //ethmac_devl
//#define ETH0_BUF 0x20000000U //ethmac_buf_devl
#define ETH0_BASE 0x70000000U //ethmac_devl
#define ETH0_BASE 0x30005000U //ethmac_devl
#define ETH0_BUF 0x20000000U //ethmac_buf_devl
#define ETH0_IRQ 0
//#define ETH0_PHY 0
......@@ -52,6 +52,30 @@
#define OETH_RX_BUFF_SIZE BUFF_SIZE
#define OETH_TX_BUFF_SIZE BUFF_SIZE
/****************************/
/* IDs */
/****************************/
/*
* IDs of general components
*/
#define GEN_LED_GPIO_ID 0
#define GEN_BUTTON_GPIO_ID 1
#define FMC150_ID 0
#define FMC516_ID 0
#define TICS_ID 0
/*
* IDs of FMC516 components
*/
#define FMC516_SYS_I2C_ID 0
#define FMC516_VCXO_I2C_ID 1
#define FMC516_ISLA216P25_SPI_ID 0
#define FMC516_LMK02000_SPI_ID 1
#define FMC516_DS2431_OWR_ID 0
#define FMC516_DS2432_OWR_ID 1
int board_init();
int board_update();
......
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "components.h"
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef _COMPONENTS_H_
#define _COMPONENTS_H_
#include <inttypes.h>
struct dev_components_t
{
uint8_t id;
};
#endif
This diff is collapsed.
#include "gpio.h" // GPIO device funtions
#include "gpio.h" // GPIO device funtions
#include "i2c.h" // I2V device functions
#include "onewire.h" // Onewire device functions
#include "dma.h" // DMA device functions
#include "fmc150.h" // FMC150 device functions
//#include "fmc150.h" // FMC150 device functions
#include "fmc516.h" // FMC516 device functions
#include "uart.h" // UART device functions
#include "memmgr.h" // memory pool functions
#include "board.h" // board definitions
......@@ -26,20 +29,13 @@
#define NUM_LEDS 8
#define NUM_LED_ITER 4
#define NUM_FMC150_TRIES 5
//#define NUM_FMC150_TRIES 5
/* Ethernet MAC + Etherbone testing */
//unsigned char myIP[] = { 10, 0, 18, 100 };
//unsigned char myMAC[] = { ETH_MACADDR0, ETH_MACADDR1, ETH_MACADDR2, ETH_MACADDR3, ETH_MACADDR4, ETH_MACADDR5 };
//unsigned char allMAC[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/* His info */
//volatile int sawARP = 0;
//volatile static int sawPING = 0;
//volatile static int hisBodyLen;
//static unsigned char hisBody[1516];
//unsigned char hisIP[4];
//unsigned char hisMAC[6];
#define NUM_BUTTONS 8
#define TEST_BUTTONS_MASK 0x00000003
#define TEST_BUTTONS_TRIES 10
#define TEST_BUTTONS_ITER 2
#define TEST_BUTTONS_DELAY (100000000/4/5)
static volatile int eb_done;
......@@ -133,9 +129,9 @@ void user_recv(unsigned char* data, int length) {
eb_done = 0;
//ethmac_adapt->length = iplen + 16;
ethmac_adapt_set_length(iplen + 16);
ethmac_adapt_set_length(0, iplen + 16);
//ethmac_adapt->doit = 1;
ethmac_adapt_go();
ethmac_adapt_go(0);
while (!eb_done);
dbg_print("> EBONE request\n");
......@@ -183,15 +179,30 @@ int dbe_init(void)
return -1;
}
if(spi_init() == -1){
pp_printf("> error initializing SPI! Exiting...\n");
return -1;
}
if(i2c_init() == -1){
pp_printf("> error initializing I2C! Exiting...\n");
return -1;
}
if(owr_init() == -1){
pp_printf("> error initializing Onewire! Exiting...\n");
return -1;
}
//if(fmc150_init() == -1){
// pp_printf("> Error initializing FMC150! Exiting...\n");
// return -1;
//}
//if(fmc516_init() == -1){
// pp_printf("> Error initializing FMC516! Exiting...\n");
// return -1;
//}
if(fmc516_init() == -1){
pp_printf("> Error initializing FMC516! Exiting...\n");
return -1;
}
// Ethernet initilization
if(ethmac_adapt_init() == -1){
......@@ -208,6 +219,16 @@ int dbe_init(void)
return 0;
}
int dbe_exit()
{
gpio_exit();
uart_exit();
fmc516_exit();
//always succeeds
return 0;
}
void print_header(void)
{
pp_printf("-------------------------------------------\n");
......@@ -259,11 +280,12 @@ void leds_test(void)
pp_printf("-------------------------------------------\n\n");
pp_printf("leds_test:\n");
pp_printf("> blinking leds\n");
/* Rotate the LEDs */
for ( j = 0; j < NUM_LED_ITER; ++j)
for (i = 0; i < NUM_LEDS; ++i){
// Set led at position i
gpio_out(i, 1);
gpio_out(0, i, 1);
/* Each loop iteration takes 4 cycles.
* It runs at 100MHz.
......@@ -272,15 +294,53 @@ void leds_test(void)
delay(LED_DELAY);
// Clear led at position i
gpio_out(i, 0);
gpio_out(0, i, 0);
}
pp_printf("> testing leds\n");
// End test with 4 leds set
gpio_out(0, 1);
gpio_out(2, 1);
gpio_out(4, 1);
gpio_out(6, 1);
gpio_out(0, 0, 1);
gpio_out(0, 2, 1);
gpio_out(0, 4, 1);
gpio_out(0, 6, 1);
pp_printf("> test passed!\n");
}
void button_test()
{
int i, j;
unsigned int button_pressed = 0;
pp_printf("-------------------------------------------\n");
pp_printf("| Button test |\n");
pp_printf("-------------------------------------------\n\n");
pp_printf("buttons_test:\n");
pp_printf("> press (switch) buttons ");
for (i = 0; i < TEST_BUTTONS_ITER-1; ++i)
pp_printf("%d, ", i);
pp_printf("%d\n", TEST_BUTTONS_ITER);
for (i = 0; i < TEST_BUTTONS_TRIES; ++i) {
for (j = 0; j < TEST_BUTTONS_ITER; ++j) {
if ((!(button_pressed & (0x1 << j))) & gpio_in(1, j)) {
button_pressed |= 1 << j;
pp_printf("button%d pressed!\n", j);
}
}
if (button_pressed == TEST_BUTTONS_MASK) {
pp_printf("> test passed!\n");
return;
}
pp_printf("> remaining time to press buttons: %ds\n", (TEST_BUTTONS_TRIES-i));
delay(TEST_BUTTONS_DELAY);
}
pp_printf("> test failed!\n");
}
//void fmc150_test()
......@@ -299,6 +359,124 @@ void leds_test(void)
// pp_printf("> FMC150 CDCE72010 initialized\n");
//}
void print_fmc516_data(unsigned int id)
{
pp_printf("> ADC data0 %d\n", fmc516_read_adc0(DEFAULT_FMC516_ID));
delay(LED_DELAY+32);
pp_printf("> ADC data0 %d\n", fmc516_read_adc0(DEFAULT_FMC516_ID));
delay(LED_DELAY+124);
pp_printf("> ADC data0 %d\n", fmc516_read_adc0(DEFAULT_FMC516_ID));
delay(LED_DELAY+1);
pp_printf("> ADC data0 %d\n", fmc516_read_adc0(DEFAULT_FMC516_ID));
delay(LED_DELAY);
pp_printf("> ADC data0 %d\n", fmc516_read_adc0(DEFAULT_FMC516_ID));
delay(LED_DELAY+12384);
pp_printf("> ADC data1 %d\n", fmc516_read_adc1(DEFAULT_FMC516_ID));
delay(LED_DELAY+32);
pp_printf("> ADC data1 %d\n", fmc516_read_adc1(DEFAULT_FMC516_ID));
delay(LED_DELAY+124);
pp_printf("> ADC data1 %d\n", fmc516_read_adc1(DEFAULT_FMC516_ID));
delay(LED_DELAY+1);
pp_printf("> ADC data1 %d\n", fmc516_read_adc1(DEFAULT_FMC516_ID));
delay(LED_DELAY);
pp_printf("> ADC data1 %d\n", fmc516_read_adc1(DEFAULT_FMC516_ID));
delay(LED_DELAY+12384);
pp_printf("> ADC data2 %d\n", fmc516_read_adc2(DEFAULT_FMC516_ID));
delay(LED_DELAY+32);
pp_printf("> ADC data2 %d\n", fmc516_read_adc2(DEFAULT_FMC516_ID));
delay(LED_DELAY+124);
pp_printf("> ADC data2 %d\n", fmc516_read_adc2(DEFAULT_FMC516_ID));
delay(LED_DELAY+1);
pp_printf("> ADC data2 %d\n", fmc516_read_adc2(DEFAULT_FMC516_ID));
delay(LED_DELAY);
pp_printf("> ADC data2 %d\n", fmc516_read_adc2(DEFAULT_FMC516_ID));
delay(LED_DELAY+456);
pp_printf("> ADC data3 %d\n", fmc516_read_adc3(DEFAULT_FMC516_ID));
delay(LED_DELAY+32);
pp_printf("> ADC data3 %d\n", fmc516_read_adc3(DEFAULT_FMC516_ID));
delay(LED_DELAY+124);
pp_printf("> ADC data3 %d\n", fmc516_read_adc3(DEFAULT_FMC516_ID));
delay(LED_DELAY+1);
pp_printf("> ADC data3 %d\n", fmc516_read_adc3(DEFAULT_FMC516_ID));
delay(LED_DELAY);
pp_printf("> ADC data3 %d\n", fmc516_read_adc3(DEFAULT_FMC516_ID));
delay(LED_DELAY+79);
}
void fmc516_test()
{
int i;
pp_printf("-------------------------------------------\n");
pp_printf("| FMC516 test |\n");
pp_printf("-------------------------------------------\n\n");
pp_printf("> FMC516 ADCs info...\n");
//pp_printf("> FMC516 ADCs resetting...\n");
//delay(LED_DELAY);
//fmc516_reset_adcs(FMC516_ID);
//delay(LED_DELAY);
for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
pp_printf("> FMC516_ISLA216_ADC%d calibration progress...\n", i);
while(!(fmc516_isla216_chkcal_stat(i)));
pp_printf("done\n");
}
//for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
// pp_printf("> FMC516_ISLA216_ADC%d port_config: %d\n",
// i, fmc516_isla216_read_byte(0x00, i));
//}
//
//for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
// pp_printf("> FMC516_ISLA216_ADC%d user_pat: %d\n",
// i, fmc516_isla216_read_byte(0xC1, i));
//}
for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
pp_printf("> FMC516_ISLA216_ADC%d chip id: %d\n",
i, fmc516_isla216_get_chipid(i));
}
for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
pp_printf("> FMC516_ISLA216_ADC%d chip version: %d\n",
i, fmc516_isla216_get_chipver(i));
}
for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
pp_printf("> FMC516_ISLA216_ADC%d test mode off\n", i);
fmc516_isla216_write_byte(ISLA216_OUT_TESTMODE(ISLA216_OUT_TESTIO_OFF),
ISLA216_TESTIO_REG, i);
}
//for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
// fmc516_isla216_test_ramp(i);
// pp_printf("> FMC516_ISLA216_ADC%d: ramp test enabled!\n", i);
//}
//for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
// fmc516_isla216_test_midscale(i);
// pp_printf("> FMC516_ISLA216_ADC%d: test miscale enabled!\n", i);
//}
for (i = 0; i < FMC516_NUM_ISLA216; ++i) {
pp_printf("> FMC516_ISLA216_ADC%d: testio reg: 0X%8X\n", i,
fmc516_isla216_read_byte(ISLA216_TESTIO_REG, i));
}
//print_fmc516_data(DEFAULT_FMC516_ID);
dbg_print("> initilizing fmc516 delays\n");
fmc516_sweep_delays(DEFAULT_FMC516_ID);
pp_printf("> test finished...\n");
}
int main(void)
{
// Board initialization
......@@ -322,7 +500,7 @@ int main(void)
/* clear tx_done, the tx interrupt handler will set it when it's been transmitted */
/* Configure EB DMA */
ethmac_adapt_set_base((unsigned int)hisBody, (unsigned int)hisBody);
ethmac_adapt_set_base(0, (unsigned int)hisBody, (unsigned int)hisBody);
int_add(4, &set_eb_done, 0);
print_header();
......@@ -333,11 +511,14 @@ int main(void)
/* Test leds */
leds_test();
/* Test button */
button_test();
/* FMC150 test */
//fmc150_test();
/* FMC516 test */
//fmc516_test();
fmc516_test();
print_end_header();
......@@ -354,5 +535,7 @@ int main(void)
}
}
dbe_exit();
return 0;
}
This diff is collapsed.
This diff is collapsed.
OBJS_DEV = dev/dma.o \
dev/fmc150.o \
dev/gpio.o \
dev/uart.o \
dev/sdb.o \
dev/ethmac_adapt.o
dev/ethmac_adapt.o \
dev/spi.o \
dev/i2c.o \
dev/onewire.o
#include "board.h" // Board definitions: DMA device structure
#include "dma.h" // DMA device functions
#include "board.h" // Board definitions: DMA device structure
#include "dma.h" // DMA device functions
#include "memmgr.h"
// Global DMA handler.
dma_t *dma;
//dma_t *dma;
dma_t **dma;
int dma_init(void)
{
if (dma_devl->devices){
// get first dma device found
dma = (dma_t *)dma_devl->devices->base;//BASE_DMA;
return 0;
}
int i;
struct dev_node *dev_p = 0;
return -1;
if (!dma_devl->devices)
return -1;
// get all base addresses
dma = (dma_t **) memmgr_alloc(sizeof(dma_t *)*dma_devl->size);
//dbg_print("> dma size: %d\n", dma_devl->size);
for (i = 0, dev_p = dma_devl->devices; i < dma_devl->size;
++i, dev_p = dev_p->next) {
dma[i] = (dma_t *) dev_p->base;
//dbg_print("> dma addr[%d]: %08X\n", i, gpio[i]);
}
//dma = (dma_t *)dma_devl->devices->base;//BASE_GPIO;
return 0;
}
/* DMA user interface definition */
int read_is_addr(void)
int read_is_addr(unsigned int id)
{
return dma->RD_ADDR;
return dma[id]->RD_ADDR;
}
void write_is_addr(int addr)
void write_is_addr(unsigned int id, int addr)
{
dma->WR_ADDR = (uint32_t)addr;
dma[id]->WR_ADDR = (uint32_t)addr;
}
int read_strd(void)
int read_strd(unsigned int id)
{
return dma->RD_STRD;
return dma[id]->RD_STRD;
}
void write_strd(int strd)
void write_strd(unsigned int id, int strd)
{
dma->WR_STRD = (uint32_t) strd;
dma[id]->WR_STRD = (uint32_t) strd;
}
int read_tr_count(void)
int read_tr_count(unsigned int id)
{
return dma->TR_COUNT;
return dma[id]->TR_COUNT;
}
......@@ -2,43 +2,55 @@
#include "board.h"
#include "ethmac_adapt.h" // Etherbone MAC Adapter device functions
#include "memmgr.h"
#include "debug_print.h"
// Global handler.
ethmac_adapt_t *ethmac_adapt;
ethmac_adapt_t **ethmac_adapt;
int ethmac_adapt_init(/*gpio_t * gpio, int id*/)
int ethmac_adapt_init(void)
{
if (ethmac_adapt_devl->devices){
// get first device found
ethmac_adapt = (ethmac_adapt_t *)ethmac_adapt_devl->devices->base;//BASE_ETHAMC_ADAPTER;
return 0;
}
int i;
struct dev_node *dev_p = 0;
return -1;
if (!ethmac_adapt_devl->devices)
return -1;
// get all base addresses
ethmac_adapt = (ethmac_adapt_t **) memmgr_alloc(sizeof(ethmac_adapt_t *)*ethmac_adapt_devl->size);
//dbg_print("> ethmac_adapt size: %d\n", ethmac_adapt_devl->size);
for (i = 0, dev_p = ethmac_adapt_devl->devices; i < ethmac_adapt_devl->size;
++i, dev_p = dev_p->next) {
ethmac_adapt[i] = (ethmac_adapt_t *) dev_p->base;
//dbg_print("> dma addr[%d]: %08X\n", i, gpio[i]);
}
//ethmac_adapt = (ethmac_adapt_t *)ethmac_adapt_devl->devices->base;//BASE_GPIO;
return 0;
}
int ethmac_adapt_set_base(unsigned int base_rx, unsigned int base_tx)
int ethmac_adapt_set_base(unsigned int id, unsigned int base_rx, unsigned int base_tx)
{
ethmac_adapt->base_rx = base_rx;
ethmac_adapt->base_tx = base_tx;
ethmac_adapt[id]->base_rx = base_rx;
ethmac_adapt[id]->base_tx = base_tx;
return 0;
return 0;
}
int ethmac_adapt_set_length(unsigned int length)
int ethmac_adapt_set_length(unsigned int id, unsigned int length)
{
ethmac_adapt->length = length;
ethmac_adapt[id]->length = length;
return 0;
return 0;
}
int ethmac_adapt_go(void)
int ethmac_adapt_go(unsigned int id)
{
// write anything to trigger a transaction
ethmac_adapt->doit = 1;
// write anything to trigger a transaction
ethmac_adapt[id]->doit = 1;
return 0;
return 0;
}
......
#include "board.h"
#include "inttypes.h"
#include "fmc150.h"
// Delay in number of processor clock cycles
#define SPI_DELAY 300
#define SPI_BUSY_MAX_TRIES 10
/* Register values for cdce72010 */
uint32_t cdce72010_regs[CDCE72010_NUMREGS] = {
//internal reference clock. Default config.
/*0x683C0310,
0x68000021,
0x83040002,
0x68000003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68050CC9,
0x05FC270A,
0x0280044B,
0x0000180C*/
//3.84MHz ext clock. Does not lock.
/*0x682C0290,
0x68840041,
0x83840002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000C49,
0x0BFC02FA,
0x8000050B,
0x0000180C*/
//61.44MHz ext clock. LOCK.
/*0x682C0290,
0x68840041,
0x83040002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x0024009A,
0x8000050B,
0x0000180C*/
//7.68MHz ext clock. Lock.
// Use with Libera RF & clock generator. RF = 291.840MHz, MCf = 7.680MHz, H = 38
// DDS = 3.072MHz -> Phase increment = 2048d
0x682C0290,
0x68840041,
0x83860002, //divide by 5
//0x83840002, //divide by 4
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x007C003A, // PFD_freq = 1.92MHz
0x8000050B,
//0x0000180C
//15.36MHz ext clock.
/*0x682C0290,
0x68840041,
0x83840002,
/*;83020002,;divide by 6
;83860002, ;divide by 5
;83800002, ;divide by 2
;83840002, ;divide by 4
;83060002, ;divide by 8
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x003C003A,
0x8000050B,
0x0000180C*/
//9.6MHz ext clock.
/*0x682C0290,
0x68840041,
0x83860002,//;divide by 5
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x007C004A,
0x8000050B,
0x0000180C*/
//9.250MHz ext clock. No lock
/*0x682C0290,
0x68840041,
0x83860002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x5FFC39CA,
//0x8000390B, // DIvide by 32
0x8000050B, //Divide by 8
0x0000180C*/
//10.803 (originally 10.803 actually) ext clock.
//Could it be something related to the lock window? see cdce72010 datasheet
/*0x682C0290,
0x68840041,
0x83840002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x03FC02CA,
0x8000050B,
0x0000180C*/
};
// Global FMC150 handler.
fmc150_t *fmc150;
int fmc150_init(void)
{
if (fmc150_devl->devices){
// get first gpio device found
fmc150 = (fmc150_t *)fmc150_devl->devices->base;//BASE_FMC150;
return 0;
}
return -1;
}
void update_fmc150_adc_delay(uint8_t adc_strobe_delay, uint8_t adc_cha_delay, uint8_t adc_chb_delay)
{
fmc150->ADC_DLY = (uint32_t) FMC150_ADC_DLY_STR_W(adc_strobe_delay) +
(uint32_t) FMC150_ADC_DLY_CHA_W(adc_cha_delay) +
(uint32_t) FMC150_ADC_DLY_CHB_W(adc_chb_delay);
fmc150->FLGS_PULSE = 0x1;
}
/* Check if 150 is busy */
int fmc150_spi_busy(void)
{
return fmc150->FLGS_OUT & FMC150_FLGS_OUT_SPI_BUSY;
}
int read_fmc150_register(uint32_t cs, uint32_t addr, uint32_t* data)
{
// Test if SPI interface is busy
if (fmc150_spi_busy())
return -1;
// Set bit to read from SPI
fmc150->FLGS_IN |= FMC150_FLGS_IN_SPI_RW;
// Set address to read from
fmc150->ADDR = addr;
// Toggle chipselect
fmc150->CS ^= cs;
// Sleeps SPI_DELAY*4 processor cycles. Is that enough? */
delay(SPI_DELAY);
// Get data from register
*data = fmc150->DATA_OUT;
return 0;
}
int write_fmc150_register(uint32_t cs, uint32_t addr, uint32_t data)
{
// Test if SPI interface is busy
if (fmc150_spi_busy())
return -1;
// Set bit to write from SPI
fmc150->FLGS_IN &= ~FMC150_FLGS_IN_SPI_RW;
// Set address to write to
fmc150->ADDR = addr;
// Set value to write to
fmc150->DATA_IN = data;
// Toggle chipselect
fmc150->CS ^= cs;
return 0;
}
static int fmc150_spi_busy_loop()
{
int i = 0;
for(i = 0; i < SPI_BUSY_MAX_TRIES; ++i){
if(!fmc150_spi_busy())
break;
delay(SPI_DELAY);
}
// return error (-1) if max tries reached
if (i == SPI_BUSY_MAX_TRIES)
return -1;
else
return 0;
}
// TODO: implement a register structure and associate permissions
// (RO, RW, WO)
int init_cdce72010()
{
int i;
uint32_t reg;
/* Write regs to cdce72010 statically */
// Do not write the last register, as it is Read-only
for(i = 0; i < CDCE72010_NUMREGS; ++i){
if(fmc150_spi_busy_loop() < 0){
pp_printf("init_cdce72010: max SPI tries excceded!\n");
return -1;
}
pp_printf("init_cdce72010: writing data: 0x%x at register addr: 0x%x\n", cdce72010_regs[i], i);
// The CDCE72010 chip word addressed , hence the "i" addressing index
write_fmc150_register(FMC150_CS_CDCE72010, i, cdce72010_regs[i]);
// Do a write-read cycle in order to ensure that we wrote the correct value
delay(SPI_DELAY);
if(fmc150_spi_busy_loop() < 0){
pp_printf("init_cdce72010: max SPI tries excceded!\n");
return -1;
}
// The CDCE72010 chip word addressed , hence the "i" addressing index
read_fmc150_register(FMC150_CS_CDCE72010, i, &reg);
pp_printf("init_cdce72010: reading data: 0x%x at register addr: 0x%x\n", reg, i);
// Check if value written is the same of the value just read
if(cdce72010_regs[i] != reg){
pp_printf("init_cdce72010: error: data written (0x%x) != data read (0x%x)!\n",
cdce72010_regs[i], reg);
return -1;
}
delay(SPI_DELAY);
}
return 0;
}
#include "board.h" // Board definitions: GPIO device structure
#include "gpio.h" // GPIO device functions
#include "memmgr.h"
#include "debug_print.h"
// Global GPIO handler.
gpio_t *gpio;
gpio_t **gpio;
int gpio_init(/*gpio_t * gpio, int id*/)
int gpio_init()
{
if (gpio_devl->devices){
// get first gpio device found
gpio = (gpio_t *)gpio_devl->devices->base;//BASE_GPIO;
return 0;
}
int i;
struct dev_node *dev_p = 0;
return -1;
if (!gpio_devl->devices)
return -1;
// get all base addresses
gpio = (gpio_t **) memmgr_alloc(sizeof(gpio_t *)*gpio_devl->size);
for (i = 0, dev_p = gpio_devl->devices; i < gpio_devl->size;
++i, dev_p = dev_p->next) {
gpio[i] = (gpio_t *) dev_p->base;
dbg_print("> gpio addr[%d]: %08X\n", i, dev_p->base);
}
dbg_print("> gpio size: %d\n", gpio_devl->size);
//gpio = (gpio_t *)gpio_devl->devices->base;//BASE_GPIO;
return 0;
}
int gpio_exit()
{
// free gpio structure
memmgr_free(gpio);
return 0;
}
/* GPIO user interface definition */
void gpio_out(int pin, int val)
void gpio_out(unsigned int id, int pin, int val)
{
if(val)
gpio->SODR = (1<<pin);
else
gpio->CODR = (1<<pin);
if(val)
gpio[id]->SODR = (1<<pin);
else
gpio[id]->CODR = (1<<pin);
}
void gpio_dir(int pin, int val)
void gpio_dir(unsigned int id, int pin, int val)
{
if(val)
gpio->DDR |= (1<<pin);
else
gpio->DDR &= ~(1<<pin);
if(val)
gpio[id]->DDR |= (1<<pin);
else
gpio[id]->DDR &= ~(1<<pin);
}
int gpio_in(int pin)
int gpio_in(unsigned int id, int pin)
{
return gpio->PSR & (1<<pin) ? 1 : 0;
return gpio[id]->PSR & (1<<pin) ? 1 : 0;
}
// Parts taken from pts (http://www.ohwr.org/projects/pts/repository)
// Parts taken from wr-switch-sw (http://www.ohwr.org/projects/wr-switch-sw/repository)
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "i2c.h" // SPI device functions
#include "memmgr.h" // malloc and free clones
#include "debug_print.h"
// Global SPI handler.
i2c_t **i2c;
int i2c_init(void)
{
int i;
struct dev_node *dev_p = 0;
if (!i2c_devl->devices)
return -1;
// get all base addresses
i2c = (i2c_t **) memmgr_alloc(sizeof(i2c)*i2c_devl->size);
//dbg_print("> i2c size: %d\n", i2c_devl->size);
for (i = 0, dev_p = i2c_devl->devices; i < i2c_devl->size;
++i, dev_p = dev_p->next) {
i2c[i] = (i2c_t *) dev_p->base;
// Default configuration
i2c[i]->CTR = 0;
i2c[i]->PREL = DEFAULT_I2C_PRESCALER & 0xFF;
i2c[i]->PREH = (DEFAULT_I2C_PRESCALER >> 8) & 0xFF;
// Enbale core
i2c[i]->CTR = I2C_CTR_EN;
// Check if the core is indeed enabled
if (!(i2c[i]->CTR & I2C_CTR_EN))
return -1;
//dbg_print("> i2c addr[%d]: %08X\n", i, i2c[i]);
}
//i2c = (i2c_t *)i2c_devl->devices->base;;
return 0;
}
void i2c_exit(void)
{
memmgr_free(i2c);
}
int oc_i2c_poll(unsigned int id)
{
return (i2c[id]->SR & I2C_SR_TIP) ? 1 : 0;
}
int oc_i2c_start(unsigned int id, int addr, int read)
{
uint32_t i2c_addr;
// shift addr bits as the last one represents rw bit (read = 1, write = 0)
i2c_addr = I2C_ADDR(addr);
if (read == 1)
i2c_addr |= I2C_TXR_READ;
i2c[id]->TXR = i2c_addr;
// Start transaction. Generates repeated start condition and write to slave
i2c[id]->CR = I2C_CR_STA | I2C_CR_WR;
// Wait for completion
while(oc_i2c_poll(id));
// Check if we received an ACK from slave
if (i2c[id]->SR & I2C_SR_RXACK) {
dbg_print("> no ack received from slave at addr 0X%2X\n", addr);
return -1;
}
return 0;
}
int oc_i2c_rx(unsigned int id, uint32_t *out, int last)
{
uint32_t i2c_cmd;
i2c_cmd = I2C_CR_RD;
// Generates STOP condition and send NACK on completion
if(last)
i2c_cmd |= I2C_CR_STO | I2C_CR_ACK;
i2c[id]->CR = i2c_cmd;
// Wait for completion
while(oc_i2c_poll(id));
// Check if we received an ACK from slave
if (i2c[id]->SR & I2C_SR_RXACK) {
dbg_print("> no ack received from slave at rx transaction\n");
return -1;
}
*out = i2c[id]->RXR & 0xFF;
return 0;
}
int oc_i2c_tx(unsigned int id, uint32_t in, int last)
{
uint32_t i2c_cmd;
// We don't really care about sizes here as only the 8 LSB
// are effectivelly written to the I2C core and no harm is inflicted
// by doing this.
i2c[id]->TXR = in;
// Write command
i2c_cmd = I2C_CR_WR;
// Generates STOP condition
if(last)
i2c_cmd |= I2C_CR_STO;
i2c[id]->CR = i2c_cmd;
// Wait for completion
while(oc_i2c_poll(id));
// Check if we received an ACK from slave
if (i2c[id]->SR & I2C_SR_RXACK) {
dbg_print("> no ack received from slave at tx transaction\n");
return -1;
}
return 0;
}
// This just prints if devices have been found at specified addresses
int oc_i2c_scan(unsigned int id)
{
int i;
uint32_t i2c_addr;
for (i = 0; i < 128; ++i) {
i2c_addr = I2C_ADDR(i) | I2C_TXR_READ;
i2c[id]->TXR = i2c_addr;
i2c[id]->CR = I2C_CR_STA | I2C_CR_WR;
// Wait for completion
while(oc_i2c_poll(id));
// Check if we received an ACK from slave
if (!(i2c[id]->SR & I2C_SR_RXACK)) {
dbg_print("> device found at addr 0X%02X\n", i);
i2c[id]->TXR = 0;
i2c[id]->CR = I2C_CR_STO | I2C_CR_WR;
while(oc_i2c_poll(id));
}
}
return 0;
}
// Parts taken from pts (http://www.ohwr.org/projects/pts/repository)
// Parts taken from wr-switch-sw (http://www.ohwr.org/projects/wr-switch-sw/repository)
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "onewire.h" // SPI device functions
#include "memmgr.h" // malloc and free clones
#include "debug_print.h"
// Global SPI handler.
owr_t **owr;
int owr_init(void)
{
int i;
struct dev_node *dev_p = 0;
if (!owr_devl->devices)
return -1;
// get all base addresses
owr = (owr_t **) memmgr_alloc(sizeof(owr)*owr_devl->size);
//dbg_print("> owr size: %d\n", owr_devl->size);
for (i = 0, dev_p = owr_devl->devices; i < owr_devl->size;
++i, dev_p = dev_p->next) {
owr[i] = (owr_t *) dev_p->base;
// Default configuration
owr[i]->CDR = (OWR_CDR_NOR(DEFAULT_OWR_DIVIDER_NOR)) |
(OWR_CDR_OVD(DEFAULT_OWR_DIVIDER_OVD));
dbg_print("> owr addr[%d]: %08X\n", i, owr[i]);
}
dbg_print("> owr size: %d\n", owr_devl->size);
//owr = (owr_t *)owr_devl->devices->base;
return 0;
}
void owr_exit(void)
{
memmgr_free(owr);
}
int oc_owr_poll(unsigned int id)
{
return (owr[id]->CSR & OWR_CSR_CYC) ? 1 : 0;
}
int oc_owr_reset(unsigned int id, int port)
{
// Request reset
owr[id]->CSR = OWR_CSR_SEL(port) | OWR_CSR_CYC | OWR_CSR_RST;
// Wait for completion
while(oc_owr_poll(id));
// Read presence status. 0 -> presence detected, 1 -> presence NOT detected
//return (owr[id]->CSR & OWR_CSR_DAT) ? 0 : 1;
return (~(owr[id]->CSR) & OWR_CSR_DAT);
}
int oc_owr_slot(unsigned int id, int port, uint32_t in_bit, uint32_t *out_bit)
{
uint32_t rval;
// Avoid breaking the code when just issuing a read command (out_bit can be null).
// This is the case when in_bit = 0 (write 0 slot), but not for in_bit = 1
// (write 1 and/or read slot)
if (!out_bit)
out_bit = &rval;
owr[id]->CSR = OWR_CSR_SEL(port) | OWR_CSR_CYC | (in_bit & OWR_CSR_DAT);
// Wait for completion
while(oc_owr_poll(id));
*out_bit = owr[id]->CSR & OWR_CSR_DAT;
return 0;
}
int oc_owr_read_bit(unsigned int id, int port, uint32_t *out_bit)
{
return oc_owr_slot(id, port, 0x1, out_bit);
}
int oc_owr_write_bit(unsigned int id, int port, uint32_t in_bit, uint32_t *out_bit)
{
return oc_owr_slot(id, port, in_bit, out_bit);
}
int read_byte(unsigned int id, int port, uint32_t *out_byte)
{
int i;
uint32_t owr_data = 0;
uint32_t owr_bit = 0;
for (i = 0; i < 8; ++i) {
oc_owr_read_bit(id, port, &owr_bit);
owr_data |= owr_bit << i;
}
*out_byte = owr_data;
return 0;
}
int write_byte(unsigned int id, int port, uint32_t in_byte)
{
int i;
uint32_t owr_data = 0;
uint32_t owr_byte = in_byte;
uint32_t owr_bit;
for (i = 0; i < 8; ++i) {
oc_owr_write_bit(id, port, owr_byte & 0x1, &owr_bit);
owr_data |= owr_bit << i;
owr_byte >>= 1;
}
if(owr_data == in_byte)
return 0;
else
return -1;
}
......@@ -92,8 +92,8 @@ static unsigned char *find_device_deep(unsigned int base, unsigned int sdb,
record->device.sdb_component.addr_first.low);
}
static void find_device_deep_all_rec(struct dev_node **dev, unsigned int base,
unsigned int sdb, unsigned int devid)
static void find_device_deep_all_rec(struct dev_node **dev, unsigned int *size,
unsigned int base, unsigned int sdb, unsigned int devid)
{
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
......@@ -101,9 +101,8 @@ static void find_device_deep_all_rec(struct dev_node **dev, unsigned int base,
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
find_device_deep_all_rec(dev, base +
record->bridge.sdb_component.
addr_first.low,
find_device_deep_all_rec(dev, size, base +
record->bridge.sdb_component.addr_first.low,
record->bridge.sdb_child.low,
devid);
}
......@@ -117,6 +116,7 @@ static void find_device_deep_all_rec(struct dev_node **dev, unsigned int base,
(*dev)->next = 0;
// Pass new node address
dev = &(*dev)->next;
(*size)++;
}
}
}
......@@ -129,10 +129,11 @@ static struct dev_list *find_device_deep_all(unsigned int base, unsigned int sdb
// Initialize structure
dev->devid = devid;
dev->size = 0;
dev->devices = 0;
// Fill device list with the appropriate nodes
find_device_deep_all_rec(&(dev->devices), base, sdb, devid);
find_device_deep_all_rec(&(dev->devices), &(dev->size), base, sdb, devid);
return dev;
}
......@@ -184,23 +185,21 @@ void sdb_print_devices(void)
void sdb_find_devices(void)
{
//BASE_DMA = find_device(0xcababa56);
//BASE_DMA = (unsigned char *)0x20000400;
//BASE_FMA150 = find_device(0xf8c150c1);
//BASE_FMA150 = (unsigned char *)0x20000500;
//BASE_UART = find_device(0x8a5719ae);
//BASE_UART = (unsigned char *)0x20000600;
//BASE_GPIO = find_device(0x35aa6b95);
//BASE_GPIO = (unsigned char *)0x20000700;
// Enumerate devices
// get the second device form this list. Just for testing! with the etherbone
// core
mem_devl = find_device_all(0x66cfeb52);
dma_devl = find_device_all(0xcababa56);
ethmac_devl = find_device_all(0xf8cfeb16);
ethmac_adapt_devl = find_device_all(0x2ff9a28e);
ebone_cfg_devl = find_device_all(0x68202b22);
dma_devl = find_device_all(0xcababa56);
fmc150_devl = find_device_all(0xf8c150c1);
fmc516_devl = find_device_all(0x27b95341);
spi_devl = find_device_all(0x40286417);
i2c_devl = find_device_all(0x97b6323d);
owr_devl = find_device_all(0x525fbb09);
uart_devl = find_device_all(0x8a5719ae);
gpio_devl = find_device_all(0x35aa6b95);
// get the second device form this list. Just for testing! with the etherbone
// core
ethmac_buf_devl = find_device_all(0x66cfeb52);
tics_devl = find_device_all(0xfdafb9dd);
}
// Parts taken from pts (http://www.ohwr.org/projects/pts/repository)
// Parts taken from wr-switch-sw (http://www.ohwr.org/projects/wr-switch-sw/repository)
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "memmgr.h" // malloc and free clones
#include "debug_print.h"
#define SPI_DELAY 300
// Global SPI handler.
spi_t **spi;
static uint32_t *spi_config;
int spi_init(void)
{
int i;
struct dev_node *dev_p = 0;
if (!spi_devl->devices)
return -1;
// get all base addresses
spi = (spi_t **) memmgr_alloc(sizeof(spi)*spi_devl->size);
spi_config = (uint32_t *) memmgr_alloc(sizeof(spi_config)*spi_devl->size);
dbg_print("> spi size: %d\n", spi_devl->size);
for (i = 0, dev_p = spi_devl->devices; i < spi_devl->size;
++i, dev_p = dev_p->next) {
spi[i] = (spi_t *) dev_p->base;
// Default configuration
spi[i]->DIVIDER = DEFAULT_SPI_DIVIDER & SPI_DIV_MASK;
spi_config[i] = SPI_CTRL_ASS | SPI_CTRL_TXNEG;
spi[i]->CTRL = spi_config[i];
dbg_print("> spi addr[%d]: %08X\n", i, spi[i]);
dbg_print("> spi rx0 addr[%d]: %08X\n", i, &spi[i]->RX0);
dbg_print("> spi tx0 addr[%d]: %08X\n", i, &spi[i]->TX0);
dbg_print("> spi rx1 addr[%d]: %08X\n", i, &spi[i]->RX1);
dbg_print("> spi tx1 addr[%d]: %08X\n", i, &spi[i]->TX1);
dbg_print("> spi rx2 addr[%d]: %08X\n", i, &spi[i]->RX2);
dbg_print("> spi tx2 addr[%d]: %08X\n", i, &spi[i]->TX2);
dbg_print("> spi rx3 addr[%d]: %08X\n", i, &spi[i]->RX3);
dbg_print("> spi tx3 addr[%d]: %08X\n", i, &spi[i]->TX3);
dbg_print("> spi ctrl addr[%d]: %08X\n", i, &spi[i]->CTRL);
dbg_print("> spi divider addr[%d]: %08X\n", i, &spi[i]->DIVIDER);
dbg_print("> spi ss addr[%d]: %08X\n", i, &spi[i]->SS);
dbg_print("> reading some fields back:\n");
dbg_print("> spi ctrl_busy: %08X\n", spi[i]->CTRL & SPI_CTRL_GO_BSY);
dbg_print("> spi ctrl_ass: %08X\n", spi[i]->CTRL & SPI_CTRL_ASS);
dbg_print("> spi ctrl_txneg: %08X\n", spi[i]->CTRL & SPI_CTRL_TXNEG);
dbg_print("> spi ctrl_lsb: %08X\n", spi[i]->CTRL & SPI_CTRL_LSB);
dbg_print("> spi ctrl_dir: %08X\n", spi[i]->CTRL & SPI_CTRL_DIR);
dbg_print("> spi ctrl_three_mode: %08X\n", spi[i]->CTRL & SPI_CTRL_THREE_WIRE);
}
//spi = (spi_t *)spi_devl->devices->base;;
return 0;
}
void spi_exit(void)
{
memmgr_free(spi);
memmgr_free(spi_config);
}
int oc_spi_poll(unsigned int id)
{
return (spi[id]->CTRL & SPI_CTRL_BSY) ? 1 : 0;
}
int oc_spi_three_mode(unsigned int id)
{
return spi[id]->CTRL & SPI_CTRL_THREE_WIRE;
}
void oc_spi_config(unsigned int id, int ass, int rx_neg, int tx_neg,
int lsb, int ie)
{
spi_config[id] = 0;
if(ass)
spi_config[id] |= SPI_CTRL_ASS;
if(tx_neg)
spi_config[id] |= SPI_CTRL_TXNEG;
if(rx_neg)
spi_config[id] |= SPI_CTRL_RXNEG;
if(lsb)
spi_config[id] |= SPI_CTRL_LSB;
if(ie)
spi_config[id] |= SPI_CTRL_IE;
}
// For use only with spi three-wire mode
int oc_spi_three_mode_tx(unsigned int id, int ss, int nbits, uint32_t in)
{
// Write configuration to SPI core. SPI_CTRL_DIR = 1
spi[id]->CTRL = spi_config[id] | SPI_CTRL_DIR | SPI_CTRL_CHAR_LEN(nbits);
// Transmit to core
spi[id]->TX0 = in;
//spi[id]->TX1 = 0;
//spi[id]->TX2 = 0;
//spi[id]->TX3 = 0;
dbg_print("> spi[id]->TX0: 0x%8X\n", spi[id]->TX0);
dbg_print("> spi[id]->RX0: 0x%8X\n", spi[id]->RX0);
spi[id]->SS = (1 << ss);
// Initiate transaction
spi[id]->CTRL |= SPI_CTRL_GO_BSY;
// Wait for completion
dbg_print("> waiting for spi...\n");
while(oc_spi_poll(id))
delay(SPI_DELAY);
delay(SPI_DELAY);
dbg_print("> spi[id]->TX0: 0x%8X\n", spi[id]->TX0);
dbg_print("> spi[id]->RX0: 0x%8X\n", spi[id]->RX0);
return 0;
}
// For use only with spi three-wire mode
int oc_spi_three_mode_rx(unsigned int id, int ss, int nbits, uint32_t *out)
{
// Write configuration to SPI core. SPI_CTRL_DIR = 0
spi[id]->CTRL = spi_config[id] | SPI_CTRL_CHAR_LEN(nbits);
spi[id]->SS = (1 << ss);
dbg_print("> spi[id]->TX0: 0x%8X\n", spi[id]->TX0);
dbg_print("> spi[id]->RX0: 0x%8X\n", spi[id]->RX0);
// Initiate transaction
spi[id]->CTRL |= SPI_CTRL_GO_BSY;
// Wait for reception
dbg_print("> waiting for spi...\n");
while(oc_spi_poll(id))
delay(SPI_DELAY);
delay(SPI_DELAY);
*out = spi[id]->RX0;
dbg_print("> spi[id]->TX0: 0x%8X\n", spi[id]->TX0);
dbg_print("> spi[id]->RX0: 0x%8X\n", spi[id]->RX0);
return 0;
}
int oc_spi_txrx(unsigned int id, int ss, int nbits, uint32_t in, uint32_t *out)
{
uint32_t rval;
// Avoid breaking the code when just issuing a read command (out can be null)
if (!out)
out = &rval;
// Write configuration to SPI core
spi[id]->CTRL = spi_config[id] | SPI_CTRL_CHAR_LEN(nbits);
// Transmit to core
spi[id]->TX0 = in;
// Receive from core
spi[id]->SS = (1 << ss);
spi[id]->CTRL |= SPI_CTRL_GO_BSY;
dbg_print("> waiting for spi...\n");
while(oc_spi_poll(id))
delay(SPI_DELAY);
*out = spi[id]->RX0;
return 0;
}
#include <inttypes.h>
#include "board.h" // Board definitions: UART device structure
#include "uart.h" // UART device functions
#include "board.h" // Board definitions: UART device structure
#include "uart.h" // UART device functions
#include "debug_print.h"
#include "memmgr.h"
#define CALC_BAUD(baudrate) \
( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
(CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) )
( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
(CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) )
// Global UART handler.
uart_t *uart;
uart_t **uart;
int uart_init(void)
{
if (uart_devl->devices){
// get first uart device found
uart = (uart_t *)uart_devl->devices->base;//BASE_UART;
uart->BCR = CALC_BAUD(UART_BAUDRATE);
return 0;
}
// return error in case none uart device found
return -1;
int i;
struct dev_node *dev_p = 0;
if (!uart_devl->devices)
return -1;
// get all base addresses
uart = (uart_t **) memmgr_alloc(sizeof(uart_t *)*uart_devl->size);
for (i = 0, dev_p = uart_devl->devices; i < uart_devl->size;
++i, dev_p = dev_p->next) {
uart[i] = (uart_t *) dev_p->base;
uart[i]->BCR = CALC_BAUD(UART_BAUDRATE);
dbg_print("> uart addr[%d]: %08X\n", i, dev_p->base);
}
dbg_print("> uart size: %d\n", uart_devl->size);
//uart = (uart_t *)uart_devl->devices->base;//BASE_GPIO;
return 0;
}
int uart_exit()
{
// free uart structure
memmgr_free(uart);
return 0;
}
void uart_write_byte(unsigned int id, int b)
{
if (b == '\n')
uart_write_byte(id, '\r');
while (uart[id]->SR & UART_SR_TX_BUSY) ;
uart[id]->TDR = b;
}
void uart_write_byte(int b)
void uart_write_string(unsigned int id, char *s)
{
if (b == '\n')
uart_write_byte('\r');
while (uart->SR & UART_SR_TX_BUSY) ;
uart->TDR = b;
while (*s)
uart_write_byte(id, *(s++));
}
void uart_write_string(char *s)
// Only for use with puts
void uart_default_write_string(char *s)
{
while (*s)
uart_write_byte(*(s++));
while (*s)
uart_write_byte(DEFAULT_UART, *(s++));
}
// See http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
// for the __attribute__ explanation
int puts(const char *s) __attribute__((alias("uart_write_string")));
int puts(const char *s) __attribute__((alias("uart_default_write_string")));
int uart_poll(void)
int uart_poll(unsigned int id)
{
return uart->SR & UART_SR_RX_RDY;
return uart[id]->SR & UART_SR_RX_RDY;
}
int uart_read_byte(void)
int uart_read_byte(unsigned int id)
{
if (!uart_poll())
return -1;
if (!uart_poll(id))
return -1;
return uart->RDR & 0xff;
return uart[id]->RDR & 0xff;
}
ifdef CONFIG_FMC150
OBJS_FMC150 += fmc/fmc150/fmc150.o
endif
ifdef CONFIG_FMC516
OBJS_FMC516 += fmc/fmc516/lmk02000.o fmc/fmc516/isla216p25.o fmc/fmc516/fmc516.o
endif
OBJS_FMC += $(OBJS_FMC150) $(OBJS_FMC516)
#include "board.h"
#include "inttypes.h"
#include "fmc150.h"
// Delay in number of processor clock cycles
#define SPI_DELAY 300
#define SPI_BUSY_MAX_TRIES 10
/* Register values for cdce72010 */
uint32_t cdce72010_regs[CDCE72010_NUMREGS] = {
//internal reference clock. Default config.
/*0x683C0310,
0x68000021,
0x83040002,
0x68000003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68050CC9,
0x05FC270A,
0x0280044B,
0x0000180C*/
//3.84MHz ext clock. Does not lock.
/*0x682C0290,
0x68840041,
0x83840002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000C49,
0x0BFC02FA,
0x8000050B,
0x0000180C*/
//61.44MHz ext clock. LOCK.
/*0x682C0290,
0x68840041,
0x83040002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x0024009A,
0x8000050B,
0x0000180C*/
//7.68MHz ext clock. Lock.
// Use with Libera RF & clock generator. RF = 291.840MHz, MCf = 7.680MHz, H = 38
// DDS = 3.072MHz -> Phase increment = 2048d
0x682C0290,
0x68840041,
0x83860002, //divide by 5
//0x83840002, //divide by 4
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x007C003A, // PFD_freq = 1.92MHz
0x8000050B,
//0x0000180C
//15.36MHz ext clock.
/*0x682C0290,
0x68840041,
0x83840002,
/*;83020002,;divide by 6
;83860002, ;divide by 5
;83800002, ;divide by 2
;83840002, ;divide by 4
;83060002, ;divide by 8
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x003C003A,
0x8000050B,
0x0000180C*/
//9.6MHz ext clock.
/*0x682C0290,
0x68840041,
0x83860002,//;divide by 5
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x007C004A,
0x8000050B,
0x0000180C*/
//9.250MHz ext clock. No lock
/*0x682C0290,
0x68840041,
0x83860002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x5FFC39CA,
//0x8000390B, // DIvide by 32
0x8000050B, //Divide by 8
0x0000180C*/
//10.803 (originally 10.803 actually) ext clock.
//Could it be something related to the lock window? see cdce72010 datasheet
/*0x682C0290,
0x68840041,
0x83840002,
0x68400003,
0xE9800004,
0x68000005,
0x68000006,
0x83800017,
0x68000098,
0x68000049,
0x03FC02CA,
0x8000050B,
0x0000180C*/
};
// Global FMC150 handler.
fmc150_t *fmc150;
int fmc150_init(void)
{
if (fmc150_devl->devices){
// get first gpio device found
fmc150 = (fmc150_t *)fmc150_devl->devices->base;//BASE_FMC150;
return 0;
}
return -1;
}
void update_fmc150_adc_delay(uint8_t adc_strobe_delay, uint8_t adc_cha_delay, uint8_t adc_chb_delay)
{
fmc150->ADC_DLY = (uint32_t) FMC150_ADC_DLY_STR_W(adc_strobe_delay) +
(uint32_t) FMC150_ADC_DLY_CHA_W(adc_cha_delay) +
(uint32_t) FMC150_ADC_DLY_CHB_W(adc_chb_delay);
fmc150->FLGS_PULSE = 0x1;
}
/* Check if 150 is busy */
int fmc150_spi_busy(void)
{
return fmc150->FLGS_OUT & FMC150_FLGS_OUT_SPI_BUSY;
}
int read_fmc150_register(uint32_t cs, uint32_t addr, uint32_t* data)
{
// Test if SPI interface is busy
if (fmc150_spi_busy())
return -1;
// Set bit to read from SPI
fmc150->FLGS_IN |= FMC150_FLGS_IN_SPI_RW;
// Set address to read from
fmc150->ADDR = addr;
// Toggle chipselect
fmc150->CS ^= cs;
// Sleeps SPI_DELAY*4 processor cycles. Is that enough? */
delay(SPI_DELAY);
// Get data from register
*data = fmc150->DATA_OUT;
return 0;
}
int write_fmc150_register(uint32_t cs, uint32_t addr, uint32_t data)
{
// Test if SPI interface is busy
if (fmc150_spi_busy())
return -1;
// Set bit to write from SPI
fmc150->FLGS_IN &= ~FMC150_FLGS_IN_SPI_RW;
// Set address to write to
fmc150->ADDR = addr;
// Set value to write to
fmc150->DATA_IN = data;
// Toggle chipselect
fmc150->CS ^= cs;
return 0;
}
static int fmc150_spi_busy_loop()
{
int i = 0;
for(i = 0; i < SPI_BUSY_MAX_TRIES; ++i){
if(!fmc150_spi_busy())
break;
delay(SPI_DELAY);
}
// return error (-1) if max tries reached
if (i == SPI_BUSY_MAX_TRIES)
return -1;
else
return 0;
}
// TODO: implement a register structure and associate permissions
// (RO, RW, WO)
int init_cdce72010()
{
int i;
uint32_t reg;
/* Write regs to cdce72010 statically */
// Do not write the last register, as it is Read-only
for(i = 0; i < CDCE72010_NUMREGS; ++i){
if(fmc150_spi_busy_loop() < 0){
pp_printf("init_cdce72010: max SPI tries excceded!\n");
return -1;
}
pp_printf("init_cdce72010: writing data: 0x%x at register addr: 0x%x\n", cdce72010_regs[i], i);
// The CDCE72010 chip word addressed , hence the "i" addressing index
write_fmc150_register(FMC150_CS_CDCE72010, i, cdce72010_regs[i]);
// Do a write-read cycle in order to ensure that we wrote the correct value
delay(SPI_DELAY);
if(fmc150_spi_busy_loop() < 0){
pp_printf("init_cdce72010: max SPI tries excceded!\n");
return -1;
}
// The CDCE72010 chip word addressed , hence the "i" addressing index
read_fmc150_register(FMC150_CS_CDCE72010, i, &reg);
pp_printf("init_cdce72010: reading data: 0x%x at register addr: 0x%x\n", reg, i);
// Check if value written is the same of the value just read
if(cdce72010_regs[i] != reg){
pp_printf("init_cdce72010: error: data written (0x%x) != data read (0x%x)!\n",
cdce72010_regs[i], reg);
return -1;
}
delay(SPI_DELAY);
}
return 0;
}
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "memmgr.h"
#include "fmc516.h"
// Global FMC516 handler.
fmc516_t **fmc516;
int fmc516_init(void)
{
int i;
struct dev_node *dev_p = 0;
if (!fmc516_devl->devices)
return -1;
// get all base addresses
fmc516 = (fmc516_t **) memmgr_alloc(sizeof(fmc516_t *)*fmc516_devl->size);
for (i = 0, dev_p = fmc516_devl->devices; i < fmc516_devl->size;
++i, dev_p = dev_p->next) {
fmc516[i] = (fmc516_t *) dev_p->base;
// Initialize fmc516 components
dbg_print("> initilizing fmc516 regs\n");
fmc516_init_regs(i);
dbg_print("> initilizing fmc516 lmk02000\n");
fmc516_lmk02000_init();
dbg_print("> fmc516 addr[%d]: %08X\n", i, dev_p->base);
delay(100);
dbg_print("> resetting ADCs\n");
fmc516_reset_adcs(i);
delay(100);
fmc516_resetdiv_adcs(i);
//dbg_print("> ADCs reset values(rst|divrst)): %08X|%08X\n",
// fmc516[i]->ADC_CTL & FMC516_ADC_CTL_RST_ADCS,
// fmc516[i]->ADC_CTL & FMC516_ADC_CTL_RST_DIV_ADCS);
delay(100);
dbg_print("> initilizing fmc516 isla216\n");
fmc516_isla216_all_init();
}
dbg_print("> fmc516 size: %d\n", fmc516_devl->size);
//fmc516 = (fmc516_t *)fmc516_devl->devices->base;//BASE_FMC516;
return 0;
}
int fmc516_exit()
{
// free fmc516 structure
memmgr_free(fmc516);
return 0;
}
// For now just a few registers are initialized
void fmc516_init_regs(unsigned int id)
{
int commit= 1;
dbg_print("> Leds and clock select\n");
// No test data. External reference on. Led0 on. Led1 on. VCXO off
fmc516_clk_sel(id, 1);
fmc516_led1(id, 1);
// Adjsut the delays of all channels
fmc516_adj_delay(id, FMC516_ISLA216_ADC0, 5, 7, commit);
fmc516_adj_delay(id, FMC516_ISLA216_ADC1, 5, 9, commit);
fmc516_adj_delay(id, FMC516_ISLA216_ADC2, 5, 9, commit);
fmc516_adj_delay(id, FMC516_ISLA216_ADC3, 5, 9, commit);
// Delay the falling edge of all channels
fmc516_fe_dly(id, FMC516_ISLA216_ADC0, 0, 0);
fmc516_fe_dly(id, FMC516_ISLA216_ADC1, 0, 0);
fmc516_fe_dly(id, FMC516_ISLA216_ADC2, 0, 0);
fmc516_fe_dly(id, FMC516_ISLA216_ADC3, 0, 0);
}
void fmc516_sweep_delays(unsigned int id)
{
//int commit = 1;
//int i;
dbg_print("> ADC%d data delay: %d...\n", 0, FMC516_CH0_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH0_CTL));
dbg_print("> ADC%d data delay: %d...\n", 1, FMC516_CH1_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH1_CTL));
dbg_print("> ADC%d data delay: %d...\n", 2, FMC516_CH2_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH2_CTL));
dbg_print("> ADC%d data delay: %d...\n", 3, FMC516_CH3_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH3_CTL));
//for (i = 25; i < 32; ++i){
// dbg_print("> sweeping ADC%d data delay values: %d...\n", 1, i);
// fmc516_adj_delay(id, 1, -1, i, commit);
// delay(200000000);
// dbg_print("> ADC%d data delay: %d...\n", 1, FMC516_CH1_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH1_CTL));
//}
//
//fmc516_adj_delay(id, 1, -1, 27, commit);
//
//for (i = 0; i < 32; ++i){
// dbg_print("> sweeping ADC%d clk delay values: %d...\n", 1, i);
// fmc516_adj_delay(id, 1, i, -1, commit);
// delay(80000000);
// dbg_print("> ADC%d data delay: %d...\n", 1, FMC516_CH1_CTL_CLK_CHAIN_DLY_R(fmc516[id]->CH1_CTL));
// }
//for (i = 0; i < 32; ++i){
// dbg_print("> sweeping ADC%d delay values: %d...\n", 2, i);
// fmc516_adj_ch2_delay(id, -1, i, commit);
// delay(50000000);
// dbg_print("> ADC%d data delay: %d...\n", 2, FMC516_CH2_CTL_DATA_CHAIN_DLY_R(fmc516[id]->CH2_CTL));
//}
}
void fmc516_update_clk_dly(unsigned int id)
{
fmc516[id]->ADC_CTL |= FMC516_ADC_CTL_UPDATE_CLK_DLY;
}
void fmc516_update_data_dly(unsigned int id)
{
fmc516[id]->ADC_CTL |= FMC516_ADC_CTL_UPDATE_DATA_DLY;
}
void fmc516_adj_delay(unsigned int id, int ch, int clk_dly, int data_dly, int commit)
{
uint32_t adc_ctl_reg;
uint32_t *fmc_ch_handler;
// Find the correct ADC instance to operate on
switch(ch) {
case FMC516_ISLA216_ADC0:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH0_CTL;
break;
case FMC516_ISLA216_ADC1:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH1_CTL;
break;
case FMC516_ISLA216_ADC2:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH2_CTL;
break;
case FMC516_ISLA216_ADC3:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH3_CTL;
break;
default:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH0_CTL;
}
// Read the register value once
adc_ctl_reg = *fmc_ch_handler;
/* All Masks are the same for all channels. Use the first one */
/* All Read/Write macros are the same for all channels. Use the first one */
if (clk_dly != -1) {
/* Clear clk delay bits and write the desired value*/
adc_ctl_reg = (adc_ctl_reg & ~FMC516_CH0_CTL_CLK_CHAIN_DLY_MASK) |
FMC516_CH0_CTL_CLK_CHAIN_DLY_W(clk_dly);
}
if (data_dly != -1) {
/* Clear clk delay bits and write the desired value*/
adc_ctl_reg = (adc_ctl_reg & ~FMC516_CH0_CTL_DATA_CHAIN_DLY_MASK) |
FMC516_CH0_CTL_DATA_CHAIN_DLY_W(data_dly);
}
// Write the register value once
*fmc_ch_handler = adc_ctl_reg;
// Update data/clock delay values
if (commit) {
fmc516_update_data_dly(id);
fmc516_update_clk_dly(id);
}
}
void fmc516_clk_sel(unsigned int id, int ext_clk)
{
if (ext_clk)
fmc516[id]->FMC_CTL |= FMC516_FMC_CTL_CLK_SEL;
}
void fmc516_led0(unsigned int id, int on)
{
if (on)
fmc516[id]->FMC_CTL |= FMC516_FMC_CTL_LED_0;
}
void fmc516_led1(unsigned int id, int on)
{
if (on)
fmc516[id]->FMC_CTL |= FMC516_FMC_CTL_LED_1;
}
void fmc516_reset_adcs(unsigned int id)
{
fmc516[id]->ADC_CTL |= FMC516_ADC_CTL_RST_ADCS;
}
void fmc516_resetdiv_adcs(unsigned int id)
{
fmc516[id]->ADC_CTL |= FMC516_ADC_CTL_RST_DIV_ADCS;
}
//#define fmc516_read_adc0(id) (FMC516_CH0_STA_VAL_R(fmc516[id]->CH0_STA))
uint32_t fmc516_read_adc0(unsigned int id)
{
return FMC516_CH0_STA_VAL_R(fmc516[id]->CH0_STA);
}
//#define fmc516_read_adc1(id) (FMC516_CH1_STA_VAL_R(fmc516[id]->CH1_STA))
uint32_t fmc516_read_adc1(unsigned int id)
{
return FMC516_CH1_STA_VAL_R(fmc516[id]->CH1_STA);
}
//#define fmc516_read_adc2(id) (FMC516_CH2_STA_VAL_R(fmc516[id]->CH2_STA))
uint32_t fmc516_read_adc2(unsigned int id)
{
return FMC516_CH2_STA_VAL_R(fmc516[id]->CH2_STA);
}
//#define fmc516_read_adc3(id) (FMC516_CH3_STA_VAL_R(fmc516[id]->CH3_STA))
uint32_t fmc516_read_adc3(unsigned int id)
{
return FMC516_CH3_STA_VAL_R(fmc516[id]->CH3_STA);
}
// ADC delay falling edge control
void fmc516_fe_dly(unsigned int id, int ch, int fe_dly_d1, int fe_dly_d2)
{
uint32_t *fmc_ch_handler;
uint32_t fe_dly_reg;
switch(ch) {
case FMC516_ISLA216_ADC0:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH0_DLY_CTL;
break;
case FMC516_ISLA216_ADC1:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH1_DLY_CTL;
break;
case FMC516_ISLA216_ADC2:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH2_DLY_CTL;
break;
case FMC516_ISLA216_ADC3:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH3_DLY_CTL;
break;
default:
fmc_ch_handler = (uint32_t *) &fmc516[id]->CH0_DLY_CTL;
}
// Read register value once
fe_dly_reg = *fmc_ch_handler;
if (fe_dly_d2)
fe_dly_reg |= (fe_dly_reg & ~FMC516_CH0_DLY_CTL_FE_DLY_MASK) |
FMC516_CH0_DLY_CTL_FE_DLY_W(0x3);
else if (fe_dly_d1)
fe_dly_reg |= (fe_dly_reg & ~FMC516_CH0_DLY_CTL_FE_DLY_MASK) |
FMC516_CH0_DLY_CTL_FE_DLY_W(0x1);
// Write register value once
*fmc_ch_handler = fe_dly_reg;
}
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "isla216p25.h"
#include "isla216p25_regs.h"
#include "debug_print.h"
/*
* Which SPI ID is isla216p25? See board.h for definitions.
* Should be dynamically detected...
*/
static void fmc516_isla216_load_regset(const struct default_dev_regs_t *regs, int ss);
static void fmc516_isla216_write_instaddr_raw(uint32_t val, int ss);
static void fmc516_isla216_readw_raw(uint32_t *val, int ss);
static void fmc516_isla216_writew_raw(uint32_t val, int ss);
int fmc516_isla216_all_init()
{
int i;
for (i = 0; i < FMC516_NUM_ISLA216; ++i)
fmc516_isla216_load_regset(isla216p25_regs_default, i);
return 0;
}
int fmc516_isla216_init(int ss)
{
fmc516_isla216_load_regset(isla216p25_regs_default, ss);
return 0;
}
// isla216p25 has 16 bits for instruction/address: addr(13)+length(2)+rw(1)
static void fmc516_isla216_write_instaddr_raw(uint32_t val, int ss)
{
// three-wire mode
oc_spi_three_mode_tx(FMC516_ISLA216P25_SPI_ID, ss,
FMC516_ISLA216_INSTADDR_SIZE, val);
}
static void fmc516_isla216_readw_raw(uint32_t *val, int ss)
{
// three-wire mode
oc_spi_three_mode_rx(FMC516_ISLA216P25_SPI_ID, ss,
FMC516_ISLA216_WORD_SIZE, val);
}
static void fmc516_isla216_writew_raw(uint32_t val, int ss)
{
// three-wire mode
oc_spi_three_mode_tx(FMC516_ISLA216P25_SPI_ID, ss,
FMC516_ISLA216_WORD_SIZE, val);
}
void fmc516_isla216_write_instaddr(int addr, int length, int read, int ss)
{
uint32_t fmc516_isla216_reg;
// 1-byte length
fmc516_isla216_reg = FMC516_ISLA216_ADDR(addr) |
FMC516_ISLA216_LENGTH(length-1);
if (read)
fmc516_isla216_reg |= FMC516_ISLA216_READ;
fmc516_isla216_write_instaddr_raw(fmc516_isla216_reg, ss);
}
//ISLA216_CALSTATUS_REG
// word is 8-bit (1 byte) long for isla216p25
int fmc516_isla216_read_byte(int addr, int ss)
{
uint32_t val;
// TESTING! LENGTH MUST BE 1
fmc516_isla216_write_instaddr(addr, 1, 1, ss);
// Read the desired byte
fmc516_isla216_readw_raw(&val, ss);
dbg_print("fmc_read_byte: 0X%8X\n", val);
return val & 0xff;
}
void fmc516_isla216_write_byte(int val, int addr, int ss)
{
fmc516_isla216_write_instaddr(addr, 1, 0, ss);
// Write the desired byte
fmc516_isla216_writew_raw(val, ss);
}
// Read up to 4 bytes
int fmc516_isla216_read_n(int addr, int length, int ss)
{
int i;
int ret = 0;
int mask = 0;
uint32_t fmc516_isla216_val;
// n-byte length
fmc516_isla216_write_instaddr(addr, length, 1, ss);
// Read the desired bytes
for (i = 0; i < length; ++i) {
fmc516_isla216_readw_raw(&fmc516_isla216_val, ss);
ret |= (fmc516_isla216_val & 0xff) << 8*i;
mask |= (0xff << 8*i);
}
return ret & mask;
}
// Write up to 4 bytes
void fmc516_isla216_write_n(int val, int addr, int length, int ss)
{
int i;
// n-byte length
fmc516_isla216_write_instaddr(addr, length, 0, ss);
// Write the desired bytes
for (i = 0; i < length; ++i) {
fmc516_isla216_writew_raw(val >> 8*i, ss);
}
}
static void fmc516_isla216_load_regset(const struct default_dev_regs_t *regs, int ss)
{
int i = 0;
while (regs[i].type != REGS_DEFAULT_END){
if (regs[i].type == REGS_DEFAULT_INIT)
fmc516_isla216_write_byte(regs[i].val, regs[i].addr, ss);
++i;
}
}
/*
* Specififc ISLA216P Functions
*/
int fmc516_isla216_chkcal_stat(int ss)
{
return fmc516_isla216_read_byte(ISLA216_CALSTATUS_REG, ss) & 0x01;
}
void fmc516_isla216_test_ramp(int ss)
{
fmc516_isla216_write_byte(ISLA216_OUT_TESTMODE(ISLA216_OUT_TESTIO_RAMP),
ISLA216_TESTIO_REG, ss);
}
void fmc516_isla216_test_midscale(int ss)
{
fmc516_isla216_write_byte(ISLA216_OUT_TESTMODE(ISLA216_OUT_TESTIO_MIDSHORT),
ISLA216_TESTIO_REG, ss);
}
int fmc516_isla216_get_chipid(int ss)
{
return fmc516_isla216_read_byte(ISLA216_CHIPID_REG, ss) & 0xff;
}
int fmc516_isla216_get_chipver(int ss)
{
return fmc516_isla216_read_byte(ISLA216_CHIPVER_REG, ss) & 0xff;
}
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "debug_print.h"
#include "lmk02000.h"
#include "lmk02000_regs.h"
/*
* Which SPI ID is lmk02000? See board.h for definitions.
* Should be dynamically detected...
*/
static void fmc516_lmk02000_load_regset(const struct default_dev_regs_t *regs);
int fmc516_lmk02000_init(void)
{
dbg_print("> fmc516_lmk02000_init...\n");
fmc516_lmk02000_load_regset(lmk02000_regs_default);
return 0;
}
// lmk02000 has 28 msb value and 4 lsb addr
void fmc516_lmk02000_write_reg(int val)
{
dbg_print("> fmc516_lmk02000_write_reg...\n");
oc_spi_txrx(FMC516_LMK02000_SPI_ID, FMC516_LMK02000_CS,
FMC516_LMK02000_SIZE, val, 0);
}
// No readback is available for lmk02000
/*
int fmc516_lmk02000_read_reg(int addr)
{
}
*/
static void fmc516_lmk02000_load_regset(const struct default_dev_regs_t *regs)
{
int i = 0;
dbg_print("> fmc516_lmk02000_load_regset...\n");
while (regs[i].type != REGS_DEFAULT_END){
dbg_print("> fmc516_lmk02000_load_regset while: %d...\n", i);
if (regs[i].type == REGS_DEFAULT_INIT)
fmc516_lmk02000_write_reg(regs[i].val);
++i;
}
}
../boards/ml605/board.h
\ No newline at end of file
......@@ -3,28 +3,28 @@
#include "inttypes.h"
/*
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_dma.vhd
*/
/*
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_dma.vhd
*/
struct DMA_WB
{
uint32_t RD_ADDR; /* Read issue address register */
uint32_t WR_ADDR; /* Write issue address register */
uint32_t RD_STRD; /* Read stride */
uint32_t WR_STRD; /* Write stride */
uint32_t TR_COUNT; /* Transfer count */
uint32_t RD_ADDR; /* Read issue address register */
uint32_t WR_ADDR; /* Write issue address register */
uint32_t RD_STRD; /* Read stride */
uint32_t WR_STRD; /* Write stride */
uint32_t TR_COUNT; /* Transfer count */
};
typedef volatile struct DMA_WB dma_t;
/* DMA user interface */
int dma_init(void);
int read_is_addr(void);
void write_is_addr(int addr);
int read_strd(void);
void write_strd(int strd);
int read_tr_count(void);
int read_is_addr(unsigned int id);
void write_is_addr(unsigned int id, int addr);
int read_strd(unsigned int id);
void write_strd(unsigned int id, int strd);
int read_tr_count(unsigned int id);
#endif
......@@ -16,9 +16,9 @@ typedef volatile struct ETHMAC_ADAPT ethmac_adapt_t;
int ethmac_adapt_init(void);
/* User interface */
int ethmac_adapt_set_base(unsigned int base_rx, unsigned int base_tx);
int ethmac_adapt_set_length(unsigned int length);
int ethmac_adapt_go(void);
int ethmac_adapt_set_base(unsigned int id, unsigned int base_rx, unsigned int base_tx);
int ethmac_adapt_set_length(unsigned int id, unsigned int length);
int ethmac_adapt_go(unsigned int id);
#endif
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "debug_print.h"
#include "hw/wb_fmc516.h"
#include "isla216p25.h"
#include "lmk02000.h"
#define DEFAULT_FMC516_ID 0
/* Type definitions */
typedef volatile struct FMC516_WB fmc516_t;
int fmc516_init(void);
int fmc516_exit(void);
// For now just ta few registers are initialized
void fmc516_init_regs(unsigned int id);
void fmc516_clk_sel(unsigned int id, int ext_clk);
void fmc516_led0(unsigned int id, int on);
void fmc516_led1(unsigned int id, int on);
void fmc516_reset_adcs(unsigned int id);
void fmc516_resetdiv_adcs(unsigned int id);
void fmc516_update_clk_dly(unsigned int id);
void fmc516_update_data_dly(unsigned int id);
/* Fix This! Code repetition! Fixed? */
void fmc516_adj_delay(unsigned int id, int ch, int clk_dly, int data_dly, int commit);
//void fmc516_adj_ch0_delay(unsigned int id, int clk_dly, int data_dly, int commit);
//void fmc516_adj_ch1_delay(unsigned int id, int clk_dly, int data_dly, int commit);
//void fmc516_adj_ch2_delay(unsigned int id, int clk_dly, int data_dly, int commit);
//void fmc516_adj_ch3_delay(unsigned int id, int clk_dly, int data_dly, int commit);
void fmc516_sweep_delays(unsigned int id);
uint32_t fmc516_read_adc0(unsigned int id);
uint32_t fmc516_read_adc1(unsigned int id);
uint32_t fmc516_read_adc2(unsigned int id);
uint32_t fmc516_read_adc3(unsigned int id);
void fmc516_fe_dly(unsigned int id, int ch, int fe_dly_d1, int fe_dly_d2);
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "regs.h"
#define FMC516_ISLA216_ADC0 0
#define FMC516_ISLA216_SS_ADC0 ((1 << 0) & 0xff)
#define FMC516_ISLA216_ADC1 1
#define FMC516_ISLA216_SS_ADC1 ((1 << 1) & 0xff)
#define FMC516_ISLA216_ADC2 2
#define FMC516_ISLA216_SS_ADC2 ((1 << 2) & 0xff)
#define FMC516_ISLA216_ADC3 3
#define FMC516_ISLA216_SS_ADC3 ((1 << 3) & 0xff)
#define FMC516_NUM_ISLA216 4
#define FMC516_ISLA216_RW_SIZE 1
#define FMC516_ISLA216_RW_OFS 15
#define FMC516_ISLA216_RW_MASK 0x8000
#define FMC516_ISLA216_RW(x) (((x) << FMC516_ISLA216_RW_OFS) & FMC516_ISLA216_RW_MASK)
#define FMC516_ISLA216_READ (FMC516_ISLA216_RW(1))
//#define FMC516_ISLA216_WRITE (~FMC516_ISLA216_READ)
#define FMC516_ISLA216_LENGTH_SIZE 2
#define FMC516_ISLA216_LENGTH_OFS 13
#define FMC516_ISLA216_LENGTH_MASK 0x6000
#define FMC516_ISLA216_LENGTH(x) (((x) << FMC516_ISLA216_LENGTH_OFS) & FMC516_ISLA216_LENGTH_MASK)
#define FMC516_ISLA216_ADDR_SIZE 13
#define FMC516_ISLA216_ADDR_OFS 0
#define FMC516_ISLA216_ADDR_MASK 0x1FFF
#define FMC516_ISLA216_ADDR(x) (((x) << FMC516_ISLA216_ADDR_OFS) & FMC516_ISLA216_ADDR_MASK)
#define FMC516_ISLA216_INSTADDR_SIZE (FMC516_ISLA216_RW_SIZE + \
FMC516_ISLA216_LENGTH_SIZE + \
FMC516_ISLA216_ADDR_SIZE)
#define FMC516_ISLA216_WORD_SIZE 8
/*
* Internal ISLA216P register description from ISLA216P25
* datasheet Incomplete! Byte addressed!
*/
#define ISLA216_PORTCONFIG_REG 0x00000000
//#define ISLA216_RES0_REG 0x00000001
#define SPI_REG_BURSTEND_REG 0x00000002
//#define ISLA216_RES1_REG 0x00000003
//#define ISLA216_RES2_REG 0x00000004
//#define ISLA216_RES3_REG 0x00000005
//#define ISLA216_RES4_REG 0x00000006
//#define ISLA216_RES5_REG 0x00000007
#define ISLA216_CHIPID_REG 0x00000008
#define ISLA216_CHIPID_MASK 0xff
#define ISLA216_CHIPVER_REG 0x00000009
#define ISLA216_CHIPVER_MASK 0xff
//#define ISLA216_RES6_REG 0x0000000a
//#define ISLA216_RES7_REG 0x0000000b
//#define ISLA216_RES8_REG 0x0000000c
//#define ISLA216_RES9_REG 0x0000000d
//#define ISLA216_RES10_REG 0x0000000e
//#define ISLA216_RES11_REG 0x0000000f
//
//#define ISLA216_RES12_REG 0x00000010
//#define ISLA216_RES13_REG 0x00000011
//#define ISLA216_RES14_REG 0x00000012
//#define ISLA216_RES15_REG 0x00000013
//#define ISLA216_RES16_REG 0x00000014
//#define ISLA216_RES17_REG 0x00000015
//#define ISLA216_RES18_REG 0x00000016
//#define ISLA216_RES19_REG 0x00000017
//#define ISLA216_RES20_REG 0x00000018
//#define ISLA216_RES21_REG 0x00000019
//#define ISLA216_RES22_REG 0x0000001a
//#define ISLA216_RES23_REG 0x0000001b
//#define ISLA216_RES24_REG 0x0000001c
//#define ISLA216_RES25_REG 0x0000001d
//#define ISLA216_RES26_REG 0x0000001e
//#define ISLA216_RES27_REG 0x0000001f
#define ISLA216_MODESADC0_REG 0x00000025
#define ISLA216_MODESADC1_REG 0x0000002b
#define ISLA216_CLKDIV_REG 0x00000072
#define ISLA216_OUTMODEA_REG 0x00000073
#define ISLA216_OUTFMT_MASK 0x00000007
#define ISLA216_OUTFMT_OFS 0
#define ISLA216_OUTFMT(x) (((x) << ISLA216_OUTFMT_OFS) & ISLA216_OUTFMT_MASK)
#define ISLA216_OUTFMT_2COMPL 0
#define ISLA216_OUTFMT_GRAYCODE (1<<1)
#define ISLA216_OUTFMT_OFSBIN (1<<2)
#define ISLA216_OUTMODE_MASK 0x000000E0
#define ISLA216_OUTMODE_OFS 4
#define ISLA216_OUTMODE(x) (((x) << ISLA216_OUTMODE_OFS) & ISLA216_OUTMODE_MASK)
#define ISLA216_OUTMODE_LVDS3 0
#define ISLA216_OUTMODE_LVDS2 1
#define ISLA216_OUTMODE_LVCMOS (1<<2)
#define ISLA216_OUTMODEB_REG 0x00000074
#define ISLA216_CALSTATUS_REG 0x000000b6
#define ISLA216_CALDONE_MASK 0x1
#define ISLA216_TESTIO_REG 0x000000C0
#define ISLA216_USR_TESTMODE_MASK 0x00000007
#define ISLA216_USR_TESTMODE_OFS 0
#define ISLA216_USR_TESTMODE(x) (((x) << ISLA216_USR_TESTMODE_OFS) & ISLA216_USR_TESTMODE_MASK)
#define ISLA216_USR_TESTIO_USRPAT1 0
#define ISLA216_USR_TESTIO_CYCPAT13 1
#define ISLA216_USR_TESTIO_CYCPAT135 2
#define ISLA216_USR_TESTIO_CYCPAT1357 3
#define ISLA216_OUT_TESTMODE_MASK 0x000000f0
#define ISLA216_OUT_TESTMODE_OFS 4
#define ISLA216_OUT_TESTMODE(x) (((x) << ISLA216_OUT_TESTMODE_OFS) & ISLA216_OUT_TESTMODE_MASK)
#define ISLA216_OUT_TESTIO_OFF 0
#define ISLA216_OUT_TESTIO_MIDSHORT 1
#define ISLA216_OUT_TESTIO_PLUS_FSSHORT 2
#define ISLA216_OUT_TESTIO_MINUS_FSSHORT 3
#define ISLA216_OUT_TESTIO_RES0 4
#define ISLA216_OUT_TESTIO_RES1 5
#define ISLA216_OUT_TESTIO_RES2 6
#define ISLA216_OUT_TESTIO_RES3 7
#define ISLA216_OUT_TESTIO_USRPAT 8
#define ISLA216_OUT_TESTIO_RES4 9
#define ISLA216_OUT_TESTIO_RAMP 10
#define ISLA216_OUT_TESTIO_RES5 11
#define ISLA216_OUT_TESTIO_RES6 12
#define ISLA216_OUT_TESTIO_RES7 13
#define ISLA216_OUT_TESTIO_RES8 14
#define ISLA216_OUT_TESTIO_RES9 15
/*
* ISLA216P Functions
*/
int fmc516_isla216_init(int ss);
int fmc516_isla216_all_init(void);
void fmc516_isla216_write_instaddr(int addr, int length, int read, int ss);
// word is 8-bit (1 byte) long for isla216p25
int fmc516_isla216_read_byte(int addr, int ss);
void fmc516_isla216_write_byte(int val, int addr, int ss);
// Read up to 4 bytes
int fmc516_isla216_read_n(int addr, int length, int ss);
// Write up to 4 bytes
void fmc516_isla216_write_n(int val, int addr, int length, int ss);
/*
* Convinient ISLA216P Functions
*/
int fmc516_isla216_chkcal_stat(int ss);
void fmc516_isla216_test_ramp(int ss);
int fmc516_isla216_get_chipid(int ss);
int fmc516_isla216_get_chipver(int ss);
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "regs.h"
// isla216p25 has 8-bit value and 13-bit register address
const struct default_dev_regs_t isla216p25_regs_default[] =
{
/*
{REGS_DEFAULT_INIT, 1, 0x0, 1 << 1 },
{REGS_DEFAULT_INIT, 1, 0x0, 1 << 0 },
*/
{REGS_DEFAULT_INIT, 1, 0x00, 1 << 5 },
{REGS_DEFAULT_INIT, 1, 0x00, 0 << 5 },
{REGS_DEFAULT_INIT, 1, 0x2b, 1 << 0 },
{REGS_DEFAULT_INIT, 1, 0x72, 1 << 0 },
{REGS_DEFAULT_END, 0, 0 , 0 }
};
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include "board.h" // Board definitions: SPI device structure
#include "spi.h" // SPI device functions
#include "regs.h"
#define FMC516_LMK02000_CS 0
#define FMC516_LMK02000_VAL_SIZE 28
#define FMC516_LMK02000_VAL_OFS 4
#define FMC516_LMK02000_ADDR_SIZE 4
#define FMC516_LMK02000_ADDR_OFS 0
#define FMC516_LMK02000_SIZE (FMC516_LMK02000_VAL_SIZE + FMC516_LMK02000_ADDR_SIZE)
int fmc516_lmk02000_init(void);
// lmk02000 has 28 msb value and 4 lsb addr
void fmc516_lmk02000_write_reg(int val);
/*
* Copyright (C) 2013 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "regs.h"
// lmk02000 has 28 msb value and 4 lsb addr
const struct default_dev_regs_t lmk02000_regs_default[] =
{
{REGS_DEFAULT_INIT, 4, 0x0, 1 << 31 },
{REGS_DEFAULT_INIT, 4, 0x0, 1 << 8 },
{REGS_DEFAULT_NO_INIT, 4, 0x1, 0 },
{REGS_DEFAULT_INIT, 4, 0x2, (1<<16)|(1<<8)|2 },
{REGS_DEFAULT_NO_INIT, 4, 0x3, 0 },
{REGS_DEFAULT_INIT, 4, 0x4, (1<<16)|(1<<8)| 4 },
{REGS_DEFAULT_INIT, 4, 0x5, (1<<16)|(1<<8)| 5 },
{REGS_DEFAULT_INIT, 4, 0x6, (1<<16)|(1<<8)| 6 },
{REGS_DEFAULT_INIT, 4, 0x7, (1<<16)|(1<<8)| 7 },
/*
{REGS_TYPE_RESERVED, 4, 0x8, 0 },
{REGS_TYPE_RESERVED, 4, 0x9, 0 },
{REGS_TYPE_RESERVED, 4, 0xa, 0 },
*/
{REGS_DEFAULT_NO_INIT, 4, 0xb, 0 },
/*
{REGS_TYPE_RESERVED, 4, 0xc, 0 },
{REGS_TYPE_RESERVED, 4, 0xd, 0 },
*/
{REGS_DEFAULT_INIT, 4, 0xe, 0x2b100100|14 },
{REGS_DEFAULT_NO_INIT, 4, 0xf, 0x4003e800|15 },
{REGS_DEFAULT_END, 0, 0 , 0 }
};
//const struct default_dev_regs_t lmk02000_regs_default[] =
//{
// // Power down LMK02000 (1<<26)
// {REGS_DEFAULT_INIT, 4, 0xe, (1<<26)|14 },
// {REGS_DEFAULT_END, 0, 0 , 0 }
//};
......@@ -4,8 +4,8 @@
#include "inttypes.h"
/*
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_gpio_port.vhd
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_gpio_port.vhd
*/
struct GPIO_WB
{
......@@ -20,9 +20,10 @@ typedef volatile struct GPIO_WB gpio_t;
/* GPIO user interface */
int gpio_init(void);
void gpio_out(int pin, int val);
void gpio_dir(int pin, int val);
int gpio_in(int pin);
int gpio_exit(void);
void gpio_out(unsigned int id, int pin, int val);
void gpio_dir(unsigned int id,int pin, int val);
int gpio_in(unsigned int id,int pin);
#endif
......@@ -8,38 +8,47 @@
//#define NUM_GPIO_DEVS 2
/* Simple device nodes for supporting various instances
of the same component */
of the same component */
struct dev_node{
//int i;
unsigned char *base;
//unsigned char *end;
//struct dev_node *parent;
struct dev_node *next;
};
/* List of devices of the same kind (same devid).*/
struct dev_list{
unsigned int devid;
//unsigned int size;
unsigned int size;
struct dev_node *devices;
};
/* Automate the address peripheral discover. use SDB */
#define SDB_ADDRESS 0x30000000
//unsigned char *BASE_DMA;
//unsigned char *BASE_FMA150;
//unsigned char *BASE_UART;
//unsigned char *BASE_GPIO;
struct dev_list *ethmac_buf_devl;
//General components
struct dev_list *mem_devl;
struct dev_list *dma_devl;
struct dev_list *fmc150_devl;
struct dev_list *uart_devl;
struct dev_list *gpio_devl;
struct dev_list *ethmac_devl;
struct dev_list *ethmac_adapt_devl;
struct dev_list *ebone_cfg_devl;
// FMC516 components
struct dev_list *fmc516_devl;
struct dev_list *spi_devl;
struct dev_list *i2c_devl;
struct dev_list *owr_devl;
// Peripheral components
struct dev_list *uart_devl;
struct dev_list *gpio_devl;
struct dev_list *tics_devl;
// Unused components
struct dev_list *fmc150_devl;
//#define FMC_EEPROM_ADR 0x50
void sdb_find_devices(void);
......
/*
Register definitions for slave core: FMC ADC/DAC interface registers
Register definitions for slave core: FMC ADC/DAC interface registers
* File : wb_fmc150.h
* Author : auto-generated by wbgen2 from xfmc150.wb
......
This diff is collapsed.
#ifndef __I2C_REGDEFS_WB
#define __I2C_REGDEFS_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
// OpenCores I2C registers description
#define I2C_PREL 0x00000000
#define I2C_PREH 0x00000004
#define I2C_CTR 0x00000008
#define I2C_TXR 0x0000000C
#define I2C_RXR 0x0000000C
#define I2C_CR 0x00000010
#define I2C_SR 0x00000010
#define I2C_CTR_EN (1<<7)
#define I2C_TXR_READ (1<<0)
#define I2C_CR_STA (1<<7)
#define I2C_CR_STO (1<<6)
#define I2C_CR_RD (1<<5)
#define I2C_CR_WR (1<<4)
#define I2C_CR_ACK (1<<3)
#define I2C_SR_RXACK (1<<7)
#define I2C_SR_TIP (1<<1)
#define I2C_ADDR(x) (((x) << 1) & 0xff)
PACKED struct I2C_WB {
uint32_t PREL;
uint32_t PREH;
uint32_t CTR;
uint32_t TXR;
uint32_t RXR;
uint32_t CR;
uint32_t SR;
};
#endif
#ifndef __OWR_REGDEFS_WB
#define __OWR_REGDEFS_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
// OpenCores 1-wire registers description
#define OWR_CSR 0x00000000
#define OWR_CDR 0x00000004
#define OWR_CSR_DAT (1<<0)
#define OWR_CSR_RST (1<<1)
#define OWR_CSR_OVD (1<<2)
#define OWR_CSR_CYC (1<<3)
#define OWR_CSR_PWR (1<<4)
#define OWR_CSR_IRQ (1<<6)
#define OWR_CSR_IEN (1<<7)
#define OWR_CSR_SEL_OFS 8
#define OWR_CSR_SEL_MASK (0xF << OWR_CSR_SEL_OFS)
#define OWR_CSR_SEL(x) (((x) << OWR_CSR_SEL_OFS) & OWR_CSR_SEL_MASK)
#define OWR_CSR_POWER_OFS 16
#define OWR_CSR_POWER_MASK (0xFFFF << OWR_CSR_POWER_OFS)
#define OWR_CSR_POWER(x) (((x) << OWR_CSR_POWER_OFS) & OWR_CSR_POWER_MASK)
#define OWR_CDR_NOR_OFS 0
#define OWR_CDR_NOR_MASK (0xFFFF << OWR_CDR_NOR_OFS)
#define OWR_CDR_NOR(x) (((x) << OWR_CDR_NOR_OFS) & OWR_CDR_NOR_MASK)
#define OWR_CDR_OVD_OFS 16
#define OWR_CDR_OVD_MASK (0XFFFF << OWR_CDR_OVD_OFS)
#define OWR_CDR_OVD(x) (((x) << OWR_CDR_OVD_OFS) & OWR_CDR_OVD_MASK)
PACKED struct OWR_WB {
uint32_t CSR;
uint32_t CDR;
};
#endif
#ifndef __SPI_REGDEFS_WB
#define __SPI_REGDEFS_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
//OpenCores SPI registers description
#define SPI_REG_RX0 0x00000000
#define SPI_REG_TX0 0x00000000
#define SPI_REG_RX1 0x00000004
#define SPI_REG_TX1 0x00000004
#define SPI_REG_RX2 0x00000008
#define SPI_REG_TX2 0x00000008
#define SPI_REG_RX3 0x0000000C
#define SPI_REG_TX3 0x0000000C
#define SPI_REG_CTRL 0x00000010
#define SPI_REG_DIVIDER 0x00000014
#define SPI_REG_SS 0x00000018
#define SPI_CTRL_THREE_WIRE (1<<16)
#define SPI_CTRL_RES2 (1<<15)
#define SPI_CTRL_DIR (1<<14)
#define SPI_CTRL_ASS (1<<13)
#define SPI_CTRL_IE (1<<12)
#define SPI_CTRL_LSB (1<<11)
#define SPI_CTRL_TXNEG (1<<10)
#define SPI_CTRL_RXNEG (1<<9)
#define SPI_CTRL_GO_BSY (1<<8)
#define SPI_CTRL_BSY (1<<8)
#define SPI_CTRL_CHAR_LEN(x) ((x) & 0x7f)
#define SPI_CTRL_SS(x) ((x) & 0xff)
#define SPI_LGH_MASK 0x7F
#define SPI_DIV_MASK 0xFFFF
PACKED struct SPI_WB {
union {
uint32_t RX0;
uint32_t TX0;
};
union {
uint32_t RX1;
uint32_t TX1;
};
union {
uint32_t RX2;
uint32_t TX2;
};
union {
uint32_t RX3;
uint32_t TX3;
};
uint32_t CTRL;
uint32_t DIVIDER;
uint32_t SS;
};
#endif
/*
Register definitions for slave core: Simple Wishbone UART
Register definitions for slave core: Simple Wishbone UART
* File : ../../../../software/include/hw/wb_uart.h
* Author : auto-generated by wbgen2 from uart.wb
......
/*
Register definitions for slave core: Virtual UART
Register definitions for slave core: Virtual UART
* File : wb_vuart.h
* Author : auto-generated by wbgen2 from wb_virtual_uart.wb
......
#ifndef _I2C_H_
#define _I2C_H_
/* Hardware definitions */
#include <hw/wb_i2c.h>
/*
* wb_clk_i
* prescaler = --------- - 1
* 5*scl
*
* For wb_clk_i = 100MHz and desired scl = 100 KHz:
* prescaler = 0.2*10^3 - 1 = 199
*/
#define DEFAULT_I2C_PRESCALER 199
/* Type definitions */
typedef volatile struct I2C_WB i2c_t;
/* I2C API */
int i2c_init(void);
void i2c_exit(void);
int oc_i2c_poll(unsigned int id);
int oc_i2c_start(unsigned int id, int addr, int read);
int oc_i2c_rx(unsigned int id, uint32_t *out, int last);
int oc_i2c_tx(unsigned int id, uint32_t in, int last);
int oc_i2c_scan(unsigned int id);
#endif
#ifndef _ONEWIRE_H_
#define _ONEWIRE_H_
/* Hardware definitions */
#include <hw/wb_onewire.h>
//clk_div_nor = clock divider normal operation, clk_div_nor = Fclk * 5E-6 - 1
//clk_div_ovd = clock divider overdrive operation, clk_div_ovd = Fclk * 1E-6 - 1
// Clock divider for 100MHz bus clock
#define DEFAULT_OWR_DIVIDER_NOR 499
#define DEFAULT_OWR_DIVIDER_OVD 99
/* Type definitions */
typedef volatile struct OWR_WB owr_t;
/* Onewire API */
int owr_init(void);
void owr_exit(void);
int oc_owr_poll(unsigned int id);
int oc_owr_reset(unsigned int id, int port);
int oc_owr_slot(unsigned int id, int port, uint32_t in_bit, uint32_t *out_bit);
int oc_owr_read_bit(unsigned int id, int port, uint32_t *out_bit);
int oc_owr_write_bit(unsigned int id, int port, uint32_t in_bit, uint32_t *out_bit);
int read_byte(unsigned int id, int port, uint32_t *out_byte);
int write_byte(unsigned int id, int port, uint32_t in_byte);
#endif
......@@ -8,8 +8,26 @@
#ifndef _REGS_H_
#define _REGS_H_
#define READ_ONLY 0x1
#define WRITE_ONLY 0x2
#define READ_WRITE (READ_ONLY | WRITE_ONLY)
#include <inttypes.h>
#define REGS_DEFAULT_NO_INIT 0
#define REGS_DEFAULT_INIT 1
#define REGS_DEFAULT_END 2
#define REGS_TYPE_READ_ONLY (1 << 0)
#define REGS_TYPE_WRITE_ONLY (1 << 1)
#define REGS_TYPE_READ_WRITE (1 << 2)
#define REGS_TYPE_RESERVED (1 << 3)
#define REGS_DEFAULT_SIZE 4
#define REGS_DEFAULT_TYPE REGS_READ_WRITE
struct default_dev_regs_t
{
uint8_t type;
uint8_t size; // in bytes
uint32_t addr;
uint32_t val;
};
#endif
#ifndef _SPI_H_
#define _SPI_H_
/* Hardware definitions */
#include <hw/wb_spi.h>
/*
* fsclk = fs_wbclk / (divider+1)*2
*/
#define DEFAULT_SPI_DIVIDER 99
//#define DEFAULT_SPI_DIVIDER 9
/* Type definitions */
typedef volatile struct SPI_WB spi_t;
/* SPI API */
int spi_init(void);
void spi_exit(void);
int oc_spi_poll(unsigned int id);
int oc_spi_three_mode(unsigned int id);
void oc_spi_config(unsigned int id, int ass, int rx_neg, int tx_neg,
int lsb, int ie);
// For use only with spi three-wire mode
int oc_spi_three_mode_tx(unsigned int id, int ss, int nbits, uint32_t in);
// For use only with spi three-wire mode
int oc_spi_three_mode_rx(unsigned int id, int ss, int nbits, uint32_t *out);
int oc_spi_txrx(unsigned int id, int ss, int nbits, uint32_t in, uint32_t *out);
#endif
......@@ -4,6 +4,9 @@
/* Hardware definitions */
#include <hw/wb_vuart.h>
// Default UART index to output text
#define DEFAULT_UART 0
/* Type definitions */
typedef volatile struct UART_WB uart_t;
......@@ -11,10 +14,11 @@ int mprintf(char const *format, ...);
/* UART API */
int uart_init(void);
void uart_write_byte(int b);
void uart_write_string(char *s);
int uart_exit(void);
void uart_write_byte(unsigned int id, int b);
void uart_write_string(unsigned int id, char *s);
int puts(const char *s);
int uart_poll(void);
int uart_read_byte(void);
int uart_poll(unsigned int id);
int uart_read_byte(unsigned int id);
#endif
......@@ -3,19 +3,19 @@
void debug_print(const char *fmt, ...)
{
va_list l;
va_list l;
va_start(l, fmt);
pp_printf(fmt, l);
va_end(l);
va_start(l, fmt);
pp_printf(fmt, l);
va_end(l);
}
void debug_print2(const char *fmt, const char *data, int len)
{
int i;
int i;
for (i = 0; i < len; ++i)
pp_printf(fmt, data[i]);
for (i = 0; i < len; ++i)
pp_printf(fmt, data[i]);
pp_printf("\n");
pp_printf("\n");
}
......@@ -12,13 +12,13 @@
#include "pp-printf.h"
void debug_print(const char *fmt, ...);
//__attribute__((format(printf,1,2)));
//__attribute__((format(printf,1,2)));
void debug_print2(const char *fmt, const char *data, int len);
#ifdef DEBUG_PRINT
#define dbg_print(fmt, ...) \
pp_printf("%s (%d): "fmt, __FILE__, __LINE__, ##__VA_ARGS__)
pp_printf("%s: %s (%d): "fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define dbg_print2(fmt, data, len) \
debug_print2(fmt, data, len)
#else
......
......@@ -5,100 +5,100 @@
static void oeth_rx(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
volatile oeth_bd *rx_bdp;
int pkt_len, i;
int bad = 0;
dbg_print("oeth_rx:\n");
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
/* Find RX buffers marked as having received data */
for(i = 0; i < OETH_RXBD_NUM; i++)
{
dbg_print("> rxbd_num: %d\n", i);
bad=0;
/* Looking for buffer descriptors marked not empty */
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){
/* Check status for errors.
*/
dbg_print("> len_status: 0X%8X\n", rx_bdp[i].len_status);
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
bad = 1;
dbg_print("> short!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
bad = 1;
dbg_print("> dribble!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
bad = 1;
dbg_print("> CRC error!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
bad = 1;
dbg_print("> overrun!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
bad = 1;
dbg_print("> missed!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
bad = 1;
dbg_print("> late collision!\n");
}
if (bad) {
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
}
else {
/*
* Process the incoming frame.
*/
unsigned char* buf = (unsigned char*)rx_bdp[i].addr;
dbg_print("> processing incoming packet\n");
pkt_len = rx_bdp[i].len_status >> 16;
dbg_print("> len_status: 0X%8X\n", rx_bdp[i].len_status);
dbg_print("> pkt_len_d: %d, pkt_len_h: 0X%08X\n", pkt_len, pkt_len);
user_recv(buf, pkt_len);
/* finish up */
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
}
} else {
dbg_print("> empty!\n");
}
}
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
volatile oeth_bd *rx_bdp;
int pkt_len, i;
int bad = 0;
dbg_print("oeth_rx:\n");
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
/* Find RX buffers marked as having received data */
for(i = 0; i < OETH_RXBD_NUM; i++)
{
dbg_print("> rxbd_num: %d\n", i);
bad=0;
/* Looking for buffer descriptors marked not empty */
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){
/* Check status for errors.
*/
dbg_print("> len_status: 0X%8X\n", rx_bdp[i].len_status);
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
bad = 1;
dbg_print("> short!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
bad = 1;
dbg_print("> dribble!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
bad = 1;
dbg_print("> CRC error!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
bad = 1;
dbg_print("> overrun!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
bad = 1;
dbg_print("> missed!\n");
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
bad = 1;
dbg_print("> late collision!\n");
}
if (bad) {
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
}
else {
/*
* Process the incoming frame.
*/
unsigned char* buf = (unsigned char*)rx_bdp[i].addr;
dbg_print("> processing incoming packet\n");
pkt_len = rx_bdp[i].len_status >> 16;
dbg_print("> len_status: 0X%8X\n", rx_bdp[i].len_status);
dbg_print("> pkt_len_d: %d, pkt_len_h: 0X%08X\n", pkt_len, pkt_len);
user_recv(buf, pkt_len);
/* finish up */
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
}
} else {
dbg_print("> empty!\n");
}
}
}
static void oeth_tx(void)
{
volatile oeth_bd *tx_bd;
int i;
dbg_print("oeth_tx:\n");
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
/* Go through the TX buffs, search for one that was just sent */
for(i = 0; i < OETH_TXBD_NUM; i++)
{
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
{
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
/* Probably good to check for TX errors here */
}
}
return;
volatile oeth_bd *tx_bd;
int i;
dbg_print("oeth_tx:\n");
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
/* Go through the TX buffs, search for one that was just sent */
for(i = 0; i < OETH_TXBD_NUM; i++)
{
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
{
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
/* Probably good to check for TX errors here */
}
}
return;
}
/* The interrupt handler.
......@@ -106,52 +106,52 @@ static void oeth_tx(void)
void oeth_interrupt(void* arg)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
dbg_print("oeth_interrupt:\n");
uint int_events;
int serviced;
serviced = 0;
/* Get the interrupt events that caused us to be here.
*/
int_events = regs->int_src;
regs->int_src = int_events;
dbg_print("> int_events = 0x%8X\n", int_events);
/* Handle receive event in its own function.
*/
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
serviced |= 0x1;
dbg_print("> interrupt on rx line\n");
oeth_rx();
}
/* Handle transmit event in its own function.
*/
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
serviced |= 0x2;
dbg_print("> interrupt on tx line\n");
oeth_tx();
serviced |= 0x2;
}
/* Check for receive busy, i.e. packets coming but no place to
* put them.
*/
if (int_events & OETH_INT_BUSY) {
serviced |= 0x4;
dbg_print("> receive busy\n");
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) {
oeth_rx();
}
}
dbg_print("> nothing\n");
return;
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
dbg_print("oeth_interrupt:\n");
uint int_events;
int serviced;
serviced = 0;
/* Get the interrupt events that caused us to be here.
*/
int_events = regs->int_src;
regs->int_src = int_events;
dbg_print("> int_events = 0x%8X\n", int_events);
/* Handle receive event in its own function.
*/
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
serviced |= 0x1;
dbg_print("> interrupt on rx line\n");
oeth_rx();
}
/* Handle transmit event in its own function.
*/
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
serviced |= 0x2;
dbg_print("> interrupt on tx line\n");
oeth_tx();
serviced |= 0x2;
}
/* Check for receive busy, i.e. packets coming but no place to
* put them.
*/
if (int_events & OETH_INT_BUSY) {
serviced |= 0x4;
dbg_print("> receive busy\n");
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) {
oeth_rx();
}
}
dbg_print("> nothing\n");
return;
}
......@@ -97,7 +97,7 @@ struct oeth_private {
unsigned short tx_last; /* Next buffer to be checked if packet sent */
unsigned short tx_full; /* Buffer ring fuul indicator */
unsigned short rx_cur; /* Next buffer to be checked if packet
received */
received */
oeth_regs *regs; /* Address of controller registers. */
oeth_bd *rx_bd_base; /* Address of Rx BDs. */
......@@ -623,7 +623,7 @@ main ()
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
/* clear tx_done, the tx interrupt handler will set it when it's been
transmitted */
transmitted */
tx_done = 0;
rx_done = 0;
......
......@@ -97,7 +97,7 @@ struct oeth_private {
unsigned short tx_last; /* Next buffer to be checked if packet sent */
unsigned short tx_full; /* Buffer ring fuul indicator */
unsigned short rx_cur; /* Next buffer to be checked if packet
received */
received */
oeth_regs *regs; /* Address of controller registers. */
oeth_bd *rx_bd_base; /* Address of Rx BDs. */
......@@ -627,7 +627,7 @@ main ()
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
/* clear tx_done, the tx interrupt handler will set it when it's been
transmitted */
transmitted */
tx_done = 0;
rx_done = 0;
......
This diff is collapsed.
......@@ -198,4 +198,7 @@ void tx_packet(void* data, int length);
void user_recv(unsigned char* data, int length);
/* ETHMAC init */
//int ethmac_init(void);
#endif
......@@ -5,17 +5,17 @@
#endif
extern int pp_printf(const char *fmt, ...)
__attribute__((format(printf,1,2)));
__attribute__((format(printf,1,2)));
extern int pp_sprintf(char *s, const char *fmt, ...)
__attribute__((format(printf,2,3)));
__attribute__((format(printf,2,3)));
extern int pp_vprintf(const char *fmt, va_list args);
extern int pp_vprintf(const char *fmt, va_list args);
extern int pp_vsprintf(char *buf, const char *, va_list)
__attribute__ ((format (printf, 2, 0)));
__attribute__ ((format (printf, 2, 0)));
/* This is what we rely on for output */
extern int puts(const char *s);
/* This is what we rely on for output */
extern int puts(const char *s);
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment