use symlinks for SW IP BSP files

This commit is contained in:
marqs 2019-09-30 18:56:27 +03:00
parent 077ce8afdc
commit c7fc62c038
7 changed files with 7 additions and 1656 deletions

View File

@ -1,126 +0,0 @@
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2015 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#ifndef __ALT_EPCQ_CONTROLLER_H__
#define __ALT_EPCQ_CONTROLLER_H__
#include "alt_types.h"
#include "sys/alt_flash_dev.h"
#include "sys/alt_llist.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/**
* Description of the EPCQ controller
*/
typedef struct alt_epcq_controller_dev
{
alt_flash_dev dev;
alt_u32 data_base; /** base address of data slave */
alt_u32 data_end; /** end address of data slave (not inclusive) */
alt_u32 csr_base; /** base address of CSR slave */
alt_u32 size_in_bytes; /** size of memory in bytes */
alt_u32 is_epcs; /** 1 if device is an EPCS device */
alt_u32 number_of_sectors; /** number of flash sectors */
alt_u32 sector_size; /** size of each flash sector */
alt_u32 page_size; /** page size */
alt_u32 silicon_id; /** ID of silicon used with EPCQ IP */
} alt_epcq_controller_dev;
/**
* Macros used by alt_sys_init.c to create data storage for driver instance
*/
#define ALTERA_EPCQ_CONTROLLER_MOD_AVL_MEM_AVL_CSR_INSTANCE(epcq_name, avl_mem, avl_csr, epcq_dev) \
alt_epcq_controller_dev epcq_dev = \
{ \
.dev = { \
.llist = ALT_LLIST_ENTRY, \
.name = avl_mem##_NAME, \
.write = alt_epcq_controller_write, \
.read = alt_epcq_controller_read, \
.get_info = alt_epcq_controller_get_info, \
.erase_block = alt_epcq_controller_erase_block, \
.write_block = alt_epcq_controller_write_block, \
.base_addr = ((void*)(avl_mem##_BASE)), \
.length = ((int)(avl_mem##_SPAN)), \
.lock = alt_epcq_controller_lock , \
}, \
.data_base = ((alt_u32)(avl_mem##_BASE)), \
.data_end = ((alt_u32)(avl_mem##_BASE) + (alt_u32)(avl_mem##_SPAN)), \
.csr_base = ((alt_u32)(avl_csr##_BASE)), \
.size_in_bytes = ((alt_u32)(avl_mem##_SPAN)), \
.is_epcs = ((alt_u32)(avl_mem##_IS_EPCS)), \
.number_of_sectors = ((alt_u32)(avl_mem##_NUMBER_OF_SECTORS)), \
.sector_size = ((alt_u32)(avl_mem##_SECTOR_SIZE)), \
.page_size = ((alt_u32)(avl_mem##_PAGE_SIZE)) , \
}
/*
Public API
Refer to Using Flash Devices in the
Developing Programs Using the Hardware Abstraction Layer chapter
of the Nios II Software Developer's Handbook.
*/
int alt_epcq_controller_read(alt_flash_dev *flash_info, int offset, void *dest_addr, int length);
int alt_epcq_controller_get_info(alt_flash_fd *fd, flash_region **info, int *number_of_regions);
int alt_epcq_controller_erase_block(alt_flash_dev *flash_info, int block_offset);
int alt_epcq_controller_write_block(alt_flash_dev *flash_info, int block_offset, int data_offset, const void *data, int length);
int alt_epcq_controller_write(alt_flash_dev *flash_info, int offset, const void *src_addr, int length);
int alt_epcq_controller_lock(alt_flash_dev *flash_info, alt_u32 sectors_to_lock);
/*
* Initialization function
*/
extern alt_32 altera_epcq_controller_init(alt_epcq_controller_dev *dev);
/*
* alt_sys_init.c will call this macro automatically initialize the driver instance
*/
#define ALTERA_EPCQ_CONTROLLER_MOD_INIT(name, dev) \
altera_epcq_controller_init(&dev);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __ALT_EPCQ_CONTROLLER_H__ */

View File

@ -0,0 +1 @@
../../../../ip/altera_epcq_controller_mod/HAL/inc/altera_epcq_controller_mod.h

View File

@ -1,260 +0,0 @@
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2014 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#ifndef __ALTERA_EPCQ_CONTROLLER_REGS_H__
#define __ALTERA_EPCQ_CONTROLLER_REGS_H__
#include <io.h>
/*
* EPCQ_RD_STATUS register offset
*
* The EPCQ_RD_STATUS register contains information from the read status
* register operation. A full description of the register can be found in the
* data sheet,
*
*/
#define ALTERA_EPCQ_CONTROLLER_STATUS_REG (0x0)
/*
* EPCQ_RD_STATUS register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_STATUS(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_STATUS(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_STATUS(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_STATUS_REG, data)
/*
* EPCQ_RD_STATUS register description macros
*/
/** Write in progress bit */
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_AVAILABLE (0x00000000)
#define ALTERA_EPCQ_CONTROLLER_STATUS_WIP_BUSY (0x00000001)
/** When to time out a poll of the write in progress bit */
/* 0.7 sec time out */
#define ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE 700000
/*
* EPCQ_RD_SID register offset
*
* The EPCQ_RD_SID register contains the information from the read silicon ID
* operation and can be used to determine what type of EPCS device we have.
* Only support in EPCS16 and EPCS64.
*
* This register is valid only if the device is an EPCS.
*
*/
#define ALTERA_EPCQ_CONTROLLER_SID_REG (0x4)
/*
* EPCQ_RD_SID register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_SID(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_SID_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_SID(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_SID_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_SID(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_SID_REG, data)
/*
* EPCQ_RD_SID register description macros
*
* Specific device values obtained from Table 14 of:
* "Serial Configuration (EPCS) Devices Datasheet"
*/
#define ALTERA_EPCQ_CONTROLLER_SID_MASK (0x000000FF)
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS16 (0x00000014)
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS64 (0x00000016)
#define ALTERA_EPCQ_CONTROLLER_SID_EPCS128 (0x00000018)
/*
* EPCQ_RD_RDID register offset
*
* The EPCQ_RD_RDID register contains the information from the read memory
* capacity operation and can be used to determine what type of EPCQ device
* we have.
*
* This register is only valid if the device is an EPCQ.
*
*/
#define ALTERA_EPCQ_CONTROLLER_RDID_REG (0x8)
/*
* EPCQ_RD_RDID register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_RDID(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_RDID_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_RDID(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_RDID_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_RDID(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_RDID_REG, data)
/*
* EPCQ_RD_RDID register description macros
*
* Specific device values obtained from Table 28 of:
* "Quad-Serial Configuration (EPCQ (www.altera.com/literature/hb/cfg/cfg_cf52012.pdf))
* Devices Datasheet"
*/
#define ALTERA_EPCQ_CONTROLLER_RDID_MASK (0x000000FF)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ16 (0x00000015)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ32 (0x00000016)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ64 (0x00000017)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ128 (0x00000018)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ256 (0x00000019)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ512 (0x00000020)
#define ALTERA_EPCQ_CONTROLLER_RDID_EPCQ1024 (0x00000021)
/*
* EPCQ_MEM_OP register offset
*
* The EPCQ_MEM_OP register is used to do memory protect and erase operations
*
*/
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_REG (0xC)
/*
* EPCQ_MEM_OP register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_MEM_OP(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_MEM_OP(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_MEM_OP_REG, data)
/*
* EPCQ_MEM_OP register description macros
*/
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_CMD_MASK (0x00000003)
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_BULK_ERASE_CMD (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_ERASE_CMD (0x00000002)
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_PROTECT_CMD (0x00000003)
/** see datasheet for sector values */
#define ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_VALUE_MASK (0x00FFFF00)
/*
* EPCQ_ISR register offset
*
* The EPCQ_ISR register is used to determine whether an invalid write or erase
* operation triggered an interrupt
*
*/
#define ALTERA_EPCQ_CONTROLLER_ISR_REG (0x10)
/*
* EPCQ_ISR register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_ISR(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_ISR_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_ISR(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_ISR_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_ISR(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_ISR_REG, data)
/*
* EPCQ_ISR register description macros
*/
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_ACTIVE (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK (0x00000002)
#define ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_ACTIVE (0x00000002)
/*
* EPCQ_IMR register offset
*
* The EPCQ_IMR register is used to mask the invalid erase or the invalid write
* interrupts.
*
*/
#define ALTERA_EPCQ_CONTROLLER_IMR_REG (0x14)
/*
* EPCQ_IMR register access macros
*/
#define IOADDR_ALTERA_EPCQ_CONTROLLER_IMR(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CONTROLLER_IMR_REG)
#define IORD_ALTERA_EPCQ_CONTROLLER_IMR(base) \
IORD_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_IMR_REG)
#define IOWR_ALTERA_EPCQ_CONTROLLER_IMR(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CONTROLLER_IMR_REG, data)
/*
* EPCQ_IMR register description macros
*/
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_ERASE_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_ERASE_ENABLED (0x00000001)
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_WRITE_MASK (0x00000002)
#define ALTERA_EPCQ_CONTROLLER_IMR_ILLEGAL_WRITE_ENABLED (0x00000002)
/*
* EPCQ_CHIP_SELECT register offset
*
* The EPCQ_CHIP_SELECT register is used to issue chip select
*/
#define ALTERA_EPCQ_CHIP_SELECT_REG (0x18)
/*
* EPCQ_CHIP_SELECT register access macros
*/
#define IOADDR_ALTERA_EPCQ_CHIP_SELECT(base) \
__IO_CALC_ADDRESS_DYNAMIC(base, ALTERA_EPCQ_CHIP_SELECT_REG)
#define IOWR_ALTERA_EPCQ_CHIP_SELECT(base, data) \
IOWR_32DIRECT(base, ALTERA_EPCQ_CHIP_SELECT_REG, data)
/*
* EPCQ_CHIP_SELECT register description macros
*/
#define ALTERA_EPCQ_CHIP1_SELECT (0x00000001)
#define ALTERA_EPCQ_CHIP2_SELECT (0x00000002)
#define ALTERA_EPCQ_CHIP3_SELECT (0x00000003)
#endif /* __ALTERA_EPCQ_CONTROLLER_REGS_H__ */

View File

@ -0,0 +1 @@
../../../../ip/altera_epcq_controller_mod/inc/altera_epcq_controller_mod_regs.h

View File

@ -1,33 +0,0 @@
#ifndef __I2C_OPENCORES_H__
#define __I2C_OPENCORES_H__
#include "alt_types.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define SCL_MIN_CLKDIV 10
void I2C_init(alt_u32 base,alt_u32 clk,alt_u32 speed);
int I2C_start(alt_u32 base, alt_u32 add, alt_u32 read);
alt_u32 I2C_read(alt_u32 base,alt_u32 last);
alt_u32 I2C_write(alt_u32 base,alt_u8 data, alt_u32 last);
void SPI_read(alt_u32 base, alt_u8 *rdata, int len);
void SPI_write(alt_u32 base, alt_u8 *wdata, int len);
#define I2C_OK (0)
#define I2C_ACK (0)
#define I2C_NOACK (1)
#define I2C_ABITRATION_LOST (2)
#define I2C_OPENCORES_INSTANCE(name, dev) extern int alt_no_storage
#define I2C_OPENCORES_INIT(name, dev) while (0)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __I2C_OPENCORES_H__ */

View File

@ -0,0 +1 @@
../../../../ip/i2c_opencores/HAL/inc/i2c_opencores.h

View File

@ -1,77 +0,0 @@
#ifndef __I2C_OPENCORES_REGS_H__
#define __I2C_OPENCORES_REGS_H__
#include <io.h>
/* prescal clock/(5*desired_SCL) */
/* all registers are 8 bits wide but on 32 bit address boundaries.*/
/* reg definitions take from i2c_specs.pdf in the docs folder */
#define IOADDR_I2C_OPENCORES_PRERLO(base) __IO_CALC_ADDRESS_NATIVE(base, 0)
#define IORD_I2C_OPENCORES_PRERLO(base) IORD(base, 0)
#define IOWR_I2C_OPENCORES_PRERLO(base, data) IOWR(base, 0, data)
#define IOADDR_I2C_OPENCORES_PRERHI(base) __IO_CALC_ADDRESS_NATIVE(base, 0)
#define IORD_I2C_OPENCORES_PRERHI(base) IORD(base, 1)
#define IOWR_I2C_OPENCORES_PRERHI(base, data) IOWR(base, 1, data)
#define IOADDR_I2C_OPENCORES_CTR(base) __IO_CALC_ADDRESS_NATIVE(base, 2)
#define IORD_I2C_OPENCORES_CTR(base) IORD(base, 2)
#define IOWR_I2C_OPENCORES_CTR(base, data) IOWR(base, 2, data)
/* bit definitions*/
#define I2C_OPENCORES_CTR_EN_MSK (0x80)
#define I2C_OPENCORES_CTR_EN_OFST (7)
#define I2C_OPENCORES_CTR_IEN_MSK (0x40)
#define I2C_OPENCORES_CTR_IEN_OFST (6)
#define IOADDR_I2C_OPENCORES_TXR(base) __IO_CALC_ADDRESS_NATIVE(base, 3)
#define IOWR_I2C_OPENCORES_TXR(base, data) IOWR(base, 3, data)
/* bit definitions*/
#define I2C_OPENCORES_TXR_RD_MSK (0x1)
#define I2C_OPENCORES_TXR_RD_OFST (0)
#define I2C_OPENCORES_TXR_WR_MSK (0x0)
#define I2C_OPENCORES_TXR_WR_OFST (0)
#define IOADDR_I2C_OPENCORES_RXR(base) __IO_CALC_ADDRESS_NATIVE(base, 3)
#define IORD_I2C_OPENCORES_RXR(base) IORD(base, 3)
#define IOADDR_I2C_OPENCORES_CR(base) __IO_CALC_ADDRESS_NATIVE(base, 4)
#define IOWR_I2C_OPENCORES_CR(base, data) IOWR(base, 4, data)
/* bit definitions*/
#define I2C_OPENCORES_CR_STA_MSK (0x80)
#define I2C_OPENCORES_CR_STA_OFST (7)
#define I2C_OPENCORES_CR_STO_MSK (0x40)
#define I2C_OPENCORES_CR_STO_OFST (6)
#define I2C_OPENCORES_CR_RD_MSK (0x20)
#define I2C_OPENCORES_CR_RD_OFST (5)
#define I2C_OPENCORES_CR_WR_MSK (0x10)
#define I2C_OPENCORES_CR_WR_OFST (4)
#define I2C_OPENCORES_CR_NACK_MSK (0x8)
#define I2C_OPENCORES_CR_NACK_OFST (3)
#define I2C_OPENCORES_CR_SPIM_MSK (0x4)
#define I2C_OPENCORES_CR_SPIM_OFST (2)
#define I2C_OPENCORES_CR_IACK_MSK (0x1)
#define I2C_OPENCORES_CR_IACK_OFST (0)
#define IOADDR_I2C_OPENCORES_SR(base) __IO_CALC_ADDRESS_NATIVE(base, 4)
#define IORD_I2C_OPENCORES_SR(base) IORD(base, 4)
/* bit definitions*/
#define I2C_OPENCORES_SR_RXNACK_MSK (0x80)
#define I2C_OPENCORES_SR_RXNACK_OFST (7)
#define I2C_OPENCORES_SR_BUSY_MSK (0x40)
#define I2C_OPENCORES_SR_BUSY_OFST (6)
#define I2C_OPENCORES_SR_AL_MSK (0x20)
#define I2C_OPENCORES_SR_AL_OFST (5)
#define I2C_OPENCORES_SR_TIP_MSK (0x2)
#define I2C_OPENCORES_SR_TIP_OFST (1)
#define I2C_OPENCORES_SR_IF_MSK (0x1)
#define I2C_OPENCORES_SR_IF_OFST (0)
#endif /* __I2C_OPENCORES_REGS_H__ */

View File

@ -0,0 +1 @@
../../../../ip/i2c_opencores/inc/i2c_opencores_regs.h

View File

@ -1,136 +0,0 @@
//
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef SC_CONFIG_REGS_H_
#define SC_CONFIG_REGS_H_
#include <alt_types.h>
// bit-fields coded as little-endian
typedef union {
struct {
alt_u16 vmax:11;
alt_u8 interlace_flag:1;
alt_u8 sc_rsv2:4;
alt_u8 fpga_vsyncgen:2;
alt_u16 vmax_tvp:11;
alt_u8 sc_rsv:2;
alt_u8 vsync_flag:1;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} sc_status_reg;
typedef union {
struct {
alt_u32 pcnt_frame:20;
alt_u16 sc_rsv:12;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} sc_status2_reg;
typedef union {
struct {
alt_u16 lt_lat_result:16;
alt_u16 lt_stb_result:12;
alt_u8 lt_rsv:3;
alt_u8 lt_finished:1;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} lt_status_reg;
typedef union {
struct {
alt_u16 h_active:11;
alt_u16 h_backporch:9;
alt_u8 h_synclen:8;
alt_u8 h_l3_240x360:1;
alt_u8 h_l5fmt:1;
alt_u8 h_multmode:2;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} h_config_reg;
typedef union {
struct {
alt_u16 h_opt_startoff:10;
alt_u8 h_opt_sample_mult:3;
alt_u8 h_opt_sample_sel:3;
alt_u8 h_opt_scale:3;
alt_u16 h_mask:11;
alt_u8 h_rsv:2;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} h_config2_reg;
typedef union {
struct {
alt_u16 v_active:11;
alt_u8 v_backporch:6;
alt_u8 v_synclen:3;
alt_u8 v_mask:6;
alt_u8 v_rsv:3;
alt_u8 v_multmode:3;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} v_config_reg;
typedef union {
struct {
alt_u8 mask_br:4;
alt_u8 rev_lpf_str:5;
alt_u8 panasonic_hack:1;
alt_u32 misc_rsv:22;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} misc_config_reg;
typedef union {
struct {
alt_u32 sl_l_str_arr:20;
alt_u8 sl_l_overlay:5;
alt_u8 sl_hybr_str:5;
alt_u8 sl_method:1;
alt_u8 sl_no_altern:1;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} sl_config_reg;
typedef union {
struct {
alt_u32 sl_c_str_arr:24;
alt_u8 sl_c_overlay:6;
alt_u8 sl_rsv:1;
alt_u8 sl_altiv:1;
} __attribute__((packed, __may_alias__));
alt_u32 data;
} sl_config2_reg;
typedef struct {
sc_status_reg sc_status;
sc_status2_reg sc_status2;
lt_status_reg lt_status;
h_config_reg h_config;
h_config2_reg h_config2;
v_config_reg v_config;
misc_config_reg misc_config;
sl_config_reg sl_config;
sl_config2_reg sl_config2;
} __attribute__((packed, __may_alias__)) sc_regs;
#endif //SC_CONFIG_REGS_H_

View File

@ -0,0 +1 @@
../../../../ip/sc_config/inc/sc_config_regs.h

View File

@ -1,812 +0,0 @@
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2015 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#include <errno.h>
#include <io.h>
#include <string.h>
#include <stddef.h>
#include "sys/param.h"
#include "alt_types.h"
#include "altera_epcq_controller_mod_regs.h"
#include "altera_epcq_controller_mod.h"
#include "priv/alt_busy_sleep.h"
#include "sys/alt_debug.h"
#include "sys/alt_cache.h"
ALT_INLINE alt_32 static alt_epcq_validate_read_write_arguments(alt_epcq_controller_dev *flash_info,alt_u32 offset, alt_u32 length);
alt_32 static alt_epcq_poll_for_write_in_progress(alt_epcq_controller_dev* epcq_flash_info);
ALT_INLINE unsigned char static bitswap8(unsigned char v);
/*
* Public API
*
* Refer to Using Flash Devices in the
* Developing Programs Using the Hardware Abstraction Layer chapter
* of the Nios II Software Developers Handbook.
*/
/**
* alt_epcq_controller_lock
*
* Locks the range of the memory sectors, which
* protected from write and erase.
*
* Arguments:
* - *flash_info: Pointer to general flash device structure.
* - sectors_to_lock: Block protection bits in EPCQ ==> Bit4 | Bit3 | Bit2 | Bit1 | Bit0
* TB | BP3 | BP2 | BP1 | BP0
* For details of setting sectors protection, please refer to EPCQ datasheet.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -ETIME -> Time out and skipping the looping after 0.7 sec.
* -ENOLCK -> Sectors lock failed.
**/
int alt_epcq_controller_lock(alt_flash_dev *flash_info, alt_u32 sectors_to_lock)
{
alt_u32 mem_op_value = 0; /* value to write to EPCQ_MEM_OP register */
alt_epcq_controller_dev* epcq_flash_info = NULL;
alt_u32 result = 0;
alt_32 status = 0;
/* return -EINVAL if flash_info is NULL */
if(NULL == flash_info || 0 > sectors_to_lock)
{
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
/* sector value should occupy bits 17:8 */
mem_op_value = sectors_to_lock << 8;
/* sector protect commands 0b11 occupies lower 2 bits */
mem_op_value |= ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_PROTECT_CMD;
/* write sector protect command to EPCQ_MEM_OP register to protect sectors */
IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(epcq_flash_info->csr_base, mem_op_value);
/* poll write in progress to make sure no operation is in progress */
status = alt_epcq_poll_for_write_in_progress(epcq_flash_info);
if(status != 0)
{
return status;
}
status = IORD_ALTERA_EPCQ_CONTROLLER_STATUS(epcq_flash_info->csr_base);
result |= (status >> 2) & 0x07; /* extract out BP3 - BP0 */
result |= (status >> 3) & 0x08; /* extract out BP4 */
result |= (status >> 1) & 0x10; /* extract out TOP/BOTTOM bit */
if(result != sectors_to_lock)
{
return -ENOLCK;
}
return 0;
}
/**
* alt_epcq_controller_get_info
*
* Pass the table of erase blocks to the user. This flash will return a single
* flash_region that gives the number and size of sectors for the device used.
*
* Arguments:
* - *fd: Pointer to general flash device structure.
* - **info: Pointer to flash region
* - *number_of_regions: Pointer to number of regions
*
* For details of setting sectors protection, please refer to EPCQ datasheet.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> Could be hardware problem.
**/
int alt_epcq_controller_get_info
(
alt_flash_fd *fd, /** flash device descriptor */
flash_region **info, /** pointer to flash_region will be stored here */
int *number_of_regions /** number of regions will be stored here */
)
{
alt_flash_dev* flash = NULL;
/* return -EINVAL if fd,info and number_of_regions are NULL */
if(NULL == fd || NULL == info || NULL == number_of_regions)
{
return -EINVAL;
}
flash = (alt_flash_dev*)fd;
*number_of_regions = flash->number_of_regions;
if (!flash->number_of_regions)
{
return -EIO;
}
else
{
*info = &flash->region_info[0];
}
return 0;
}
/**
* alt_epcq_controller_erase_block
*
* This function erases a single flash sector.
*
* Arguments:
* - *flash_info: Pointer to EPCQ flash device structure.
* - block_offset: byte-addressed offset, from start of flash, of the sector to be erased
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
**/
int alt_epcq_controller_erase_block(alt_flash_dev *flash_info, int block_offset)
{
alt_32 ret_code = 0;
alt_u32 mem_op_value = 0; /* value to write to EPCQ_MEM_OP register */
alt_epcq_controller_dev* epcq_flash_info = NULL;
alt_u32 sector_number = 0;
/* return -EINVAL if flash_info is NULL */
if(NULL == flash_info)
{
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
/*
* Sanity checks that block_offset is within the flash memory span and that the
* block offset is sector aligned.
*
*/
if((block_offset < 0)
|| (block_offset >= epcq_flash_info->size_in_bytes)
|| (block_offset & (epcq_flash_info->sector_size - 1)) != 0)
{
return -EINVAL;
}
/* calculate current sector/block number */
sector_number = (block_offset/(epcq_flash_info->sector_size));
/* sector value should occupy bits 23:8 */
mem_op_value = (sector_number << 8) & ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_VALUE_MASK;
/* sector erase commands 0b10 occupies lower 2 bits */
mem_op_value |= ALTERA_EPCQ_CONTROLLER_MEM_OP_SECTOR_ERASE_CMD;
/* write sector erase command to EPCQ_MEM_OP register to erase sector "sector_number" */
IOWR_ALTERA_EPCQ_CONTROLLER_MEM_OP(epcq_flash_info->csr_base, mem_op_value);
/* check whether erase triggered a illegal erase interrupt */
if((IORD_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base) &
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK) ==
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_ACTIVE)
{
/* clear register */
/* EPCQ_ISR access is write one to clear (W1C) */
IOWR_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base,
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_ERASE_MASK );
return -EIO; /* erase failed, sector might be protected */
}
return ret_code;
}
/**
* alt_epcq_controller_write_block
*
* This function writes one block/sector of data to flash. The length of the write can NOT
* spill into the adjacent sector.
*
* It assumes that someone has already erased the appropriate sector(s).
*
* Arguments:
* - *flash_info: Pointer to EPCQ flash device structure.
* - block_offset: byte-addressed offset, from the start of flash, of the sector to written to
* - data-offset: Byte offset (unaligned access) of write into flash memory.
* For best performance, word(32 bits - aligned access) offset of write is recommended.
* - *src_addr: source buffer
* - length: size of writing
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
**/
int alt_epcq_controller_write_block
(
alt_flash_dev *flash_info, /** flash device info */
int block_offset, /** sector/block offset in byte addressing */
int data_offset, /** offset of write from base address */
const void *data, /** data to be written */
int length /** bytes of data to be written, >0 */
)
{
alt_u32 buffer_offset = 0; /** offset into data buffer to get write data */
alt_u32 remaining_length = length; /** length left to write */
alt_u32 write_offset = data_offset; /** offset into flash to write too */
alt_epcq_controller_dev *epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
/*
* Sanity checks that data offset is not larger then a sector, that block offset is
* sector aligned and within the valid flash memory range and a write doesn't spill into
* the adjacent flash sector.
*/
if(block_offset < 0
|| data_offset < 0
|| NULL == flash_info
|| NULL == data
|| data_offset >= epcq_flash_info->size_in_bytes
|| block_offset >= epcq_flash_info->size_in_bytes
|| length > (epcq_flash_info->sector_size - (data_offset - block_offset))
|| length < 0
|| (block_offset & (epcq_flash_info->sector_size - 1)) != 0)
{
return -EINVAL;
}
/*
* Do writes one 32-bit word at a time.
* We need to make sure that we pad the first few bytes so they're word aligned if they are
* not already.
*/
while (remaining_length > 0)
{
alt_u32 word_to_write = 0xFFFFFFFF; /** initialize word to write to blank word */
alt_u32 padding = 0; /** bytes to pad the next word that is written */
alt_u32 bytes_to_copy = sizeof(alt_u32); /** number of bytes from source to copy */
/*
* we need to make sure the write is word aligned
* this should only be true at most 1 time
*/
if (0 != (write_offset & (sizeof(alt_u32) - 1)))
{
/*
* data is not word aligned
* calculate padding bytes need to add before start of a data offset
*/
padding = write_offset & (sizeof(alt_u32) - 1);
/* update variables to account for padding being added */
bytes_to_copy -= padding;
if(bytes_to_copy > remaining_length)
{
bytes_to_copy = remaining_length;
}
write_offset = write_offset - padding;
if(0 != (write_offset & (sizeof(alt_u32) - 1)))
{
return -EINVAL;
}
}
else
{
if(bytes_to_copy > remaining_length)
{
bytes_to_copy = remaining_length;
}
}
/* prepare the word to be written */
memcpy((((void*)&word_to_write)) + padding, ((void*)data) + buffer_offset, bytes_to_copy);
// Bit-reverse bytes for flash
for (int i=0; i<bytes_to_copy; i++)
*((unsigned char*)&word_to_write+i) = bitswap8(*((unsigned char*)&word_to_write+i));
/* update offset and length variables */
buffer_offset += bytes_to_copy;
remaining_length -= bytes_to_copy;
/* write to flash 32 bits at a time */
IOWR_32DIRECT(epcq_flash_info->data_base, write_offset, word_to_write);
/* check whether write triggered a illegal write interrupt */
if((IORD_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base) &
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK) ==
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_ACTIVE)
{
/* clear register */
IOWR_ALTERA_EPCQ_CONTROLLER_ISR(epcq_flash_info->csr_base,
ALTERA_EPCQ_CONTROLLER_ISR_ILLEGAL_WRITE_MASK );
return -EIO; /** write failed, sector might be protected */
}
/* update current offset */
write_offset = write_offset + sizeof(alt_u32);
}
return 0;
}
/**
* alt_epcq_controller_write
*
* Program the data into the flash at the selected address.
*
* The different between this function and alt_epcq_controller_write_block function
* is that this function (alt_epcq_controller_write) will automatically erase a block as needed
* Arguments:
* - *flash_info: Pointer to EPCQ flash device structure.
* - offset: Byte offset (unaligned access) of write to flash memory. For best performance,
* word(32 bits - aligned access) offset of write is recommended.
* - *src_addr: source buffer
* - length: size of writing
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
*
**/
int alt_epcq_controller_write(
alt_flash_dev *flash_info, /** device info */
int offset, /** offset of write from base address */
const void *src_addr, /** source buffer */
int length /** size of writing */
)
{
alt_32 ret_code = 0;
alt_epcq_controller_dev *epcq_flash_info = NULL;
alt_u32 write_offset = offset; /** address of next byte to write */
alt_u32 remaining_length = length; /** length of write data left to be written */
alt_u32 buffer_offset = 0; /** offset into source buffer to get write data */
alt_u32 i = 0;
/* return -EINVAL if flash_info and src_addr are NULL */
if(NULL == flash_info || NULL == src_addr)
{
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
/* make sure the write parameters are within the bounds of the flash */
ret_code = alt_epcq_validate_read_write_arguments(epcq_flash_info, offset, length);
if(0 != ret_code)
{
return ret_code;
}
/*
* This loop erases and writes data one sector at a time. We check for write completion
* before starting the next sector.
*/
for(i = offset/epcq_flash_info->sector_size ; i < epcq_flash_info->number_of_sectors; i++)
{
alt_u32 block_offset = 0; /** block offset in byte addressing */
alt_u32 offset_within_current_sector = 0; /** offset into current sector to write */
alt_u32 length_to_write = 0; /** length to write to current sector */
if(0 >= remaining_length)
{
break; /* out of data to write */
}
/* calculate current sector/block offset in byte addressing */
block_offset = write_offset & ~(epcq_flash_info->sector_size - 1);
/* calculate offset into sector/block if there is one */
if(block_offset != write_offset)
{
offset_within_current_sector = write_offset - block_offset;
}
/* erase sector */
ret_code = alt_epcq_controller_erase_block(flash_info, block_offset);
if(0 != ret_code)
{
return ret_code;
}
/* calculate the byte size of data to be written in a sector */
length_to_write = MIN(epcq_flash_info->sector_size - offset_within_current_sector,
remaining_length);
/* write data to erased block */
ret_code = alt_epcq_controller_write_block(flash_info, block_offset, write_offset,
src_addr + buffer_offset, length_to_write);
if(0 != ret_code)
{
return ret_code;
}
/* update remaining length and buffer_offset pointer */
remaining_length -= length_to_write;
buffer_offset += length_to_write;
write_offset += length_to_write;
}
return ret_code;
}
/**
* alt_epcq_controller_read
*
* There's no real need to use this function as opposed to using memcpy directly. It does
* do some sanity checks on the bounds of the read.
*
* Arguments:
* - *flash_info: Pointer to general flash device structure.
* - offset: offset read from flash memory.
* - *dest_addr: destination buffer
* - length: size of reading
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
**/
int alt_epcq_controller_read
(
alt_flash_dev *flash_info, /** device info */
int offset, /** offset of read from base address */
void *dest_addr, /** destination buffer */
int length /** size of read */
)
{
alt_32 ret_code = 0;
alt_epcq_controller_dev *epcq_flash_info = NULL;
/* return -EINVAL if flash_info and dest_addr are NULL */
if(NULL == flash_info || NULL == dest_addr)
{
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
/* validate arguments */
ret_code = alt_epcq_validate_read_write_arguments(epcq_flash_info, offset, length);
/* copy data from flash to destination address */
if(0 == ret_code)
{
memcpy(dest_addr, (alt_u8*)epcq_flash_info->data_base + offset, length);
// Bit-reverse bytes read from flash
for (int i=0; i<length; i++)
*((unsigned char*)dest_addr+i) = bitswap8(*((unsigned char*)dest_addr+i));
}
return ret_code;
}
/**
* altera_epcq_controller_init
*
* alt_sys_init.c will call this function automatically through macro
*
* Information in system.h is checked against expected values that are determined by the silicon_id.
* If the information doesn't match then this system is configured incorrectly. Most likely the wrong
* type of EPCS or EPCQ device was selected when instantiating the soft IP.
*
* Arguments:
* - *flash: Pointer to EPCQ flash device structure.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments.
* -ENODEV -> System is configured incorrectly.
**/
alt_32 altera_epcq_controller_init(alt_epcq_controller_dev *flash)
{
alt_u32 silicon_id = 0;
alt_u32 size_in_bytes = 0;
alt_u32 number_of_sectors = 0;
/* return -EINVAL if flash is NULL */
if(NULL == flash)
{
return -EINVAL;
}
/* return -ENODEV if CSR slave is not attached */
if(NULL == (void *)flash->csr_base)
{
return -ENODEV;
}
/*
* If flash is an EPCQ device, we read the EPCQ_RD_RDID register for the ID
* If flash is an EPCS device, we read the EPCQ_RD_SID register for the ID
*
* Whether or not the flash is a EPCQ or EPCS is indicated in the system.h. The system.h gets
* this value from the hw.tcl of the IP. If this value is set incorrectly, then things will go
* badly.
*
* In both cases, we can determine the number of sectors, which we can use
* to calculate a size. We compare that size to the system.h value to make sure
* the EPCQ soft IP was configured correctly.
*/
if(0 == flash->is_epcs)
{
/* If we're an EPCQ, we read EPCQ_RD_RDID for the silicon ID */
silicon_id = IORD_ALTERA_EPCQ_CONTROLLER_RDID(flash->csr_base);
silicon_id &= ALTERA_EPCQ_CONTROLLER_RDID_MASK;
/* Determine which EPCQ device so we can figure out the number of sectors */
/* EPCQ share the same ID for the same capacity*/
switch(silicon_id)
{
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ16:
{
number_of_sectors = 32;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ32:
{
number_of_sectors = 64;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ64:
{
number_of_sectors = 128;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ128:
{
number_of_sectors = 256;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ256:
{
number_of_sectors = 512;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ512:
{
number_of_sectors = 1024;
break;
}
case ALTERA_EPCQ_CONTROLLER_RDID_EPCQ1024:
{
number_of_sectors = 2048;
break;
}
default:
{
return -ENODEV;
}
}
}
else {
/* If we're an EPCS, we read EPCQ_RD_SID for the silicon ID */
silicon_id = IORD_ALTERA_EPCQ_CONTROLLER_SID(flash->csr_base);
silicon_id &= ALTERA_EPCQ_CONTROLLER_SID_MASK;
/* Determine which EPCS device so we can figure out various properties */
switch(silicon_id)
{
case ALTERA_EPCQ_CONTROLLER_SID_EPCS16:
{
number_of_sectors = 32;
break;
}
case ALTERA_EPCQ_CONTROLLER_SID_EPCS64:
{
number_of_sectors = 128;
break;
}
case ALTERA_EPCQ_CONTROLLER_SID_EPCS128:
{
number_of_sectors = 256;
break;
}
default:
{
return -ENODEV;
}
}
}
/* Calculate size of flash based on number of sectors */
size_in_bytes = number_of_sectors * flash->sector_size;
/*
* Make sure calculated size is the same size given in system.h
* Also check number of sectors is the same number given in system.h
* Otherwise the EPCQ IP was not configured correctly
*/
if( size_in_bytes != flash->size_in_bytes ||
number_of_sectors != flash->number_of_sectors)
{
flash->dev.number_of_regions = 0;
return -ENODEV;
}
else
{
flash->silicon_id = silicon_id;
flash->number_of_sectors = number_of_sectors;
/*
* populate fields of region_info required to conform to HAL API
* create 1 region that composed of "number_of_sectors" blocks
*/
flash->dev.number_of_regions = 1;
flash->dev.region_info[0].offset = 0;
flash->dev.region_info[0].region_size = size_in_bytes;
flash->dev.region_info[0].number_of_blocks = number_of_sectors;
flash->dev.region_info[0].block_size = flash->sector_size;
}
/*
* Register this device as a valid flash device type
*
* Only register the device if it's configured correctly.
*/
alt_flash_device_register(&(flash->dev));
return 0;
}
/*
* Private API
*
* Helper functions used by Public API functions.
*
* Arguments:
* - *flash_info: Pointer to EPCQ flash device structure.
* - offset: Offset of read/write from base address.
* - length: Length of read/write in bytes.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
*/
/**
* Used to check that arguments to a read or write are valid
*/
ALT_INLINE alt_32 static alt_epcq_validate_read_write_arguments
(
alt_epcq_controller_dev *flash_info, /** device info */
alt_u32 offset, /** offset of read/write */
alt_u32 length /** length of read/write */
)
{
alt_epcq_controller_dev *epcq_flash_info = NULL;
alt_u32 start_address = 0;
alt_32 end_address = 0;
/* return -EINVAL if flash_info is NULL */
if(NULL == flash_info)
{
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller_dev*)flash_info;
start_address = epcq_flash_info->data_base + offset; /** first address of read or write */
end_address = start_address + length; /** last address of read or write (not inclusive) */
/* make sure start and end address is less then the end address of the flash */
if(
start_address >= epcq_flash_info->data_end ||
end_address >= epcq_flash_info->data_end ||
offset < 0 ||
length < 0
)
{
return -EINVAL;
}
return 0;
}
/*
* Private function that polls write in progress bit EPCQ_RD_STATUS.
*
* Write in progress will be set if any of the following operations are in progress:
* -WRITE STATUS REGISTER
* -WRITE NONVOLATILE CONFIGURATION REGISTER
* -PROGRAM
* -ERASE
*
* Assumes EPCQ was configured correctly.
*
* If ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE is set, the function will time out after
* a period of time determined by that value.
*
* Arguments:
* - *epcq_flash_info: Pointer to EPCQ flash device structure.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -ETIME -> Time out and skipping the looping after 0.7 sec.
*/
alt_32 static alt_epcq_poll_for_write_in_progress(alt_epcq_controller_dev* epcq_flash_info)
{
/* we'll want to implement timeout if a timeout value is specified */
#if ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE > 0
alt_u32 timeout = ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE;
alt_u16 counter = 0;
#endif
/* return -EINVAL if epcq_flash_info is NULL */
if(NULL == epcq_flash_info)
{
return -EINVAL;
}
/* while Write in Progress bit is set, we wait */
while((IORD_ALTERA_EPCQ_CONTROLLER_STATUS(epcq_flash_info->csr_base) &
ALTERA_EPCQ_CONTROLLER_STATUS_WIP_MASK) ==
ALTERA_EPCQ_CONTROLLER_STATUS_WIP_BUSY)
{
alt_busy_sleep(1); /* delay 1us */
#if ALTERA_EPCQ_CONTROLLER_1US_TIMEOUT_VALUE > 0
if(timeout <= counter )
{
return -ETIME;
}
counter++;
#endif
}
return 0;
}
ALT_INLINE unsigned char static bitswap8(unsigned char v)
{
return ((v * 0x0802LU & 0x22110LU) |
(v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
}

View File

@ -0,0 +1 @@
../../../../ip/altera_epcq_controller_mod/HAL/src/altera_epcq_controller_mod.c

View File

@ -1,212 +0,0 @@
#include "alt_types.h"
#include "i2c_opencores_regs.h"
#include "i2c_opencores.h"
// #define I2C_DEBUG
//int I2C_init(alt_u32 base,alt_u32 clk, alt_u32 speed)
//int I2C_start(alt_u32 base, alt_u32 add, alt_u32 write);
//alt_u32 I2C_read(alt_u32 base);
//int I2C_write(alt_u32 base, alt_u8 data);
//int I2C_stop(alt_u32 base);
/* these functions are polled only. */
/* all functions wait until the I2C is done before exiting */
/****************************************************************
int I2C_init
This function inititlizes the prescalor for the scl
and then enables the core. This must be run before
any other i2c code is executed
inputs
base = the base address of the component
clk = freuqency of the clock driving this component ( in Hz)
speed = SCL speed ie 100K, 400K ... (in Hz)
15-OCT-07 initial release
*****************************************************************/
void I2C_init(alt_u32 base,alt_u32 clk,alt_u32 speed)
{
alt_u32 prescale = (clk/( 5 * speed))-1;
#ifdef I2C_DEBUG
printf(" Initializing I2C at 0x%x, \n\twith clock speed 0x%x \n\tand SCL speed 0x%x \n\tand prescale 0x%x\n",base,clk,speed,prescale);
#endif
IOWR_I2C_OPENCORES_CTR(base, 0x00); /* turn off the core*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_IACK_MSK); /* clearn any pening IRQ*/
IOWR_I2C_OPENCORES_PRERLO(base, (0xff & prescale)); /* load low presacle bit*/
IOWR_I2C_OPENCORES_PRERHI(base, (0xff & (prescale>>8))); /* load upper prescale bit */
IOWR_I2C_OPENCORES_CTR(base, I2C_OPENCORES_CTR_EN_MSK); /* turn on the core*/
}
/****************************************************************
int I2C_start
Sets the start bit and then sends the first byte which
is the address of the device + the write bit.
inputs
base = the base address of the component
add = address of I2C device
read = 1== read 0== write
return value
0 if address is acknowledged
1 if address was not acknowledged
15-OCT-07 initial release
*****************************************************************/
int I2C_start(alt_u32 base, alt_u32 add, alt_u32 read)
{
#ifdef I2C_DEBUG
printf(" Start I2C at 0x%x, \n\twith address 0x%x \n\tand read 0x%x \n\tand prescale 0x%x\n",base,add,read);
#endif
/* transmit the address shifted by one and the read/write bit*/
IOWR_I2C_OPENCORES_TXR(base, ((add<<1) + (0x1 & read)));
/* set start and write bits which will start the transaction*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_STA_MSK | I2C_OPENCORES_CR_WR_MSK );
/* wait for the trnasaction to be over.*/
while (IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK) {}
/* now check to see if the address was acknowledged */
if(IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_RXNACK_MSK)
{
#ifdef I2C_DEBUG
printf("\tNOACK\n");
#endif
return (I2C_NOACK);
}
else
{
#ifdef I2C_DEBUG
printf("\tACK\n");
#endif
return (I2C_ACK);
}
}
/****************************************************************
int I2C_read
assumes that any addressing and start
has already been done.
reads one byte of data from the slave. on the last read
we don't acknowldge and set the stop bit.
inputs
base = the base address of the component
last = on the last read there must not be a ack
return value
byte read back.
15-OCT-07 initial release
*****************************************************************/
alt_u32 I2C_read(alt_u32 base,alt_u32 last)
{
#ifdef I2C_DEBUG
printf(" Read I2C at 0x%x, \n\twith last0x%x\n",base,last);
#endif
if( last)
{
/* start a read and no ack and stop bit*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK |
I2C_OPENCORES_CR_NACK_MSK | I2C_OPENCORES_CR_STO_MSK);
}
else
{
/* start read*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK );
}
/* wait for the trnasaction to be over.*/
while (IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK) {}
/* now read the data */
return (IORD_I2C_OPENCORES_RXR(base));
}
/****************************************************************
int I2C_write
assumes that any addressing and start
has already been done.
writes one byte of data from the slave.
If last is set the stop bit set.
inputs
base = the base address of the component
data = byte to write
last = on the last read there must not be a ack
return value
0 if address is acknowledged
1 if address was not acknowledged
15-OCT-07 initial release
*****************************************************************/
alt_u32 I2C_write(alt_u32 base,alt_u8 data, alt_u32 last)
{
#ifdef I2C_DEBUG
printf(" Read I2C at 0x%x, \n\twith data 0x%x,\n\twith last0x%x\n",base,data,last);
#endif
/* transmit the data*/
IOWR_I2C_OPENCORES_TXR(base, data);
if( last)
{
/* start a write with ack and stop bit*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK |
I2C_OPENCORES_CR_STO_MSK);
}
else
{
/* start write with ack */
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK );
}
/* wait for the trnasaction to be over.*/
while (IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK) {}
/* now check to see if the address was acknowledged */
if(IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_RXNACK_MSK)
{
#ifdef I2C_DEBUG
printf("\tNOACK\n");
#endif
return (I2C_NOACK);
}
else
{
#ifdef I2C_DEBUG
printf("\tACK\n");
#endif
return (I2C_ACK);
}
}
void SPI_read(alt_u32 base, alt_u8 *rdata, int len)
{
int i;
for (i=0; i<len; i++) {
/* start read*/
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_RD_MSK|I2C_OPENCORES_CR_NACK_MSK|I2C_OPENCORES_CR_SPIM_MSK );
/* wait for the trnasaction to be over.*/
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
/* now read the data */
if (rdata)
rdata[i] = IORD_I2C_OPENCORES_RXR(base);
}
}
void SPI_write(alt_u32 base, alt_u8 *wdata, int len)
{
int i;
for (i=0; i<len; i++) {
/* transmit the data*/
IOWR_I2C_OPENCORES_TXR(base, wdata[i]);
/* start write */
IOWR_I2C_OPENCORES_CR(base, I2C_OPENCORES_CR_WR_MSK|I2C_OPENCORES_CR_NACK_MSK|I2C_OPENCORES_CR_SPIM_MSK );
/* wait for the trnasaction to be over.*/
while( IORD_I2C_OPENCORES_SR(base) & I2C_OPENCORES_SR_TIP_MSK);
}
}

View File

@ -0,0 +1 @@
../../../../ip/i2c_opencores/HAL/src/i2c_opencores.c