From 5d3e3bbe33bf2689c8fbb838a50fc46d83956f2b Mon Sep 17 00:00:00 2001 From: marqs Date: Thu, 27 Oct 2016 01:11:33 +0300 Subject: [PATCH] remove old SD interface files from project. --- .../Altera_UP_SD_Card_Avalon_Interface_hw.tcl | 159 -- .../Altera_UP_SD_Card_Avalon_Interface_sw.tcl | 56 - .../Altera_UP_SD_Card_Avalon_Interface_mod.h | 166 -- .../Altera_UP_SD_Card_Avalon_Interface_mod.c | 1908 ----------------- .../SD_Card_Interface_for_SoPC_Builder.pdf | Bin 252601 -> 0 bytes .../hdl/Altera_UP_SD_CRC16_Generator.vhd | 79 - .../hdl/Altera_UP_SD_CRC7_Generator.vhd | 76 - ...ra_UP_SD_Card_48_bit_Command_Generator.vhd | 570 ----- .../Altera_UP_SD_Card_Avalon_Interface.vhd | 518 ----- .../hdl/Altera_UP_SD_Card_Buffer.vhd | 382 ---- .../hdl/Altera_UP_SD_Card_Clock.vhd | 80 - .../hdl/Altera_UP_SD_Card_Control_FSM.vhd | 347 --- .../hdl/Altera_UP_SD_Card_Interface.vhd | 518 ----- .../hdl/Altera_UP_SD_Card_Memory_Block.vhd | 296 --- .../Altera_UP_SD_Card_Response_Receiver.vhd | 308 --- .../hdl/Altera_UP_SD_Signal_Trigger.vhd | 57 - 16 files changed, 5520 deletions(-) delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_hw.tcl delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_sw.tcl delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/doc/SD_Card_Interface_for_SoPC_Builder.pdf delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_CRC16_Generator.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_CRC7_Generator.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Avalon_Interface.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Buffer.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Clock.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Control_FSM.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Interface.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Memory_Block.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Response_Receiver.vhd delete mode 100644 ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Signal_Trigger.vhd diff --git a/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_hw.tcl b/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_hw.tcl deleted file mode 100644 index c772941..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_hw.tcl +++ /dev/null @@ -1,159 +0,0 @@ -# (C) 2001-2015 Altera Corporation. All rights reserved. -# Your use of Altera Corporation's design tools, logic functions and other -# software and tools, and its AMPP partner logic functions, and any output -# files any of the foregoing (including device programming or simulation -# files), and any associated documentation or information are expressly subject -# to the terms and conditions of the Altera Program License Subscription -# Agreement, Altera MegaCore Function License Agreement, or other applicable -# license agreement, including, without limitation, that your use is for the -# sole purpose of programming logic devices manufactured by Altera and sold by -# Altera or its authorized distributors. Please refer to the applicable -# agreement for further details. - - -# TCL File Generated by Component Editor 8.0 -# Mon Dec 22 17:22:07 EST 2008 -# DO NOT MODIFY - -set aup_version 15.1 - - - -# +----------------------------------- -# | -# | Altera_UP_SD_Card_Avalon_Interface "Altera_UP_SD_Card_Avalon_Interface" v1.0 -# | null 2008.12.22.17:22:07 -# | A module that allows communication with an SD Card -# | -# | ./hdl/Altera_UP_SD_Card_Avalon_Interface.vhd syn -# | ./hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd syn -# | ./hdl/Altera_UP_SD_Card_Buffer.vhd syn -# | ./hdl/Altera_UP_SD_Card_Clock.vhd syn -# | ./hdl/Altera_UP_SD_Card_Control_FSM.vhd syn -# | ./hdl/Altera_UP_SD_Card_Interface.vhd syn -# | ./hdl/Altera_UP_SD_Card_Memory_Block.qip syn -# | ./hdl/Altera_UP_SD_Card_Response_Receiver.vhd syn -# | ./hdl/Altera_UP_SD_CRC16_Generator.vhd syn -# | ./hdl/Altera_UP_SD_CRC7_Generator.vhd syn -# | ./hdl/Altera_UP_SD_Signal_Trigger.vhd syn -# | -# +----------------------------------- - - -# +----------------------------------- -# | module Altera_UP_SD_Card_Avalon_Interface -# | -set_module_property DESCRIPTION "A module that allows communication with an SD Card" -set_module_property NAME Altera_UP_SD_Card_Avalon_Interface_mod -set_module_property VERSION $aup_version -set_module_property GROUP "Memory" -set_module_property DISPLAY_NAME "SD Card Interface" -set_module_property DATASHEET_URL "[pwd]/doc/SD_Card_Interface_for_SoPC_Builder.pdf" -set_module_property LIBRARIES {ieee.std_logic_1164.all ieee.std_logic_arith.all ieee.std_logic_unsigned.all std.standard.all} -set_module_property TOP_LEVEL_HDL_FILE "hdl/Altera_UP_SD_Card_Avalon_Interface.vhd" -set_module_property TOP_LEVEL_HDL_MODULE Altera_UP_SD_Card_Avalon_Interface -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE false -#set_module_property ANALYZE_HDL false -set_module_property SIMULATION_MODEL_IN_VERILOG false -set_module_property SIMULATION_MODEL_IN_VHDL false -set_module_property SIMULATION_MODEL_HAS_TULIPS false -set_module_property SIMULATION_MODEL_IS_OBFUSCATED false -# | -# +----------------------------------- - -# +----------------------------------- -# | files -# | -add_file hdl/Altera_UP_SD_Card_Avalon_Interface.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Buffer.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Clock.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Control_FSM.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Interface.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Response_Receiver.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_CRC16_Generator.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_CRC7_Generator.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Signal_Trigger.vhd {SYNTHESIS} -add_file hdl/Altera_UP_SD_Card_Memory_Block.vhd {SYNTHESIS} -# | -# +----------------------------------- - -# +----------------------------------- -# | parameters -# | -# | -# +----------------------------------- - -# +----------------------------------- -# | connection point avalon_sdcard_slave -# | -add_interface avalon_sdcard_slave avalon end -set_interface_property avalon_sdcard_slave holdTime 0 -set_interface_property avalon_sdcard_slave linewrapBursts false -set_interface_property avalon_sdcard_slave minimumUninterruptedRunLength 1 -set_interface_property avalon_sdcard_slave bridgesToMaster "" -set_interface_property avalon_sdcard_slave isMemoryDevice false -set_interface_property avalon_sdcard_slave burstOnBurstBoundariesOnly false -set_interface_property avalon_sdcard_slave addressSpan 1024 -set_interface_property avalon_sdcard_slave timingUnits Cycles -set_interface_property avalon_sdcard_slave setupTime 0 -set_interface_property avalon_sdcard_slave writeWaitTime 0 -set_interface_property avalon_sdcard_slave isNonVolatileStorage false -set_interface_property avalon_sdcard_slave addressAlignment DYNAMIC -set_interface_property avalon_sdcard_slave maximumPendingReadTransactions 0 -set_interface_property avalon_sdcard_slave readWaitTime 1 -set_interface_property avalon_sdcard_slave readLatency 0 -set_interface_property avalon_sdcard_slave printableDevice false - -set_interface_property avalon_sdcard_slave associatedClock clk -set_interface_property avalon_sdcard_slave associatedReset reset - -add_interface_port avalon_sdcard_slave i_avalon_chip_select chipselect Input 1 -add_interface_port avalon_sdcard_slave i_avalon_address address Input 8 -add_interface_port avalon_sdcard_slave i_avalon_read read Input 1 -add_interface_port avalon_sdcard_slave i_avalon_write write Input 1 -add_interface_port avalon_sdcard_slave i_avalon_byteenable byteenable Input 4 -add_interface_port avalon_sdcard_slave i_avalon_writedata writedata Input 32 -add_interface_port avalon_sdcard_slave o_avalon_readdata readdata Output 32 -add_interface_port avalon_sdcard_slave o_avalon_waitrequest waitrequest Output 1 -# | -# +----------------------------------- - -# +----------------------------------- -# | connection point clk -# | -add_interface clk clock end -set_interface_property clk enabled true - -add_interface_port clk i_clock clk Input 1 -# | -# +----------------------------------- - -# +----------------------------------- -# | connection point reset -# | -add_interface reset reset end -set_interface_property reset associatedClock clk -set_interface_property reset enabled true -set_interface_property reset synchronousEdges DEASSERT - -add_interface_port reset i_reset_n reset_n Input 1 -# | -# +----------------------------------- - -# +----------------------------------- -# | connection point conduit_end -# | -add_interface conduit_end conduit end - -add_interface_port conduit_end b_SD_cmd export Bidir 1 -add_interface_port conduit_end b_SD_dat export Bidir 1 -add_interface_port conduit_end b_SD_dat3 export Bidir 1 -add_interface_port conduit_end o_SD_clock export Output 1 -# | -# +----------------------------------- - -## Add documentation links for user guide and/or release notes -add_documentation_link "User Guide" file:///ip/altera/university_program/memory/altera_up_sd_card_avalon_interface/doc/SD_Card_Interface_for_SoPC_Builder.pdf -add_documentation_link "Release Notes" https://documentation.altera.com/#/link/hco1421698042087/hco1421698013408 diff --git a/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_sw.tcl b/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_sw.tcl deleted file mode 100644 index 9cc0821..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/Altera_UP_SD_Card_Avalon_Interface_sw.tcl +++ /dev/null @@ -1,56 +0,0 @@ -# (C) 2001-2015 Altera Corporation. All rights reserved. -# Your use of Altera Corporation's design tools, logic functions and other -# software and tools, and its AMPP partner logic functions, and any output -# files any of the foregoing (including device programming or simulation -# files), and any associated documentation or information are expressly subject -# to the terms and conditions of the Altera Program License Subscription -# Agreement, Altera MegaCore Function License Agreement, or other applicable -# license agreement, including, without limitation, that your use is for the -# sole purpose of programming logic devices manufactured by Altera and sold by -# Altera or its authorized distributors. Please refer to the applicable -# agreement for further details. - - -# TCL File Generated by Altera University Program -# DO NOT MODIFY - -set aup_version 15.1 - -# Create a new driver - this name must be different than the -# hardware component name -create_driver Altera_UP_SD_Card_Avalon_Interface_mod_driver - -# Associate it with some hardware -set_sw_property hw_class_name Altera_UP_SD_Card_Avalon_Interface_mod - -# The version of this driver -set_sw_property version $aup_version - -# This driver is proclaimed to be compatible with 'component' -# as old as version "1.0". The component hardware version is set in the -# _hw.tcl file - If the hardware component version number is not equal -# or greater than the min_compatable_hw_version number, the driver -# source files will not be copied over to the BSP driver directory -set_sw_property min_compatible_hw_version 15.1 - -# Initialize the driver in alt_sys_init() -set_sw_property auto_initialize true - -# Location in generated BSP that sources will be copied into -set_sw_property bsp_subdirectory drivers - -# -# Source file listings... -# - -# C/C++ source files -add_sw_property c_source HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c - -# Include files -add_sw_property include_source HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h - -# This driver supports HAL type -add_sw_property supported_bsp_type HAL - -# End of file - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h b/ip/altera_up_sd_card_avalon_interface_mod/HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h deleted file mode 100644 index 4e1dbef..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__ -#define __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#define SD_RAW_IFACE - -/* - * Device structure definition. Each instance of the driver uses one - * of these structures to hold its associated state. - */ -typedef struct alt_up_sd_card_dev { - /// @brief character mode device structure - /// @sa Developing Device Drivers for the HAL in Nios II Software Developer's Handbook - alt_dev dev; - /// @brief the base address of the device - unsigned int base; - -} alt_up_sd_card_dev; - -#ifndef bool - typedef enum e_bool { false = 0, true = 1 } bool; -#endif - -////////////////////////////////////////////////////////////////////////// -// HAL system functions - -alt_up_sd_card_dev* alt_up_sd_card_open_dev(const char *name); -/* Open an SD Card Interface if it is connected to the system. */ - - -bool alt_up_sd_card_is_Present(void); -/* Check if there is an SD Card insterted into the SD Card socket. - */ - -#ifndef SD_RAW_IFACE -bool alt_up_sd_card_is_FAT16(void); -/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16 - * volume. Please note that FAT12 has a similar format, but will not be supported by this driver. - */ - - -short int alt_up_sd_card_fopen(char *name, bool create); -/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16 - * volume. Please note that FAT12 has a similar format, but will not be supported by this driver. - * - * Inputs: - * name - a file name including a directory, relative to the root directory - * create - a flag set to true to create a file if it does not already exist - * Output: - * An index to the file record assigned to the specified file. -1 is returned if the file could not be opened. - */ - - -short int alt_up_sd_card_find_first(char *directory_to_search_through, char *file_name); -/* This function sets up a search algorithm to go through a given directory looking for files. - * If the search directory is valid, then the function searches for the first file it finds. - * Inputs: - * directory_to_search_through - name of the directory to search through - * file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination). - * Outputs: - * 0 - success - * 1 - invalid directory - * 2 - No card or incorrect card format. - * - * To specify a directory give the name in a format consistent with the following regular expression: - * [{[valid_chars]+}/]*. - * - * In other words, give a path name starting at the root directory, where each directory name is followed by a '/'. - * Then, append a '.' to the directory name. Examples: - * "." - look through the root directory - * "first/." - look through a directory named "first" that is located in the root directory. - * "first/sub/." - look through a directory named "sub", that is located within the subdirectory named "first". "first" is located in the root directory. - * Invalid examples include: - * "/.", "/////." - this is not the root directory. - * "/first/." - the first character may not be a '/'. - */ - - - -short int alt_up_sd_card_find_next(char *file_name); -/* This function searches for the next file in a given directory, as specified by the find_first function. - * Inputs: - * file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination). - * Outputs: - * -1 - end of directory. - * 0 - success - * 2 - No card or incorrect card format. - * 4 - find_first has not been called successfully. - */ - -void alt_up_sd_card_set_attributes(short int file_handle, short int attributes); -/* Set file attributes as needed. - */ - -short int alt_up_sd_card_get_attributes(short int file_handle); -/* Return file attributes, or -1 if the file_handle is invalid. - */ - - -short int alt_up_sd_card_read(short int file_handle); -/* Read a single character from the given file. Return -1 if at the end of a file. Any other negative number - * means that the file could not be read. A number between 0 and 255 is an ASCII character read from the SD Card. */ - - -bool alt_up_sd_card_write(short int file_handle, char byte_of_data); -/* Write a single character to a given file. Return true if successful, and false otherwise. */ - - -bool alt_up_sd_card_fclose(short int file_handle); -// This function closes an opened file and saves data to SD Card if necessary. - -#else -bool Write_Sector_Data(int sector_index, int partition_offset); -bool Save_Modified_Sector(); -bool Read_Sector_Data(int sector_index, int partition_offset); -#endif //SD_RAW_IFACE - -////////////////////////////////////////////////////////////////////////// -// file-like operation functions - -////////////////////////////////////////////////////////////////////////// -// direct operation functions - - -/* - * Macros used by alt_sys_init - */ -#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INSTANCE(name, device) \ - static alt_up_sd_card_dev device = \ - { \ - { \ - ALT_LLIST_ENTRY, \ - name##_NAME, \ - NULL , /* open */ \ - NULL , /* close */ \ - NULL, /* read */ \ - NULL, /* write */ \ - NULL , /* lseek */ \ - NULL , /* fstat */ \ - NULL , /* ioctl */ \ - }, \ - name##_BASE, \ - } - -#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INIT(name, device) \ -{ \ - alt_dev_reg(&device.dev); \ -} - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__ */ - - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c b/ip/altera_up_sd_card_avalon_interface_mod/HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c deleted file mode 100644 index b98e077..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c +++ /dev/null @@ -1,1908 +0,0 @@ -/****************************************************************************** -* * -* License Agreement * -* * -* Copyright (c) 2006 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 -#include -#include -#include -#include -#include "Altera_UP_SD_Card_Avalon_Interface_mod.h" - -/////////////////////////////////////////////////////////////////////////// -// Local Define Statements -/////////////////////////////////////////////////////////////////////////// - -#define CHAR_TO_UPPER(ch) ((char) (((ch >= 'a') && (ch <= 'z')) ? ((ch-'a')+'A'): ch)) - -// Data Buffer Address -#define SD_CARD_BUFFER(base, x) (base + x) -// 128-bit Card Identification Number -#define SD_CARD_CID(base, x) (base + 0x0200 + x) -// 128-bit Card Specific Data Register -#define SD_CARD_CSD(base, x) (base + 0x0210 + x) -// 32-bit Operating Conditions Register -#define SD_CARD_OCR(base) (base + 0x0220) -// 32-bit Card Status Register -#define SD_CARD_STATUS(base) (base + 0x0224) -// 16-bit Relative Card Address Register -#define SD_CARD_RCA(base) (base + 0x0228) -// 32-bit Card Argument Register -#define SD_CARD_ARGUMENT(base) (base + 0x022C) -// 16-bit Card Command Register -#define SD_CARD_COMMAND(base) (base + 0x0230) -// 16-bit Card Auxiliary Status Register -#define SD_CARD_AUX_STATUS(base) (base + 0x0234) -// 32-bit R1 Response Register -#define SD_CARD_R1_RESPONSE(base) (base + 0x0238) - -#define CMD_READ_BLOCK 17 -#define CMD_WRITE_BLOCK 24 - -// FAT 12/16 related stuff -//#define BOOT_SECTOR_DATA_SIZE 0x005A -#define MAX_FILES_OPENED 2 - -/******************************************************************************/ -/****** LOCAL DATA STRUCTURES ***********************************************/ -/******************************************************************************/ - - -typedef struct s_FAT_12_16_boot_sector { - unsigned char jump_instruction[3]; - char OEM_name[8]; - unsigned short int sector_size_in_bytes; - unsigned char sectors_per_cluster; - unsigned short int reserved_sectors; - unsigned char number_of_FATs; - unsigned short int max_number_of_dir_entires; - unsigned short int number_of_sectors_in_partition; - unsigned char media_descriptor; - unsigned short int number_of_sectors_per_table; - unsigned short int number_of_sectors_per_track; - unsigned short int number_of_heads; - unsigned int number_of_hidden_sectors; - unsigned int total_sector_count_if_above_32MB; - unsigned char drive_number; - unsigned char current_head; - unsigned char boot_signature; - unsigned char volume_id[4]; - char volume_label[11]; - unsigned char file_system_type[8]; - unsigned char bits_for_cluster_index; - unsigned int first_fat_sector_offset; - unsigned int second_fat_sector_offset; - unsigned int root_directory_sector_offset; - unsigned int data_sector_offset; -} t_FAT_12_16_boot_sector; - - -typedef struct s_file_record { - unsigned char name[8]; - unsigned char extension[3]; - unsigned char attributes; - unsigned short int create_time; - unsigned short int create_date; - unsigned short int last_access_date; - unsigned short int last_modified_time; - unsigned short int last_modified_date; - unsigned short int start_cluster_index; - unsigned int file_size_in_bytes; - /* The following fields are only used when a file has been created or opened. */ - unsigned int current_cluster_index; - unsigned int current_sector_in_cluster; - unsigned int current_byte_position; - // Absolute location of the file record on the SD Card. - unsigned int file_record_cluster; - unsigned int file_record_sector_in_cluster; - short int file_record_offset; - // Is this record in use and has the file been modified. - unsigned int home_directory_cluster; - bool modified; - bool in_use; -} t_file_record; - - -typedef struct s_find_data { - unsigned int directory_root_cluster; // 0 means root directory. - unsigned int current_cluster_index; - unsigned int current_sector_in_cluster; - short int file_index_in_sector; - bool valid; -} t_find_data; - - -/////////////////////////////////////////////////////////////////////////// -// Local Variables -/////////////////////////////////////////////////////////////////////////// - - -bool initialized = false; -bool is_sd_card_formated_as_FAT16 = false; -volatile short int *aux_status_register = NULL; -volatile int *status_register = NULL; -volatile short int *CSD_register_w0 = NULL; -volatile short int *command_register = NULL; -volatile int *command_argument_register = NULL; -volatile char *buffer_memory = NULL; -int fat_partition_offset_in_512_byte_sectors = 0; -int fat_partition_size_in_512_byte_sectors = 0; - -#ifndef SD_RAW_IFACE -t_FAT_12_16_boot_sector boot_sector_data; -#endif - -alt_up_sd_card_dev *device_pointer = NULL; - -#ifndef SD_RAW_IFACE -// Pointers to currently opened files. -t_file_record active_files[MAX_FILES_OPENED]; -#endif -bool current_sector_modified = false; -unsigned int current_sector_index = 0; - -#ifndef SD_RAW_IFACE -t_find_data search_data; -#endif - - -/////////////////////////////////////////////////////////////////////////// -// Local Functions -/////////////////////////////////////////////////////////////////////////// - -#ifndef SD_RAW_IFACE -static bool Write_Sector_Data(int sector_index, int partition_offset) -#else -bool Write_Sector_Data(int sector_index, int partition_offset) -#endif -// This function writes a sector at the specified address on the SD Card. -{ - bool result = false; - - if (alt_up_sd_card_is_Present()) - { - short int reg_state = 0xff; - - /* Multiply sector offset by sector size to get the address. Sector size is 512. Also, - * the SD card reads data in 512 byte chunks, so the address must be a multiple of 512. */ - IOWR_32DIRECT(command_argument_register, 0, (sector_index + partition_offset)*512); - IOWR_16DIRECT(command_register, 0, CMD_WRITE_BLOCK); - do { - reg_state = (short int) IORD_16DIRECT(aux_status_register,0); - } while ((reg_state & 0x04)!=0); - // Make sure the request did not time out. - if ((reg_state & 0x10) == 0) - { - result = true; - current_sector_modified = false; - current_sector_index = sector_index+partition_offset; - } - } - return result; -} - -#ifndef SD_RAW_IFACE -static bool Save_Modified_Sector() -#else -bool Save_Modified_Sector() -#endif -// If the sector has been modified, then save it to the SD Card. -{ - bool result = true; - if (current_sector_modified) - { - result = Write_Sector_Data(current_sector_index, 0); - } - return result; -} - -#ifndef SD_RAW_IFACE -static bool Read_Sector_Data(int sector_index, int partition_offset) -#else -bool Read_Sector_Data(int sector_index, int partition_offset) -#endif -// This function reads a sector at the specified address on the SD Card. -{ - bool result = false; - - if (alt_up_sd_card_is_Present()) - { - short int reg_state = 0xff; - - /* Write data to the SD card if the current buffer is out of date. */ - if (current_sector_modified) - { - if (Write_Sector_Data(current_sector_index, 0) == false) - { - return false; - } - } - /* Multiply sector offset by sector size to get the address. Sector size is 512. Also, - * the SD card reads data in 512 byte chunks, so the address must be a multiple of 512. */ - IOWR_32DIRECT(command_argument_register, 0, (sector_index + partition_offset)*512); - IOWR_16DIRECT(command_register, 0, CMD_READ_BLOCK); - do { - reg_state = (short int) IORD_16DIRECT(aux_status_register,0); - } while ((reg_state & 0x04)!=0); - // Make sure the request did not time out. - if ((reg_state & 0x10) == 0) - { - result = true; - current_sector_modified = false; - current_sector_index = sector_index+partition_offset; - } - } - return result; -} - -#ifndef SD_RAW_IFACE -static bool get_cluster_flag(unsigned int cluster_index, unsigned short int *flag) -// Read a cluster flag. -{ - unsigned int sector_index = (cluster_index / 256) + fat_partition_offset_in_512_byte_sectors; - - sector_index = sector_index + boot_sector_data.first_fat_sector_offset; - - if (sector_index != current_sector_index) - { - if (Read_Sector_Data(sector_index, 0) == false) - { - return false; - } - } - *flag = (unsigned short int) IORD_16DIRECT(device_pointer->base, 2*(cluster_index % 256)); - return true; -} - - -static bool mark_cluster(unsigned int cluster_index, short int flag, bool first_fat) -// Place a marker on the specified cluster in a given FAT. -{ - unsigned int sector_index = (cluster_index / 256) + fat_partition_offset_in_512_byte_sectors; - - if (first_fat) - { - sector_index = sector_index + boot_sector_data.first_fat_sector_offset; - } - else - { - sector_index = sector_index + boot_sector_data.second_fat_sector_offset; - } - - if (sector_index != current_sector_index) - { - if (Read_Sector_Data(sector_index, 0) == false) - { - return false; - } - } - IOWR_16DIRECT(device_pointer->base, 2*(cluster_index % 256), flag); - current_sector_modified = true; - return true; -} - - -static bool Check_for_Master_Boot_Record(void) -// This function reads the first 512 bytes on the SD Card. This data should -// contain the Master Boot Record. If it does, then print -// relevant information and return true. Otherwise, return false. -{ - bool result = false; - int index; - int end, offset, partition_size; - - /* Load the first 512 bytes of data from SD card. */ - if (Read_Sector_Data(0, 0)) - { - end = (short int) IORD_16DIRECT(device_pointer->base,0x1fe); - - // Check if the end of the sector contains an end string 0xaa55. - if ((end & 0x0000ffff) == 0x0000aa55) - { - // Check four partition entries and see if any are valid - for (index = 0; index < 4; index++) - { - int partition_data_offset = (index * 16) + 0x01be; - char type; - - // Read Partition type - type = (unsigned char) IORD_8DIRECT(device_pointer->base,partition_data_offset + 0x04); - - // Check if this is an FAT parition - if ((type == 1) || (type == 4) || (type == 6) || (type == 14)) - { - // Get partition offset and size. - offset = (((unsigned short int) IORD_16DIRECT(device_pointer->base,partition_data_offset + 0x0A)) << 16) | ((unsigned short int) IORD_16DIRECT(device_pointer->base,partition_data_offset + 0x08)); - partition_size = (((unsigned short int) IORD_16DIRECT(device_pointer->base,partition_data_offset + 0x0E)) << 16) | ((unsigned short int) IORD_16DIRECT(device_pointer->base,partition_data_offset + 0x0C)); - - // Check if the partition is valid - if (partition_size > 0) - { - result = true; - fat_partition_size_in_512_byte_sectors = partition_size; - fat_partition_offset_in_512_byte_sectors = offset; - break; - } - } - } - } - } - - return result; -} - - -static bool Read_File_Record_At_Offset(int offset, t_file_record *record, unsigned int cluster_index, unsigned int sector_in_cluster) -// This function reads a file record -{ - bool result = false; - if (((offset & 0x01f) == 0) && (alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - int counter; - - for (counter = 0; counter < 8; counter++) - { - record->name[counter] = (char) IORD_8DIRECT(device_pointer->base, offset+counter); - } - for (counter = 0; counter < 3; counter++) - { - record->extension[counter] = (char) IORD_8DIRECT(device_pointer->base, offset+counter+8); - } - record->attributes = (char) IORD_8DIRECT(device_pointer->base, offset+11); - /* Ignore reserved bytes at locations 12 and 13. */ - record->create_time = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+14); - record->create_date = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+16); - record->last_access_date = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+18); - /* Ignore reserved bytes at locations 20 and 21. */ - record->last_modified_time = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+22); - record->last_modified_date = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+24); - record->start_cluster_index = (unsigned short int) IORD_16DIRECT(device_pointer->base, offset+26); - record->file_size_in_bytes = (unsigned int) IORD_32DIRECT(device_pointer->base, offset+28); - record->file_record_cluster = cluster_index; - record->file_record_sector_in_cluster = sector_in_cluster; - record->file_record_offset = offset; - result = true; - } - return result; -} - - -static bool Write_File_Record_At_Offset(int offset, t_file_record *record) -// This function writes a file record at a given offset. The offset is given in bytes. -{ - bool result = false; - if (((offset & 0x01f) == 0) && (alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - int counter; - - for (counter = 0; counter < 8; counter=counter+2) - { - short int two_chars = (short int) record->name[counter+1]; - two_chars = two_chars << 8; - two_chars = two_chars | record->name[counter]; - IOWR_16DIRECT(device_pointer->base, offset+counter, two_chars); - } - for (counter = 0; counter < 3; counter++) - { - IOWR_8DIRECT(device_pointer->base, offset+counter+8, record->extension[counter]); - } - IOWR_8DIRECT(device_pointer->base, offset+11, record->attributes); - /* Ignore reserved bytes at locations 12 and 13. */ - IOWR_16DIRECT(device_pointer->base, offset+14, record->create_time); - IOWR_16DIRECT(device_pointer->base, offset+16, record->create_date); - IOWR_16DIRECT(device_pointer->base, offset+18, record->last_access_date); - /* Ignore reserved bytes at locations 20 and 21. */ - IOWR_16DIRECT(device_pointer->base, offset+22, record->last_modified_time); - IOWR_16DIRECT(device_pointer->base, offset+24, record->last_modified_date); - IOWR_16DIRECT(device_pointer->base, offset+26, record->start_cluster_index); - IOWR_32DIRECT(device_pointer->base, offset+28, record->file_size_in_bytes); - current_sector_modified = true; - result = true; - } - return result; -} - - -static bool Check_for_DOS_FAT(int FAT_partition_start_sector) -// This function reads the boot sector for the FAT file system on the SD Card. -// The offset_address should point to the sector on the card where the boot sector is located. -// The sector number is specified either in the master Boot Record, or is 0 by default for a purely FAT -// based file system. If the specified sector contains a FAT boot sector, then this function prints the -// relevant information and returns 1. Otherwise, it returns 0. -{ - bool result = false; - int counter = 0; - short int end; - - result = Read_Sector_Data(0, FAT_partition_start_sector); - end = (short int) IORD_16DIRECT(device_pointer->base, 0x1fe); - if (((end & 0x0000ffff) == 0x0000aa55) && (result)) - { - int num_clusters = 0; - - boot_sector_data.jump_instruction[0] = (char) IORD_8DIRECT(device_pointer->base, 0); - boot_sector_data.jump_instruction[1] = (char) IORD_8DIRECT(device_pointer->base, 1); - boot_sector_data.jump_instruction[2] = (char) IORD_8DIRECT(device_pointer->base, 2); - for (counter = 0; counter < 8; counter++) - { - boot_sector_data.OEM_name[counter] = (char) IORD_8DIRECT(device_pointer->base, 3+counter); - } - boot_sector_data.sector_size_in_bytes = (((unsigned char) IORD_8DIRECT(device_pointer->base, 12)) << 8 ) | ((char) IORD_8DIRECT(device_pointer->base, 11)); - boot_sector_data.sectors_per_cluster = ((unsigned char) IORD_8DIRECT(device_pointer->base, 13)); - boot_sector_data.reserved_sectors = ((unsigned short int) IORD_16DIRECT(device_pointer->base, 14)); - boot_sector_data.number_of_FATs = ((unsigned char) IORD_8DIRECT(device_pointer->base, 16)); - boot_sector_data.max_number_of_dir_entires = (((unsigned short int)(((unsigned char) IORD_8DIRECT(device_pointer->base, 18)))) << 8 ) | ((unsigned char) IORD_8DIRECT(device_pointer->base, 17)); - boot_sector_data.number_of_sectors_in_partition = (((unsigned short int)(((unsigned char) IORD_8DIRECT(device_pointer->base, 20)))) << 8 ) | ((unsigned char) IORD_8DIRECT(device_pointer->base, 19)); - boot_sector_data.media_descriptor = ((unsigned char) IORD_8DIRECT(device_pointer->base, 21)); - boot_sector_data.number_of_sectors_per_table = ((unsigned short int) IORD_16DIRECT(device_pointer->base, 22)); - boot_sector_data.number_of_sectors_per_track = ((unsigned short int) IORD_16DIRECT(device_pointer->base, 24)); - boot_sector_data.number_of_heads = ((unsigned short int) IORD_16DIRECT(device_pointer->base, 26)); - boot_sector_data.number_of_hidden_sectors = ((unsigned int) IORD_32DIRECT(device_pointer->base, 28)); - boot_sector_data.total_sector_count_if_above_32MB = ((unsigned int) IORD_32DIRECT(device_pointer->base, 32)); - boot_sector_data.drive_number = ((unsigned char) IORD_8DIRECT(device_pointer->base, 36)); - boot_sector_data.current_head = ((unsigned char) IORD_8DIRECT(device_pointer->base, 37)); - boot_sector_data.boot_signature = ((unsigned char) IORD_8DIRECT(device_pointer->base, 38)); - boot_sector_data.first_fat_sector_offset = boot_sector_data.reserved_sectors; - boot_sector_data.second_fat_sector_offset = boot_sector_data.first_fat_sector_offset + boot_sector_data.number_of_sectors_per_table; - boot_sector_data.root_directory_sector_offset = boot_sector_data.second_fat_sector_offset + boot_sector_data.number_of_sectors_per_table; - boot_sector_data.data_sector_offset = boot_sector_data.root_directory_sector_offset + (32*boot_sector_data.max_number_of_dir_entires / boot_sector_data.sector_size_in_bytes); - - if (boot_sector_data.number_of_sectors_in_partition > 0) - { - num_clusters = (boot_sector_data.number_of_sectors_in_partition / boot_sector_data.sectors_per_cluster); - } - else - { - num_clusters = (boot_sector_data.total_sector_count_if_above_32MB / boot_sector_data.sectors_per_cluster); - } - if (num_clusters < 4087) - { - boot_sector_data.bits_for_cluster_index = 12; - } - else if (num_clusters <= 65517) - { - boot_sector_data.bits_for_cluster_index = 16; - } - else - { - boot_sector_data.bits_for_cluster_index = 32; - } - - for (counter = 0; counter < 4; counter++) - { - boot_sector_data.volume_id[counter] = ((char) IORD_8DIRECT(device_pointer->base, 39+counter)); - } - for (counter = 0; counter < 11; counter++) - { - boot_sector_data.volume_label[counter] = ((char) IORD_8DIRECT(device_pointer->base, 43+counter)); - } - for (counter = 0; counter < 8; counter++) - { - boot_sector_data.file_system_type[counter] = ((char) IORD_8DIRECT(device_pointer->base, 54+counter)); - } - // Clear file records - for (counter = 0; counter < MAX_FILES_OPENED; counter++) - { - active_files[counter].in_use = false; - } - result = true; - } - else - { - result = false; - } - return result; -} - - -static bool Look_for_FAT16(void) -// Read the SD card to determine if it contains a FAT16 partition. -{ - bool result = false; - - if (alt_up_sd_card_is_Present()) - { - short int csd_file_format = *CSD_register_w0; - - fat_partition_offset_in_512_byte_sectors = 0; - fat_partition_size_in_512_byte_sectors = 0; - - if (((csd_file_format & 0x8000) == 0) && ((csd_file_format & 0x0c00) != 0x0c00)) - { - if ((csd_file_format & 0x0c00) == 0x0400) - { - /* SD Card contains files stored in a DOS FAT (floppy like) file format, without a partition table */ - result = Check_for_DOS_FAT(0); - } - if ((csd_file_format & 0x0c00) == 0x0000) - { - /* SD Card contains files stored in a Hard disk-like file format that contains a partition table */ - if (Check_for_Master_Boot_Record()) - { - result = Check_for_DOS_FAT(fat_partition_offset_in_512_byte_sectors); - } - } - if (result == true) - { - // Accept only FAT16, not FAT12. - if (boot_sector_data.bits_for_cluster_index != 16) - { - result = false; - } - else - { - fat_partition_size_in_512_byte_sectors = boot_sector_data.number_of_sectors_in_partition; - } - } - } - } - return result; -} - - -static void filename_to_upper_case(char *file_name) -// Change file name to upper case. -{ - int index; - int length = strlen(file_name); - - for (index = 0; index < length; index++) - { - if ((file_name[index] >= 'a') && (file_name[index] <= 'z')) - { - file_name[index] = (file_name[index] - 'a') + 'A'; - } - } -} - - -static bool check_file_name_for_FAT16_compliance(char *file_name) -// Check if the file complies with FAT16 naming convention. -{ - int length = strlen(file_name); - int index; - int last_dir_break_position = -1; - int last_period = -1; - bool result = true; - - for(index = 0; index < length; index++) - { - if ((file_name[index] == ' ') || - ((last_dir_break_position == (index - 1)) && ((file_name[index] == '\\') || (file_name[index] == '/'))) || - ((index - last_period == 9) && (file_name[index] != '.')) || - ((last_dir_break_position != last_period) && (index - last_period > 3) && - (file_name[index] != '\\') && (file_name[index] != '/')) - ) - { - result = false; - break; - } - if ((file_name[index] == '\\') || (file_name[index] == '/')) - { - last_period = index; - last_dir_break_position = index; - } - if (file_name[index] == '.') - { - last_period = index; - } - } - if ((file_name[length-1] == '\\') || (file_name[length-1] == '/')) - { - result = false; - } - return result; -} - - -static int get_dir_divider_location(char *name) -// Find a directory divider location. -{ - int index = 0; - int length = strlen(name); - - for(index = 0; index < length; index++) - { - if ((name[index] == '\\') || (name[index] == '/')) - { - break; - } - } - - if (index == length) - { - index = -1; - } - - return index; -} - - -static bool match_file_record_to_name_ext(t_file_record *file_record, char *name, char *extension) -/* See if the given name and extension match the file record. Return true if this is so, false otherwise. */ -{ - bool match = true; - int index; - - for (index = 0; index < 8; index++) - { - if (CHAR_TO_UPPER(file_record->name[index]) != CHAR_TO_UPPER(name[index])) - { - match = false; - break; - } - } - for (index = 0; index < 3; index++) - { - if (CHAR_TO_UPPER(file_record->extension[index]) != CHAR_TO_UPPER(extension[index])) - { - match = false; - break; - } - } - return match; -} - - -static bool get_home_directory_cluster_for_file(char *file_name, int *home_directory_cluster, t_file_record *file_record) -// Scan the directories in given in the file name and find the root directory for the file. -{ - bool result = false; - int home_dir_cluster = 0; - int location, index; - int start_location = 0; - - /* Get Next Directory. */ - location = get_dir_divider_location( file_name ); - while (location > 0) - { - char name[8] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; - char extension[3] = { ' ', ' ', ' ' }; - int ext_index = -1; - int new_cluster = home_dir_cluster; - - // Get the name of the directory in name/extension format. - for (index = 0; index < location; index++) - { - if (file_name[index+start_location] == '.') - { - ext_index = index; - } - else if (ext_index < 0) - { - name[index] = file_name[index+start_location]; - } - else - { - extension[index-ext_index] = file_name[index+start_location]; - } - } - - if (home_dir_cluster == 0) - { - /* We are in the root directory. Scan the directory (of predefined size) and see if you can find the specified file. */ - int max_root_dir_sectors = ((32*boot_sector_data.max_number_of_dir_entires) / boot_sector_data.sector_size_in_bytes); - int sector_index; - - for (sector_index = 0; sector_index < max_root_dir_sectors; sector_index++) - { - if (Read_Sector_Data(sector_index+boot_sector_data.root_directory_sector_offset, fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - - // Read file record. - Read_File_Record_At_Offset(file_counter*32, file_record, 0, sector_index); - if ((file_record->name[0] != 0xe5) && (file_record->name[0] != 0x00)) - { - bool match = match_file_record_to_name_ext(file_record, name, extension); - if (match) - { - new_cluster = file_record->start_cluster_index; - file_record->file_record_cluster = 1; // Home directory is a subdirectory in the root directory. - break; - } - } - } - } - else - { - break; - } - if (new_cluster != home_dir_cluster) - { - break; - } - } - if (new_cluster != home_dir_cluster) - { - // A valid directory is found, so go to it. - home_dir_cluster = new_cluster; - start_location = start_location+location+1; - } - else - { - // Directory path is invalid. - return false; - } - } else { - // This is a subdirectory that can have any number of elements. So scan through it as though it was a file - // and see if you can find the directory of interest. - int cluster = home_dir_cluster; - - do { - int start_sector = ( cluster - 2 ) * ( boot_sector_data.sectors_per_cluster ) + boot_sector_data.data_sector_offset; - int sector_index; - - for (sector_index = 0; sector_index < boot_sector_data.sectors_per_cluster; sector_index++) - { - if (Read_Sector_Data(sector_index + start_sector, fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - // Read file record. - Read_File_Record_At_Offset(file_counter*32, file_record, cluster, sector_index); - if ((file_record->name[0] != 0xe5) && (file_record->name[0] != 0x00)) - { - bool match = match_file_record_to_name_ext(file_record, name, extension); - if (match) - { - new_cluster = file_record->start_cluster_index; - break; - } - } - } - } - else - { - break; - } - if (new_cluster != home_dir_cluster) - { - break; - } - } - // If this is the end of the cluster and the directory has not been found, then see if there is another cluster - // that holds data for the current directory. - if (new_cluster == home_dir_cluster) - { - unsigned short int next_cluster; - - if (get_cluster_flag(new_cluster, &next_cluster)) - { - // The directory needs to be expanded to store more files. - if ((next_cluster & 0x0000fff8) == 0x0000fff8) - { - return false; - } - new_cluster = (next_cluster & 0x0000fff8); - } - else - { - // Directory path is invalid. - return false; - } - } - } while ((cluster < 0x0000fff8) && (new_cluster == home_dir_cluster)); - if (new_cluster != home_dir_cluster) - { - // A valid directory is found, so go to it. - home_dir_cluster = new_cluster; - start_location = start_location+location+1; - } - else - { - // Directory path is invalid. - return false; - } - } - location = get_dir_divider_location(&(file_name[start_location])); - if (location < 0) - { - // Directory has been located. - result = true; - } - } - - *home_directory_cluster = home_dir_cluster; - if (home_dir_cluster == 0) - { - file_record->file_record_cluster = 0; // Home directory is the root directory. - result = true; - } - return result; -} - - -static bool find_file_in_directory(int directory_start_cluster, char *file_name, t_file_record *file_record) -// Given a cluster and a file name, check if the file already exists. Return the file record if the file is found. -{ - int location = get_dir_divider_location( file_name ); - int last_dir_separator = 0; - char name[8] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; - char extension[3] = { ' ', ' ', ' ' }; - int ext_index = -1; - int cluster = directory_start_cluster; - int index; - int length = strlen(file_name); - bool result = false; - - // Skip through all directory separators. - while (location > 0) - { - last_dir_separator = last_dir_separator+location+1; - location = get_dir_divider_location( &(file_name[last_dir_separator]) ); - } - - // Get the name of the file in name/extension format. - for (index = last_dir_separator; index < length; index++) - { - if (file_name[index] == '.') - { - ext_index = index; - } - else if (ext_index < 0) - { - name[index-last_dir_separator] = file_name[index]; - } - else - { - extension[index-ext_index-1] = file_name[index]; - } - } - - // Look for the file. - if (directory_start_cluster == 0) - { - /* We are in the root directory. Scan the directory (of predefined size) and see if you can find the specified file. */ - int max_root_dir_sectors = ((32*boot_sector_data.max_number_of_dir_entires) / boot_sector_data.sector_size_in_bytes); - int sector_index; - - for (sector_index = 0; sector_index < max_root_dir_sectors; sector_index++) - { - if (Read_Sector_Data( sector_index + boot_sector_data.root_directory_sector_offset, - fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - // Read file record. - Read_File_Record_At_Offset(file_counter*32, file_record, 0, sector_index); - if ((file_record->name[0] != 0xe5) && (file_record->name[0] != 0x00)) - { - bool match = match_file_record_to_name_ext(file_record, name, extension); - - if (match) - { - result = true; - break; - } - } - } - } - else - { - break; - } - if (result) - { - break; - } - } - } - else - { - do { - int start_sector = ( cluster - 2 ) * ( boot_sector_data.sectors_per_cluster ) + boot_sector_data.data_sector_offset; - int sector_index; - - for (sector_index = 0; sector_index < boot_sector_data.sectors_per_cluster; sector_index++) - { - if (Read_Sector_Data(sector_index + start_sector, fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - // Read file record. - Read_File_Record_At_Offset(file_counter*32, file_record, cluster, sector_index); - if ((file_record->name[0] != 0xe5) && (file_record->name[0] != 0x00)) - { - bool match = match_file_record_to_name_ext(file_record, name, extension); - - if (match) - { - result = true; - break; - } - } - } - } - else - { - break; - } - if (result) - { - break; - } - } - // If this is the end of the cluster and the file has not been found, then see if there is another cluster - // that holds data for the current directory. - if (result == false) - { - unsigned short int new_cluster; - - if (get_cluster_flag(cluster, &new_cluster)) - { - // The directory needs to be expanded to store more files. - if ((new_cluster & 0x0000fff8) == 0x0000fff8) - { - return false; - } - cluster = (new_cluster & 0x0000fff8); - } - else - { - // Directory path is invalid. - return false; - } - } - } while ((cluster < 0x0000fff8) && (result == false)); - } - - return result; -} - - -static bool find_first_empty_cluster(unsigned int *cluster_number) -// Find the first empty cluster. It will be marked by a 0 entry in the File Allocation Table. -{ - unsigned int sector = boot_sector_data.first_fat_sector_offset; - unsigned int cluster_index = 2; - short int cluster = -1; - bool result = false; - unsigned max_cluster_index = 0; - unsigned int non_data_sectors = boot_sector_data.data_sector_offset; - unsigned int less_than_32 = boot_sector_data.number_of_sectors_in_partition; - unsigned int greater_than_32 = boot_sector_data.total_sector_count_if_above_32MB; - - if (less_than_32 > greater_than_32) - { - max_cluster_index = ((less_than_32 - non_data_sectors) / boot_sector_data.sectors_per_cluster) + 1; - } - else - { - max_cluster_index = ((greater_than_32 - non_data_sectors) / boot_sector_data.sectors_per_cluster) + 1; - } - // Find an empty cluster for the file. - while (sector != boot_sector_data.second_fat_sector_offset) - { - if (Read_Sector_Data( sector, fat_partition_offset_in_512_byte_sectors)) - { - do { - cluster = ((unsigned short int) IORD_16DIRECT(device_pointer->base, 2*(cluster_index % 256))); - if (cluster == 0) - { - // Free cluster found. - break; - } - else - { - cluster_index++; - } - } while ((cluster_index % 256) != 0); - } - if (cluster == 0) - { - break; - } - sector++; - } - if ((cluster == 0) && (cluster <= max_cluster_index)) - { - *cluster_number = cluster_index; - result = true; - } - return result; -} - - -static int find_first_empty_record_in_a_subdirectory(int start_cluster_index) -// Search for a free spot in a subdirectory. Return an encoded location for the file record. -{ - int result = -1; - int cluster = start_cluster_index; - do { - int start_sector = ( cluster - 2 ) * ( boot_sector_data.sectors_per_cluster ) + boot_sector_data.data_sector_offset; - int sector_index; - - for (sector_index = 0; sector_index < boot_sector_data.sectors_per_cluster; sector_index++) - { - if (Read_Sector_Data(sector_index + start_sector, fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - unsigned short int leading_char; - - // Read file record. - leading_char = ((unsigned char) IORD_8DIRECT(device_pointer->base, file_counter*32)); - if ((leading_char == 0x00e5) || (leading_char == 0)) - { - result = (cluster) | ((sector_index*16 + file_counter) << 16); - return result; - } - } - } - else - { - break; - } - } - // If this is the end of the cluster and the file has not been found, then see if there is another cluster - // that holds data for the current directory. - if (result < 0) - { - unsigned short int new_cluster; - if (get_cluster_flag(cluster, &new_cluster)) - { - // The directory needs to be expanded to store more files. - if ((new_cluster & 0x0000fff8) == 0x0000fff8) - { - unsigned int new_dir_cluster; - if (find_first_empty_cluster(&new_dir_cluster)) - { - // Add the new cluster to the linked list of the given directory. - if (mark_cluster(cluster, ((short int) (new_dir_cluster)), true) && - mark_cluster(new_dir_cluster, ((short int) (0xffff)), true) && - mark_cluster(cluster, ((short int) (new_dir_cluster)), false) && - mark_cluster(new_dir_cluster, ((short int) (0xffff)), false)) - { - Save_Modified_Sector(); - // The new file will begin at the first entry of the directory. - result = new_dir_cluster; - } - } - cluster = (new_cluster & 0x0000fff8); - } - } - else - { - // Error encountered. - result = -1; - } - } - } while ((cluster < 0x0000fff8) && (result == -1)); - return result; -} - - -static int find_first_empty_record_in_root_directory() -// Find a first unused record location to use. Return -1 if none is found. -{ - int max_root_dir_sectors = ((32*boot_sector_data.max_number_of_dir_entires) / boot_sector_data.sector_size_in_bytes); - int sector_index; - int result = -1; - - for (sector_index = 0; sector_index < max_root_dir_sectors; sector_index++) - { - if (Read_Sector_Data( sector_index + boot_sector_data.root_directory_sector_offset, - fat_partition_offset_in_512_byte_sectors)) - { - int file_counter; - - for (file_counter = 0; file_counter < 16; file_counter++) - { - unsigned short int leading_char; - - // Read first character of the file record. - leading_char = ((unsigned char) IORD_8DIRECT(device_pointer->base, file_counter*32)); - if ((leading_char == 0x00e5) || (leading_char == 0)) - { - result = (sector_index*16 + file_counter) << 16; - return result; - } - } - } - else - { - break; - } - } - return result; -} - -static void convert_filename_to_name_extension(char *filename, char *name, char *extension) -// This function converts the file name into a name . extension format. -{ - int counter; - int local = 0; - - for(counter = 0; counter < 8; counter++) - { - if (filename[local] != '.') - { - name[counter] = filename[local]; - if (filename[local] != 0) local++; - } - else - { - name[counter] = ' '; - } - } - if (filename[local] == '.') local++; - for(counter = 0; counter < 3; counter++) - { - if (filename[local] != 0) - { - extension[counter] = filename[local]; - local++; - } - else - { - extension[counter] = ' '; - } - } - -} - -static bool create_file(char *name, t_file_record *file_record, t_file_record *home_dir) -// Create a file in a given directory. Expand the directory if needed. -{ - unsigned int cluster_number; - bool result = false; - - if (find_first_empty_cluster(&cluster_number)) - { - int record_index; - - if (home_dir->file_record_cluster == 0) - { - // Put a file in the root directory. - record_index = find_first_empty_record_in_root_directory(); - } - else - { - // Put a file in a subdirectory. - record_index = find_first_empty_record_in_a_subdirectory(home_dir->start_cluster_index); - } - if (record_index >= 0) - { - unsigned int file_record_sector; - int location = get_dir_divider_location( name ); - int last_dir_separator = 0; - - // Skip through all directory separators. - while (location > 0) - { - last_dir_separator = last_dir_separator+location+1; - location = get_dir_divider_location( &(name[last_dir_separator]) ); - } - - convert_filename_to_name_extension(&(name[last_dir_separator]), (char *)file_record->name, (char *)file_record->extension); - - file_record->attributes = 0; - file_record->create_time = 0; - file_record->create_date = 0; - file_record->last_access_date = 0; - file_record->last_modified_time = 0; - file_record->last_modified_date = 0; - file_record->start_cluster_index = cluster_number; - file_record->file_size_in_bytes = 0; - file_record->current_cluster_index = cluster_number; - file_record->current_sector_in_cluster = 0; - file_record->current_byte_position = 0; - file_record->file_record_cluster = record_index & 0x0000ffff; - file_record->file_record_sector_in_cluster = ((record_index >> 16) & 0x0000ffff) / 16; - file_record->file_record_offset = (((record_index >> 16) & 0x0000ffff) % 16)*32; - file_record->home_directory_cluster = home_dir->start_cluster_index; - file_record->in_use = true; - file_record->modified = true; - // Now write the record at the specified location. - file_record_sector = (file_record->file_record_cluster == 0) ? - (boot_sector_data.root_directory_sector_offset + file_record->file_record_sector_in_cluster): - (boot_sector_data.data_sector_offset + (file_record->file_record_cluster-2)*boot_sector_data.sectors_per_cluster + - file_record->file_record_sector_in_cluster); - - if (Read_Sector_Data(file_record_sector, fat_partition_offset_in_512_byte_sectors)) - { - if (Write_File_Record_At_Offset(file_record->file_record_offset, file_record)) - { - Save_Modified_Sector(); - // Mark the first cluster of the file as the last cluster at first. - mark_cluster(cluster_number, ((short int) (0xffff)), true); - if (mark_cluster(cluster_number, ((short int) (0xffff)), false)) - { - result = true; - } - } - } - } - - } - return result; -} - - -static void copy_file_record_name_to_string(t_file_record *file_record, char *file_name) -/* Copy a file name from the file record to a given string */ -{ - int index; - int flength = 0; - - /* Copy file name.*/ - for (index = 0; index < 8; index++) - { - if (file_record->name[index] != ' ') - { - file_name[flength] = file_record->name[index]; - flength = flength + 1; - } - } - if (file_record->extension[0] != ' ') - { - file_name[flength] = '.'; - flength = flength + 1; - for (index = 0; index < 3; index++) - { - if (file_record->extension[index] != ' ') - { - file_name[flength] = file_record->extension[index]; - flength = flength + 1; - } - } - } - file_name[flength] = 0; -} -#endif //SD_RAW_IFACE - -/////////////////////////////////////////////////////////////////////////// -// Direct functions -/////////////////////////////////////////////////////////////////////////// - - -alt_up_sd_card_dev* alt_up_sd_card_open_dev(const char* name) -{ - // find the device from the device list - // (see altera_hal/HAL/inc/priv/alt_file.h - // and altera_hal/HAL/src/alt_find_dev.c - // for details) - alt_up_sd_card_dev *dev = (alt_up_sd_card_dev *) alt_find_dev(name, &alt_dev_list); - - if (dev != NULL) - { - aux_status_register = ((short int *) SD_CARD_AUX_STATUS(dev->base)); - status_register = ((int *) SD_CARD_STATUS(dev->base)); - CSD_register_w0 = ((short int *) SD_CARD_CSD(dev->base, 0)); - command_register = ((short int *) SD_CARD_COMMAND(dev->base)); - command_argument_register = ((int *) SD_CARD_ARGUMENT(dev->base)); - buffer_memory = (char *) SD_CARD_BUFFER(dev->base, 0); - device_pointer = dev; - initialized = false; -#ifndef SD_RAW_IFACE - is_sd_card_formated_as_FAT16 = false; - search_data.valid = false; -#endif - } - return dev; -} - - -bool alt_up_sd_card_is_Present(void) -// Check if there is an SD Card insterted into the SD Card socket. -{ - bool result = false; - - if ((device_pointer != NULL) && ((IORD_16DIRECT(aux_status_register,0) & 0x02) != 0)) - { - result = true; - } - else if (initialized == true) - { - int index; - - initialized = false; -#ifndef SD_RAW_IFACE - search_data.valid = false; - is_sd_card_formated_as_FAT16 = false; - - for(index = 0; index < MAX_FILES_OPENED; index++) - { - active_files[index].in_use = false; - active_files[index].modified = false; - } -#endif - } - return result; -} - -#ifndef SD_RAW_IFACE -bool alt_up_sd_card_is_FAT16(void) -/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16 - * volume. Please note that FAT12 has a similar format, but will not be supported by this driver. - * If the card contains a FAT16 volume, the local data structures will be initialized to allow reading and writing - * to the SD card as though it was a hard drive. - */ -{ - bool result = false; - - if (alt_up_sd_card_is_Present()) - { - // Check if an SD Card is in the SD Card slot. - if (initialized == false) - { - // Now determine if the card is formatted as FAT 16. - is_sd_card_formated_as_FAT16 = Look_for_FAT16(); - initialized = is_sd_card_formated_as_FAT16; - search_data.valid = false; - } - result = is_sd_card_formated_as_FAT16; - } - else - { - // If not then you may as well not open the device. - initialized = false; - is_sd_card_formated_as_FAT16 = false; - } - - return result; -} - - -short int alt_up_sd_card_find_first(char *directory_to_search_through, char *file_name) -/* This function sets up a search algorithm to go through a given directory looking for files. - * If the search directory is valid, then the function searches for the first file it finds. - * Inputs: - * directory_to_search_through - name of the directory to search through - * file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination). - * Outputs: - * 0 - success - * 1 - invalid directory - * 2 - No card or incorrect card format. - * - * To specify a directory give the name in a format consistent with the following regular expression: - * [{[valid_chars]+}/]*. - * - * In other words, give a path name starting at the root directory, where each directory name is followed by a '/'. - * Then, append a '.' to the directory name. Examples: - * "." - look through the root directory - * "first/." - look through a directory named "first" that is located in the root directory. - * "first/sub/." - look through a directory named "sub", that is located within the subdirectory named "first". "first" is located in the root directory. - * Invalid examples include: - * "/.", "/////." - this is not the root directory. - * "/first/." - the first character may not be a '/'. - */ -{ - short int result = 2; - if ((alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - int home_directory_cluster; - t_file_record file_record; - - if (get_home_directory_cluster_for_file(directory_to_search_through, &home_directory_cluster, &file_record)) - { - search_data.directory_root_cluster = home_directory_cluster; - search_data.current_cluster_index = home_directory_cluster; - search_data.current_sector_in_cluster = 0; - search_data.file_index_in_sector = -1; - search_data.valid = true; - result = alt_up_sd_card_find_next(file_name); - } - else - { - result = 1; - } - } - return result; -} - - -short int alt_up_sd_card_find_next(char *file_name) -/* This function searches for the next file in a given directory, as specified by the find_first function. - * Inputs: - * file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination). - * Outputs: - * -1 - end of directory. - * 0 - success - * 2 - No card or incorrect card format. - * 3 - find_first has not been called successfully. - */ -{ - short int result = 2; - if ((alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - if (search_data.valid) - { - t_file_record file_record; - int cluster = search_data.current_cluster_index; - - if (cluster == 0) - { - // Searching through the root directory - int max_root_dir_sectors = ((32*boot_sector_data.max_number_of_dir_entires) / boot_sector_data.sector_size_in_bytes); - int sector_index = search_data.current_sector_in_cluster; - int file_counter = search_data.file_index_in_sector+1; - - for (; sector_index < max_root_dir_sectors; sector_index++) - { - if (Read_Sector_Data( sector_index + boot_sector_data.root_directory_sector_offset, - fat_partition_offset_in_512_byte_sectors)) - { - for (; file_counter < 16; file_counter++) - { - if (Read_File_Record_At_Offset(file_counter*32, &file_record, 0, sector_index)) - { - if ((file_record.name[0] != 0) && (file_record.name[0] != 0xe5)) - { - /* Update search structure. */ - search_data.file_index_in_sector = file_counter; - search_data.current_sector_in_cluster = sector_index; - - /* Copy file name.*/ - copy_file_record_name_to_string(&file_record, file_name); - return 0; - } - } - } - file_counter = 0; - } - else - { - break; - } - } - result = -1; - } - else - { - int file_counter = search_data.file_index_in_sector+1; - do - { - int start_sector = ( cluster - 2 ) * ( boot_sector_data.sectors_per_cluster ) + boot_sector_data.data_sector_offset; - int sector_index = search_data.current_sector_in_cluster; - - for (; sector_index < boot_sector_data.sectors_per_cluster; sector_index++) - { - if (Read_Sector_Data(sector_index + start_sector, fat_partition_offset_in_512_byte_sectors)) - { - for (; file_counter < 16; file_counter++) - { - if (Read_File_Record_At_Offset(file_counter*32, &file_record, cluster, sector_index)) - { - if ((file_record.name[0] != 0) && (file_record.name[0] != 0xe5)) - { - /* Update search structure. */ - search_data.current_cluster_index = cluster; - search_data.file_index_in_sector = file_counter; - search_data.current_sector_in_cluster = sector_index; - - /* Copy file name.*/ - copy_file_record_name_to_string(&file_record, file_name); - return 0; - } - } - } - file_counter = 0; - } - else - { - break; - } - } - // If this is the end of the cluster and the file has not been found, then see if there is another cluster - // that holds data for the current directory. - if (sector_index >= boot_sector_data.sectors_per_cluster) - { - unsigned short int new_cluster; - - if (get_cluster_flag(cluster, &new_cluster)) - { - if ((new_cluster & 0x0000fff8) == 0x0000fff8) - { - result = -1; - search_data.valid = false; - } - cluster = ((new_cluster) & 0x0000fff8); - } - else - { - // Error encountered. - result = -1; - } - } - } while (cluster < 0x0000fff8); - } - } - else - { - // Call Find_First first. - result = 3; - } - } - return result; -} - - -short int alt_up_sd_card_fopen(char *name, bool create) -/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16 - * volume. Please note that FAT12 has a similar format, but will not be supported by this driver. - * - * Inputs: - * name - a file name including a directory, relative to the root directory - * create - a flag set to true to create a file if it does not already exist - * Output: - * An index to the file record assigned to the specified file. -1 is returned if the file could not be opened. - * Return -2 if the specified file has already been opened previously. - */ -{ - short int file_record_index = -1; - - if ((alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - unsigned int home_directory_cluster = 0; - t_file_record home_dir; - - /* First check the file name format. It should not be longer than 12 characters, including a period and the extension. - * Rules: - * - no spaces - * - at most 12 chatacters per name, with a period in 9th position. - * - a / or a \ every at most 12 characters. - */ - filename_to_upper_case(name); - if (check_file_name_for_FAT16_compliance(name)) - { - int index; - - /* Get home directory cluster location for the specified file. 0 means root directory. */ - if (!get_home_directory_cluster_for_file(name, (int *) &home_directory_cluster, &home_dir)) - { - return file_record_index; - } - - /* Find a free file slot to store file specs in. */ - for (index = 0; index < MAX_FILES_OPENED; index++) - { - if (active_files[index].in_use == false) - { - file_record_index = index; - break; - } - } - if (file_record_index >= 0) - { - /* If file record is found, then look for the specified file. If the create flag is set to true - * and the file is not found, then it should be created in the current directory. - */ - - if (find_file_in_directory(home_directory_cluster, name, &(active_files[file_record_index]))) - { - if (create) - { - /* Do not allow overwriting existing files for now. */ - return -1; - } - active_files[file_record_index].current_cluster_index = active_files[file_record_index].start_cluster_index; - active_files[file_record_index].current_sector_in_cluster = 0; - active_files[file_record_index].current_byte_position = 0; - active_files[file_record_index].in_use = true; - active_files[file_record_index].modified = false; - - /* Check if the file has already been opened. */ - for (index = 0; index < MAX_FILES_OPENED; index++) - { - if ((file_record_index != index) && (active_files[index].in_use == true)) - { - if ((active_files[file_record_index].file_record_cluster == active_files[index].file_record_cluster) && - (active_files[file_record_index].file_record_sector_in_cluster == active_files[index].file_record_sector_in_cluster) && - (active_files[file_record_index].file_record_offset == active_files[index].file_record_offset)) - { - // file already in use. - file_record_index = -2; - break; - } - } - } - - } - else if (create) - { - /* Create file if needed. */ - if (create_file(name, &(active_files[file_record_index]), &home_dir)) - { - active_files[file_record_index].in_use = true; - active_files[file_record_index].modified = true; - } - else - { - /* If file creation fails then return an invalid file handle. */ - file_record_index = -1; - } - } - else - { - /* Otherwise the file could not be opened.*/ - file_record_index = -1; - } - } - } - } - - return file_record_index; -} - - -void alt_up_sd_card_set_attributes(short int file_handle, short int attributes) -/* Return file attributes, or -1 if the file_handle is invalid. - */ -{ - if ((file_handle >= 0) && (file_handle < MAX_FILES_OPENED)) - { - if (active_files[file_handle].in_use) - { - active_files[file_handle].attributes = ((char)(attributes & 0x00ff)); - } - } -} - - -short int alt_up_sd_card_get_attributes(short int file_handle) -/* Return file attributes, or -1 if the file_handle is invalid. - */ -{ - short int result = -1; - if ((file_handle >= 0) && (file_handle < MAX_FILES_OPENED)) - { - if (active_files[file_handle].in_use) - { - result = ((active_files[file_handle].attributes) & 0x00ff); - } - } - return result; -} - -short int alt_up_sd_card_read(short int file_handle) -/* Read a single character from a given file. Return -1 if at the end of a file. Any other negative number - * means that the file could not be read. A number between 0 and 255 is an ASCII character read from the SD Card. */ -{ - short int ch = -1; - - if ((file_handle >= 0) && (file_handle < MAX_FILES_OPENED)) - { - if (active_files[file_handle].in_use) - { - if (active_files[file_handle].current_byte_position < active_files[file_handle].file_size_in_bytes) - { - int data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster + - active_files[file_handle].current_sector_in_cluster; - - if ((active_files[file_handle].current_byte_position > 0) && ((active_files[file_handle].current_byte_position % 512) == 0)) - { - // Read in a new sector of data. - if (active_files[file_handle].current_sector_in_cluster == boot_sector_data.sectors_per_cluster - 1) - { - // Go to the next cluster. - unsigned short int next_cluster; - if (get_cluster_flag(active_files[file_handle].current_cluster_index, &next_cluster)) - { - if ((next_cluster & 0x0000fff8) == 0x0000fff8) - { - /* End of file */ - return -1; - } - else - { - active_files[file_handle].current_cluster_index = next_cluster; - active_files[file_handle].current_sector_in_cluster = 0; - data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster + - active_files[file_handle].current_sector_in_cluster; - } - } - else - { - return -2; - } - } - else - { - active_files[file_handle].current_sector_in_cluster = active_files[file_handle].current_sector_in_cluster + 1; - data_sector = data_sector + 1; - } - } - // Reading te first byte of the file. - if (current_sector_index != (data_sector + fat_partition_offset_in_512_byte_sectors)) - { - if (!Read_Sector_Data(data_sector, fat_partition_offset_in_512_byte_sectors)) - { - return -2; - } - } - - ch = (unsigned char) IORD_8DIRECT(buffer_memory, (active_files[file_handle].current_byte_position % 512)); - active_files[file_handle].current_byte_position = active_files[file_handle].current_byte_position + 1; - } - } - } - - return ch; -} - - -bool alt_up_sd_card_write(short int file_handle, char byte_of_data) -/* Write a single character to a given file. Return true if successful, and false otherwise. */ -{ - bool result = false; - - if ((file_handle >= 0) && (file_handle < MAX_FILES_OPENED)) - { - if (active_files[file_handle].in_use) - { - int data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster + - active_files[file_handle].current_sector_in_cluster; - short int buffer_offset = active_files[file_handle].current_byte_position % boot_sector_data.sector_size_in_bytes; - - if (active_files[file_handle].current_byte_position < active_files[file_handle].file_size_in_bytes) - { - if ((active_files[file_handle].current_byte_position > 0) && (buffer_offset == 0)) - { - // Read in a new sector of data. - if (active_files[file_handle].current_sector_in_cluster == boot_sector_data.sectors_per_cluster - 1) - { - // Go to the next cluster. - unsigned short int next_cluster; - if (get_cluster_flag(active_files[file_handle].current_cluster_index, &next_cluster)) - { - if (next_cluster < 0x0000fff8) - { - active_files[file_handle].current_cluster_index = next_cluster; - active_files[file_handle].current_sector_in_cluster = 0; - data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster + - active_files[file_handle].current_sector_in_cluster; - } - } - else - { - return false; - } - } - else - { - active_files[file_handle].current_sector_in_cluster = active_files[file_handle].current_sector_in_cluster + 1; - data_sector = data_sector + 1; - } - } - } - else - { - /* You are adding data to the end of the file, so increment its size and look for an additional data cluster if needed. */ - if ((active_files[file_handle].current_byte_position > 0) && (buffer_offset == 0)) - { - if (active_files[file_handle].current_sector_in_cluster == boot_sector_data.sectors_per_cluster - 1) - { - /* Find a new cluster if possible. */ - unsigned int cluster_number; - - if (find_first_empty_cluster(&cluster_number)) - { - // mark clusters in both File Allocation Tables. - mark_cluster(active_files[file_handle].current_cluster_index, ((unsigned short int) (cluster_number & 0x0000ffff)), true); - mark_cluster(cluster_number, 0xffff, true); - mark_cluster(active_files[file_handle].current_cluster_index, ((unsigned short int) (cluster_number & 0x0000ffff)), false); - mark_cluster(cluster_number, 0xffff, false); - // Change cluster index and sector index to compute a new data sector. - active_files[file_handle].current_cluster_index = cluster_number; - active_files[file_handle].current_sector_in_cluster = 0; - } - else - { - return false; - } - } - else - { - /* Read the next sector in the cluster and modify it. We only need to change the data_sector value. The actual read happens a few lines below. */ - active_files[file_handle].current_sector_in_cluster = active_files[file_handle].current_byte_position / boot_sector_data.sector_size_in_bytes; - } - data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster + - active_files[file_handle].current_sector_in_cluster; - } - } - // Reading a data sector into the buffer. Note that changes to the most recently modified sector will be saved before - // a new sector is read from the SD Card. - if (current_sector_index != data_sector + fat_partition_offset_in_512_byte_sectors) - { - if (!Read_Sector_Data(data_sector, fat_partition_offset_in_512_byte_sectors)) - { - return false; - } - } - // Write a byte of data to the buffer. - IOWR_8DIRECT(buffer_memory, buffer_offset, byte_of_data); - active_files[file_handle].current_byte_position = active_files[file_handle].current_byte_position + 1; - - // Modify the file record only when necessary. - if (active_files[file_handle].current_byte_position >= active_files[file_handle].file_size_in_bytes) - { - active_files[file_handle].file_size_in_bytes = active_files[file_handle].file_size_in_bytes + 1; - active_files[file_handle].modified = true; - } - // Invaldiate the buffer to ensure that the buffer contents are written to the SD card whe nthe file is closed. - current_sector_modified = true; - result = true; - } - } - - return result; -} - - -bool alt_up_sd_card_fclose(short int file_handle) -// This function closes an opened file and saves data to SD Card if necessary. -{ - bool result = false; - if ((alt_up_sd_card_is_Present()) && (is_sd_card_formated_as_FAT16)) - { - if (active_files[file_handle].in_use) - { - if (active_files[file_handle].modified) - { - unsigned int record_sector = active_files[file_handle].file_record_sector_in_cluster; - if (active_files[file_handle].file_record_cluster == 0) - { - record_sector = record_sector + boot_sector_data.root_directory_sector_offset; - } - else - { - record_sector = record_sector + boot_sector_data.data_sector_offset + - (active_files[file_handle].file_record_cluster - 2)*boot_sector_data.sectors_per_cluster; - } - if (Read_Sector_Data(record_sector, fat_partition_offset_in_512_byte_sectors)) - { - if (Write_File_Record_At_Offset(active_files[file_handle].file_record_offset, &(active_files[file_handle]))) - { - // Make sure that the Data has been saved to the SD Card. - result = Save_Modified_Sector(); - } - } - } - active_files[file_handle].in_use = false; - result = true; - } - } - - return result; -} - -#endif //SD_RAW_IFACE diff --git a/ip/altera_up_sd_card_avalon_interface_mod/doc/SD_Card_Interface_for_SoPC_Builder.pdf b/ip/altera_up_sd_card_avalon_interface_mod/doc/SD_Card_Interface_for_SoPC_Builder.pdf deleted file mode 100644 index 1aa463d7520cd891f5e05f1a4660ce3c27209e23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252601 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

n3WMVQ%3!DO&n_V#0obzHN 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

q>rVhn-I96AaWU=bfR0$9-|4k=qM^KTe4e zzi-Jezy6~Eq~p_VeQ}ApR9YH1uW&kitxAo~5v0f;t}s@ya0e{gBLMZ|{PnKbi*Kyq zm$#Z_&`*G;v-)!<#T>_JBq|7{4~0~*ONzD=L+H8 zJsT1}`pMHBJX%m<*dSorfEhkWj$M!QTo#j_94o_QEs=xf*jjq#$+Hsu5R~_D5301} zAV<p*d#@y zL<=%epzT>VTNMtxW{4Fm?8iTh(!n~%@G@DEwcHCzZS0aOORXF35eXxiO(^M6Pj*Lp zsbYwGk=`BvK=%o(*xG}F_6d(Hni>_@*)&Elt_zI%%0LBNLz?=nNN365VhYcaB)Law zZ&bSUIykqXnK3$v=n0Ovn(fQL*s5@bv-Pg(t#pNv8%h_UQlPb(!82J2S?yBBVP z&D0k6+AOVb5(TCqf@NN3qM`XiOB$DK)%~!n>v^o=sbyRDNDL}4QmtsP{}Bt%srB-x zWpZ0%gkkw~w|Q=-%B!2BMyKB;)O|2ZGz~B_W;-DGZjY9FjEeT>EAtdfAo}Rdv9s%B(?n* zE6&}G?%M4~*(>JzvPr?3Tz3YM@))H*59NC(l!;!$R3HfNIw|Q8`WaEjt>TI7VE83R z=li_`_i?cWe3I5oA%Y=sHZ6dlP%ev1{0>{;W^iDu>_lq*tZaP^I~## zo91x6{|o44Ye^8Ci~q$@Z{F7W91Ah>vP(k5IjneD=}G13FFywy7d7Bf#MLj^<{dfq zO#xPp0!8_4fxuw>mGBXNuuhF95z;agdS9dmoCn2?9qi~70^-5!CakQ&dpJo+?qIkM z{j{q=PHr}q(NVk82V%(Hnwq@Fu3>iC!9o{vmwk)`#$->(ip&6tGJ{$^S=Yq7Q7e}$ zWbZVUjYq*ulo=xE2k=oVI#9n@NoFQ5JnPagwpKHPLSWSS=}WXtgFg z8J#s3zAKB>l9Jvv*DB>NJ^0$%HBJ0}Sa zJ^1PH?p36w;POp*g)rs=VFgDXnrXz1z2B$~xN1)J4#dtDT#i2a%0lH`IzB#s+`5?F zpr}%w3I#M2=stSU(A_8?fo7id%qVL}85PAIej@~iNu5T<5895xpPY73*}ei-1>C*) z7v^ofhJ{DuM{T2&DQb7ytuEEA^)9^|4BfozZY}Q^y7Neb{d7RePDL%nmd-T+epZ>B z*fA*g;AhXdx;Efjx5pV8foZqD!40+1i;SlbcK9M!0>0gB*l`c%)6J{VLcLG9(6NbW zM7;0ZN408I`OF?&%U!6wejPv6&zoo@tU?SU22;#c94BtFM3tTmbtL)GAfkf=EM$Mw ztNe@t0XdJ8b5!4w)uy&@Zn{Zo)FK@`QQ~`ei~mRv=w|A;gvS{eb1C){Soh+@>^r8<6e7 z1`s`&IW;hKYI3q+pF=i(OQM5Qw>teP5&GJqj#LGty$X1|ereDjbv(`Ws51lU^3;vz z0uu1D4MPwyY*B+h5bGqkNeL)P-pvQS3Mp|E7BrukJr;B)qRY4I1$4bQ!Suq+2w~X6 zySF=3XB5woEA+in=f4vlS|8#O7+6^-6qM)?eJ=-~Vp=>RJ{Vol(|VirPPnc0Anh(r z{BS@oAQ5Cj=X;m=4ubD}D0va?gd8A2E_LRJ%8;4gs3O@#tm;9zPPvYs@6yevS^j$T zu;Mkrq1)F|VRc*79>Ix5w(Tz7{k~)TUE~@ohv7dP`f27#;~qe)g+h%$zgb!8>PwEL z?R)B%r4Z9D#ze-#+UksnrQ;_yj9f#$(S@y#a+6JAwqr;{6+s)T!>whP0M<)b*ksSZIKaunDa1L_ z=>f_*1Qu>}tIP+|B4Rjd1Mo{-cpU4EBnPMk4tPimA6s~^5&L~ym+k{CH`$Jui}^h! zsO6SNYgGd5d@Y@gRwzx50!dLe`DBdi>I|)yinu2YY%LpqN7ad3Yd7)8(U5~(U97k&|If7j+^T$m z9Nc;-r*223>3W*c^=`{}L8M1j($+Brcgh>Gahv`<+dFowzA<}7{trvksCvTWu4Y`r zI5RM7EM4EUlDjC{gihp&MVed`A~tJ9 z)(bU8R+QR}6dy+-5w(B^W85M4QgS5TC<%jo2MAPHz!=FH%TFSTw@pArIzoOjiCi&q zEeU+#P$lBEb18c2nL&+PC#xRWTs0%b6liV9y9p-X!x;}jkZx7l-E2A z$Ek&oK^;FH|XtA)#_lI^f@Mwp;_i z$W@DSl5*kgt5lN8^ z{t0vLOyd+09Xr5#c{;c#Qm*q2klu+@%L~+QDQZ90iIe zS@1bgh)J+Rb3(AURk^=a(71W|PKgF-7{Pses+pqEUTLO~vKFRd_K%pT7GZ&f5GOXl9Af!~kSw7G z8-kCNOVrpVALM4cRgsw2C$0{R*fJ+Dt))SXw4pk0pnsRb-&*cD=S+t;G9KZ~R)!)a zX)NnP`}XVXdev6t0IjQkp(Ql2vx&@ z>TT;XW}PR3t7Hi?d-z4i1ZGKoW;oy0Q-6nr-W%=bW@F{8>rPK%da^$sM4Eg?f;9b& zhZ7bqI7m9FNj3H2`mIN;7Cr34MSfgNxgr27lx?tsyHI{nx)+YFG6M%cc&1xls8o_g z9$o`B`6d5VY`{-%i8ju8B*f@VNIzTK4jjS762VC5Ir{N#Ka(bVn4*n}tJXwyB&tqK z$Q3oq5Id8`rbtu?P4pXD%FqrP$1YHAf-T2K#rQgVAbU(F@lohbGt2c<6iT@?Q(@B% zcHkND(9$jwzF2J}hrzv*2wz3{k7(fceOc;=L!powZpz=315idKe7tI$(TRyW86gX9|{$K4-~K#ir7Y#T~E<&sHwlr z{~T@0m$Qb*JmRm}#f2;kUShb?0*3_3Lt?Ub1_SJ5%4O7-e(9m;G)29I-8tjpG%dgq zF|-Xn)l@3wWGUwjjOQJI5RvOSUR@hMm!bykr#&1y(pSwUS8BlYTaV=6k3F;)S#!PX zWECD8213=_HJ?H+oxYbtR|q3An@$Ca^ca*6zA%^NNln7KK1<5fQwIvqsda>V#FUJ~ zX%3Sw&{326YLRtERl;*;p``XtT0=EiH9nj= zz(VRNE0mmsNAYub4KtIY_Kh^P8otxg_tN~V4jT{L_rfq?wsMwr(HYZr)~@nrQ+NGZ!R`ZKUv|NSy&qu3J<=TEDK+EGpnL(4tNuX#q0` z?X|;GQl9zK_a}Z4B@IsWjEgQ7`5v)W3a^o@VZsx@&2nz!{m}JItoW{SyFYtb#PbrR z#Gy69c+lj9z6DmB3n@#H_;GqT`V8Vp%DRfE5jb7`aDRVjDSywnBP8EvODX0QI_; zwyFA&6&BU+QPVVB&i{52avHr>1ohfP*ffA9X}+5nd&tCx{aF`-EEK1P>O0uW{5(8T zUh#U|jBeHXK-U0j>gliM?6(#BCW^@iMs4NYE*`#{m!WpH)=@8I@CYq$`C~W)v4ITM z`s?|EU@N^%X+!KzNZr7qZyGxbP0rD(acE|&08yyWD zAfeLF4sNKv69RLaWkY;`KCrD0Wm{`yeEEZ#5wz0h^uO#x$|QZbSnJ%@7%(XE+Am7U zLFY`f@miWDqO*mrG4zr!N6x*#*J1dmmlUqDKmVNbXf5oAk=j8Qz&0|QYq<;k9b}2d%C`i#;67wDGVoebjA_B*f&Cqy zM`^9wH+>plr5VpG6oe_pjY8uQwE~L-AC|-1ybI7C#rwuNYe%bLUDKDK!x{7z6mr^u zMSwS_eiemdh37IEe_!E(H#K1}V!voV0%u!GJF|qdIgF@TKOI9dJ82jD9uV*!vIo`+ z+_u>c0~-%B2+(&@A{moyMr!#($8qmS-RlK{o25tZ3#%KVht8M|fjC+$DQ$05qFZK; zMC^sSD$E1{?p{v=_0x0FE@eu*S@LI?{CP`&wxip&CG#)1=fm|y5MtMT91ngzeXHaF z?|$*gIxPeGi~OU9XQg3pFFy-a1tP%XKEB;e(--9B_dM>amq=lXT_C;scsicHbm_|G zMR=wxhTLSg3m2Gcu{c_dM{!0Rl3sbfq7@bNG5lCbt5?;ee?JRnJV2>nst08$W(eh? zieIr@j}<$Kg?G7G?X`>N1qaARN;`Guk49b`G)iDI;KO|)AF+ICGiCcemPtxvI2KJ= zPElZ{Yc4(qMMj?8$KjOe=Stk()RO!tDM+d4yzw3V=~3fv?LE+bJsFgqrJ)?ri>iOs3pTitItZ zDP=9>(-~ny)Q!a=^CE6>1%gKxyYEu3m}BJbEptb&@R`?Ux2EVjBS5Tok&;*5mx#CN zaso?Zu4GH3Vm`DtL}H!OUJ;*OMiep3xbRYjE@5m)+siOnfeFjf53((~$T1cc&%yit z-8`{PHjoue;TU#WQ!DTb_`qPID(43iXJ+yu-&b^$b`L&@kHY$mTw_$D3sp#`9*J5=XHrb1AUMDiU)WxewmGW*)H%mu@{S_96UsNeKZ zWRp<3`iP>QYk%m|*ZMMk#!g-%8nMw)37Y)$*Uo!>YPH)zmCI`UiJV2>?_9l5_{b1B z8&4b~O7&FtP8XiblURVF9?Gh4M_a>A2A@XrTH}0z2LsV2ppUdccA~}O9CUN>P z5Yu7Rkd#`RNZ6;62QpVBR7@DI+e6Uv9RCh}ktxcm*^34Z3`k*Y>dXrF4ae4OIfUOm?NNZ=Bz~W9!X=t1t?FOu?`3rF_ z;X)nwQV_)yJ`M(0nt@cY%v7jkiak1kN1h%GA!S;)kOKTdeq0D)wQ`aG_*mHd0Lft;2k_AJD+J45W|3L&D$!xZo9BP#5J$9)ze z25_kp_lP5J|2vY2RXM;&fIqxobH+eM$kp80L127CdtHR^sS~GCdHXKe^DOPo} zq2JDUcC~!FES(Ii^DM=gPbA?nc)NkHN@Vpp8L)`miFH@Im^7)(r1d!tQ9EcwJp-7L zjoyLSt$~n3TTL~Qb}@sfEUtqK*}mmXo3OUQsTnCY_(i2T4CiT}%I)Vm{HFB0hHSQH zeh-fp>PVKDvpav+6~Kt|!kIg%GKvwNQ+xtZold0EXk?MW3;)+r+I6MYUcE}3(SOsQCeWRn7X2LZnC&YlkhDRMkveTUHAl2dv?NsMT|)F8&E zP)W|ojnZwS=TAfw6UD?~)~ygek%)k#RhTjA@3YwlEP|Tj!^FWLDH>6v4lPJa_Tyc4 zB<@{*SS_~&M$ICNG?m#kT{o5k{I`PvEHESw;JCBokelsi)I(Dq{WSB$l*V z)m3Vne^Qa6M9R|1QQXVymc|gf@#%E)$V*06vSB?&(Q!vRH;{Xe@Xa7B72%;9e6*t5 z^7_oSYg~EG^`vmkj`vokQ6hpiLs2C4M|6)@ol&uQ@6_7C{nVZ$5~IM#=kT_~hYG|M zjiuFrR33{;;1~&qc>gpjYWM(?MHcW=)>=&r2teo13C8^{_d7#kfD2Gr08cz>GZ3; zug5dDWU);X!dt&cVdr)LMgC`t{kMG+d-Q4uf-Eyt4=|!1rav;n4j|+3qZV>e^4oIC z@QBjWAs0xSd*HhJXq^zSxkSys^&(Adw zV{zKy$oL@n7|nj8HuNDc-GMV$M)y+#<)>f3fs8T0T^P1fmNy*X*qv`BnNctjdlw& z7eyy|*aA_I_TE^ZCL~d)VW8NDpt2hmv1CR!+s3_}jnf>0Y5<(kVs?|CZ8c&MEoIdF zhZvmliP%}wmuAi@*veir0Hd|e%1Udoor0$Wu%;A$VGt$~G4^?fO}6JN+W$#PBs=c! z#DSi0leWQ>@414=y~e7R2ZM)XU66Paf@w>L%6>*VA`#>B*kZW-waPa9HJC`AcO~Dv zygkKL_#pK90(x=11xB@@0f@|66`628dMAI^vargq=!>CTdAILNApg^r_PBK;jwgRB zFCpj!0~*?po7)$Xc6%&p-*@%U`J&FTnsS}s4l=^Z?;$ce19pklkSrWSsOn32o({U< zVQ@eXsTQ!d#*VDjt0#v^Rx$0KPWsz;R*5{~b5^s&FAR;m(+E?uW4ADXs937jh{HQCM7OAhmxOh(ujbQ8&ho>?FFW5coJ3E2`)g`esA8!Oig5r~_8nb4nsY&5>EitI zPY`qh28hS>n;?;2LHRm(C{K5vU|C8^>7lyKsE=P7%5WBLe5@M!a}ieFd>eY~;~YM) zuCm-~4+y?JQ=$;w?7h2$j1cS%I>rgY35zxn6!pt(P9mQlZz-xkob<2n)G=Yl3`v}k zfQT>WCqvXIv&h`3XY2F3Q(HYGBTY|USjD|ri(pNhlcq2vl`Rl-r37oCg|nsM`E>}L zoptLHw}4))tMK3I-h~ykCBa{Qi(?dkzaYG1zyjk$riwZf&|6DwzYY%u=ep8bV(0u| ztR!WjrnI$M*C4-!4kB<#Di)PK+++=soR}IJyl56tHBBRpSY>9tdM;Dl8fepAc}t4W#lTMRLets8t-V=ah0$R4Y-vRL0WgkL)?d@rMe0oP(#f?+Z8y z3MONSoiJ}`2c$A!UC#1UFcIv7RN<;M(tuKm@Q-|2{kgiF>O_2$9bLINWuuHcXwM0# z4K#8~EyhJgVuMF7F$ZU_L;_X(Q{j{KN+6oJ{cAhz3x0dvf&3huTAH-Ni4++Exobb%W(~&Q%_KfQ&~ucn80$HW`v5N!IMCH4vVVC?mc_5pWnQ9Hbn< z-tpCZ`FRE9{1#kx8^OzGcgcM8yAFfjt1nsBq}Qe=5?4$jE~cm6XC4*#-m8OI7n-gyiLjRysH{Oo_GDM~E8gQEn|HlP-p z0{Qwf|FeU}4s*Ie^Df`igWq~1Zzg?&aHGlIU(54jPuW?I2hNv>LkO~PdP<=yq8>R; zEEEzi^?YpuuGaGGysY~JKESjW`ah8+fB6Rjdm}3X9v&$A{})*zDkGzzCGuZniITmo zoIR%ut*ohu<^KgPVdMC#ZDL{k2VBBHz{$q&Pq>7Q^Dlt$&syq#T>cX-Vfbq?`XAvE z#(!`d|4o;$urdBST_XIKE)o3?Ym+R!+<#b`l>U}eRp{0K%i3gYZ)0!wKe?Mc9V|@k z{^BS9Zf^P)Ws{AevjzRXOPf6Dz39D6o$UY3+Qjh>_~hSl6qbLvzyHKhSpIiumFe%@ zVf{x0_CKHeHynkLne+b}M{)lfUcF4SP1pH>3r1)`#)D0Xm%McdL9a&Qmd z14P==1s=#9<9yxj<-PI#D(muBiT$d1tLZSQ?HOHXL9xoBK~h72&Zim1n;aaNq=QfZ z+|X?2uok#dApnx1nG~Q-09wX@@fh(?u&^l3`K!N17}ooZ1BC)|22=yEC?E|$P97jE zAOH{wMgZz~=K!>^E(G}W8>jAHho+xEIsj=L$>J8q1VBSL z2Vl=12Otf>n|fZqgtMvFNs<)bx#sPq9BQPgdKM#<=JRml? zgZHTgTmb^W#2(VE;hj2Ay^HneHUuY!ppN}YuR)!OHG+A0V-fNQ0JK|7H974|{Fj2Z z^O=4_u3+8Y_Uf0{5|q*TgSw=@aUDw?#WIe`EldE=c7gv$BLGmfz$~1BbNt$Roe7*= ze&3RVBiP2~CpEBH0P_6k)&vxci<@7G=kb35DS4Ib?hXLnpVzQ&AFKXH06|>91FO{( zI5~BUv;}nywgN8{HvTiwK|QP>{R7|dU8&JS{EX`POS`azKh|a#ddUoJLF>W10BQo( zC~T+@Ppl*X-+g6Fmp{M8f1r_m>L5P*h;Dymw*1%5_D@=9!4N#rC)&T#E z{Q~T!!*cfSzpMqM0Q}ZsqjL-Bdx0H)__=3k0}kZa>;e8CUr zuP7-cv<0X~lT%kw@8IYJ3Wb|9|gvzBjein)_cZlkjBiEZfWkt*cYy^ie@nT{;ArgCdSfQL#59M z0j`D7;}93Gp*{KItlM~D-|K)I>r5r==*{omZ&)?gfqlg5^sj8|&hPzyASwLz-mQ_D zjmC+VA=CH1$#9fN1$bt1>8@#W_P4rkId-)qpNeAef$q{bJ^jN>_j;_19X37KD7*B} zsJQmWUV}w3=!M1FH-A5sV`FZ`Cux22OU-ir>JOGo%Pz~|K>M=J5-&#y$9Fw@U%6w~LR(fWmX!2Gy2~^6<`kl~y+%~4vNEuu!UZRVYKb(V!iduR8XNz9 z?e->@f{Pp%H>CIMP8YmC#S0iS>$_7 zEc1F6iY7Mw=TWY07sx~MM~CLrkCubAPVXozwLW2nRO6s?|5;usJ& z6~lk!tn_+FQ$Q6;8ES6sL4Jil>1lvO9>46KE%|W+##v)a=%ZpYJS5jV!XwtId)Kb8{|fMx!Iu{cBaI{F^L-7?%jK)rbu_ofKP#k1da`pyTu;g$MH_R zvI)Xd@7<9{`oITI^(?VpD?AqbNTUloHYI}{s=l7uC)CZ(CM0{8I?QX2%?aX&s%hQi z|Es3@(kXAY-K&%?E0!p#VZxfy`*Dfu(~gdu9kh$902&|>YE$|*3jo!M;1QNK=>?6kC|4Cf1)Id zlb>Lh=aX)|);X~e;8g3GNhB{WCw^60yEHa-seaOI z?06lq(O)1@lUTZ$Y-c0n{i^XpSo=VH1;{N^Vf_d#u*QCDh2Smu)sjU{YIxXsl zC?#su@G^Bl{$bx3kx6!gIQtofV3RFYb75s>0^JMQZ(j-dNqEbG=~)l@Wlz#Wh>g|L zxX^aD9^IL`ayqt4mueFL3uLkk{S)^c^4R{r$4w0_iLtMS2UcplDZp#o4;#!M1hy3C zGMH~c82y{A1y=|0j~xU{1}U~ulojnfs>Rx`OZt1Mdv7Wy`F(dYk3xG1<(ad9i`3h> zI^+{JBjl4U(&F-97g4U>HE4>sdSMfCls#pr8HwJVAy<7*`5Im;f_eXp>S40$O4gK4 zW(i0YeLT%N{t&4`#DUz5{k{b$W+7B>=UZ*kfLPopdxwY4I=Bkue-34JrAUdP*$AP0 z#0tU8+nFP=%>zzKP7s9Oh6(!xx4ed7}(D~RF{7k1y=T+YP;&GLCbxzygf@82j^DX6vLNQo6rsN z+JSaj5wt}&FsBFgTjeopvm=p1}0-46}GR!QucAqT~c4=S<7Ao40GO6)7UUPLiKq3*w} zP;Htt#lra35*-Q7`t(SR~ZT*mgF^=)8 zFfF?gmL&*Lvv?a{O^*?6KBapa_p`JxiDgCer5zJJfM&f1gnVwxcB7aMbyQ@((jp?j zn~nLFKPmL;8pb^9$}dJLU_8GTz>Jd(^2!JqgcHMsBNB*eGqp}l&f__?SES6_ zo5$nY4H%uHdaEcKZiZF+1)9eC@4qIm5^vl4jr4Lnura>~*--{XT%@GNpq$eJPxnRw zVH91Yr$P5$YqyxEje6dn?+~h}cG0)bCOq}DtXPKx*dN)DG#lG>baGa2I*(C}BTD5H zbx-P^cUN8~%V&_w+n;b3CzV&qqSx3=LH=aqdtT;XGnaneSw>by!9<-P;pXuKk*3NU zW)Qwsfkd@!$6&nozM#DRX0u6Y9W`pr8FB1V-c}jX{tSnw96UB+(yjsb9>^h(a}i0x z|Lg;HINigRQ)f7OsPU2z8*Lpnl|4vhe<>2J)63qIiLCI*rGj1>0#+By3>K;My2;vO zmhUshEe>wPzV9jJ25RZCJ_S|<boLXdKUfIbi{ffY5XOpR6rzW=%{k}lnv)vsFA zw$eVVH)-Q0$=}T`MHH6QzvEp%d|g~_N%AJ~2dk@RRlsZ>rxuxRe3u}sz4r9$&xZP@ zsXJ^)o>z`rb&*c{L{>@fcDQPeay@mNb;4y$m1di3ZkPe4Z=J1unX&FjQy>h*U;Dej zG}c`Cw3&s4fM0$VKYDlHf>GUxxEA>~*!Wp9%d#wr$(HyLa2RZQHhO+qP}nxci$MF>}t1GcogLMby6)6;YL$Ydx9oYXkNx3VVql ze=Pl~Ga&>VkInWsQ@W%!4pFzy3L*W_4q*LX5oxYUFwG1il**uDD6X09gZhvoz2%s6 z^XNp3CrWVxr#qQLW}&Gt}qx2C8Q+7mD6}uei2n7UGM4$h7E3QOcUD zJ=<>mRm}V6OsCijt9FQc7WFclNcF`|S#D!pqd<&$W;}B%6WHAI{Jepmo9AaQH*n3z zj`(X;Mk*&U9_KJiE>%QE6KjnAe3YmW447J|Me{JV8ba!Z9?;aV>nIT<`R}c-^15Y~ z>>1Tj2>9~NxN{q*s;%48k?InOysIGgjcl?Xi_PgxJ7xTC>LO*^k(ETv zC@3iQuPfo>3xkIr6JJirb8h(M8B(Gju#<&Ti=+-_Rp5g8_`VR$)k7ch!!#8M9G-9H1%;QRy{Zr*nuEN=(Fk>S|45NVM~m7mqlqy zK1LUONRLPo5;CDMvB5}D(=`JaiuwxUuX2zqGzy4jCT`YB;wtNyZ$9oFYEzPM~x0~AsTjA?T@w!&n z-wJwBJ2aJFlEcy3R7Ed{rLSPW?x`yQC|YceitOJ+s5qG~eL{s97TQh9o|Fxw zXXR};v<{eALO*2Fsh0iVBc9Ku>!`i9fEdVFw!eb2^x&Oh>T~cePyfyZTCUFm@dS2% zrG`ZJ%Wc&SRXRq(;+nQF=x3ZE%Q-9qIy4&^BfTbRIJi23DGE`mp?&~B*Uv5+ob4oA z=tK_+#S;>TO8YTCu^CHJR?#4-nKU`Qw$o_5iliHnEMPyh1J8>V(Yw|OSm9USxU~2a zU-LHsElJC;j73=p#=QGM_HU8;fV8%{uOJu_$+YqC$8K_cLlF`<)io8RE8lzZBZb%_ z2@BhE@fnhnQP_kLWXnEs&WSX~%oPFa$6CveV6dFNkoP?EJ=GJhjWbefsiSsy#agD%ChA8DZRo}km{55L$XG^vh<+?s63o|87 zlGA2IbKkr|#P2fmn#PI+V55gRlAO9IJyHN=vs;bpP`)INvV}r{7X7f^An&G=dV_ex zwGhzrm(f(7)B9p$Xfz9Jv_p_i-+=V~SQ>*x|pGPcZa| zK~CNceNYRMu1d7NWomDEiLE=|Buk?p^mQODgk2E_5m&rm-sPl`e?9}3=2rhwrBWY= zEUgAATe%WV^e|ZL<~PeSo4xBq6=@Edhr7Up#X>BuKG|s5mCG8UUKacn$9RuxLKU=&uGh+l$aRNJ zrbm9k)L(hZ$}(DmKdmh`Q5*`fGkTp9HGSc#Z_c8pdgPV?29I!RS&+U>c`!R;vpj9H zjI?+$Cb}uR*gQtpFdU@QOku4jWb6kb3fUvA2W0WeX$Gw{HmAI*Q03rq4hm!%bK^y- zdZTCZ91<2rz)ttFSo6F^J=!FzCxOgJp^k<+SvK220Lvl$&7Z}fuoylYR}WFZjgulP z9YOBwH)SA8_WSjk)h-Al@PtC_-r^EHg*TQN5&tIZfOSy;LFMb}fa)rFlKNt8I9}&YlqBYm+F{_g$c%z9d)sQ8};3UyZ_Mf#O-=-`!k8KIR}? zZPj+dD<0|UC?|4#Z?4`pawWgS$tTAK>%_diJ~Qc5$K4iILQnuEc4U~e@j4$p^Fxo9 z!vbs8Kuzua>p}n;m!xY5K|pW7WmR$_+^&_|@aG(q`_kj6=43!@te<1tLC^{LHyTY! zDz=M_t(-937)`f=X&REYEYXq+`_KKIQ8jEmLTCrAk}GC zUO7cvA%j$y6)MDIMPC3oUB~Fb$pjy^shDKZPyH?Iy9? zxu<(_Uqz@Nl>JjT2IlU@DM!5yVvX4Jtz=%W5RTN!)6IAv{Qgb>6G5^T~6B(49ie(U4AJBG-+@2owIZ~<>Z7L@H1`k&6F2s-Jl(w zO&?1L(M-!-B$1^|v0N>md)0#;5(FFOXvWKQeoraRL~1DtdoD}2VXuUaT4_DaRyOw5 zq->)kkcN%ED-N-*Loq(QE!-Q>$a97s)4uG?T|=N(>w-}>?OfKYi}@ephWIJVBxQ0V z&Yg6|E}W(&o*=&tYT87P%xQych%Hj>Ve*mtq&VBv1f#lQyzhtYyf%KJ z^=6A0ZB3WzEmdKa>SLl$AyJf=q4_ZR9IK!H>DcJ>rt6mT^5-^+exr-z5UPu5Mbl$XQ>XF{QO)}3kyR`%~;5=fMJWsJhBYV}9uMi$OUDtJu-VGBWNvsx+PN4nuBuP?By^;&i zND1=&iSGbn?VcAq=DK6tZb`q%A6eK0XG4;7%(hDHPF)s~?B&$JbOX$7 z3&PmFZD~SWAJF`lhm->HyQzFSwsSl@@IPTS0GyM#K$^)>3MRW`>MFX=Nm8J&8MaJ@ zj<6G!>S;K=JkHq_vyqQzrUzW&Ld}uU9tv98GXZk{7rD+-f(upOtT1c?VtwZaKg{OlPfUHkgz1MYxg^6&0DUCL8BAwv)O}6TT3OpZ zWUNVu{54^OUC~$}w!J`Fw;$?G+XEp(f!RUy2x3q%3uZ+5^-yCfORBSxI_@9Mcn^ ztDlbY$NtwEf5coh+XTqkHE>!|hpx0OkeNe93&P@k1UDht+;fdAYD&7)9aGH22)= zf=$}byASR1f(1bKm|n{?S+Rc+=|twT7%8TmfZSk3zivjhDrCjKfPJ*nKvG(NDTu`{ zK9_sf)9#snJ^l9-m(Mnn$J$fS`L+kcG$O@>L`(fX-U4ns*ocfm_(n~h%8V%)1JZAnpp|{Zf^y?!gBOXxLME_Wwe?yO=0=9^4YHMt zwmi+;ueG*R2JfcKMCTyYf*S*NvPlCr=Z>>mQl;JGGVWbZw1Qt89L}RbVAJ*H(mTTr zZ$RKJ0J){{M{oe&!Y0YPOnWR&@ulxu^)v!~*#xBS3aw4-emxTqp(m+QX`WBY4vG&cd zteinmhX`rmjYnr}{Hq1D89qN#&|2(ym&_B`D>hVF-v^jK-3>Fh`iz{wmzd5x!lRmV zZ>}Y&Cmd1CJmewwR;h2>Mp^Mu?K*pVg_b1LLz(QwcT4_G|7Xv;X#**m8|Wz2&4MwY zbGMG7L{G!3vr-K?dl^1ND-2;*2Ud!u&>Tf4(CyZ0wkUQ2S5#GfnQhC`5nJ&UJf399 zplko5N&bgYCd{YZvkKM?hN%ct{XoiFV}~p_2wK$v&wn}E{2gYI;|e}fMF(k zBT`|*I|mV3TXsiHe4@`#5p}S__0PK4W2F{rgf3OX2SdEL=K)y&u1Q>U6KyS3W)LGh zbP2iO{pRVvd`SP$tN3;g_QnKPgv?uX&@0*Kd7UM|ZD@k(uuZ&}U9ja8_m^HHU^$HFCuDfeN&Tyu2D$QiR4sDAr9-B6wS+zi}ETI z)D7b?DaoXL!!-}|xg`)1v25c0#Vs}WT_+0czE3axr?{MFRCISlk*XHSvxbFtzsN?s z)7Ya%3Y!vEhh~Z(9P3Gr5#9WB>NyvVX6T_EU*; znU&8OkZF+nyLw8#opxytO&`NsY{x7M8f#A}G`T%O^$-(!s@Xq&z-1Nta93Mc7VwLU zrIB~5?)G8}TlO+tF)^011*!3ya&*wXN+{>A%j6O5S9jH*=GqyCn>7v2VA}?I&sm|& zihl~;K~K)1$>!IwVG$57ChwrV7rlQ8pUgwesqYVlj6!s1zJ>2shx_O^Jv(!7+JPo% zA3HSHL6k4uZ+qsC5@U1!)KfkM0?tr5Qy9LY75{bJVMb0|-+2Fwx)<+#eQ&s6dRY=_ z#w?XM03lX?Y*FklipDXOiV0l9t{;u2r#Y+k(!01AJ`6~pqaSu)Z&m?fXeSUGPJjO3mPw&j-Q$tL|!&qpPM-6xG; z-7H-^$0hcf+mrK9GOsdej0u7%kO4a=DMfpu1l8Z9WelCsfY4_g9thwBaD~}Z@kXTM=qoxwZ&L0g)1}`Cpur9 zq%CNjc{Ya$p;}n4kFP^Y!CdZlwAwe!{KnmuW~NsuVT{=z$wLapCjk>zkO}HHYz)r6 z3a^+Huq=GV9Hvn(QCdA_fzOLisE)bsJMG@UyE{KK;WPuEe$@^X@8`wkBiJMosqTQA zf>ug3SeFrA{%hrI@)jaEH*gFv|3-nOQTlmOAj+&MdYn*_xTcJj*{l8KC3}20wc0cn zH)lgNw&HLplWURyg92`|kiJTL1fCIE$Ry%Umj!pJGcaIlXfHcC1?LVmka++G`lkPIttt(yA}|Wl@~shjL4i46$FdOsXG0j<}CMw5LT| zL~uHXpVs7^UMAkR_xA}KrMgGcM}4rBg}UN|9%zy09PI3{fXKq+Oz|W=6RP{y#ta2W zznIDIaC6|T1EcXBgQ0*CfY-qkuEh7EHU2|yQi3h1_u4W9;ej2m_AfKL zKHlpeKU@InMIXj(;TpOvi)@0H3UlaLPTXEme!kem@>|?}&5-8oH>49o=!7*bOGKA? zXzXUSs%su>tcc36W1JfDf^~hCsk@y98P-eKKeayp-feeo;n%{7f26S2FSaSD_(u3F z1T>IkFNa1~=0yG_pZGxq?M2U_d-hrXcvB+pTV8Z{o3-`Q7%5;tq3T}{w0U1COmrRU zh7HOUN$mj56MP$C6hYc&-uvDn-n4&3DT@T*T`-V;Yqu`2!tMQU1S{S%K6fk%&7}ybY^%E7 zKr3149YHZiHm_-@b zuFtTfc=Km_N&gHD(#qV56%2&J9jZG@24wHPx+}&+!mXtGIWUpCe_6$H(n>ll)d#cF zYF_E{0_RTexn3uqU>$!1Rc>YJG;%cVY<*gz1*}Y)XxiU*SW~idlsj_ZcZz7WT2LBU z4@V-N=K$DS8W(F*=Ty8=)srU00g)NK+`_T8ZstRe&I?!bmN1VG+aT(Apn?WYZ*@K^ zIChti60bH=z<3rZYI#0CCZ9lVv#D_@IwKcQ6xVGkIgmXJ%xGoF@3?=K4alu_lkS?x zI~?SjKKwl<%T^t?&thiz5^MXx+$NV{dGx#>JG z@4Qm74iD+6#nll5z!)7Z-XM1Ogey*l`@GM8U7>%_*~eGJ^~HrG;99>wCsf_pPy243 zVz{NtT#3<+TH&{_KK7NBAMAh@FDuwIoqlu^R@pnV#)JQ!XC#HHcq=TO&Np0EkP-dV zhD`GqPgu@2+Jr?)RBk8ZOX3%_QbHP)KhtonB&Ywz7vD)(AE>wR| zmeSOdM-!dPY$~=HM{WMe`9aJF%mdL1Qrn~xy)f+k!vBw}rLWAo{`jl=ZYqux;-z~< zH*f#JIFzl=R_|1m+|Y#M#}{~N+t%&9R5)XVjmgh3AT^y?Bi$k=TUpTF_DO0CM2Z5S zmYziiLoJy^uN6p}ld)AVlWZ(ccLx{A5Nnb;<^U08_KozBiZg;tn?z;(5P|@Cw~Fxc zH0CvzYK8gU)dHpOc7x93j`iPifmD(L>_W@#skN-`0dU~8Vs4LB!;YvSQg=5>8}&>R zTRwC>&H|Ic#h(*(!cCdH3HtkSBFoh1Ne5Q-FLR`AjHuCqijk~`pqMWk3Ru+h zoAfIZt$JOn*ePU+V|(Qzm$xyiM$gVR6vvdg5s8ntKcV29!Gl&d%12v2XZG=4xhATr%BQ`-Jd;=`S+qUu*2M zGS#DQ&s}@m>wJ(%|uAyDy%3g?Rk4P9(rfd@x@n{#Y!Vh-G*INZ%tknJL z*>-n$+}b@c0zPBNX0`4Qx^qXk3#|+Z?IoS8wdJ!#nSWx|%W_n&-w!PMv~lMD?W+nP zcmcOC$RzFa0uxBOjDQF3{pd*%6bw7fP*CWuDZB6now1q0#qpiz#vOhy%DKJC9>p#H zwsy_&4E#>;n4vcV&s-+Edpmb|OYbV}M@#a)Ta<>)z5HVCV61P~o1&6Amse-LQI~>A zV*knW2|}kJUwdoJ1kR#3G>*Frru|HluP#myb(;a{)wl%8s@-?1Cw+DOMN&ObQF{|_ ze(yHmFHz@ZsbgZKWK(vwV4Ph|CCfmxaY@W46o+Y|Cbcbjp+iE+y2exOlH=Y-;}&t2t-L*hw68=4sv1UIpoTk$k{8yR8Z$}~?+CjMr&ZClnmwl75{f9Cx!C6Q&Ihzc z;kA97PcyGR5I^8x0OS!oiJiY5OAN6r4qBh+cjQvrt!&f|fn0JgGj7&{<3XoO1j0J? z9$~|fXix#M4)i&6W*@Ij@v6Zp+&|TVNzB-CV)_!zM3JHj$`B*+=$Z=cN9odHmYiiw z4k;RI){<5nMVfBztO~TmZ&2^9Mw;DCdK!K61n=vGIDiwkijuTKd}KoSHE& zVa>Y}x#;7m;KU6UNbyjq_oH8c!J%%C|B02e{ulQA|HaA`MHK{9RR0H7{vQMWKhtui zf1sR}nTdsflauYAENA&IvYdnCzsd6dT>ihya$3fJxdLS;V{0`6MyCH}%l{KUFw=KX zHg+PQpckb7-?m)x|Ed@K?-sDi|Iq@bH?ehg_*XM9`=2$row0+ttr7iyQ2GA>$^W|` z|Bn~{?}D7|zue0IN02lB-vxtzf}Deu?O$o(e-PxHER6qu1$kAgp;NI=D_K^NfvVNj zT8nii>SoKe%CO0Bi}hxUwXge5t9&lr>E+L&x6c*h4XeGZw&Qd?8>D|1QnX)uwSRqC zbu=<8FfA{+z{=J}-@4-biq=YsaE93Y+7jj+t*Jj5A)*7riYrrVGvdF`6Ob}YY`~ys zSiq<#05CW>I5Q-_xa#cA!1nTVWIt_D#pr;Dh!1|!-!uT2tzY5C>vJ<33t)opA3MgD zhUP}L7W|A%_Pnqy_^32S!a)zqI=3`oJDkft~ffi7f;I zYa27GLo*pbhI(fJjqgtYhNfmlrr%N)@eNxVKyg35zWJH8xv$OXwduLF8+=sOzL~ZD zjjj3nPi(y#2nOf5R{M_||3uopt&zEj^|M@%o@26>U#YQ~{+G>xk3X-lWVV-QM`mYw zHm4wOF;w(4AGbW&Q%~7H;n!wA)nIEGUVpIGvABMf7kZs`8FsbEy&bW|{Sxal7y0X9 zq5#ECVqDZdZg%T?`~STZev?BQ3)`d5eN6;l?HJgWT^SmfT%5i_-ba2)xqmgu_k7EB zcV}iMzW?sD{5E{#a;9-}V*N><6JloY8D(+$h_SY?0hWE8t&&(vTLZ#4`=w=fX!(TC zj;tT-#S;0Mol@{3&$l(QG(3i5U}EzxNo;ohfP*CX?KMn)>5V=51&jFo1My><|N0xf z^*b^D>k$6?_x8~@7|pq*Az``o2hY#<7NhSqVZIg6>lV|GWiMCMu=w`w_i?_Jt<~XQ z*Y{i9lJ(HH^wSq0(Qe__CeknZoSpTl>FF0OgF7Ol6BBzplN&PwQ0A$+$Mc20Jt8{3 zJ}|jG`kuY@*MizF#6Rb!_bh383YOOThtU6cm&y>k@K>v!UFUZqS58J!Nkc2}!naZH z*O=m$7ea30#$~ttJJ!O;D*ESiA0IHICty?0Wr^vV`t$GMYi{Y^Ur@23k-3$#+<8TZg;vIooR(k8H*xE;tGzqf zhhDTk*X3XPpVcjF?0;WgsFr2}%K=ogsHl`nwa^qk2HNu3h4~8uriHpf`6u&K-F)*n z6RBldvE)@3Rpt->`1|@nkDbM9J-wtm!&bD3=t{DYS9;{3tjK&~Xq({1h?p~iK&diF zsz(Xhu{$e$H)zGURINuHb4^~E@*7+X_xi{Yfcvw^zW7nXX{gYb8ThSXnl^UiMvMY{ zkV>|%hZvUc*OSBwKNAbboHOuBW2|g4DzxZ8aqLZ^n^fH1QO&8{U(+|pmy3ZDjh?vq zBDHXg+Jg)K@0PPD`7eaV=&3l5{vgv2Qh+Y;*SGT~EFk2;H};rREMFBfDNUu) z5^u!=t90k*u9Q^fVJ7c%;t`yaIz9(Qn&30~$rJJdD$ZWFU#||6F??csRS%aS6;Rk^ zi5yC{6D%4&Bt+dei64vJ_=OF}RupVq~=A#z1O41TRWhM%*yf8l_ZE5}Dex z{ICP;mFKrCMWl5SS6$a|E?FHd+-yoB8bCWoFArt$?q{W7?zkK0K&*pobb(9_VYe+!av#655wE@h8O5qZitScy$f^N93;8=pw8?adsJ*Vh&AnVQ!mCk2M^t-6$ zqFobTSej5+YWw8`0sr`9ayM=iERuTZtp=T~BwBX-VrG;PtLS3MrGmDiuCflQp{THl zC2+4{OXwozU}}vj#Hw%M2bdQa-^*s%S1iET&Iw4tGtvno>Dd(}<2*3JOXrEu54hDK} z%x=oLl~orZ%CmlWM|zo~@{Yhmy0o~)j!Ju6qR{hw;$shixvM=$vEmf^Pdwu>ya<K%@CYFmBodPjOXBC?Cw_v8SS z^<24`@|mitb3In2O1}XxAzS_9YX&u;rU-1(1f&W$+p)0J&zfLCUgS%li2&>T(! zE-&EYtc8ddxat?{xq*Z4z^n5ui#`I(e&r8E*v7P=@o8`kKO5mgu3pJ%`nOpP+P{Sp zCRc-;=v0^Jp+MUU{AEeIRARwJg3P~!{v_UkuY3Eta!X={xQC(5X6Pt}Q0_WIDwA0} zZ1$9d@2S4nORA z-@0L{juwfn_|TJGYfgzk5$j}miFXBdeqKC&)(RKZ59ErlFr*P;&!GS{SfznFrn@>9VP$7ioDOL!mg4BHJ4`Gg7N_Sr~swWRIUK|#&e9h;1c z5BT(gO834DeQHWVfv>6oUea1WQEt#eaH2%!Ei6@PWh zthrKzt`Kg?8EPS^aZ+!K4{`2{Zt$3@0;xOWHrPmR0xmpiNgD<-eXGV*WzR1 zh(}kc^uATe_H_|62B)nWiU`k4-^YA2bL?CTg$y1^qUqUr=cN7J31D!}`}7*OX{-1p zPcx%g2LF2@CJgmKPlJJ6SyXdrnM{(1{iuK;7BCT&UC6^`3dwR{Z{%e+Ye)s(3;ll0 zpj8H0`2C!;%OL&SGyAdm7yC@%UyXP*Pb#?o9ffcw#uw>TeO}#f`gKLHO@E6{fKPyn z<{AwR`Z5TN5w7GJqK`HnVG+-tIi$OQSL>XkTAz3%^sS4S6Bog)F!f%K!Y3j zkBdz}EM-avycn6F8os0ek~Z2Z9KxtxO)kMBxejwn7!@0{i*&LJoe%s-YF?6!P&}BHi{P{kB7udC zEP++MGF=nEE#q$?L6wa!T5VmT(|(8)N0XFDb-O-?pE%6&LIRjH`UU_ybl!k4ZKEQ~ z#cgrxaMKu`&kfZ>Rjn)NcHy6VcJF8ct|a(Q_rtX)l4=GKd9B4Jt4K_Z07D&ah;{&m{y`XeH|pew<;;N5qH0R^vJ&H-$_$CX>41Yc_( z`wh!f`8Wl@Gc=l^@4c;|dg^1$PP~x{L25N0&+4LGgkjF97dM+7Th2Wf7;$0gvZtoJiuPE?os?2&e%$Z0$< z_;eJNWv~NMVd74U>oIh`LU_Ic-1FElvY>yo?XzT2yqEXW>8GjeKA$VRoJOqYg~U!6RVUCJ9~c!iCS@0tAzFDh1fFDs2xe zHy#>s3a#47W@d}wUE}V|Cyw1J>UI+3B^DBs*DGu09&aQ-rzG}V16}C|Dcj3zu^`ef zSsY^_rvBSy8dVx3u%il61LN0)ni|m0A?yYwB-xIyC+c6481>thPhxh!wN2T#be5Zq z#_)G+)PU{{5f~kJIA@JWGCvdwZ&Q(NQROFO&hpW8;OgC_`-s zS=*R*=J+cd&04}F(#9=lnpqc&42F2bvRRJ>=go&m@`=UP9K!(DQ=^qu8#M(}`pkj` zE=Nt?a2P)CV&t{V8~VreMN-Tj=p9J_c*UDs!GhS-N0d+e8<6EU@c2j*TXW$qVGIpo9xW31j#x&2|Xy z1G`6xooe1ZTvneCqOB;>s5_U@E#w1QHz z6o!dYj$EGW+$hp<&*pP3wsYZM7%n&+1NAIZmDuKs5FBc!r!h3Vr9cg{pX`tI(mE=JFy-6hlIP5aR|_7DWt|%-xpYDRK6=gv zbRB&b>mb(`5V$qgqhg+LUPTPOcROeNbxhzZh^nH3`yoo`JLnUDV`5nXHUf?844+ep zjb^ZOJat4vD%f}-B7LHQq+ODBy|T}7%D#s{AM8xw5qU#u12w5CQMt=P7=TGa>47bQ(5TPYx(}|Q(w@Mz?LKYNc&5fb>UdNPHCCD!uNB4MX+6H`*t;by# zThi(0a$md>{N>Qilgr-zK=XQKy^Gz_0Uh$qnVg`6={~OmT(uXaOiF1(em&PBk>mcx zr+3HNz=OR4H>_&DSzJCJ^PGS&k758?lNR`*BwVyj!R7iIjl6`LdT2p<_~26;lyBJR zHZr_ysbr01MCmQ1`n~b2YH1i&F?gt-EAKS@p#3p}f)d=LpN=Yc-%(bi1)VUIp?;l0 zV49*Jvd&$Kt#Vb}LC>#Vx{@oiwPrVlo~a}IaLb%YSMTe$B_E)e?9aritq5GuGU_W zn+zqOX8?tXkr(s?OWlKWtHo@ooWQ9|X^I+Xlb|c|GB3@eZ;_I53*!BW&#N2ZajqIr z0-c}3mU>SpO3|oP`-o5hCL!=y==-a{!tKPML8I@(H-N4~_YJ5w(M>X{ zBFgqA$SXlsE%v%joqQXzSFK=x$yeX31!bPdhJcJzZ~ZI&s=xJi#e>y#}#t(*YG;V>A55a1&s{4EkW2+FEJrPkLXJ{QMqjew^;5LbsQ;1$`uasYI_UQ16ozBVS>ek zr_gFos&QzYL~!b;1zE3Q;kqouC{FIhTZZ z$# zMK?;+1#P`IV4qF`BEABq`%7zgFO?ZRSWBZO==wKl%XQ?cl> zd*XCmlFI_VhhgFcWhJALtY+Cs>uV&2J?qza+vMIEe{{znTnb3L$W26@1>80P*yZ?mSD(|@oPHz65NS`; zSixp3C8U6rcz%>h!TN59FPc=Q#$qa&yDL1?Gm0hEGKQl#vGncN%fiEns|kj%#TiUh zIBh1eYE3rIXEf$d{|T~hfRu1LLxZdMRygffeLmuzpwM;{G#V!6ESm%9E>c)gbx#E} zODPh{b6xph%3-ELyza_v=B&Zfuz(Q2Dx6gDURB}3Oj>Y zdizQR=8i=dUceee6^+@EA?ZHI^Hs{&Fe+BF20C#iD$R*|hN%PSoq+ zoV_r;fJrz%%|BIv8jp;chUHN`^C!BcZ*DOYnOUz|eRt*fOM0n>5&nX;MVV~}^Q^qU zxN!^2o#wx~nWI!EYI*c_YQpZ6J;ai-XMmW7Hzj3=;@Hf6{uRBrO7Kfsa;llazXn`O zy+Y(P6dRHK9>52NoXeW{mNmJmfnhStf$N%5lomTgW*aLxt{C7!WwXd?wWK~=K0y}_ z-ok)V>yY#ne8sV>S??f3i?lo*cL+*n8*4@FUJ?!2=!&oSs;)a;C;)|-F8&#u!=lBHl*sC)NjQK!KrkMRfL6h+WD)1=@5P;x!Fsv1 zy=evy%QvY8hCos;y~DKaLG5DP(x!qv#Mx|F=D{20X&3 zJ`TT8o86LBazry#v}~DsCB)q0NLjCH(z1}>xPH?jlLidut$F9$6Ruixfe{36mEE!) zLRo2GUEJDGY}eSIrM=lMP6*K_EthQwPOn$o&O_wv-FTsCA6`Z@9Dw- z9<%FxK3nN`iaRCnvIw(&2^s{>tDS{BV30@t(#>g#Ps!hSfW!1Puhj5T47|8_7V(3^Ni5A zZ1JoEfv*{tHTv0!TU})g&(OF{e+=J71BWgBBn?booYNVOiRs3`Fu%;GZ`Ao*LD!3G zEg^}cjkva8qw#KvOYRFm_!DNZBd^^}&sRc>hIc^43`01R^6hjO)O$LO4*N$QlAa{0 zy0KAatL%0nW(Mg%o5A%_lDW-5x1KcL-^CgC&M;=nF=b)QkloW#OvunE7$+M47*OqD zsGt}bgKb`0c6?`1194iikd!>)k^%$O<9RX{5x2dxL-k!=9UPkolHJ^FGnyMEO*Z*` zbW9(1`f(ZU6F-S^gb7B>m~YY z($B1hGo#Zk(eAPs1=T#uJ2wZP-d#Re2_z``ExCrk;-3`Hs3gHH5Ih$h?o8<*LTvi$`aZ^Z3f*^bNA zK?aPiXy=c}fyn5HvSV&vCxh|ZsWq{6WN~xlFx+^}On{<}yoA9M8{O1CBp?}DLa8E( z*Hd6|3%nW<=-dLSS!r}~3{`#~(j5E=Lhb#tx)#h@fLJN_7=)||9ITILs#^8!8i0$+ z+^ToOooM+KFR4q<1frO~{epzdKh3>X7m|9R{KcHV6=SMDqPwLY(!ppFk`i@S65$y=IrJQij+f@Bi93PqXqs;#VWUDgB?UJzJ7TuFbdL{KTSDYs$>A2m>)zBu z$QeU`V0ggj&pUeDuNl;)=p9J5$U^<`=|^i)Jxmsra}R&6MKN8{OC!s$uhkS-saXQN z83;8f$*wrqHbPaf(*nj3(MFN@9-wLQP4OoT8ia-oK*6Y`G{5_2X_-sI700jNLh^3D zYB6o440;JdTyyj?2g@QYM83TTG|x+>g?R{a;DsE;vB$jzY+wa1J7`E~&}Wi>(Qe zIPU(Nt_UB$zc3w-y~^+5C_hkPSekqhD!-be{@nH>Y|X>45Q6L$VvLo3&r2;R#@z)* zoqH84Y}o`+U7)IUxR1(#{^4n;+;FZnTnWg}l#Ir8!4!EhD( zP5zjQN(zkMti(CSp=wVvkx;p7H#1q_rNqMjeltR@et(#m=^^PT zDZ^Z-hiacM?`Dy@WeM0bSvL$MxUxCRdkh;STv+8|T${e?Z6V*90)WxT-#kGXUc&R~Kz7YV^;Yi0Z82ZXoh#(oVDgs=dvEGpM4H5DpjKpls2 z6fg+g0c{r+xGV;SW^jJtO!=ntk=)3(NS)pD%KVVan1Sj(YW&E(7`rzx#LxH7(1Lj3 zhF)f5{|c6bhxxy58>8O^5%lPKE zs%X1V!S0n_c}jKr>G#y$innxxT23%WQY{~6N-fewh#47y0-Bq?uID^KmklRFU(cEba+ye|ffGr6`W3k%_bQCiyE~0bTxDwY1vm`V6 z!jr&K(laSkrsY%s%YD*p`u5~Sz?0c5fD!Ag&_7TNHe8XUW6i+yXmvBVD4fwlol^JE zeZ?rEodD8KK+4Mwr;KKkYwkAAkZ#Ule`M%Zx3QiI+jS?UttyzJnmjjEIp=kr-@fGi z3aH@nfoZBXd9%(|g|73d-nw=1pXq$Gitl#Do5R{%+2u>sIi1mU@~KDnwws)^NWktG zLGsx_Kk>hb>+vyB9(gpnWFun<`yYA2M5D#9UN(8+q>xU(xpHE*ET`J9w^*xY#srMl z@2Tt{ED${j#!DNctX|}OjYQ+)eGxj(a1pzzsQSgzf?e`xlDubV{}*BJ7@S)aEn3Dt zv27<`Y}>YNoH#i#PHfw@ZQJIFZM$>teXrkr-LI>w_K#J2|5&qD&04h=<``2Z)6GfF z{8##_j{3LTNlk7~R^>hyTdQ_zS`0ZAL>GFAJsR8Ga*`*h`26jJU5w;f?#9?BEfB3t zYQOrY{{`(^w|Zh5en0&!%UEV$cj%LbLLCUiTabY_MNi|feX&ri4Fgy8e!EQClPQz$ zqai0CFn+>Mm{C^k{!2Z&CCj0i;qL)n3`q)9k48`eT@>{cfS6&IG z0MH>UoX{T$JBfNmt5+0mE9LdA?YbeY`a%qA0pm2-OI*q@pGmq|8ebXnQ^^18W>X2i zdDuQas6Bkf<8z#ei&oN)1KP~!`z|y7-wBkOIGJUAUA+q4*IVVXRj3$R2pLcI=XmIw zp}T*B7~yh}TUrT9+1(#SsT9HD+JSeIV2m$%)j-N${6BkFDAnF)dI1M%EXa2X1M6B$ zB{pu8r7<&qbifFN;n+l5BL3~v+12a{QI22WwZWRVBA2o3CRmzl*3~PyGmLTb449}Q z=O+V)B}T>8U=Nait-CxyLTWmD`&cCk*eg`_7i&ayE}09_GmqkD%;U|68`~)*$G`sb zVr#@j7W`*uPgNO@jPub@brlCcTZA`Or6%M6*4~6_;YoT@{FkIzy zXUL`Vn?p(`bFw9<)kJr^clVu-YULn_feA3o{ubykhz#lU88$ByKK0cM<-Z=9JO|*& zR2x_rL2gVY#|PXa-f_u0jum18t={>nEOX;FTjJDeYZ9d4u0iAb1`nwvjFS%?WaHMQqRZs z)I+rzN1pZVze)S-92hAWdbt$byn4XygF={stC8&jz~kqYh6w>G5)_r)wboR*Q>q6T zm`K&I+<$RMIxSs?;L>M zt;rp9f%z;sl3?flaS`-x8t*NIypS*)kz1~jAChBBSaf$(v?9+4-mn<0!oyl>!&HjQ zVv1`8>IQNQLozE0515u3j8v2+Ta&gKL1NK5)r~dTg&CG6yi0K6Zi;j5Uy?Vrg$==Z zXXn$0L3Eb=LsAHzzL3L;d?;Y$Wmjo~&51WfrI-{M+HDb~B!kdg(ztT*h`7~t!%wzI z@xF%3^HzOz;6lj6AiX=59b0QfEqvW32fEFuI8^BGdcoL_lZvC;fF4hI8}jP51K2XI6Y(IzN+*<*FEzfTKDV`&9J-5Jt34~1mdP(J(#JgbLB1auWPg_XSi>G5i>RoZN}N#(#|S|In% z@I)7=e72(eAPKJ_Vp=Bf=u@^To>iVmy`BElIqY@CpJSght z@BipPU&eoKV}3k61f|m|G^`7bB{lX20tMIbb$$>lQ5J7!MV3CnRo(_-#NMRFSq^V6 zXw2-E{T4Sg!M&Nn_SL!S>pONWiDrYf@+^weku{tDJCuHo`)#E{xmr$%lgA^t6al^| zOZfq!w-IoVdr9!iccG8)MHfgpKZD!px&*e)mN7EWOh%)>X0y zp=7_as_fbpRhty)g$nsV&z<5lvMO(gB{4r?$k4@}SHcQ@aiY$$M+NRl+Al5N&L$zT zlaHXa=kCsK7;g}@S;uLgQm9bS!SXlhXk{mZ_f#LzPWbS(Ma+DhYq+jU_Vz)|FdxaQ zGXZ>XPcBnI4mtF*IbDm~^k7qSpEUVCDR?`1r<-Hxzk|8{!eW8HHKar&{O#rOC1w-3 z^|>D~B;#ZnFW5LaG8?xIPVdF1Cy&~R1Ez}oMp5|Xm&ZEVeA^72F2eza`-;*t>9CHIez4h6z|KHLw>gHKZm zZp`NK1~=5E!{mDdLKb3$8kWaf*V$E%Y)-fsjXSs@Y}T@Kn00|MW)i>b?Hh=+%v> zFDeb@2WatH3Pne#s{ybZKN;S~(UXnIyjT z+%qsJ4nx4Y1+~HRY$Nj(7Z6ffSTiubYzsEirB1dOWPaPAG&9ObnMcyxZfS&GKyfg+HU5cZ18>vYEqsj}xFRw*tNz zcTE%9l1`A2*d`Za%bZ`TWAtZuO9qp5if=phZCHX_I<;KmkWZefiPfq? z0}`;cQ=9zb%442H%o~Z`Bl@^V66gUlHVNC`>z%dNaSI-H-ZazfjX2_b=S?0vcR7x( zbt;n2MfS+!S+O?U3ir0v$2eYA^@23&#BgKs#~^Qi;%Xw+O(l3`uZg6sk7*`(_;b$T z(y*W2GdD)2oz@dN#f1g3Hd2z+dgnN%7UlF>jvj}%G=FD@OM3o~FH60_m?~w4*Q?Ed zcFPt|RCCGTdvRCn;2-{sNIZMGJT|B{O=4xA(0YVApsW3aI{f&}*4N{#RJB^BPBjla_y|SNmPVA=`G3IL zSEvt`1RiX#sRF0Re|AMlJ3;nQy4Sg62XT()0$uv~(wk)mcsg;#yKE7blhem7vC5bH z6i@ThicBXPgr@|eNu#~&06U|5Te*nG*9$b+0zRzwV~WOjBsDR0A%ry{`wDg17%5!) zwvzU+^c*TSfRj=eIZh7CJBQA4G%5EbSF8{mO;{VR*pp_B4y@&qw>*Q4V3SJk5r&51 zTuIby%q%rGkpO*T_Z@-B-XdBD`wy4)sr0R3U|=dTpNZ+AptKN`Xv*4J?=-iFFpmiZ z2UXUL?5@-rbLnwNQw$xB`y%~V>A(Hu${Lb^rdP1?v z#&qZ08^imV!aW_D>ujZNcy3Mv{qek2RwL0=i!S<*!eC!A!%}T20;uGx-Vo7YlQU@= zWm@UeZS7Sq5DQB7`OaS`DlriPI#k?%1vHyICtB7E;b&#)wj=S(`!)qeL$usTC;z>b z1a&UiXz9%W$9XXRh=t&at9ubSWv#!w++aa7Gn?jY+p^*O3dch@lDLizDz%MBD5kVbhUzl zCXWSyE?EnOJwZl?tqrQBc)C z#_5)nii#uAi@MKJcd^jJ$_)Os9}*~RO&(*mSgm)Jcp<_H3S)u?d;8?Mg|_8XaU6J_ z56y{`?-R5pk2FLraoigC&@szO5?J*H3l`tb-Zb%#J6w1;O za6SxJ^;ezJpjz#ZuxG%&R-M`Ss&_l?^|=M$aVv;mei)*U|E1g-^GoY&Sjf5l;Kb02 z^rX@limkguu@_&dTI^MU%D*>Co8O3-z^YFXua4%SBn+P(RlAI|RtLIDHm(M31PR)! zB-CAYZeG=ML@z_hxm^jTviGG=yqMx2Aor*?4)!3x4wL7_gt#r7Z z!)NI{D?!NY*M74)_EO2GEt#9%>PT8t=585^s=%dN3#}N|2;P>yJ>{NG_kbXjd zdUtyLXC(PF5;B5|ByN_lrEZQIO=F1@k_S}Rga7ZK+>0lW8k2ru9S~+;72UlpBv5z_ zIHwoWj&pnTte0~=UNU#4=;^JHj&HhkUyp2fu39Kw{m`jTrI5!c4P4Er0JS3UussJd zG*=)jp92SGnl2V?U93t0elKY`F{`_){4ZAS5<7c(YUB>y!Gr7xLYyM@DRX#=F^AR^ zs)64pG4d!gush^$;TKz6d(98xY1#B#YPLYu*g73cqaauZhql7#`9mc;f z(`ZsKH?lykqB|P>%f|NlR2>=Af?QRzBgmAthU=_lKkro~{P(d@^s&7NFeKHjvmh{Z z2bJmuABEUT4H%CIIs3iB|HSjLrnUr1Ub~;M8GoHf>v*@&iJC>A z^IR4q^x5Pm&{Ohh=wkGh6qK*PzHYs#K~T`hOG|Q*FuR=zjPEtIymu}S;FqD#O=@0J zeMs(mvGt;n5r8gO#Xg>N5ipm|)87qpw50R~!wNta=Bb5^2Mw@P76sneZHj=JK@&Gm z@t+2`1Mo*t{b)N;vUMO3}_Gkf%swH*J7%k6%!P z3df;C0=^xVKr-co_T@<%rG>n*oBKA8ZJ58r+QGq6e5br ztqT;DfAOw**chcosTPuoXEwuX(y8!H72)o%U5P>oH6N5Ys9;Un7X=-uJ4qVJm%*y{v(#7!!8Ld~dkJkc%go($Y>} zuov`?J99f8ZGb^Zm%c@cG@rIUZRh7oEXS<@pi`{3SFpBpz}+F#0jj2uJpwm&yU|@P zNZnSB1^-Bl&eL0V&d6-wnw$yx7U%vL6;1?`okQ;gv%vw9lh()|7)kn^O%6T;$T$+VH%}y z6c_NeybA0x@Cy$ozU^11wvDHwuhj3x1M}?1(-59jgQ20CW938|DtM+yk^ObNe2_4F zu2PnjP_+O0BHS9UlYE4*am7?Zv<^1(^P!oAmwPFu5(FvOknI6Q;Qrz3lCAsZh+89X z8Me>FMoOY&^&K1BbjgS+Ny`HwQ)enKV##Y0Ku37SYj^Uj0Lqka5i`QFeiqcdRqhbZ z0*!bXRZ#fs$Rc5VURO zWFucd`|c5Y)$8ruaAyNF*u;XbV76l%0|rI~QnlqbiW1U>ZLAv|Gz>;JXMRH*;3i^69y$kAckZs6GCF zk&T3M&t@(M2AFOCwY)XbM-zmP?D-C!3z;PjeB{DX})5URSf8DDnF2;B>7N93NJ9!H}2T|qP*w7amGbO ziEG(}3RtlIqCIGlSW$B2fdj4cmC}H$r^35=CW}&rG2XNngr=ua z8k;pvGYjtO-)Vkc^uiLsH~oSdeJ>v=Y9u}PmbSem6Z(Vxq=DqHeLTBq@^hG5rN^+n zxTtzp^{u_TS+0L^s?FlwZAL}V7~f&+b1{r#mjOWal+EQvvhGawkm zWC!1OA|hwo$VJ>tx>qA~P3$Httj1yO4zI`@3Ni~~|1IklxPzEo8()OfsOv?rWZV9-?GNruOwD`w>GmA9rC#Z@0%*Z6P4=BB zP)yP@Ea``_GI=-n$(PrLheA4{i)5p_J$r~Q@e13rj{&@_RuXW?4rcPnB#oP0FVsBO z)B%tAA)M`wgR32@9R~bi@jO()g zq5=ez4W|PP>uGR#=`bl29n66l@w7!fMe%;}k8BkgdDif`67F~Nm>J#@uKiNSfHyfL8r^2C8=+O%x~*gC~X#m3`2J?o#?P%>x9|vYE0$i=sUVAWL(49teR;^~5^l z#%at?ivnR}3l3bXwY!g%4Tp!G`Y5Ws$QO#k*%uMyN=g#x<5-RptXu~*8t>X?FkfNn7_78g z`$cHU##LDtK1q(`aiHfAWXpQtuA#X#@-Fm7kU;bGc_knl1Ha4?Y^7-X%vcw#TgUjy0Ioe(LWM8aib;o5PcyKk(kN*9FhEA%jga{ z`jA~3D-s1WY6Q$lX3E6XzS>cM*6OhH2J84E!Pk9InyUv=d1iQ4rOum|H%1?1eI-`G?sYqTYr>uyeyp^+jDZKBWo_+QKf0w!GL`&g~8;*ecwwr4Mf zkZP20jTLzQv**igydAYws>fkDD<~(4K(C%>NyI6w3Yj!rVYa8%lN%wbqLfj$btroi zc|V7#P+4Y5)Xh+3ty_sBs&RhfcE3O6i-9VI-XIzM?j{Pp4=0MTA4z!zKa@;L=+0Qc z9%dXtN?FDI7(pC4Gz#h8FCxnQx4yRnmQG&XZ>$mM3^R93(axgO3XCCkNmiSszZjCH z)Yl>+bPPF_m-!-|214WYDk61gSAGjd6m|v&zGCPZ=r$$_x$d?Z75t^nlBxvH*xJe95RW@h?mBdW1dMVT`D*E8hLc-+f$KJ#)_ zUY!Wzt#X{k1ltvh;>+p~@Yf5E$Axj=yeCc9q|s)Nc}6gAHIp2+%cJikZhgkTYsz0} zMPl@=rH+70;OJ94(A!iGk~Y((jw}J495%D+g zPOMvLq=DfAO$q%2iZ8@1efHYUedQS}S2kn@YPw7cO*`k#BKk+?sS}zb6rVoRoQXf; z^^}i6?p0yz{ntEX`^w!7;Jn(zcS6HvCsPLJlAd zrA(vrpg!9ruqbnjG+BpT{uTzl6He4cQ zmeD?xiq)|jw`O8Dv~afOI4}jBL|iO>_V906RXlUcd2kM1BR;6KwV}m)a#T{7(&mf) zQyY1yAa4G0dQ#-R_M42;DY?fQe=7zPfF3c^w0)D)JkUM6G4=(bx2qg5UkSF_`6 zZ$C%)O8lJ-HdhMU*D{-$MQK9cYqOYiSj7Jph>Oe9n$u1~j_Kq<%I?SQmZCaE0^2~b zp%9Ju?fh4P{B?_e1Z^rCD&PGWdvT;oIB4MF$q&Cxkq4nAFbgAuXN~cCE zD(ta5x&{NNH^S$Eo}wPP_xZ7Zw{3C**k)CbH+>#@&B5 z6Wt>ex>i06KQq}fJgK}$M2=x;?B6`9OSr3`3&sC7kCDS z;Smb9tp8UTmWh--MvrMmB$TE*8tK=2b@|-*f~uqd{V)CCobW=U23%h!Gv;u%vI`L$ z?W&H&%@5{dYhhJZjaC%)x5fz?MgLB)OID8RoAly4d5Rcdi`PFKv6Teq> zkwPN6^-)>H_Pwc9gF_qso=-y69c**#uQI!c7q#zI6eUc6!)!Ic>KN-6brF9cs|agcKsr>yt<2@Z7N7FJ zEO_&x&-egw1{UU?v!@ zfmb@ik-b~{M*93$?VMm=TZgAA=5Iy*$%32sTIi2P0FU+&HE9nMc2_@r?(SuM`qZF` z3L3Bw-ZC#r02CA^T%ONrmWUwc=Kwy@JUjPqWC(Tc(2bZhy{4FA6!Jzt;t37(CdJl) z!Aax(xO>2 z{-+m=XY0h&TjS0;F{luz3$pt~v^M*V?s~yZqf3%60k%0FK^+;Fl{O)J!Stg!j(zrB zP6oziIp6YrqH6-iCuV4@ne!;4j-?JpCddaRrvS{IUS<50=11w=)^H9K>sf+kEB3P2 z)3FZq(uqZk`(a=U;C2{i1cT0FogtB8@kOcvHm9!|dl)||W>kT`+y84Z2*)4N0aB!c*vy#`_&I0eOwHh4kq?ZtD?oT>`x^MK{4F}1$$zH$}wYj z!m?ydJ#F7g$c5NWE*83D``~bh4Nl!V%zKc}gx6nu%dm@+Ts8rJ@nnqcY{?6#c_Myu zyI{QrQ(|klpd5eeamena0L}(xeO(A`E*e$2~uKG^h?z43iYIxF2Pt5pzRM48bf2{0)9*F zNE!2{lew+0p~{XS7y?Bh>VdkFdw&qSy6dnjUc6dqN^_BXxHuFyf6o4P5~(hU(H6G3 z0aCo@WX!pH5HqcQKFMr!KjV_-Wsn#0j0Dj}{SIYoD zZU4C_0KrD;@jF2<4ri}^=d_PnsK!cv^{5WlNWuQ(lV+AF8ozp4v zxJ|L)x#7HPFtWXvCv#kq5FueQrxJ)puZ7DDzXmj3YH~apa4i5#!7pPzZXGW%CeJGC zEAO%uG>4H*3MJYUZ#chDz%HP_(#|=PZnXIZP$2##bEU53^4R~Ane_zZJy^6ISP*B+ zOJVrtQCZpUaM8m^S_>fuS+EBZ`Y9kOr34D(d{~Hu)$piVm)*ntjBj-AbYCP7f$(3e zmXlQKb;XnZxTBG%VDv!?j1A^8o|3W-7+X1UzK0LdPKWOXw)%_rmOgdA+FmXx-D;B6 zBXCUQ;%W2O!&)FqQt-F4skmD4JW;|4E7Bk%-Y(i@=KMb|Y}ke41lEEJ7432>F0WU6 z5zTNi-wdnLvN5T!!JUVi*@K>NR5y`VQfcSr%Sc=+%k9S2mQLk83W65}4og7512pgG zG*REIk-P}u?Pyi88nO`wU`o;@?q%APbaPeMog-2m4us6GedcsTnhOk^&n_FO^FrTz z4I|lKc9SUL*aWKs3LkDc%o)r7@MyY4%Qs1j-G^TW5gX+k`AIQu{G!EWv!<%z9pXGA z7Y4x6*#CpUto$Q}(*pe%^+#%Kd+raPy*O}Vkz(`+FWhNL%$9n3?y`S+G8_sD!oDDn zlGmbqUE8GAqyZmc^)RsVgQD-@EU+V5nt=uji@G^LEU4kWk936gwF=D4q9_y2#t-q{1Nj1W zW~?;4wT;Y-pv^E*=j5`{?qrq+NmQqFT_RK7#to85Rop(EBmPv(SFI4 zvvoSaBDeBt9Tp`fA~Uc&)DV*E31u@Ch1S@ZlU(NqrB+ys;)3OFinNwEFDt64P!L)2 z-yLgCkDr?&w_GS;NoHPDl>Jcu=B3|=!XhQw$AGa8V#Y@=?MH!j=|An$6ArFXc%H*6 zd_M%cyb4Zq(l=8*Q?h)jFki1$grm=nHtb0~siV%l5}<6<+@NkhPo}En;K8=z;N_CH z-N`FNUai#_lT(JAO+@UJ2xa;8K~6U55F^r$L*OMNC0WV!#k5HJ%PjkBW}jEx;ISd%~L=${2RymF7+<}A#j zN4xubI!^7h;Y*Gi1hDz8>)P8~9Ox@4z><$V<_7lEHE;1|%oiada1WU~Z-ZT%*rBrZ zw){I<-Ic7;rc{r9^@<0m#JeTr5#Or2y=sc?t}baSdG$_Ph(qgLCefp<)u)tTP23Hd zUzI}!--obOGjgb}@CKS{BrOnmC|WzK7PgUF#hUGwV(e4*F>Ph6xXe z=S1HNIHQke0#jm>y|`9ZY7fzh@n{va9iBfxLfCxvgQXR*7RhiTFaEQ#zWp>>BRw~$ z;{#>@IaNf2zIq`=>^x|+_m&sp|3qbD|8FR<|3505xU$rb@9h6UWm7UWclkdP*%<#r z_RYlcKV{!c{~gK3{=XyHSbuES{|m{+$oBss`{wvTv;E($Z`S|th5t7mo6!FtvWWr2 z|I_#_4UqX^v;CL#`+xG;Q~_!~?r#l%)(@%8(Dnzw=45DR0x)!P{z0)hSp$p!MvjKY zrZ%Q#&i~bNv^2N)X}Z|hm^uTD0so~7H@3I6H3XOdOaZ3<`PtOL#n1*|>TYafXbUg{ zm|6ZjuBHGp8^HhIznMFl8vgVEu=rmjI4gklk6YZv)X5283$O#&S=yNb>|AV(ej>6o zw*%M%?0;VT2K+X3G`0KBaQ?IPU*Y@@Zkz+a!NuO$)WpcyNwK z$ap&luUlxUW}vn5txM z#j}!vA>gwJK*C;KT_Ng#fLUT&RQlU(27dAh}iDpSoq8fq32e0<0uBK|f0*@Qupoo`Z4~k*+my8xdFu5fL zVrheBGt#SASwTa_GQz>tC9wqizW}cjD*KT_K^d4s*52OU<|%=a61rCZn7m;z{nV6Y zGotGu8nQ>(v z)rVf=6v%d4MK17c!#WoUvB z%$s4E+4Pk=&T#?x(taFvbzQFZ^$`AAf7IvnGgOFe!eXYzd3TZ_yx?r+Tt!bhl6S=k&+@;v!t<=M{d=4636VTwX^rfMF6gRSfRU76!5ScB5wgei!*- zm-w(pdfEBWmdkGXE}it~?tPzof2mtpid$Qo8fP3sym(FnWkW{Q(f#vS20{h)4UTH6 z1N}GC3k>>Apl*y)+jRbY@KMvzBc(u#9?O@T(b|H{xUEm5;lw{tLF)5Ew#h?MpH6+#brr`mKhQ=ln?> zoOaKMTC2Pr?t7r|)4E~YNxhdv=TgA$JF>6}jPbK(h=AI`Ar!VZD=aDlp?7e4;LQsw zr-p=pyX5$r;zD1<=39pbYXG;G9*9@XOihig_x_om?^_4!12!s=4$RCUSpJ8^cZ&&lSr?}7Q@LS{C1zLa*0};{XiUN%CpMBZ`E7nsMVS$^5QcXkFrK!E2 zu3(awU9&t^;S@KO#owCMlRO^3wm*sAZh_|y*<1U;JfCL1+})4w&0w>N%i8i%?a?+D zWa;Gi!BaD|IWT$@*VZ9z1oBj0LNB9J;98$Q`ILbwkVKBX0&+9#dYB6{W z)!v<&t4w#?xlH|zeR6&-rMGn@QbAJcO>+A+Z;K3==})o8A(T8-C-kLCyOAyobY!7K zKY%?bzLGnSS5c3$7!c@;TrC?HI6b50&M<&^)VjEl_~$42v@BkXR=gU8japVAeEc-?8hL;mw^ zIYveY)H>2Gh3RVrrN#o#r-fVD^*%tzorLma$!aZ}iO%aRaBRYa{ z@U=(^fzkM`Xpd|cVc2da-hPzY-zb1^gW9rYKrC=<>L2Exxrb@*wD#Zt*% zTN>>~M_Lk>eQ6x+HqBkneVPK8KQ2ebjkTCQ^wM?sqF;JF)GUt>K0hMWtW`^eU-qdy zaF%+Fk>xtnhy>LGcLs!+-^egV*XALsf?a*o1C}o=glQX_z{of-!Jl6- zmUdeXI=w)GY@fUd*wu!JN%{D7o6ZJ9MXIy%EYdDmUW5^VAG{N5uo_>!-&&%=uBc!Y z-}@*+K=wt5VP!F-(>_~V`CD5dcxKZ>{6`R0ZB7MGZhsv4^kZJXwCMNKb?ihd@m4! zdVA@5Y7$h6I$r!s$1e$>$)bMHAou(;UQE3?+9s+FN5-qQ3LkIqcO@*`*$&_k32BOy zjB#g0B2wl4z^EEyh*2gV9~pl+c`n78Bjuw#OZF(jyF!P?pAtdIX{#DK*~;lh0eJn2 z>p-n)MVye(!z5Hl%5m+~!q&aepJ=_07I6C*D?!Iy6)d;mK+ydKIgieI_o7{6of+Mi zsmP93x6fhfrSWjBMB8r#39YMjS#TWx z!&fXx@T~SJ0I^(LmqN%syO~pL{ab!fmVY;rL=96KIRr?WGzs9Y|9~o)+Gig z+Cs=3yr-2A5k(7czyeMEAxj>IDE|C6#jd+`yAW9ut{!(znQC_WI_5wQ!Y-DlO(2%0 zpI%xBSxWX=b8Pv*c}cn@w^T49T~m6L>lGm+_+D9%v1^gUhM{x!_@kZkC9dcHN)J=LzL&^LkJY0jD$dm5QjD&y;8MuuQR{E~tSJ4|Mc5crsOdL(sV;}4KH!E# z9~p+WVY(C>ItHu!E80jbe;^`L%0O#ZB^^KIe1*ZY`>f3A%ip+bO29mu6P^8f*~(~b z_8{wl_hv1Iu6r_h(yZs4B#XwB_bH(o&#OVM$`!jE`EMQuX;k5dlX(i1Gru_}JoJLq zP)JDnOL~GWpsCR|5-0I@8@&5yqw4zM*WqVc%OP(#5#3(&+2TB7&||t7MZWZgD6GrXvq~vs2cdshYmF(G}42 zIvq8~hQWz|*_ORY#}ING+oRfT7jzY}g`1AJveToAs!0URGh|tjbJTcv^)&672x|vq zauUIgX=5|CBGQ5kbNErq5hrxb( z4!NN5CMd%ypfhUMN?^*b8pze|j<3tE7o!LJSrMWl5y`#xFTwD&CWGM2iSl?&7{la% z-E@Q(1@{84=}(E)+Jw?N5b4B@dror-kHpQ1j=6pc#X)98yQ2jSp{+$DUna{4(~Q(# zQt?WTXX_YnWOQ{rQsh4?wvn9XfQz0r!*G;PF#SYR7%qtf5VaP`;3)J8fIiP5mrThO zC};nY8UM4Y12P7GPuZbvWreU!jdpASsC1qQCEQ2Sh@%q<;?! zW$QfLGH!7*CX@}Ol$yiI^2t9v+>H)drx8jDiwD!_i3j=|9^WKxz}q$;f`D>G=#5w{ zH~&)+{K)HjmiK{b!xiDZ%H$$rRv^VAYDP$@jY+^GX^MXfHz*I(U^epw)9}7C?da%Z zFHpD!hweyUQ}^UU$zMGO!IYt+VS397rbb)CEMCRBRJ#jSmZXLd9G;@?8cCxFCq7Yw zp41#u3o;MWkNmsCxs6(4=I0f1PG$SXe1z`wOA$4NlcLIDS*Bu0_-KOuV7`sCu?mm& z`3mU6*x?ey`ElfrVe`RK^IJYzLW0nk+qpzkrh^^3%&x`|br$;VZNFo{!g)DWN&p8l zO;gS)Y|LFjI~b^fuxA4CdYRNy)w+Lremi$ca?6K`rPA6w*oyF8wcjie=IigpvkdJO z^<~i|TPW-zZKxF9%Mvtk{y*c1lGeV5hNd}h*kWPm|*-_>!d;u3-gN7ZxLXp)}8NI9J-jKih%!s^j-;o^r0=aCIHZ(FgR|F2W-Yf0I+sYE@&gPt!9a#;CVJA6hT1 zwr*wP`j#5EqHV%%JxuWx>^)Ms!UVjxqF-p?;UZEm{yXnE(UsD^mUT^(aKO{{H^d!Z zvZ#qYIG=#BrDb}lm$PWsI-TfkjWh=`y{#d}mg5(IV^m2q(iWhJ->?i_3#i-sa(+h)w zihz11CPo>7QOiHv`ce%ykW(_joiPxrm^)6$-F`$L1n^a_(1L4)&4*$p%H2@O`_#ed2e;Da z!+)?$hBMFZY~IvC)Vy|~N-?e0)}VKYj%|pwKRpgO3X;xi(jc7^jnuj6|S`XIw-l|H@eH+B? z7*5FRB1&6g7N*J{c3DJymS!?0CKU>JF;`r9HzEH$%YgZ|y)#{>|L~s50>^n(9Y;ar z>?D*O%irN+z7tnZ22aSUhUM2ipA<-s%AP;QwFlV)2chpMElv-XyEDOeT@6u|7Uon@ z=k-fiHuvP6>!Bci+K&ncz`mIJmLrW9CVyvV6mS(<8vH=pwvp3t7@Ab`{ zQU1GZl@V_1X915^wH&enwsRoJuP?e_GW?B*xHpwc=#xaSxH+@*%V(2!*}G)RSb!Xe zu*%{Wv2{*Z{K@h;%@7{lzrx5E?dH+iMxC=NiQm4~5-7%uK+5R)k6n|TMG8#a8)d>F zpfWTl-LHmF@)mnn`KPgUZzPC88`>x_EViQFer@Jt!;>vI7psmU-A}McNOiU^irYRa z(*HIHCju^HH0yUXZ^aFba$a({eZ<>TI0CMpshGJR9mkiELvO+)5!xcKje0h6Un9Rz zb=%ZOdO78&`l(Z2+C#mDlH{}MHM>~j;1fE-_u~kOiai0-?b$Y)EA6(JjlM2s?0(nl zf&5r}QIHXnm-bwBSKnyM3)U{nRhX@=A0oS1n0{LPqE=60`=iQY0q;dEGAHq<1({7= zDjS=jSK0;dKF+2spC-asBk@Qw*VU{&3vFpCBfp1^xI6r*>X>E$O_fsKo}39Zh4P1L z|5s;U0uNR9|KB1>MJXOh8cLyLFF}_io7`|09XUTw&AmV)=(P&jjc^40Yb@^Odu)Qs%x=Wm)hv`4fKm)b@lYBaZPt zcgp6ga)uNR9eVKO=J(o3g)^RecaJKSU#RGaPHrhW^C&;?V`x~5=G>+`o~9iKtM;Tj zA6zic_NI)hjkC+lrNSrOT%sRwSRJ>e7b=#D%&+_Gpi{MS#>N?&jlPS?ok{yzEoIQ` z5+$+y+;9XrQ*GxSC)>i_W#1HDTD?iW?VTQ1NU7*zhK{x`T-l>ql+>Vb?-27g&0$Mw zmi2?8zJAr4o#}R0ew2p`UD2LWBRt7N++5N5PV#=ana7g~y4YOly(o5dRhC}5=HIm=95F^LZt>t z1?HY-6{i_`6p6fQy{GMOAul`dIV(K!A;aMQm2Wpkr&T%*pRW0ty+HoiB(>_v@eCuK z`_b-SZCt9-#eVHm-Jenr-NEcg)%Vd&zjHX^Ns-^RHrZs`&RuUO&3@eddCM|S2Qi9d z<{Xo$to+Df*?k2$58mvUR9sbNcisLj$D*RFCL#Jo(G`a{T4nQMcBCw&%H8Eh^+__ zev!EBcK=;>GmS}0H6;x^Wseh_p0r;qSo%2s*{u(UtU4w0HhAq5H@w{}SEe!RezDRy z3B%4l+>3arIjj&$K=|-;1^ts5A142t{f=rKY255E&t|?a!_fYf@3w26?6$vkVrD%W zcy{{KxA03TF0$Wp8x$uc#wGm}u6mHNOpPVJ&}da#m3~>+d^d%&c?GiBj0Gp(Ga}rU zt&sDXMoHM!&7Ooea$54SY`(C+uvCnprQfCioaco&kA(@=<@xcxBE*lZovEU>S1Pq0 zocbVDF8)l%nw<8va+i7ilAwCS<2mNn3b)DjJ~T)R+9%uNTk zx~DyLSw!2~S5d4l%w3ti9@CT_-aDHRddyDzLwkXgVbVxgzKXi#E~dz2xq18O@p)2= zE6YUFPhS1U;7U4Mv3QrxHHWc`HPjk!Z_Y;vxc)en=gGguh%t8mB{=V6) zu-LWnM(3s%{WwLG=(7vxpZxf=@gd2FdW*mx+|l$u`cpF$XR&7$@t^D5vzB|)hXMnS zl{zlzAJJS!I!)PDXII?mBIFx;e_Dady8{i6ye}5_*jp_-vRJ?UrN%ldxdFXW@&ysb zxk?`)!iMntv`g(LPOSa7g}w9R+WC|KhuC?wt+DRIk79<)4{sIG7Tu}t$$Y#6Uwv6| z%bSMqHM7qe(oIQ|gEDJH-Mg;m5+nO`nwJ+_7kBta%4ZGCZdUPEcCZVW_SSUc`_{ew zYrZGKS^k zy1G(a&}j>ICrDD$Fn?YnB(pf&ujeQ_a;>SDxb@n-HBiDx1udlF|eP=53b&-wnu{{Ys zca2+!+J*|f?sf^XCuXdFm~>^Q$E-WX&0HBqow%h-*225KS|x?{ijU;l6Grlb9jmnl zw=Qq*cydE!_WBRyR#Tq7S?s9Tp!cM&v!w5=ps|LL0E4qeB+TMEj!C1@8OqEht+8_F+pz3&it8A01dSun3%wj!f)wFf#zvQ=w zhxaJCE+{>>FlU?1P~CwC7t{J|n4%PByq7db?P}q32g$C-*R9>e4HF z@jU3lalgGzXO0YvHupa9fBqx;`r>o57puud>nobOd{a%&P$k9gUBBs43W**P-J&(n z-Jq*~MT5{?kegSmERhoLv;wHo;2Z96+rwLdjVXy&DHfKkdr#}+!obO7lY_^EBJDQ_arbx+AZ2;O-*A3H8@)?kX#dqm^*BCk_VdoPHctlB`%2w9Mow ztK0AFGus=Ke1Ch5Ya9A5&*MbDPqi!by`UkYJ@be)T|E4DXP{y>t4X4B{w2w|0ScwF znwQ@Gpq&3=&QeZg;}VaBDSI{CFUeN!lY5dR?sio=P!?|$IAE6>rev=5wcGx^L@;B6 zX4A_9#kx!PNyn7Gs8BmRXE()Vr7v+(X3Bg(+N*v74!T|d?(+eE6WZL4^e zl&|KOYPI*d)6FyMcK`hte|_eGS=F(HAC}J}xhm8)MbuQdV>ga!YH#6b2wa(ho$TA@lXf~*q;@c8<>2;x{$6$N$Otr45U2cET`ZAP66BN81>~(sZ`mY3kR8%yrk?i8nULTTsShFA9vYg7#B4TJXrQitPyNs+hCg1wIq&>%#BGYpmSMU^Y~}GU z@nQJ}p@aJUXIzQ#suFq3=1h(pX&QcT+kAy;w#F3a`n{?2oQp}94#zw_-u1Y!V(Tx* z$b%nV8!|8DY>-?s^JmmPg}cJ1{ibiHmMN{@lb*A5(NEo{9naY>Y*w7kH?MN)o29t^ zgw;+>slCl+ea&iZtZyB4v(1S&7Dg~DPSYpVucF0io%-T)HF5O3>peNQ&g<&InU&Q8 zWNV?Lx);5bhse1PDf#BMt7rJD7*tfGC8s8ps=O^-v(!<1tNgE((<;;xk9b(m3TLw7 zb`7f!-7CHvl@&Ai#nWSs!?1lnS1ZS1(=huZ^{d3eoRb=LEc3x8)uvxB+iN0TRR@Li z)H@_KdTA+&C|JFH7hY|YD&gEdw8C$|Rx`MW@mTFjdTQ4Z_rGUmYo=@d_04>vj6$VUdx(9ey2-Aj>d>ff3#JEm z`+$SEgDq~0+%HI^efnT_d;iLy`C`=tiKFH?ZBeDGgHt-h#Tfe&&#m(IFnD+NNqR=Z zQHib-b-~FsU#ah=-_>aiIpzA=m#eab$%(eb9c)d^+8tTe$gG+dyJ+C2clFaF)7M>W zySv2sjD$+|Q2yr^WySL}=6XvvJ32J&XdAX&I6Jd0d`9^m*&QL$#i!17$Bx90$Q&=~ zaW85A(SN%s*Y^6fXiZsez{>rLFO@Zm-P$+sPE$qFah_qVVR*#w_Qr2MSHBz&sSj$* z7-ZT@3{0;%grAam!Z`f0_EPoPeT_E;mq(nC-V+#iWn*UG-Q8K)hRWUN&#Dx-$hSt) z)H%<>ZP!$PJDRjs3_l}rwU<<^qLxl?zzLH_>0Hudoq|UVaeLN#x|WoB2iBB*z3@Ea zc)QAsk)fY2&n-Tjzjzt*j>uarzF zd3r3YmNNVpX$YXbnm3znhZbp+O54isaxaUru%&po zPucuDHGn--?p<;-Z%5N7ocKu0oA1rDADXiVYrmaev#GUjC-LL$_J~ z6@mU;-Ad&Wp{(|l-mXFXGT)+g8bYzcPv4Z-Usg{LyCoHK_o-&qUkdvpFE0+8nljp) zT2U}`?rRA9QIEn@r}h{5a_+1~-!?^E_$ys}*rV@B+4I`*kT zzcrI9A!Iyn(p!@yFEhANlYDNR+^20}eA&{yss9Y^Hci%3Pj`=W>)Wk_zuR`@w;3*G z9}VA?Vx($MZmaQou`}cC>W&&Z?PhjP+&udZ)u{{3lxmXnT1H!jqDYQSF`@SvE&d&k zYgRb_AbbkwisOuIihewDWjk5pexthm=aB3OGk2Str0a)1+Amol^+t%hje3MD6H=9H z@%F)qFVp&1q`LVtn`BiUx3}DilI_*6Sf16J);VHsBa?RG?8WdXoney$lErUEOHxD& zC-uI!Eg7_)nJ0Xw?2O2;%u4BivTk|3lKEN0D_7sWTvETs#afC(&mZ_)QPn;7nU%tV zhju<~|FDfnZ?;xT2z}%p74i&osGhajdTT-1+mCM^9CE+ikiPRw>-&Pqx#3T;iK8kh ze|Z}PbUgZ*lhv+vX#e4NM{YEa^ws6vED6jBE2U{=XIAWXmfS;a^c&2(qanIw;0>qa zV?(lfYsWiri}{n~x25&VW(3AbETwZ>aw`i}r+jyn9?^Ef)wAEz>2=9bHy25suB>d$ zn0)f4TV?pKof28Kx;kBkL^YP7$j_KbuYPSF)GRL{r33ta9hP;(a{c)Kf9RwqzsN5u+FKLFIp zu>-uo6xg1gEKn2Z&I-mklHgiHKOC7nR(&{L5%{~75JzSpN*&<_{4&CcY756oA#oH6 zsCIoQr}kJaD^?G6UcT|g-U4sT!TPyBzOoJX%IV*%L&2}=|tE# zK+$ASFc-2z90e+{1WJOxFiE0#JGKYcI~Yd<6_$`4;m1q`M}+MNX;}=Y2>^^!R~LmL zfhx@Zz-eHxVZ&ORF`PV)nE)mk4U<7Zz$6kujp#T|(tqQGn*47#^>wW5wKwo9lTA4R zCa_E=Knh(#4W#s2pk$;#i6o>%`NIE$L}}2~%>NrwJ98WJwFZ2o)~*1l4#&@90;Eu3 zwg6HZD1IJSJ&^?LX(U6yoK*i z0gE>A%L#wN`=?hF&{#1ZCV&-+wBruOtA_t0R%Chn|C@vTSHgqFi}f+^p2WWhm#>FE zST4w#(3WfA>ct8M2@fX(tWkis1(YFhaYQD6Z82thfUJWG8yb!d%LK=OQQ?@pZ$tuY zu^=CVwToOOfoJ`H4hYr{$h4uwnD<{Yj0Z;~^9QBCYYJGMv4c{vY7v+vh@unElE|B; zzzkqH2!?w>W+1EN$p{uMgcy!CU@gWXV`9Z&9>VnlFMRFhP(NPo|=Hz>05E6SLxD zHDiU3V@2?Vo}&2j!xi8=25HRN#=b)kiTpufz8Jh@f#?fQox-t^oL~{a5Rf7uV%0(#R}0UX ze{(`AcuYq;5%3YhAr8kMWFis3HX;a|$Pd`sAV~bd0f>B?;8_>HC2w$e4q!Ru$)Dej z=X?V4hgqNoA6GX@+px<6p0M-rtrH%aZ{@#rfmQ0bPRC4UB5&c(fX9=E`8QAKp&-z4 z?T)zyiYLs6hx0cZA`_b47$Y-Re`qJFq{nerwdT48ag}j2c=|XcPqtS`5KGP7HIU2Z z1gMdeada3T<_T39tQWkHj_yPQk9bPL^rAzLCLW3b9`Ov$87PqL&*q{aqK9E93&we* zsK#c9nhp~hgFk#ASU1&(VCJwKaZ0@J1ki#Et8I(|nh+_x)sx=_2!%-HPo39`3{ha~ zMPkPe&SyYIA&0o5bptbo#E%36#^ISG9~=dIM?Qy@0^1tD0jvrnR9FG9g(H!U4aUPq zN5O*_P6!WH8Ek6&;UM{v`SJ~Bxx*#|K4+b>f*D zauQ=a0iFrF2wF8VsEk=Pb|8R)G&T_w3KE2Z%r{_kPZH$eWA@Huv%FTufZgFTY(*{EKSWl{N7EBFX> z;_Woi>>xjbjTkvA!M;T7l+ebBTwr+_Coe36l#|I5Cy~k16OqYtV&Yha&V=zIM@Pi& zKTDDXN9i$1j*SbOGLql_I2#fH5-yr699Y0*GO#Zrx&J#_K_QU{keJ8Vf>SlH2=InN zrYa8R%-#sdfUOfH%v*E8^S; zoJA1FE6CL!XU%d4%PdY0fX3;%26^C&ETFC|W$5_P2SiRKWxOu*0y^Mq;%dX%fD2=D zy>Z}JmlYJm^27y#vr~Xu8Du3Kj}UiOkW!$BCupWhRHG2oh!kbKF)JdB6XX%h2eA@| zMX?g69}eE92U`#82=Fq!KRDus#{>&M0LH>8>8%2?rxNHyGC0&^l4z;~%5nl>IcNt2 z_FqkGf?NXwSsviH($z1R1>|g_zd_9ayp-?e8V~?pCReiYW(VWI|4iA&5OUrGa3nRR z8ifhWKxu3$$_UYigUO2$fJsnA3FH63Av6_i1w3)%G$=KL{^0`nG$xq_#YZHKM4=I& zd;>{?K0{}+Xd2|60yMx6I+#V$NE9ld3ev!HIGaGWgJ|f!Ad_N3`2(^Y;KzVgA|wrb zCPCW+G!5F;BWXkeg$C`=kTk%LK0#kHv_K)-fzM>t#iPS0v(_t+kwwCXg`Xg z(V?6LNh1=;1Slg$(f~g)6(s}koDLoLA=`n^3@E8U(f~gqlszD6fFJZ{HUwzk3uO8j z8d_FFB8>zs3DCbW8;AH2P&8m_K!SqpAQ}|XkbMC^3IVGRBD9}EwuAaYKb)XwM6`}T zB2Pfe1>hq0I0MZO(3o_zte9jX zMjuQX88ZfxOoD#7L1HE_$#f{~5}*-?6to?Hb`{0C~SUaGQq0|rA4uk_51*Kmo)}i?U8YW&r zzYfzd`k;}}aT3UnfsF?QOzZ^nprP%LL?JOTz6HjGcCW~JfWGi~CXxmmfrgeTpfS*K z63mSRrE$ojGh1_S!#9^H-#{hTJ)m%?OV_%VQj1=|7H(=jpt6GrQo2qp)m#R6l15C)wQp=bnX z!y-Tn z*m=;YSXt2-7~23+LFY|iJp##!;J9E6I&>I<08dA^ z192B412XutPUvs-~1xy4>!`LZ_4xAO;j!whm5hOZsf-%6#kLgRn*a2AMF>w;O z5jtN3u0=-Ybwm=AiO&CkOViQ0Jm`yAKOlZ+Uj;T!hYsYCItLmePk;qDgJ3(rkA{h1 zAdSHI3|LYy^B@zc=$sma4QxJ1CShYSnMB9<5gC9%$3!xjiq1jB{IOsXnio~1dQ)9 z=)gfxSeQ&ERKg&ja}W;DzC{9=JbG><@S7nzj|G994jmK-@B`TuTBg9RKr(=8N1-s# zc{{L4209)=qU!26yfu3Z3qBaYTX8sC@CjgsN-K;4JUQSS z&;655n3#F|`BWU9OyNNRn{sVa6#}oKW Rf '0'); - else - if (rising_edge(i_clock)) then - if (i_sync_reset = '1') then - shift_register <= (OTHERS => '0'); - elsif (i_enable = '1') then - if (i_shift = '0') then - shift_register(0) <= i_datain XOR shift_register(15); - shift_register(4 downto 1) <= shift_register(3 downto 0); - shift_register(5) <= shift_register(4) XOR i_datain XOR shift_register(15); - shift_register(11 downto 6) <= shift_register(10 downto 5); - shift_register(12) <= shift_register(11) XOR i_datain XOR shift_register(15); - shift_register(15 downto 13) <= shift_register(14 downto 12); - else -- shift CRC out (no more calculation now) - shift_register(15 downto 1) <= shift_register(14 downto 0); - shift_register(0) <= '0'; - end if; - end if; - end if; - end if; - end process; - - o_dataout <= shift_register(15); - o_crcout <= shift_register; -end rtl; - - - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_CRC7_Generator.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_CRC7_Generator.vhd deleted file mode 100644 index 3ae9430..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_CRC7_Generator.vhd +++ /dev/null @@ -1,76 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - ---------------------------------------------------------------------------------------- --- This generates the necessary 7-CRC for Command and Response --- Implementation: serial input/parallel output --- --- When input stream ends, the crcout output is the CRC checksum for the input stream. --- --- NOTES/REVISIONS: ---------------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity Altera_UP_SD_CRC7_Generator is - - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(6 downto 0) - ); - -end entity; - -architecture rtl of Altera_UP_SD_CRC7_Generator is - - -- Local wires - -- REGISTERED - signal shift_register : std_logic_vector(6 downto 0); -begin - - process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - shift_register <= (OTHERS => '0'); - else - if (rising_edge(i_clock)) then - if (i_enable = '1') then - if (i_shift = '0') then - shift_register(0) <= i_datain XOR shift_register(6); - shift_register(1) <= shift_register(0); - shift_register(2) <= shift_register(1); - shift_register(3) <= shift_register(2) XOR i_datain XOR shift_register(6); - shift_register(4) <= shift_register(3); - shift_register(5) <= shift_register(4); - shift_register(6) <= shift_register(5); - else -- shift CRC out (no more calculation now) - shift_register(0) <= '0'; - shift_register(6 downto 1) <= shift_register(5 downto 0); - end if; - end if; - end if; - end if; - end process; - - o_dataout <= shift_register(6); - o_crcout <= shift_register; -end rtl; - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd deleted file mode 100644 index f9bb3b0..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd +++ /dev/null @@ -1,570 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - -------------------------------------------------------------------------------------- --- This module takes a command ID and data, and generates a 48-bit message for it. --- It will first check if the command is a valid 48-bit command and produce the --- following outputs: --- 1. o_dataout -> a single bit output that produces the message to be sent to the --- SD card one bit at a time. Every time the i_message_bit_out input --- is high and the i_clock has a positive edge, a new bit is produced. --- 2. o_message_done -> a signal that is asserted high when the entire message has been --- produced through the o_dataout output. --- 3. o_valid -> is a signal that is asserted high if the specified message is valid. --- 4. o_response_type -> indicates the command response type. --- 5. o_returning_ocr -> the response from the SD card will contain the OCR register --- 6. o_returning_cid -> the response from the SD card will contain the CID register --- 7. o_returning_rca -> the response from the SD card will contain the RCA register --- 8. o_returning_csd -> the response from the SD card will contain the CSD register --- 9. o_data_read -> asserted when the command being sent is a data read command. --- 10. o_data_write -> asserted when the command being sent is a data write command. --- 11. o_wait_cmd_busy -> is set high when the response to this command will be --- followed by a busy signal. --- --- NOTES/REVISIONS: -------------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_48_bit_Command_Generator is - generic ( - -- Basic commands - COMMAND_0_GO_IDLE : STD_LOGIC_VECTOR(5 downto 0) := "000000"; - COMMAND_2_ALL_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "000010"; - COMMAND_3_SEND_RCA : STD_LOGIC_VECTOR(5 downto 0) := "000011"; - COMMAND_4_SET_DSR : STD_LOGIC_VECTOR(5 downto 0) := "000100"; - COMMAND_6_SWITCH_FUNCTION : STD_LOGIC_VECTOR(5 downto 0) := "000110"; - COMMAND_7_SELECT_CARD : STD_LOGIC_VECTOR(5 downto 0) := "000111"; - COMMAND_9_SEND_CSD : STD_LOGIC_VECTOR(5 downto 0) := "001001"; - COMMAND_10_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "001010"; - COMMAND_12_STOP_TRANSMISSION : STD_LOGIC_VECTOR(5 downto 0) := "001100"; - COMMAND_13_SEND_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101"; - COMMAND_15_GO_INACTIVE : STD_LOGIC_VECTOR(5 downto 0) := "001111"; - -- Block oriented read/write/lock commands - COMMAND_16_SET_BLOCK_LENGTH : STD_LOGIC_VECTOR(5 downto 0) := "010000"; - -- Block oriented read commands - COMMAND_17_READ_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "010001"; - COMMAND_18_READ_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010010"; - -- Block oriented write commands - COMMAND_24_WRITE_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "011000"; - COMMAND_25_WRITE_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "011001"; - COMMAND_27_PROGRAM_CSD : STD_LOGIC_VECTOR(5 downto 0) := "011011"; - -- Block oriented write-protection commands - COMMAND_28_SET_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011100"; - COMMAND_29_CLEAR_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011101"; - COMMAND_30_SEND_PROTECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "011110"; - -- Erase commands - COMMAND_32_ERASE_BLOCK_START : STD_LOGIC_VECTOR(5 downto 0) := "100000"; - COMMAND_33_ERASE_BLOCK_END : STD_LOGIC_VECTOR(5 downto 0) := "100001"; - COMMAND_38_ERASE_SELECTED_GROUPS: STD_LOGIC_VECTOR(5 downto 0) := "100110"; - -- Block lock commands - COMMAND_42_LOCK_UNLOCK : STD_LOGIC_VECTOR(5 downto 0) := "101010"; - -- Command Type Settings - COMMAND_55_APP_CMD : STD_LOGIC_VECTOR(5 downto 0) := "110111"; - COMMAND_56_GEN_CMD : STD_LOGIC_VECTOR(5 downto 0) := "111000"; - -- Application Specific commands - must be preceeded with command 55. - ACOMMAND_6_SET_BUS_WIDTH : STD_LOGIC_VECTOR(5 downto 0) := "000110"; - ACOMMAND_13_SD_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101"; - ACOMMAND_22_SEND_NUM_WR_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010100"; - ACOMMAND_23_SET_BLK_ERASE_COUNT : STD_LOGIC_VECTOR(5 downto 0) := "010101"; - ACOMMAND_41_SEND_OP_CONDITION : STD_LOGIC_VECTOR(5 downto 0) := "101001"; - ACOMMAND_42_SET_CLR_CARD_DETECT : STD_LOGIC_VECTOR(5 downto 0) := "101010"; - ACOMMAND_51_SEND_SCR : STD_LOGIC_VECTOR(5 downto 0) := "110011"; - -- First custom_command - FIRST_NON_PREDEFINED_COMMAND : STD_LOGIC_VECTOR(3 downto 0) := "1010" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_message_bit_out : in std_logic; - i_command_ID : in std_logic_vector(5 downto 0); - i_argument : in std_logic_vector(31 downto 0); - i_predefined_message : in std_logic_vector(3 downto 0); - i_generate : in std_logic; - i_DSR : in std_logic_vector(15 downto 0); - i_OCR : in std_logic_vector(31 downto 0); - i_RCA : in std_logic_vector(15 downto 0); - o_dataout : out std_logic; - o_message_done : out std_logic; - o_valid : out std_logic; - o_returning_ocr : out std_logic; - o_returning_cid : out std_logic; - o_returning_rca : out std_logic; - o_returning_csd : out std_logic; - o_returning_status : out std_logic; - o_data_read : out std_logic; - o_data_write : out std_logic; - o_wait_cmd_busy : out std_logic; - o_last_cmd_was_55 : out std_logic; - o_response_type : out std_logic_vector(2 downto 0) - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_48_bit_Command_Generator is - - component Altera_UP_SD_CRC7_Generator - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(6 downto 0) - ); - end component; - - -- Local wires - -- REGISTERED - signal counter : std_logic_vector(6 downto 0); - signal last_command_id : std_logic_vector(5 downto 0); - signal message_bits : std_logic_vector(39 downto 0); - signal last_command_sent_was_CMD55, valid : std_logic; - signal bit_to_send, sending_CRC, command_valid : std_logic; - signal returning_cid_reg, returning_rca_reg, returning_csd_reg, returning_dsr_reg, returning_ocr_reg, returning_status_reg : std_logic; - -- UNREGISTERED - signal temp_4_bits : std_logic_vector(3 downto 0); - signal message_done, CRC_generator_out, produce_next_bit : std_logic; - signal app_specific_valid, regular_command_valid : std_logic; - signal response_type, response_type_reg : std_logic_vector(2 downto 0); - signal cmd_argument : std_logic_vector(31 downto 0); -begin - -- This set of bits is necessary to allow the SD card to accept a VDD level for communication. - temp_4_bits <= "1111" when ((i_OCR(23) = '1') or (i_OCR(22) = '1') or (i_OCR(21) = '1') or (i_OCR(20) = '1')) else "0000"; - -- Generate the bits to be sent to the SD card. These bits must pass through the CRC generator - -- to produce error checking code. The error checking code will follow the message. The message terminates with - -- a logic '1'. Total message length is 48 bits. - message_data_generator: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - message_bits <= (OTHERS => '0'); - else - if (rising_edge(i_clock)) then - if (i_generate = '1') then - -- Store type of a response. - response_type_reg <= response_type; - -- Generate a message. Please note that the predefined messages are used for initialization. - -- If executed in sequence, they will initialize the SD card to work correctly. Only once these - -- instructions are completed can the data transfer begin. - case (i_predefined_message) is - when "0000" => - -- Generate a predefined message - CMD0. - message_bits <= ("01" & COMMAND_0_GO_IDLE & "00000000000000000000000000000000"); - when "0001" => - -- Generate a predefined message - CMD55. - message_bits <= ("01" & COMMAND_55_APP_CMD & "0000000000000000" & "0000000000000000"); - when "0010" => - -- Generate a predefined message - ACMD41. - message_bits <= ("01" & ACOMMAND_41_SEND_OP_CONDITION & "0000" & temp_4_bits & "000" & i_OCR(20) & "00000000000000000000"); - when "0011" => - -- Generate a predefined message - CMD2. - message_bits <= ("01" & COMMAND_2_ALL_SEND_CID & "00000000000000000000000000000000"); - when "0100" => - -- Generate a predefined message - CMD3. - message_bits <= ("01" & COMMAND_3_SEND_RCA & "00000000000000000000000000000000"); - when "0101" => - -- Generate a predefined message - CMD9. - message_bits <= ("01" & COMMAND_9_SEND_CSD & i_RCA & "0000000000000000"); - when "0110" => - -- Generate a predefined message - CMD4. - message_bits <= ("01" & COMMAND_4_SET_DSR & i_DSR & "0000000000000000"); - when "0111" => - -- Generate a predefined message - CMD16. Set block length to 512. - message_bits <= ("01" & COMMAND_16_SET_BLOCK_LENGTH & "0000000000000000" & "0000001000000000" ); - when "1000" => - -- Generate a predefined message - CMD7. Select the card so we can access it's data. - message_bits <= ("01" & COMMAND_7_SELECT_CARD & i_RCA & "0000001000000000" ); - when "1001" => - -- Generate a predefined message - CMD13. Send SD card status. - message_bits <= ("01" & COMMAND_13_SEND_STATUS & i_RCA & "0000000000000000"); - - when others => - -- Generate a custom message - message_bits <= ("01" & i_command_ID & cmd_argument); - end case; - else - -- Shift bits out as needed - if (produce_next_bit = '1') then - -- Shift message bits. - message_bits(39 downto 1) <= message_bits(38 downto 0); - message_bits(0) <= '0'; - end if; - end if; - end if; - end if; - end process; - - -- Generate command argument based on the command_ID. For most commands, the argument is user specified. - -- For some commands, it is necessary to send a particular SD Card register contents. Hence, these contents are - -- sent instead of the user data. - argument_generator: process (i_command_ID, last_command_sent_was_CMD55, i_generate, i_RCA, i_DSR, i_OCR, i_argument) - begin - cmd_argument <= i_argument; - if (i_generate = '1') then - case (i_command_ID) is - when COMMAND_4_SET_DSR => - cmd_argument <= i_DSR & i_argument(15 downto 0); - when COMMAND_7_SELECT_CARD => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when COMMAND_9_SEND_CSD => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when COMMAND_10_SEND_CID => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when COMMAND_13_SEND_STATUS => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when COMMAND_15_GO_INACTIVE => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when COMMAND_55_APP_CMD => - cmd_argument <= i_RCA & i_argument(15 downto 0); - when ACOMMAND_41_SEND_OP_CONDITION => - if (last_command_sent_was_CMD55 = '1') then - cmd_argument <= i_OCR; - end if; - when others => - cmd_argument <= i_argument; - end case; - end if; - end process; - - -- Validate the message ID before sending it out. - command_validator: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - command_valid <= '0'; - else - if (rising_edge(i_clock)) then - if (i_generate = '1') then - if (("0" & i_predefined_message) >= ("0" & FIRST_NON_PREDEFINED_COMMAND)) then - -- Check the custom message - if (last_command_sent_was_CMD55 = '1') then - -- Check the application specific messages - command_valid <= app_specific_valid; - else - -- Check the default messages. - command_valid <= regular_command_valid; - end if; - else - -- A command is valid if the message is predefined. - command_valid <= '1'; - end if; - end if; - end if; - end if; - end process; - - -- Registers that indicate that the command sent will return contents of a control register. - -- The contents of the response should therefore be stored in the appropriate register. - responses_with_control_regs: process(i_clock, i_reset_n, last_command_sent_was_CMD55, last_command_id, message_done) - begin - if (i_reset_n = '0') then - returning_ocr_reg <= '0'; - returning_cid_reg <= '0'; - returning_rca_reg <= '0'; - returning_csd_reg <= '0'; - returning_status_reg <= '0'; - elsif (rising_edge(i_clock)) then - if (i_generate = '1') then - returning_ocr_reg <= '0'; - returning_cid_reg <= '0'; - returning_rca_reg <= '0'; - returning_csd_reg <= '0'; - returning_status_reg <= '0'; - elsif (message_done = '1') then - -- OCR - if ((last_command_sent_was_CMD55 = '1') and (last_command_id = ACOMMAND_41_SEND_OP_CONDITION)) then - returning_ocr_reg <= '1'; - end if; - -- CID - if (last_command_id = COMMAND_2_ALL_SEND_CID) then - returning_cid_reg <= '1'; - end if; - -- RCA - if (last_command_id = COMMAND_3_SEND_RCA) then - returning_rca_reg <= '1'; - end if; - -- CSD - if (last_command_id = COMMAND_9_SEND_CSD) then - returning_csd_reg <= '1'; - end if; - -- Status - if ((last_command_sent_was_CMD55 = '0') and (last_command_id = COMMAND_13_SEND_STATUS)) then - returning_status_reg <= '1'; - end if; - - end if; - end if; - end process; - - -- Count the number of bits sent using a counter. - sent_bit_counter: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter) - begin - if (i_reset_n = '0') then - counter <= (OTHERS => '0'); - else - if (rising_edge(i_clock)) then - if (i_generate = '1') then - -- Reset the counter indicating the number of bits produced. - counter <= "0000000"; - else - if (produce_next_bit = '1') then - -- Update the number of message bits sent. - counter <= counter + '1'; - end if; - end if; - end if; - end if; - end process; - - -- Select the source for the output data to be either the message data or the CRC bits. - source_selector: process(i_clock, i_reset_n, i_generate) - begin - if (i_reset_n = '0') then - sending_CRC <= '0'; - else - if (rising_edge(i_clock)) then - if (i_generate = '1') then - -- Set sending CRC flag to 0. - sending_CRC <= '0'; - else - -- If this is the last bit being sent, then bits that follow are the CRC bits. - if (counter = "0101000") then - sending_CRC <= '1'; - end if; - end if; - end if; - end if; - end process; - - -- When the message is sent, store its ID. In a special case when CMD55 is sent, the next command can be an application - -- specific command. We need to check those command IDs to verify the validity of the message. - CMD55_recognizer: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter, message_done, last_command_id) - begin - if (i_reset_n = '0') then - last_command_sent_was_CMD55 <= '0'; - else - if (rising_edge(i_clock)) then - if (i_generate = '0') then - -- Store the ID of the current command. - if (produce_next_bit = '1') then - if (counter = "0000000") then - last_command_id <= message_bits(37 downto 32); - end if; - end if; - -- When message has been sent then check if it was CMD55. - if (message_done = '1') then - if (last_command_id = COMMAND_55_APP_CMD) then - last_command_sent_was_CMD55 <= '1'; - else - last_command_sent_was_CMD55 <= '0'; - end if; - end if; - end if; - end if; - end if; - end process; - - -- Instantiate a CRC7 generator. Message bits will pass through it to create the CRC code for the message. - CRC7_Gen: Altera_UP_SD_CRC7_Generator PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_enable => i_message_bit_out, - i_shift => sending_CRC, - i_datain => message_bits(39), - o_dataout => CRC_generator_out - ); - - -- Define the source of the data produced by this module, depending on the counter value and the sending_CRC register state. - data_bit_register: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter) - begin - if (i_reset_n = '0') then - bit_to_send <= '1'; - else - if (rising_edge(i_clock)) then - if (i_generate = '1') then - bit_to_send <= '1'; - elsif (produce_next_bit = '1') then - -- Send data to output. - if (sending_CRC = '0') then - -- Send message bits - bit_to_send <= message_bits(39); - else - -- Send CRC bits - if ((counter = "0101111") or (counter = "0110000")) then - -- At the end of CRC bits put a 1. - bit_to_send <= '1'; - else - bit_to_send <= CRC_generator_out; - end if; - end if; - end if; - end if; - end if; - end process; - - -- Define conditions to produce the next message bit on the module output port o_dataout. - produce_next_bit <= i_message_bit_out and (not message_done); - -- Message is done when the last bit appears at the output. - message_done <= '1' when (counter = "0110001") else '0'; - -- Check the application specific messages - app_specific_valid <= '1' when ( - --(i_command_ID = COMMAND_0_GO_IDLE) or - (i_command_ID = COMMAND_2_ALL_SEND_CID) or - (i_command_ID = COMMAND_3_SEND_RCA) or - (i_command_ID = COMMAND_4_SET_DSR) or - --(i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or - --(i_command_ID = COMMAND_7_SELECT_CARD) or - (i_command_ID = COMMAND_9_SEND_CSD) or - (i_command_ID = COMMAND_10_SEND_CID) or - --(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or - (i_command_ID = ACOMMAND_13_SD_STATUS) or - --(i_command_ID = COMMAND_15_GO_INACTIVE) or - --(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or - (i_command_ID = COMMAND_17_READ_BLOCK) or - --(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or - (i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or - (i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or - (i_command_ID = COMMAND_24_WRITE_BLOCK) or - (i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or - (i_command_ID = COMMAND_27_PROGRAM_CSD) or - (i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or - (i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or - (i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or - (i_command_ID = COMMAND_32_ERASE_BLOCK_START) or - (i_command_ID = COMMAND_33_ERASE_BLOCK_END) or - (i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or - (i_command_ID = ACOMMAND_41_SEND_OP_CONDITION) or - (i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or - (i_command_ID = ACOMMAND_51_SEND_SCR) or - (i_command_ID = COMMAND_55_APP_CMD) or - (i_command_ID = COMMAND_56_GEN_CMD) - ) - else '0'; - -- Check the default messages. - regular_command_valid <= '1' when ( - ------------------------------------------------------- - -- Disabled to prevent malfunction of the core - ------------------------------------------------------- - --(i_command_ID = COMMAND_0_GO_IDLE) or - --(i_command_ID = COMMAND_6_SWITCH_FUNCTION) or - --(i_command_ID = COMMAND_7_SELECT_CARD) or - --(i_command_ID = COMMAND_15_GO_INACTIVE) or - --(i_command_ID = COMMAND_27_PROGRAM_CSD) or - --(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or - --(i_command_ID = COMMAND_42_LOCK_UNLOCK) or - ------------------------------------------------------- - (i_command_ID = COMMAND_2_ALL_SEND_CID) or - (i_command_ID = COMMAND_3_SEND_RCA) or - (i_command_ID = COMMAND_4_SET_DSR) or - (i_command_ID = COMMAND_9_SEND_CSD) or - (i_command_ID = COMMAND_10_SEND_CID) or - (i_command_ID = COMMAND_13_SEND_STATUS) or - ------------------------------------------------------- - -- Disabled to simplify the circuit - ------------------------------------------------------- - --(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or - --(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or - --(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or - --(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or - ------------------------------------------------------- - (i_command_ID = COMMAND_17_READ_BLOCK) or - (i_command_ID = COMMAND_24_WRITE_BLOCK) or - (i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or - (i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or - (i_command_ID = COMMAND_32_ERASE_BLOCK_START) or - (i_command_ID = COMMAND_33_ERASE_BLOCK_END) or - (i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or - (i_command_ID = COMMAND_55_APP_CMD) or - (i_command_ID = COMMAND_56_GEN_CMD) - ) - else '0'; - - response_type <= "001" when -- Wait for type 1 response when - ( - (i_predefined_message = "0001") or - (i_predefined_message = "0111") or - (i_predefined_message = "1000") or - (i_predefined_message = "1001") or - ((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and - ((i_command_ID = COMMAND_6_SWITCH_FUNCTION) or - (i_command_ID = COMMAND_7_SELECT_CARD) or - (i_command_ID = COMMAND_12_STOP_TRANSMISSION) or - (i_command_ID = COMMAND_13_SEND_STATUS) or - (i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or - (i_command_ID = COMMAND_17_READ_BLOCK) or - (i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or - (i_command_ID = COMMAND_24_WRITE_BLOCK) or - (i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or - (i_command_ID = COMMAND_27_PROGRAM_CSD) or - (i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or - (i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or - (i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or - (i_command_ID = COMMAND_32_ERASE_BLOCK_START) or - (i_command_ID = COMMAND_33_ERASE_BLOCK_END) or - (i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or - (i_command_ID = COMMAND_42_LOCK_UNLOCK) or - (i_command_ID = COMMAND_55_APP_CMD) or - (i_command_ID = COMMAND_56_GEN_CMD) or - ((last_command_sent_was_CMD55 = '1') and - ((i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or - (i_command_ID = ACOMMAND_13_SD_STATUS) or - (i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or - (i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or - (i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or - (i_command_ID = ACOMMAND_51_SEND_SCR))))) - ) else - "010" when -- Wait for type 2 response when - ( - ((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and - ((i_command_ID = COMMAND_2_ALL_SEND_CID) or - (i_command_ID = COMMAND_9_SEND_CSD) or - (i_command_ID = COMMAND_10_SEND_CID))) or - (i_predefined_message = "0011") or - (i_predefined_message = "0101") - ) else - "011" when -- Wait for type 3 response when - ( - ((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (last_command_sent_was_CMD55 = '1') and (i_command_ID = ACOMMAND_41_SEND_OP_CONDITION)) or - (i_predefined_message = "0010") - ) else - "110" when -- Wait for type 6 response when - (((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (i_command_ID = COMMAND_3_SEND_RCA)) or - (i_predefined_message = "0100")) - else "000"; -- Otherwise there is no response pending. - - -- Define circuit outputs - o_message_done <= message_done; - o_response_type <= response_type_reg; - o_valid <= command_valid; - o_dataout <= bit_to_send; - o_returning_ocr <= returning_ocr_reg; - o_returning_cid <= returning_cid_reg; - o_returning_rca <= returning_rca_reg; - o_returning_csd <= returning_csd_reg; - o_returning_status <= returning_status_reg; - o_data_read <= '1' when (last_command_id = COMMAND_17_READ_BLOCK) else '0'; - o_data_write <= '1' when (last_command_id = COMMAND_24_WRITE_BLOCK) else '0'; - o_last_cmd_was_55 <= last_command_sent_was_CMD55; - o_wait_cmd_busy <= '1' when ( - (last_command_id = COMMAND_7_SELECT_CARD) or - (last_command_id = COMMAND_12_STOP_TRANSMISSION) or - (last_command_id = COMMAND_28_SET_WRITE_PROTECT) or - (last_command_id = COMMAND_29_CLEAR_WRITE_PROTECT) or - (last_command_id = COMMAND_38_ERASE_SELECTED_GROUPS)) - else '0'; -end rtl; \ No newline at end of file diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Avalon_Interface.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Avalon_Interface.vhd deleted file mode 100644 index 9900419..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Avalon_Interface.vhd +++ /dev/null @@ -1,518 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - ----------------------------------------------------------------------------------------------------------------- --- This is an FSM that allows access to the SD Card IP core via the Avalon Interconnect. --- --- This module takes a range of addresses on the Avalon Interconnect. Specifically: --- - 0x00000000 to 0x000001ff --- word addressable buffer space. The data to be written to the SD card as well --- as data read from the SD card can be accessed here. --- --- - 0x00000200 to 0x0000020f --- 128-bit containing the Card Identification Number. The meaning of each bit is described in the --- SD Card Physical Layer Specification Document. --- --- - 0x00000210 to 0x0000021f --- 128-bit register containing Card Specific Data. The meaning of each bit is described in the --- SD Card Physical Layer Specification Document. --- --- - 0x00000220 to 0x00000223 --- 32-bit register containing Operating Conditions Register. The meaning of each bit is described --- in the SD Card Physical Layer Specification Document. --- --- - 0x00000224 to 0x00000227 --- 32-bit register containing the Status Register. The meaning of each bit is described --- in the SD Card Physical Layer Specification Document. However, if the card is not connected or the --- status register could not be read from the SD card, this register will contain invalid data. In such --- a case, wait for a card to be connected by checking the Auxiliary Status Register (UP Core Specific), and --- a command 13 (SEND_STATUS) to update the contents of this register when possible. If a card is connected then --- the Auxiliary Status Register can be polled until such a time that Status Register is valid, as the SD Card --- interface circuit updates the status register approximately every 0.1 of a second, and after every command --- is executed. --- --- - 0x00000228 to 0x000000229 --- 16-bit register containing the Relative Card Address. This address uniquely identifies a card --- connected to the SD Card slot. --- --- - 0x0000022C to 0x00000022F --- 32-bit register used to set the argument for a command to be sent to the SD Card. --- --- - 0x00000230 to 0x000000231 --- 16-bit register used to send a command to an SD card. Once written, the interface will issue the --- specified command. The meaning of each bit in this register is as follows: --- - 0-5 - command index. This is a command index as per SD Card Physical Layer specification document. --- - 6 - use most recent RCA. If this bit is set, the command argument will be replaced with the contents of --- the Relative Card Address register, followed by 16 0s. For commands that require RCA to be sent as --- an argument, this bit should be set and users will not need to specify RCA themselves. --- - 7-15 - currently unused bits. They will be ignored. --- NOTE: If a specified command is determined to be invalid, or the card is not connected to the SD Card socket, --- then the SD Card interface circuit will not issue the command. --- --- - 0x00000234 to 0x00000235 --- 16-bit register with Auxiliary Status Register. This is the Altera UP SD Card Interface status. The meaning of --- the bits is as follows: --- - 0 - last command valid - Set to '1' if the most recently user issued command was valid. --- - 1 - card connected - Set to '1' if at present an SD card --- - 2 - execution in progress - Set to '1' if the command recently issued is currently being executed. If true, --- then the current state of SD Card registers should be ignored. --- - 3 - status register valid - Set to '1' if the status register is valid. --- - 4 - command timed out - Set to '1' if the last command timed out. --- - 5 - crc failed - Set to '1' if the last command failed a CRC check. --- - 6-15 - unused. --- --- - 0x00000238 to 0x0000023B --- 32-bit register containing the 32-bit R1 response message. Use it to test validity of the response. This register --- will not store the response to SEND_STATUS command. Insteand, read the SD_status register at location 0x00000224. --- --- Date: December 8, 2008 --- NOTES/REVISIONS: --- December 17, 2008 - added R1 response register to the core. It is now available at 0x00000238. ----------------------------------------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_Avalon_Interface is - generic ( - ADDRESS_BUFFER : std_logic_vector(7 downto 0) := "00000000"; - ADDRESS_CID : std_logic_vector(7 downto 0) := "10000000"; - ADDRESS_CSD : std_logic_vector(7 downto 0) := "10000100"; - ADDRESS_OCR : std_logic_vector(7 downto 0) := "10001000"; - ADDRESS_SR : std_logic_vector(7 downto 0) := "10001001"; - ADDRESS_RCA : std_logic_vector(7 downto 0) := "10001010"; - ADDRESS_ARGUMENT : std_logic_vector(7 downto 0) := "10001011"; - ADDRESS_COMMAND : std_logic_vector(7 downto 0) := "10001100"; - ADDRESS_ASR : std_logic_vector(7 downto 0) := "10001101"; - ADDRESS_R1 : std_logic_vector(7 downto 0) := "10001110" - ); - port - ( - -- Clock and Reset signals - i_clock : in STD_LOGIC; - i_reset_n : in STD_LOGIC; -- Asynchronous reset - - -- Avalon Interconnect Signals - i_avalon_address : in STD_LOGIC_VECTOR(7 downto 0); - i_avalon_chip_select : in STD_LOGIC; - i_avalon_read : in STD_LOGIC; - i_avalon_write : in STD_LOGIC; - i_avalon_byteenable : in STD_LOGIC_VECTOR(3 downto 0); - i_avalon_writedata : in STD_LOGIC_VECTOR(31 downto 0); - o_avalon_readdata : out STD_LOGIC_VECTOR(31 downto 0); - o_avalon_waitrequest : out STD_LOGIC; - - -- SD Card interface ports - b_SD_cmd : inout STD_LOGIC; - b_SD_dat : inout STD_LOGIC; - b_SD_dat3 : inout STD_LOGIC; - o_SD_clock : out STD_LOGIC - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_Avalon_Interface is - - component Altera_UP_SD_Card_Interface is - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - - -- Command interface - b_SD_cmd : inout std_logic; - b_SD_dat : inout std_logic; - b_SD_dat3 : inout std_logic; - i_command_ID : in std_logic_vector(5 downto 0); - i_argument : in std_logic_vector(31 downto 0); - i_user_command_ready : in std_logic; - - o_SD_clock : out std_logic; - o_card_connected : out std_logic; - o_command_completed : out std_logic; - o_command_valid : out std_logic; - o_command_timed_out : out std_logic; - o_command_crc_failed : out std_logic; - - -- Buffer access - i_buffer_enable : in std_logic; - i_buffer_address : in std_logic_vector(7 downto 0); - i_buffer_write : in std_logic; - i_buffer_data_in : in std_logic_vector(15 downto 0); - o_buffer_data_out : out std_logic_vector(15 downto 0); - - -- Show SD Card registers as outputs - o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0); - o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0); - o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0); - o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0); - o_SD_REG_status_register : out std_logic_vector(31 downto 0); - o_SD_REG_response_R1 : out std_logic_vector(31 downto 0); - o_SD_REG_status_register_valid : out std_logic - ); - end component; - - -- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state - -- of the switches. - type buffer_state_type is ( s_RESET, s_WAIT_REQUEST, s_READ_FIRST_WORD, s_READ_SECOND_WORD, s_RECEIVE_FIRST_WORD, - s_RECEIVE_SECOND_WORD, s_WR_READ_FIRST_WORD, s_WR_READ_FIRST_WORD_DELAY, s_WRITE_FIRST_BYTE, s_WRITE_FIRST_WORD, - s_WR_READ_SECOND_WORD, s_WR_READ_SECOND_WORD_DELAY, s_WRITE_SECOND_BYTE, s_WRITE_SECOND_WORD, s_WAIT_RELEASE); - type command_state_type is (s_RESET_CMD, s_WAIT_COMMAND, s_WAIT_RESPONSE, s_UPDATE_AUX_SR); - - -- Register to hold the current state - signal current_state : buffer_state_type; - signal next_state : buffer_state_type; - signal current_cmd_state : command_state_type; - signal next_cmd_state : command_state_type; - - ------------------- - -- Local signals - ------------------- - -- REGISTERED - signal auxiliary_status_reg : std_logic_vector(5 downto 0); - signal buffer_data_out_reg : std_logic_vector(31 downto 0); - signal buffer_data_in_reg : std_logic_vector(31 downto 0); - signal buffer_data_out : std_logic_vector(15 downto 0); - signal command_ID_reg : std_logic_vector( 5 downto 0); - signal argument_reg : std_logic_vector(31 downto 0); - signal avalon_address : std_logic_vector(7 downto 0); - signal avalon_byteenable : std_logic_vector(3 downto 0); - -- UNREGISTERED - signal buffer_address : std_logic_vector(7 downto 0); - signal buffer_data_in : std_logic_vector(15 downto 0); - signal SD_REG_card_identification_number : std_logic_vector(127 downto 0); - signal SD_REG_relative_card_address : std_logic_vector(15 downto 0); - signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0); - signal SD_REG_card_specific_data : std_logic_vector(127 downto 0); - signal SD_REG_status_register : std_logic_vector(31 downto 0); - signal SD_REG_response_R1 : std_logic_vector(31 downto 0); - signal command_ready, send_command_ready, - command_valid, command_completed, card_connected : std_logic; - signal status_reg_valid, argument_write : std_logic; - signal read_buffer_request, write_buffer_request, buffer_enable, buffer_write : std_logic; - signal command_timed_out, command_crc_failed : std_logic; - -begin - -- Define state transitions for buffer interface. - state_transitions_buffer: process (current_state, read_buffer_request, write_buffer_request, i_avalon_byteenable, avalon_byteenable) - begin - case current_state is - when s_RESET => - -- Reset local registers. - next_state <= s_WAIT_REQUEST; - - when s_WAIT_REQUEST => - -- Wait for a user command. - if (read_buffer_request = '1') then - next_state <= s_READ_FIRST_WORD; - elsif (write_buffer_request = '1') then - if ((i_avalon_byteenable(1) = '1') and (i_avalon_byteenable(0) = '1')) then - next_state <= s_WRITE_FIRST_WORD; - elsif ((i_avalon_byteenable(3) = '1') and (i_avalon_byteenable(2) = '1')) then - next_state <= s_WRITE_SECOND_WORD; - elsif ((i_avalon_byteenable(1) = '1') or (i_avalon_byteenable(0) = '1')) then - next_state <= s_WR_READ_FIRST_WORD; - elsif ((i_avalon_byteenable(3) = '1') or (i_avalon_byteenable(2) = '1')) then - next_state <= s_WR_READ_SECOND_WORD; - else - next_state <= s_WAIT_REQUEST; - end if; - else - next_state <= s_WAIT_REQUEST; - end if; - - when s_READ_FIRST_WORD => - -- Read first 16-bit word from the buffer - next_state <= s_READ_SECOND_WORD; - - when s_READ_SECOND_WORD => - -- Read second 16-bit word from the buffer - next_state <= s_RECEIVE_FIRST_WORD; - - when s_RECEIVE_FIRST_WORD => - -- Store first word read - next_state <= s_RECEIVE_SECOND_WORD; - - when s_RECEIVE_SECOND_WORD => - -- Store second word read - next_state <= s_WAIT_RELEASE; - - -- The following states control writing to the buffer. To write a single byte it is necessary to read a - -- word and then write it back, changing only on of its bytes. - when s_WR_READ_FIRST_WORD => - -- Read first 16-bit word from the buffer - next_state <= s_WR_READ_FIRST_WORD_DELAY; - - when s_WR_READ_FIRST_WORD_DELAY => - -- Wait a cycle - next_state <= s_WRITE_FIRST_BYTE; - - when s_WRITE_FIRST_BYTE => - -- Write one of the bytes in the given word into the memory. - if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then - next_state <= s_WRITE_SECOND_WORD; - elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then - next_state <= s_WR_READ_SECOND_WORD; - else - next_state <= s_WAIT_RELEASE; - end if; - - when s_WR_READ_SECOND_WORD => - -- Read second 16-bit word from the buffer - next_state <= s_WR_READ_SECOND_WORD_DELAY; - - when s_WR_READ_SECOND_WORD_DELAY => - -- Wait a cycle - next_state <= s_WRITE_SECOND_BYTE; - - when s_WRITE_SECOND_BYTE => - -- Write one of the bytes in the given word into the memory. - next_state <= s_WAIT_RELEASE; - - -- Full word writing can be done without reading the word in the first place. - when s_WRITE_FIRST_WORD => - -- Write the first word into memory - if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then - next_state <= s_WRITE_SECOND_WORD; - elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then - next_state <= s_WR_READ_SECOND_WORD; - else - next_state <= s_WAIT_RELEASE; - end if; - - when s_WRITE_SECOND_WORD => - -- Write the second word into memory - next_state <= s_WAIT_RELEASE; - - when s_WAIT_RELEASE => - -- if ((read_buffer_request = '1') or (write_buffer_request = '1')) then - -- next_state <= s_WAIT_RELEASE; - -- else - next_state <= s_WAIT_REQUEST; - -- end if; - - when others => - -- Make sure to start in the reset state if the circuit powers up in an odd state. - next_state <= s_RESET; - end case; - end process; - - -- State Registers - buffer_state_regs: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - current_state <= s_RESET; - elsif(rising_edge(i_clock)) then - current_state <= next_state; - end if; - end process; - - helper_regs: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - avalon_address <= (OTHERS => '0'); - buffer_data_out_reg <= (OTHERS => '0'); - buffer_data_in_reg <= (OTHERS => '0'); - avalon_byteenable <= (OTHERS => '0'); - elsif(rising_edge(i_clock)) then - if (current_state = s_WAIT_REQUEST) then - avalon_address <= i_avalon_address; - buffer_data_in_reg <= i_avalon_writedata; - avalon_byteenable <= i_avalon_byteenable; - end if; - if (current_state = s_RECEIVE_FIRST_WORD) then - buffer_data_out_reg(15 downto 0) <= buffer_data_out; - end if; - if (current_state = s_RECEIVE_SECOND_WORD) then - buffer_data_out_reg(31 downto 16) <= buffer_data_out; - end if; - end if; - end process; - - -- FSM outputs - o_avalon_waitrequest <= (read_buffer_request or write_buffer_request) when (not (current_state = s_WAIT_RELEASE)) else '0'; - buffer_address(7 downto 1) <= avalon_address(6 downto 0); - buffer_address(0) <= '1' when ( (current_state = s_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_WORD) or - (current_state = s_WR_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else - '0'; - buffer_enable <= '1' when ( (current_state = s_READ_FIRST_WORD) or (current_state = s_WR_READ_FIRST_WORD) or - (current_state = s_READ_SECOND_WORD) or (current_state = s_WR_READ_SECOND_WORD) or - (current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or - (current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else - '0'; - buffer_write <= '1' when ( (current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or - (current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else - '0'; - buffer_data_in <= (buffer_data_out(15 downto 8) & buffer_data_in_reg(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "01")) else - (buffer_data_in_reg(15 downto 8) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "10")) else - (buffer_data_out(15 downto 8) & buffer_data_in_reg(23 downto 16)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "01")) else - (buffer_data_in_reg(31 downto 24) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "10")) else - buffer_data_in_reg(15 downto 0) when (current_state = s_WRITE_FIRST_WORD) else - buffer_data_in_reg(31 downto 16); - -- Glue Logic - read_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_read); - write_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_write); - - -- Define state transitions for command interface. - state_transitions_cmd: process (current_cmd_state, command_completed, command_valid, command_ready) - begin - case current_cmd_state is - when s_RESET_CMD => - -- Reset local registers. - next_cmd_state <= s_WAIT_COMMAND; - - when s_WAIT_COMMAND => - -- Wait for a user command. - if (command_ready = '1') then - next_cmd_state <= s_WAIT_RESPONSE; - else - next_cmd_state <= s_WAIT_COMMAND; - end if; - - when s_WAIT_RESPONSE => - -- Generate a predefined command to the SD card. This is the identification process for the SD card. - if ((command_completed = '1') or (command_valid = '0')) then - next_cmd_state <= s_UPDATE_AUX_SR; - else - next_cmd_state <= s_WAIT_RESPONSE; - end if; - - when s_UPDATE_AUX_SR => - -- Update the Auxiliary status register. - if (command_ready = '1') then - next_cmd_state <= s_UPDATE_AUX_SR; - else - next_cmd_state <= s_WAIT_COMMAND; - end if; - - when others => - -- Make sure to start in the reset state if the circuit powers up in an odd state. - next_cmd_state <= s_RESET_CMD; - end case; - end process; - - -- State registers - cmd_state_regs: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - current_cmd_state <= s_RESET_CMD; - elsif(rising_edge(i_clock)) then - current_cmd_state <= next_cmd_state; - end if; - end process; - - -- FSM outputs - send_command_ready <= '1' when ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) else '0'; - - -- Glue logic - command_ready <= '1' when ( (i_avalon_chip_select = '1') and (i_avalon_write = '1') and - (i_avalon_address = ADDRESS_COMMAND)) else '0'; - argument_write <= '1' when ((i_avalon_chip_select = '1') and (i_avalon_write = '1') and - (i_avalon_address = ADDRESS_ARGUMENT)) else '0'; - -- Local Registers - local_regs: process(i_clock, i_reset_n, current_cmd_state, card_connected, command_valid, i_avalon_writedata, command_completed, command_ready) - begin - if (i_reset_n = '0') then - auxiliary_status_reg <= "000000"; - command_ID_reg <= (OTHERS => '0'); - elsif(rising_edge(i_clock)) then - -- AUX Status Register - if ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) then - auxiliary_status_reg(2) <= not command_completed; - auxiliary_status_reg(4) <= command_timed_out; - auxiliary_status_reg(5) <= command_crc_failed; - end if; - auxiliary_status_reg(0) <= command_valid; - auxiliary_status_reg(1) <= card_connected; - auxiliary_status_reg(3) <= status_reg_valid; - -- Command - if (command_ready = '1') then - command_ID_reg <= i_avalon_writedata(5 downto 0); - end if; - end if; - end process; - - argument_regs_processing: process(i_clock, i_reset_n, current_cmd_state, i_avalon_writedata, command_ready) - begin - if (i_reset_n = '0') then - argument_reg <= (OTHERS => '0'); - elsif(rising_edge(i_clock)) then - -- Argument register - if ((command_ready = '1') and ( i_avalon_writedata(6) = '1')) then - argument_reg <= SD_REG_relative_card_address & "0000000000000000"; - elsif (argument_write = '1') then - argument_reg <= i_avalon_writedata; - end if; - end if; - end process; - - o_avalon_readdata <= buffer_data_out_reg when (not (current_state = s_WAIT_REQUEST)) else - SD_REG_card_identification_number(31 downto 0) when (i_avalon_address = ADDRESS_CID) else - SD_REG_card_identification_number(63 downto 32) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "01") else - SD_REG_card_identification_number(95 downto 64) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "10") else - SD_REG_card_identification_number(127 downto 96) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "11") else - SD_REG_card_specific_data(31 downto 0) when (i_avalon_address = ADDRESS_CSD) else - SD_REG_card_specific_data(63 downto 32) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "01") else - SD_REG_card_specific_data(95 downto 64) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "10") else - SD_REG_card_specific_data(127 downto 96) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "11") else - SD_REG_operating_conditions_register when (i_avalon_address = ADDRESS_OCR) else - SD_REG_status_register when (i_avalon_address = ADDRESS_SR) else - ("0000000000000000" & SD_REG_relative_card_address)when (i_avalon_address = ADDRESS_RCA) else - argument_reg when (i_avalon_address = ADDRESS_ARGUMENT) else - ("00000000000000000000000000" & command_ID_reg) when (i_avalon_address = ADDRESS_COMMAND) else - SD_REG_response_R1 when (i_avalon_address = ADDRESS_R1) else - ("00000000000000000000000000" & auxiliary_status_reg); - - -- Instantiated Components - SD_Card_Port: Altera_UP_SD_Card_Interface - port map - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - - -- Command interface - b_SD_cmd => b_SD_cmd, - b_SD_dat => b_SD_dat, - b_SD_dat3 => b_SD_dat3, - i_command_ID => command_ID_reg, - i_argument => argument_reg, - i_user_command_ready => send_command_ready, - - o_SD_clock => o_SD_clock, - o_card_connected => card_connected, - o_command_completed => command_completed, - o_command_valid => command_valid, - o_command_timed_out => command_timed_out, - o_command_crc_failed => command_crc_failed, - - -- Buffer access - i_buffer_enable => buffer_enable, - i_buffer_address => buffer_address, - i_buffer_write => buffer_write, - i_buffer_data_in => buffer_data_in, - o_buffer_data_out => buffer_data_out, - - -- Show SD Card registers as outputs - o_SD_REG_card_identification_number => SD_REG_card_identification_number, - o_SD_REG_relative_card_address => SD_REG_relative_card_address, - o_SD_REG_operating_conditions_register => SD_REG_operating_conditions_register, - o_SD_REG_card_specific_data => SD_REG_card_specific_data, - o_SD_REG_status_register => SD_REG_status_register, - o_SD_REG_response_R1 => SD_REG_response_R1, - o_SD_REG_status_register_valid => status_reg_valid - ); - -end rtl; - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Buffer.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Buffer.vhd deleted file mode 100644 index 3cdb04f..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Buffer.vhd +++ /dev/null @@ -1,382 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - -------------------------------------------------------------------------------------- --- This module is a dual port memory block. It has a 16-bit port and a 1-bit port. --- The 1-bit port is used to either send or receive data, while the 16-bit port is used --- by Avalon interconnet to store and retrieve data. --- --- NOTES/REVISIONS: -------------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_Buffer is - generic ( - TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111"; - BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - - -- 1 bit port to transmit and receive data on the data line. - i_begin : in std_logic; - i_sd_clock_pulse_trigger : in std_logic; - i_transmit : in std_logic; - i_1bit_data_in : in std_logic; - o_1bit_data_out : out std_logic; - o_operation_complete : out std_logic; - o_crc_passed : out std_logic; - o_timed_out : out std_logic; - o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it. - - -- 16 bit port to be accessed by a user circuit. - i_enable_16bit_port : in std_logic; - i_address_16bit_port : in std_logic_vector(7 downto 0); - i_write_16bit : in std_logic; - i_16bit_data_in : in std_logic_vector(15 downto 0); - o_16bit_data_out : out std_logic_vector(15 downto 0) - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_Buffer is - - component Altera_UP_SD_CRC16_Generator - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_sync_reset : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(15 downto 0) - ); - end component; - - component Altera_UP_SD_Card_Memory_Block - PORT - ( - address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); - address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0); - clock_a : IN STD_LOGIC ; - clock_b : IN STD_LOGIC ; - data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0); - data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0); - enable_a : IN STD_LOGIC := '1'; - enable_b : IN STD_LOGIC := '1'; - wren_a : IN STD_LOGIC := '1'; - wren_b : IN STD_LOGIC := '1'; - q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); - q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) - ); - END component; - - -- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state - -- of the switches. - type state_type is (s_RESET, s_WAIT_REQUEST, s_SEND_START_BIT, s_SEND_DATA, s_SEND_CRC, s_SEND_STOP, s_WAIT_BUSY, s_WAIT_BUSY_END, - s_WAIT_DATA_START, s_RECEIVING_LEADING_BITS, s_RECEIVING_DATA, s_RECEIVING_STOP_BIT, s_WAIT_DEASSERT); - - -- Register to hold the current state - signal current_state : state_type; - signal next_state : state_type; - -- Local wires - -- REGISTERED - signal crc_counter : std_logic_vector(3 downto 0); - signal local_mode : std_logic; - signal dataout_1bit : std_logic; - signal bit_counter : std_logic_vector(2 downto 0); - signal byte_counter : std_logic_vector(8 downto 0); - signal shift_register : std_logic_vector(16 downto 0); - signal timeout_register : std_logic_vector(15 downto 0); - signal data_in_reg : std_logic; - -- UNREGISTERED - signal crc_out : std_logic_vector(15 downto 0); - signal single_bit_conversion, single_bit_out : std_logic_vector( 0 downto 0); - signal packet_mem_addr_b : std_logic_vector(11 downto 0); - signal local_reset, to_crc_generator, from_crc_generator, from_mem_1_bit, shift_crc, - recv_data, crc_generator_enable : std_logic; -begin - -- State transitions - state_transitions: process( current_state, i_begin, i_sd_clock_pulse_trigger, i_transmit, byte_counter, - bit_counter, crc_counter, i_1bit_data_in, timeout_register, data_in_reg) - begin - case (current_state) is - when s_RESET => - -- Reset local registers and begin waiting for user input. - next_state <= s_WAIT_REQUEST; - - when s_WAIT_REQUEST => - -- Wait for i_begin to be high - if ((i_begin = '1') and (i_sd_clock_pulse_trigger = '1')) then - if (i_transmit = '1') then - next_state <= s_SEND_START_BIT; - else - next_state <= s_WAIT_DATA_START; - end if; - else - next_state <= s_WAIT_REQUEST; - end if; - - when s_SEND_START_BIT => - -- Send a 0 first, followed by 4096 bits of data, 16 CRC bits, and stop bit. - if (i_sd_clock_pulse_trigger = '1') then - next_state <= s_SEND_DATA; - else - next_state <= s_SEND_START_BIT; - end if; - - when s_SEND_DATA => - -- Send 4096 data bits - if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then - next_state <= s_SEND_CRC; - else - next_state <= s_SEND_DATA; - end if; - - when s_SEND_CRC => - -- Send 16 CRC bits - if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then - next_state <= s_SEND_STOP; - else - next_state <= s_SEND_CRC; - end if; - - when s_SEND_STOP => - -- Send stop bit. - if (i_sd_clock_pulse_trigger = '1') then - next_state <= s_WAIT_BUSY; - else - next_state <= s_SEND_STOP; - end if; - - when s_WAIT_BUSY => - -- After a write, wait for the busy signal. Do not return a done signal until you receive a busy signal. - -- If you do not and a long time expires, then the data must have been rejected (due to CRC error maybe). - -- In such a case return failure. - if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0') and (timeout_register = "0000000000010000")) then - next_state <= s_WAIT_BUSY_END; - else - if (timeout_register = BUSY_WAIT) then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_BUSY; - end if; - end if; - - when s_WAIT_BUSY_END => - if (i_sd_clock_pulse_trigger = '1') then - if (data_in_reg = '1') then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_BUSY_END; - end if; - else - next_state <= s_WAIT_BUSY_END; - end if; - - when s_WAIT_DATA_START => - -- Wait for the start bit - if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0')) then - next_state <= s_RECEIVING_LEADING_BITS; - else - if (timeout_register = TIMEOUT) then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_DATA_START; - end if; - end if; - - when s_RECEIVING_LEADING_BITS => - -- shift the start bit in as well as the next 16 bits. Once they are all in you can start putting data into memory. - if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then - next_state <= s_RECEIVING_DATA; - else - next_state <= s_RECEIVING_LEADING_BITS; - end if; - - when s_RECEIVING_DATA => - -- Wait until all bits arrive. - if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then - next_state <= s_RECEIVING_STOP_BIT; - else - next_state <= s_RECEIVING_DATA; - end if; - - when s_RECEIVING_STOP_BIT => - -- Wait until all bits arrive. - if (i_sd_clock_pulse_trigger = '1')then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_RECEIVING_STOP_BIT; - end if; - - when s_WAIT_DEASSERT => - if (i_begin = '1') then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_REQUEST; - end if; - - when others => - next_state <= s_RESET; - end case; - end process; - - -- State registers - state_regs: process(i_clock, i_reset_n, local_reset) - begin - if (i_reset_n = '0') then - current_state <= s_RESET; - elsif (rising_edge(i_clock)) then - current_state <= next_state; - end if; - end process; - - -- FSM outputs - to_crc_generator <= shift_register(16) when (current_state = s_RECEIVING_DATA) else - from_mem_1_bit when (current_state = s_SEND_DATA) else - '0'; - shift_crc <= '1' when (current_state = s_SEND_CRC) else '0'; - local_reset <= '1' when ((current_state = s_RESET) or (current_state = s_WAIT_REQUEST)) else '0'; - recv_data <= '1' when (current_state = s_RECEIVING_DATA) else '0'; - single_bit_conversion(0) <= shift_register(15); - crc_generator_enable <= '0' when (current_state = s_WAIT_DEASSERT) else i_sd_clock_pulse_trigger; - o_operation_complete <= '1' when (current_state = s_WAIT_DEASSERT) else '0'; - o_dat_direction <= '1' when ( (current_state = s_SEND_START_BIT) or - (current_state = s_SEND_DATA) or - (current_state = s_SEND_CRC) or - (current_state = s_SEND_STOP)) - else '0'; - o_1bit_data_out <= dataout_1bit; - o_crc_passed <= '1' when ((crc_out = shift_register(16 downto 1)) and (shift_register(0) = '1')) else '0'; - o_timed_out <= '1' when (timeout_register = TIMEOUT) else '0'; - - -- Local components - local_regs: process(i_clock, i_reset_n, local_reset) - begin - if (i_reset_n = '0') then - bit_counter <= (OTHERS => '1'); - byte_counter <= (OTHERS => '0'); - dataout_1bit <= '1'; - crc_counter <= (OTHERS => '0'); - shift_register <= (OTHERS => '0'); - elsif (rising_edge(i_clock)) then - -- counters and serial output - if (local_reset = '1') then - bit_counter <= (OTHERS => '1'); - byte_counter <= (OTHERS => '0'); - dataout_1bit <= '1'; - data_in_reg <= '1'; - crc_counter <= (OTHERS => '0'); - shift_register <= (OTHERS => '0'); - elsif (i_sd_clock_pulse_trigger = '1') then - if ((not (current_state = s_RECEIVING_LEADING_BITS)) and (not (current_state = s_SEND_CRC))) then - crc_counter <= (OTHERS => '0'); - else - if (not (crc_counter = "1111")) then - crc_counter <= crc_counter + '1'; - end if; - end if; - if ((current_state = s_RECEIVING_DATA) or (current_state = s_SEND_DATA)) then - if (not ((bit_counter = "000") and (byte_counter = "111111111"))) then - if (bit_counter = "000") then - byte_counter <= byte_counter + '1'; - bit_counter <= "111"; - else - bit_counter <= bit_counter - '1'; - end if; - end if; - end if; - -- Output data bit. - if (current_state = s_SEND_START_BIT) then - dataout_1bit <= '0'; - elsif (current_state = s_SEND_DATA) then - dataout_1bit <= from_mem_1_bit; - elsif (current_state = s_SEND_CRC) then - dataout_1bit <= from_crc_generator; - else - dataout_1bit <= '1'; -- Stop bit. - end if; - - -- Shift register to store the CRC bits once the message is received. - if ((current_state = s_RECEIVING_DATA) or - (current_state = s_RECEIVING_LEADING_BITS) or - (current_state = s_RECEIVING_STOP_BIT)) then - shift_register(16 downto 1) <= shift_register(15 downto 0); - shift_register(0) <= data_in_reg; - end if; - data_in_reg <= i_1bit_data_in; - end if; - end if; - end process; - - -- Register holding the timeout value for data transmission. - timeout_reg: process(i_clock, i_reset_n, current_state, i_sd_clock_pulse_trigger) - begin - if (i_reset_n = '0') then - timeout_register <= (OTHERS => '0'); - elsif (rising_edge(i_clock)) then - if ((current_state = s_SEND_STOP) or - (current_state = s_WAIT_REQUEST)) then - timeout_register <= (OTHERS => '0'); - elsif (i_sd_clock_pulse_trigger = '1') then - -- Increment the timeout counter - if (((current_state = s_WAIT_DATA_START) or - (current_state = s_WAIT_BUSY)) and (not (timeout_register = TIMEOUT))) then - timeout_register <= timeout_register + '1'; - end if; - end if; - end if; - end process; - - -- Instantiated components. - crc16_checker: Altera_UP_SD_CRC16_Generator - port map - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_sync_reset => local_reset, - i_enable => crc_generator_enable, - i_shift => shift_crc, - i_datain => to_crc_generator, - o_dataout => from_crc_generator, - o_crcout => crc_out - ); - - packet_memory: Altera_UP_SD_Card_Memory_Block - PORT MAP - ( - address_a => i_address_16bit_port, - address_b => packet_mem_addr_b, - clock_a => i_clock, - clock_b => i_clock, - data_a => i_16bit_data_in, - data_b => single_bit_conversion, - enable_a => i_enable_16bit_port, - enable_b => '1', - wren_a => i_write_16bit, - wren_b => recv_data, - q_a => o_16bit_data_out, - q_b => single_bit_out - ); - from_mem_1_bit <= single_bit_out(0); - packet_mem_addr_b <= (byte_counter & bit_counter); - -end rtl; diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Clock.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Clock.vhd deleted file mode 100644 index 094d9dd..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Clock.vhd +++ /dev/null @@ -1,80 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - -------------------------------------------------------------------------------------- --- This module is a clock generator for the SD card interface. It takes a 50 MHz --- clock as input and produces a clock signal that depends on the mode in which the --- SD card interface is in. For a card identification mode a clock with a frequency of --- 390.625 kHz is generated. For the data transfer mode, a clock with a frequency of --- 12.5MHz is generated. --- --- In addition, the generator produces a clock_mode value that identifies the frequency --- of the o_SD_clock that is currently being generated. --- --- NOTES/REVISIONS: -------------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_Clock is - - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_enable : in std_logic; - i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode. - o_SD_clock : out std_logic; - o_clock_mode : out std_logic; - o_trigger_receive : out std_logic; - o_trigger_send : out std_logic - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_Clock is - - -- Local wires - -- REGISTERED - signal counter : std_logic_vector(6 downto 0); - signal local_mode : std_logic; - -- UNREGISTERED -begin - process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - counter <= (OTHERS => '0'); - local_mode <= '0'; - else - if (rising_edge(i_clock)) then - if (i_enable = '1') then - counter <= counter + '1'; - end if; - -- Change the clock pulse only when at the positive edge of the clock - if (counter = "1000000") then - local_mode <= i_mode; - end if; - end if; - end if; - end process; - - o_clock_mode <= local_mode; - o_SD_clock <= counter(6) when (local_mode = '0') else counter(1); - o_trigger_receive <= '1' when ((local_mode = '0') and (counter = "0111111")) else - ((not counter(1)) and (counter(0))) when (local_mode = '1') else '0'; - o_trigger_send <= '1' when ((local_mode = '0') and (counter = "0011111")) else - ((counter(1)) and (counter(0))) when (local_mode = '1') else '0'; - -end rtl; \ No newline at end of file diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Control_FSM.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Control_FSM.vhd deleted file mode 100644 index c020fbd..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Control_FSM.vhd +++ /dev/null @@ -1,347 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - ----------------------------------------------------------------------------------------------------------------- --- This is an FSM that controls the SD Card interface circuitry. --- --- On reset, the FSM will initiate a predefined set of commands in an attempt to connect to the SD Card. --- When successful, it will allow commands to be issued to the SD Card, otherwise it will return a signal that --- no card is present in the SD Card slot. --- --- NOTES/REVISIONS: ----------------------------------------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_Control_FSM is - generic ( - PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001" - ); - port - ( - -- Clock and Reset signals - i_clock : in STD_LOGIC; - i_reset_n : in STD_LOGIC; - - -- FSM Inputs - i_user_command_ready : in std_logic; - i_response_received : in STD_LOGIC; - i_response_timed_out : in STD_LOGIC; - i_response_crc_passed : in STD_LOGIC; - i_command_sent : in STD_LOGIC; - i_powerup_busy_n : in STD_LOGIC; - i_clocking_pulse_enable : in std_logic; - i_current_clock_mode : in std_logic; - i_user_message_valid : in std_logic; - i_last_cmd_was_55 : in std_logic; - i_allow_partial_rw : in std_logic; - - -- FSM Outputs - o_generate_command : out STD_LOGIC; - o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0); - o_receive_response : out STD_LOGIC; - o_drive_CMD_line : out STD_LOGIC; - o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode. - o_resetting : out std_logic; - o_card_connected : out STD_LOGIC; - o_command_completed : out std_logic; - o_clear_response_register : out std_logic; - o_enable_clock_generator : out std_logic - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_Control_FSM is - - -- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state - -- of the switches. - type state_type is (s_RESET, s_WAIT_74_CYCLES, s_GENERATE_PREDEFINED_COMMAND, s_WAIT_PREDEFINED_COMMAND_TRANSMITTED, s_WAIT_PREDEFINED_COMMAND_RESPONSE, - s_GO_TO_NEXT_COMMAND, s_TOGGLE_CLOCK_FREQUENCY, s_AWAIT_USER_COMMAND, s_REACTIVATE_CLOCK, - s_GENERATE_COMMAND, s_SEND_COMMAND, s_WAIT_RESPONSE, s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE, s_WAIT_DEASSERT, - s_PERIODIC_STATUS_CHECK); - - -- Register to hold the current state - signal current_state : state_type; - signal next_state : state_type; - - ------------------- - -- Local signals - ------------------- - -- REGISTERED - signal SD_clock_mode, waiting_for_vdd_setup : std_logic; - signal id_sequence_step_index : std_logic_vector(3 downto 0); - signal delay_counter : std_logic_vector(6 downto 0); - signal periodic_status_check : std_logic_vector(23 downto 0); - -- UNREGISTERED - -begin - -- Define state transitions. - state_transitions: process (current_state, i_command_sent, i_response_received, id_sequence_step_index, - i_response_timed_out, i_response_crc_passed, delay_counter, waiting_for_vdd_setup, - i_user_command_ready, i_clocking_pulse_enable, i_current_clock_mode, - i_user_message_valid, i_last_cmd_was_55, periodic_status_check) - begin - case current_state is - when s_RESET => - -- Reset local registers and begin identification process. - next_state <= s_WAIT_74_CYCLES; - - when s_WAIT_74_CYCLES => - -- Wait 74 cycles before the card can be sent commands to. - if (delay_counter = "1001010") then - next_state <= s_GENERATE_PREDEFINED_COMMAND; - else - next_state <= s_WAIT_74_CYCLES; - end if; - - when s_GENERATE_PREDEFINED_COMMAND => - -- Generate a predefined command to the SD card. This is the identification process for the SD card. - next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED; - - when s_WAIT_PREDEFINED_COMMAND_TRANSMITTED => - -- Send a predefined command to the SD card. This is the identification process for the SD card. - if (i_command_sent = '1') then - next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE; - else - next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED; - end if; - - when s_WAIT_PREDEFINED_COMMAND_RESPONSE => - -- Wait for a response from SD card. - if (i_response_received = '1') then - if (i_response_timed_out = '1') then - if (waiting_for_vdd_setup = '1') then - next_state <= s_GO_TO_NEXT_COMMAND; - else - next_state <= s_RESET; - end if; - else - if (i_response_crc_passed = '0') then - next_state <= s_GENERATE_PREDEFINED_COMMAND; - else - next_state <= s_GO_TO_NEXT_COMMAND; - end if; - end if; - else - next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE; - end if; - - when s_GO_TO_NEXT_COMMAND => - -- Process the next command in the ID sequence. - if (id_sequence_step_index = PREDEFINED_COMMAND_GET_STATUS) then - next_state <= s_TOGGLE_CLOCK_FREQUENCY; - else - next_state <= s_GENERATE_PREDEFINED_COMMAND; - end if; - - when s_TOGGLE_CLOCK_FREQUENCY => - -- Now that the card has been initialized, increase the SD card clock frequency to 25MHz. - -- Wait for the clock generator to switch operating mode before proceeding further. - if (i_current_clock_mode = '1') then - next_state <= s_AWAIT_USER_COMMAND; - else - next_state <= s_TOGGLE_CLOCK_FREQUENCY; - end if; - - when s_AWAIT_USER_COMMAND => - -- Wait for the user to send a command to the SD card - if (i_user_command_ready = '1') then - next_state <= s_REACTIVATE_CLOCK; - else - -- Every 5 million cycles, or 0.1 of a second. - if (periodic_status_check = "010011000100101101000000") then - next_state <= s_PERIODIC_STATUS_CHECK; - else - next_state <= s_AWAIT_USER_COMMAND; - end if; - end if; - - when s_PERIODIC_STATUS_CHECK => - -- Update status every now and then. - next_state <= s_GENERATE_PREDEFINED_COMMAND; - - when s_REACTIVATE_CLOCK => - -- Activate the clock signal and wait 8 clock cycles. - if (delay_counter = "0001000") then - next_state <= s_GENERATE_COMMAND; - else - next_state <= s_REACTIVATE_CLOCK; - end if; - - when s_GENERATE_COMMAND => - -- Generate user command. If valid, proceed further. Otherwise, indicate that the command is invalid. - if (i_user_message_valid = '0') then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_SEND_COMMAND; - end if; - - when s_SEND_COMMAND => - -- Wait for the command to be sent. - if (i_command_sent = '1') then - next_state <= s_WAIT_RESPONSE; - else - next_state <= s_SEND_COMMAND; - end if; - - when s_WAIT_RESPONSE => - -- Wait for the SD card to respond. - if (i_response_received = '1') then - if (i_response_timed_out = '1') then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE; - end if; - else - next_state <= s_WAIT_RESPONSE; - end if; - - when s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE => - -- Wait for a positive clock edge before you disable the clock. - if (i_clocking_pulse_enable = '1') then - next_state <= s_WAIT_DEASSERT; - else - next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE; - end if; - - when s_WAIT_DEASSERT => - -- wait for the user to release command generation request. - if (i_user_command_ready = '1') then - next_state <= s_WAIT_DEASSERT; - else - if (i_last_cmd_was_55 = '1') then - next_state <= s_AWAIT_USER_COMMAND; - else - -- Send a get status command to obtain the result of sending the last command. - next_state <= s_GENERATE_PREDEFINED_COMMAND; - end if; - end if; - - when others => - -- Make sure to start in the reset state if the circuit powers up in an odd state. - next_state <= s_RESET; - end case; - end process; - - -- State registers. - state_registers: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - current_state <= s_RESET; - elsif (rising_edge(i_clock)) then - current_state <= next_state; - end if; - end process; - - -- Local FFs: - local_ffs:process ( i_clock, i_reset_n, i_powerup_busy_n, current_state, - id_sequence_step_index, i_response_received, i_response_timed_out, - i_allow_partial_rw) - begin - if (i_reset_n = '0') then - SD_clock_mode <= '0'; - id_sequence_step_index <= (OTHERS => '0'); - periodic_status_check <= (OTHERS => '0'); - waiting_for_vdd_setup <= '0'; - elsif (rising_edge(i_clock)) then - -- Set SD clock mode to 0 initially, thereby using a clock with frequency between 100 kHz and 400 kHz as - -- per SD card specifications. When the card is initialized change the clock to run at 25 MHz. - if (current_state = s_WAIT_DEASSERT) then - periodic_status_check <= (OTHERS => '0'); - elsif (current_state = s_AWAIT_USER_COMMAND) then - periodic_status_check <= periodic_status_check + '1'; - end if; - - if (current_state = s_RESET) then - SD_clock_mode <= '0'; - elsif (current_state = s_TOGGLE_CLOCK_FREQUENCY) then - SD_clock_mode <= '1'; - end if; - -- Update the ID sequence step as needed. - if (current_state = s_RESET) then - id_sequence_step_index <= (OTHERS => '0'); - elsif (current_state = s_GO_TO_NEXT_COMMAND) then - if ((i_powerup_busy_n = '0') and (id_sequence_step_index = "0010")) then - id_sequence_step_index <= "0001"; - else - if (id_sequence_step_index = "0110") then - if (i_allow_partial_rw = '0') then - -- If partial read-write not allowed, then skip SET_BLK_LEN command - it will fail. - id_sequence_step_index <= "1000"; - else - id_sequence_step_index <= "0111"; - end if; - else - id_sequence_step_index <= id_sequence_step_index + '1'; - end if; - end if; - elsif (current_state = s_WAIT_DEASSERT) then - if (i_last_cmd_was_55 = '0') then - -- After each command execute a get status command. - id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS; - end if; - elsif (current_state = s_PERIODIC_STATUS_CHECK) then - id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS; - end if; - - -- Do not reset the card when SD card is having its VDD set up. Wait for it to respond, this may take some time. - if (id_sequence_step_index = "0010") then - waiting_for_vdd_setup <= '1'; - elsif ((id_sequence_step_index = "0011") or (current_state = s_RESET)) then - waiting_for_vdd_setup <= '0'; - end if; - - end if; - end process; - - -- Counter that counts to 74 to delay any commands. - initial_delay_counter: process(i_clock, i_reset_n, i_clocking_pulse_enable ) - begin - if (i_reset_n = '0') then - delay_counter <= (OTHERS => '0'); - elsif (rising_edge(i_clock)) then - if ((current_state = s_RESET) or (current_state = s_AWAIT_USER_COMMAND))then - delay_counter <= (OTHERS => '0'); - elsif (((current_state = s_WAIT_74_CYCLES) or (current_state = s_REACTIVATE_CLOCK)) and - (i_clocking_pulse_enable = '1')) then - delay_counter <= delay_counter + '1'; - end if; - end if; - end process; - - -- FSM outputs. - o_SD_clock_mode <= SD_clock_mode; - o_generate_command <= '1' when ((current_state = s_GENERATE_PREDEFINED_COMMAND) or - (current_state = s_GENERATE_COMMAND)) - else '0'; - o_receive_response <= '1' when ((current_state = s_WAIT_PREDEFINED_COMMAND_RESPONSE) or - (current_state = s_WAIT_RESPONSE)) - else '0'; - o_drive_CMD_line <= '1' when ( (current_state = s_WAIT_PREDEFINED_COMMAND_TRANSMITTED) or - (current_state = s_SEND_COMMAND)) else '0'; - o_predefined_command_ID <= id_sequence_step_index; - o_card_connected <= '1' when (id_sequence_step_index(3) = '1') and ( - (id_sequence_step_index(2) = '1') or - (id_sequence_step_index(1) = '1') or - (id_sequence_step_index(0) = '1')) - else '0'; - o_resetting <= '1' when (current_state = s_RESET) else '0'; - o_command_completed <= '1' when (current_state = s_WAIT_DEASSERT) else '0'; - o_enable_clock_generator <= '0' when (current_state = s_AWAIT_USER_COMMAND) else '1'; - o_clear_response_register <= '1' when (current_state = s_REACTIVATE_CLOCK) else '0'; - -end rtl; - diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Interface.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Interface.vhd deleted file mode 100644 index ba2f743..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Interface.vhd +++ /dev/null @@ -1,518 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - -------------------------------------------------------------------------------------- --- This module is an interface to the Secure Data Card. This module is intended to be --- used with the DE2 board. --- --- This version of the interface supports only a 1-bit serial data transfer. This --- allows the interface to support a MultiMedia card as well. --- --- NOTES/REVISIONS: -------------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity Altera_UP_SD_Card_Interface is - - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - - -- Command interface - b_SD_cmd : inout std_logic; - b_SD_dat : inout std_logic; - b_SD_dat3 : inout std_logic; - i_command_ID : in std_logic_vector(5 downto 0); - i_argument : in std_logic_vector(31 downto 0); - i_user_command_ready : in std_logic; - - o_SD_clock : out std_logic; - o_card_connected : out std_logic; - o_command_completed : out std_logic; - o_command_valid : out std_logic; - o_command_timed_out : out std_logic; - o_command_crc_failed : out std_logic; - - -- Buffer access - i_buffer_enable : in std_logic; - i_buffer_address : in std_logic_vector(7 downto 0); - i_buffer_write : in std_logic; - i_buffer_data_in : in std_logic_vector(15 downto 0); - o_buffer_data_out : out std_logic_vector(15 downto 0); - - -- Show SD Card registers as outputs - o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0); - o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0); - o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0); - o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0); - o_SD_REG_status_register : out std_logic_vector(31 downto 0); - o_SD_REG_response_R1 : out std_logic_vector(31 downto 0); - o_SD_REG_status_register_valid : out std_logic - ); - -end entity; - -architecture rtl of Altera_UP_SD_Card_Interface is - - component Altera_UP_SD_Card_Clock - - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_enable : in std_logic; - i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode. - o_SD_clock : out std_logic; - o_clock_mode : out std_logic; - o_trigger_receive : out std_logic; - o_trigger_send : out std_logic - ); - - end component; - - component Altera_UP_SD_CRC7_Generator - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(6 downto 0) - ); - end component; - - component Altera_UP_SD_CRC16_Generator - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(15 downto 0) - ); - end component; - - component Altera_UP_SD_Signal_Trigger - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_signal : in std_logic; - o_trigger : out std_logic - ); - end component; - - component Altera_UP_SD_Card_48_bit_Command_Generator - generic ( - -- Basic commands - COMMAND_0_GO_IDLE : STD_LOGIC_VECTOR(5 downto 0) := "000000"; - COMMAND_2_ALL_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "000010"; - COMMAND_3_SEND_RCA : STD_LOGIC_VECTOR(5 downto 0) := "000011"; - COMMAND_4_SET_DSR : STD_LOGIC_VECTOR(5 downto 0) := "000100"; - COMMAND_6_SWITCH_FUNCTION : STD_LOGIC_VECTOR(5 downto 0) := "000110"; - COMMAND_7_SELECT_CARD : STD_LOGIC_VECTOR(5 downto 0) := "000111"; - COMMAND_9_SEND_CSD : STD_LOGIC_VECTOR(5 downto 0) := "001001"; - COMMAND_10_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "001010"; - COMMAND_12_STOP_TRANSMISSION : STD_LOGIC_VECTOR(5 downto 0) := "001100"; - COMMAND_13_SEND_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101"; - COMMAND_15_GO_INACTIVE : STD_LOGIC_VECTOR(5 downto 0) := "001111"; - -- Block oriented read/write/lock commands - COMMAND_16_SET_BLOCK_LENGTH : STD_LOGIC_VECTOR(5 downto 0) := "010000"; - -- Block oriented read commands - COMMAND_17_READ_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "010001"; - COMMAND_18_READ_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010010"; - -- Block oriented write commands - COMMAND_24_WRITE_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "011000"; - COMMAND_25_WRITE_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "011001"; - COMMAND_27_PROGRAM_CSD : STD_LOGIC_VECTOR(5 downto 0) := "011011"; - -- Block oriented write-protection commands - COMMAND_28_SET_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011100"; - COMMAND_29_CLEAR_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011101"; - COMMAND_30_SEND_PROTECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "011110"; - -- Erase commands - COMMAND_32_ERASE_BLOCK_START : STD_LOGIC_VECTOR(5 downto 0) := "100000"; - COMMAND_33_ERASE_BLOCK_END : STD_LOGIC_VECTOR(5 downto 0) := "100001"; - COMMAND_38_ERASE_SELECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "100110"; - -- Block lock commands - COMMAND_42_LOCK_UNLOCK : STD_LOGIC_VECTOR(5 downto 0) := "101010"; - -- Command Type Settings - COMMAND_55_APP_CMD : STD_LOGIC_VECTOR(5 downto 0) := "110111"; - COMMAND_56_GEN_CMD : STD_LOGIC_VECTOR(5 downto 0) := "111000"; - -- Application Specific commands - must be preceeded with command 55. - ACOMMAND_6_SET_BUS_WIDTH : STD_LOGIC_VECTOR(5 downto 0) := "000110"; - ACOMMAND_13_SD_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101"; - ACOMMAND_22_SEND_NUM_WR_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010100"; - ACOMMAND_23_SET_BLK_ERASE_COUNT : STD_LOGIC_VECTOR(5 downto 0) := "010101"; - ACOMMAND_41_SEND_OP_CONDITION : STD_LOGIC_VECTOR(5 downto 0) := "101001"; - ACOMMAND_42_SET_CLR_CARD_DETECT : STD_LOGIC_VECTOR(5 downto 0) := "101010"; - ACOMMAND_51_SEND_SCR : STD_LOGIC_VECTOR(5 downto 0) := "110011"; - -- First custom_command - FIRST_NON_PREDEFINED_COMMAND : STD_LOGIC_VECTOR(3 downto 0) := "1010" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_message_bit_out : in std_logic; - i_command_ID : in std_logic_vector(5 downto 0); - i_argument : in std_logic_vector(31 downto 0); - i_predefined_message : in std_logic_vector(3 downto 0); - i_generate : in std_logic; - i_DSR : in std_logic_vector(15 downto 0); - i_OCR : in std_logic_vector(31 downto 0); - i_RCA : in std_logic_vector(15 downto 0); - o_dataout : out std_logic; - o_message_done : out std_logic; - o_valid : out std_logic; - o_returning_ocr : out std_logic; - o_returning_cid : out std_logic; - o_returning_rca : out std_logic; - o_returning_csd : out std_logic; - o_returning_status : out std_logic; - o_data_read : out std_logic; - o_data_write : out std_logic; - o_wait_cmd_busy : out std_logic; - o_last_cmd_was_55 : out std_logic; - o_response_type : out std_logic_vector(2 downto 0) - ); - end component; - - component Altera_UP_SD_Card_Response_Receiver - generic ( - TIMEOUT : std_logic_vector(7 downto 0) := "00111000"; - BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000"; - PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_begin : in std_logic; - i_scan_pulse : in std_logic; - i_datain : in std_logic; - i_wait_cmd_busy : in std_logic; - i_response_type : in std_logic_vector(2 downto 0); - o_data : out std_logic_vector(127 downto 0); - o_CRC_passed : out std_logic; - o_timeout : out std_logic; - o_done : out std_logic - ); - end component; - - component Altera_UP_SD_Card_Control_FSM - generic ( - PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001" - ); - port - ( - -- Clock and Reset signals - i_clock : in STD_LOGIC; - i_reset_n : in STD_LOGIC; - - -- FSM Inputs - i_user_command_ready : in std_logic; - i_response_received : in STD_LOGIC; - i_response_timed_out : in STD_LOGIC; - i_response_crc_passed : in STD_LOGIC; - i_command_sent : in STD_LOGIC; - i_powerup_busy_n : in STD_LOGIC; - i_clocking_pulse_enable : in std_logic; - i_current_clock_mode : in std_logic; - i_user_message_valid : in std_logic; - i_last_cmd_was_55 : in std_logic; - i_allow_partial_rw : in std_logic; - - -- FSM Outputs - o_generate_command : out STD_LOGIC; - o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0); - o_receive_response : out STD_LOGIC; - o_drive_CMD_line : out STD_LOGIC; - o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode. - o_resetting : out std_logic; - o_card_connected : out STD_LOGIC; - o_command_completed : out std_logic; - o_clear_response_register : out std_logic; - o_enable_clock_generator : out std_logic - ); - end component; - - component Altera_UP_SD_Card_Buffer - generic ( - TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111"; - BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - - -- 1 bit port to transmit and receive data on the data line. - i_begin : in std_logic; - i_sd_clock_pulse_trigger : in std_logic; - i_transmit : in std_logic; - i_1bit_data_in : in std_logic; - o_1bit_data_out : out std_logic; - o_operation_complete : out std_logic; - o_crc_passed : out std_logic; - o_timed_out : out std_logic; - o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it. - - -- 16 bit port to be accessed by a user circuit. - i_enable_16bit_port : in std_logic; - i_address_16bit_port : in std_logic_vector(7 downto 0); - i_write_16bit : in std_logic; - i_16bit_data_in : in std_logic_vector(15 downto 0); - o_16bit_data_out : out std_logic_vector(15 downto 0) - ); - end component; - - -- Local wires - -- REGISTERED - signal sd_mode : std_logic; - -- SD Card Registers: - signal SD_REG_card_identification_number : std_logic_vector(127 downto 0); - signal SD_REG_response_R1 : std_logic_vector(31 downto 0); - signal SD_REG_relative_card_address : std_logic_vector(15 downto 0); - signal SD_REG_driver_stage_register : std_logic_vector(15 downto 0); - signal SD_REG_card_specific_data : std_logic_vector(127 downto 0); - signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0); - signal SD_REG_status_register : std_logic_vector(31 downto 0); - signal SD_REG_status_register_valid : std_logic; - -- UNREGISTERED - signal data_from_buffer : std_logic_vector(15 downto 0); - signal clock_generator_mode, enable_generator, SD_clock, create_message : std_logic; - signal send_next_bit, receive_next_bit : std_logic; - signal timed_out, response_done, passed_crc, begin_reading_response, resetting : std_logic; - signal returning_cid, returning_rca, returning_csd, returning_ocr : std_logic; - signal response_type : std_logic_vector(2 downto 0); - signal message_valid, messange_sent, data_to_CMD_line, CMD_tristate_buffer_enable, message_sent : std_logic; - signal predef_message_ID : std_logic_vector(3 downto 0); - signal receive_data_out : std_logic_vector(127 downto 0); - signal data_line_done, data_line_crc, data_line_timeout, data_line_direction, data_line_out : std_logic; - signal data_read, data_write, wait_cmd_busy, clear_response_register : std_logic; - signal response_done_combined : std_logic; - signal timeout_combined : std_logic; - signal crc_combined, allow_partial_rw : std_logic; - signal begin_data_line_operations, last_cmd_was_55, message_sent_trigger, returning_status : std_logic; - signal data_line_sd_clock_pulse_trigger : std_logic; -begin - -- Glue logic - SD_REG_driver_stage_register <= (OTHERS => '0'); - response_done_combined <= (response_done and (not data_read) and (not data_write)) or - (response_done and (data_read or data_write) and data_line_done); - timeout_combined <= (timed_out and (not data_read) and (not data_write)) or - (timed_out and (data_read or data_write) and data_line_timeout); - crc_combined <= (passed_crc and (not data_read) and (not data_write)) or - (passed_crc and (data_read or data_write) and data_line_crc); - begin_data_line_operations <= (data_read and message_sent) or (data_write and response_done); - - -- Partial read and write are only allowed when both bit 79 (partial read allowed) is high and - -- bit 21 (partial write allowed) is high. - allow_partial_rw <= SD_REG_card_specific_data(79) and SD_REG_card_specific_data(21); - - -- SD Card control registers - control_regs: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - SD_REG_operating_conditions_register <= (OTHERS => '0'); - SD_REG_card_identification_number <= (OTHERS => '0'); - SD_REG_relative_card_address <= (OTHERS => '0'); - SD_REG_card_specific_data <= (OTHERS => '0'); - SD_REG_status_register <= (OTHERS => '0'); - SD_REG_response_R1 <= (OTHERS => '1'); - SD_REG_status_register_valid <= '0'; - elsif (rising_edge(i_clock)) then - if ((response_type = "001") and (response_done = '1') and (returning_status = '0') and (clear_response_register = '0')) then - SD_REG_response_R1 <= receive_data_out(31 downto 0); - elsif (clear_response_register = '1') then - SD_REG_response_R1 <= (OTHERS => '1'); - end if; - if (resetting = '1') then - SD_REG_operating_conditions_register <= (OTHERS => '0'); - elsif ((returning_ocr = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then - SD_REG_operating_conditions_register <= receive_data_out(31 downto 0); - end if; - if ((returning_cid = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then - SD_REG_card_identification_number <= receive_data_out; - end if; - if ((returning_rca = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then - SD_REG_relative_card_address <= receive_data_out(31 downto 16); - end if; - if ((returning_csd = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then - SD_REG_card_specific_data <= receive_data_out; - end if; - if (message_sent_trigger = '1') then - SD_REG_status_register_valid <= '0'; - elsif ((returning_status = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then - SD_REG_status_register <= receive_data_out(31 downto 0); - SD_REG_status_register_valid <= '1'; - end if; - end if; - end process; - - -- Instantiated components - command_generator: Altera_UP_SD_Card_48_bit_Command_Generator PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_message_bit_out => send_next_bit, - i_command_ID => i_command_ID, - i_argument => i_argument, - i_predefined_message => predef_message_ID, - i_generate => create_message, - i_DSR => SD_REG_driver_stage_register, - i_OCR => SD_REG_operating_conditions_register, - i_RCA => SD_REG_relative_card_address, - o_dataout => data_to_CMD_line, - o_message_done => message_sent, - o_valid => message_valid, - o_returning_ocr => returning_ocr, - o_returning_cid => returning_cid, - o_returning_rca => returning_rca, - o_returning_csd => returning_csd, - o_returning_status => returning_status, - o_data_read => data_read, - o_data_write => data_write, - o_wait_cmd_busy => wait_cmd_busy, - o_last_cmd_was_55 => last_cmd_was_55, - o_response_type => response_type - ); - - response_receiver: Altera_UP_SD_Card_Response_Receiver PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_begin => begin_reading_response, - i_scan_pulse => receive_next_bit, - i_datain => b_SD_cmd, - i_response_type => response_type, - i_wait_cmd_busy => wait_cmd_busy, - o_data => receive_data_out, - o_CRC_passed => passed_crc, - o_timeout => timed_out, - o_done => response_done - ); - - control_FSM: Altera_UP_SD_Card_Control_FSM PORT MAP - ( - -- Clock and Reset signals - i_clock => i_clock, - i_reset_n => i_reset_n, - - -- FSM Inputs - i_user_command_ready => i_user_command_ready, - i_clocking_pulse_enable => receive_next_bit, - i_response_received => response_done_combined, - i_response_timed_out => timeout_combined, - i_response_crc_passed => crc_combined, - i_command_sent => message_sent, - i_powerup_busy_n => SD_REG_operating_conditions_register(31), - i_current_clock_mode => clock_generator_mode, - i_user_message_valid => message_valid, - i_last_cmd_was_55 => last_cmd_was_55, - i_allow_partial_rw => allow_partial_rw, - - -- FSM Outputs - o_generate_command => create_message, - o_predefined_command_ID => predef_message_ID, - o_receive_response => begin_reading_response, - o_drive_CMD_line => CMD_tristate_buffer_enable, - o_SD_clock_mode => sd_mode, -- 0 means slow clock for card identification, 1 means fast clock for transfer mode. - o_card_connected => o_card_connected, - o_command_completed => o_command_completed, - o_resetting => resetting, - o_clear_response_register => clear_response_register, - o_enable_clock_generator => enable_generator - ); - - clock_generator: Altera_UP_SD_Card_Clock PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_mode => sd_mode, - i_enable => enable_generator, - o_SD_clock => SD_clock, - o_clock_mode => clock_generator_mode, - o_trigger_receive => receive_next_bit, - o_trigger_send => send_next_bit - ); - - SD_clock_pulse_trigger: Altera_UP_SD_Signal_Trigger PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_signal => message_sent, - o_trigger => message_sent_trigger - ); - - data_line: Altera_UP_SD_Card_Buffer - port map - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - - -- 1 bit port to transmit and receive data on the data line. - i_begin => begin_data_line_operations, - i_sd_clock_pulse_trigger => data_line_sd_clock_pulse_trigger, - i_transmit => data_write, - i_1bit_data_in => b_SD_dat, - o_1bit_data_out => data_line_out, - o_operation_complete => data_line_done, - o_crc_passed => data_line_crc, - o_timed_out => data_line_timeout, - o_dat_direction => data_line_direction, - - -- 16 bit port to be accessed by a user circuit. - i_enable_16bit_port => i_buffer_enable, - i_address_16bit_port => i_buffer_address, - i_write_16bit => i_buffer_write, - i_16bit_data_in => i_buffer_data_in, - o_16bit_data_out => data_from_buffer - ); - data_line_sd_clock_pulse_trigger <= (data_write and send_next_bit) or ((not data_write) and receive_next_bit); - - -- Buffer output registers. - buff_regs: process(i_clock, i_reset_n, data_from_buffer) - begin - if (i_reset_n = '0') then - o_buffer_data_out <= (OTHERS=> '0'); - elsif (rising_edge(i_clock)) then - o_buffer_data_out <= data_from_buffer; - end if; - end process; - - -- Circuit outputs. - o_command_valid <= message_valid; - o_command_timed_out <= timeout_combined; - o_command_crc_failed <= not crc_combined; - o_SD_clock <= SD_clock; - b_SD_cmd <= data_to_CMD_line when (CMD_tristate_buffer_enable = '1') else 'Z'; - b_SD_dat <= data_line_out when (data_line_direction = '1') else 'Z'; - b_SD_dat3 <= 'Z'; -- Set SD card to SD mode. - -- SD card registers - o_SD_REG_card_identification_number <= SD_REG_card_identification_number; - o_SD_REG_relative_card_address <= SD_REG_relative_card_address; - o_SD_REG_operating_conditions_register <= SD_REG_operating_conditions_register; - o_SD_REG_card_specific_data <= SD_REG_card_specific_data; - o_SD_REG_status_register <= SD_REG_status_register; - o_SD_REG_response_R1 <= SD_REG_response_R1; - o_SD_REG_status_register_valid <= SD_REG_status_register_valid; - -end rtl; diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Memory_Block.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Memory_Block.vhd deleted file mode 100644 index 5b1d0cc..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Memory_Block.vhd +++ /dev/null @@ -1,296 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - --- megafunction wizard: %RAM: 2-PORT% --- GENERATION: STANDARD --- VERSION: WM1.0 --- MODULE: altsyncram - --- ============================================================ --- File Name: Altera_UP_SD_Card_Memory_Block.vhd --- Megafunction Name(s): --- altsyncram --- --- Simulation Library Files(s): --- altera_mf --- ============================================================ --- ************************************************************ --- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! --- --- 8.0 Build 215 05/29/2008 SJ Full Version --- ************************************************************ - - ---Copyright (C) 1991-2013 Altera Corporation ---Your use of Altera Corporation's design tools, logic functions ---and other software and tools, and its AMPP partner logic ---functions, and any output files from any of the foregoing ---(including device programming or simulation files), and any ---associated documentation or information are expressly subject ---to the terms and conditions of the Altera Program License ---Subscription Agreement, Altera MegaCore Function License ---Agreement, or other applicable license agreement, including, ---without limitation, that your use is for the sole purpose of ---programming logic devices manufactured by Altera and sold by ---Altera or its authorized distributors. Please refer to the ---applicable agreement for further details. - - -LIBRARY ieee; -USE ieee.std_logic_1164.all; - -LIBRARY altera_mf; -USE altera_mf.all; - -ENTITY Altera_UP_SD_Card_Memory_Block IS - PORT - ( - address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); - address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0); - clock_a : IN STD_LOGIC ; - clock_b : IN STD_LOGIC ; - data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0); - data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0); - enable_a : IN STD_LOGIC := '1'; - enable_b : IN STD_LOGIC := '1'; - wren_a : IN STD_LOGIC := '1'; - wren_b : IN STD_LOGIC := '1'; - q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); - q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) - ); -END Altera_UP_SD_Card_Memory_Block; - - -ARCHITECTURE SYN OF altera_up_sd_card_memory_block IS - - SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0); - SIGNAL sub_wire1 : STD_LOGIC_VECTOR (0 DOWNTO 0); - - - - COMPONENT altsyncram - GENERIC ( - address_reg_b : STRING; - clock_enable_input_a : STRING; - clock_enable_input_b : STRING; - clock_enable_output_a : STRING; - clock_enable_output_b : STRING; - indata_reg_b : STRING; - init_file : STRING; - init_file_layout : STRING; - intended_device_family : STRING; - lpm_type : STRING; - numwords_a : NATURAL; - numwords_b : NATURAL; - operation_mode : STRING; - outdata_aclr_a : STRING; - outdata_aclr_b : STRING; - outdata_reg_a : STRING; - outdata_reg_b : STRING; - power_up_uninitialized : STRING; - widthad_a : NATURAL; - widthad_b : NATURAL; - width_a : NATURAL; - width_b : NATURAL; - width_byteena_a : NATURAL; - width_byteena_b : NATURAL; - wrcontrol_wraddress_reg_b : STRING - ); - PORT ( - clocken0 : IN STD_LOGIC ; - clocken1 : IN STD_LOGIC ; - wren_a : IN STD_LOGIC ; - clock0 : IN STD_LOGIC ; - wren_b : IN STD_LOGIC ; - clock1 : IN STD_LOGIC ; - address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); - address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0); - q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); - q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0); - data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0); - data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0) - ); - END COMPONENT; - -BEGIN - q_a <= sub_wire0(15 DOWNTO 0); - q_b <= sub_wire1(0 DOWNTO 0); - - altsyncram_component : altsyncram - GENERIC MAP ( - address_reg_b => "CLOCK1", - clock_enable_input_a => "NORMAL", - clock_enable_input_b => "NORMAL", - clock_enable_output_a => "BYPASS", - clock_enable_output_b => "BYPASS", - indata_reg_b => "CLOCK1", - init_file => "initial_data.mif", - init_file_layout => "PORT_A", - intended_device_family => "Cyclone II", - lpm_type => "altsyncram", - numwords_a => 256, - numwords_b => 4096, - operation_mode => "BIDIR_DUAL_PORT", - outdata_aclr_a => "NONE", - outdata_aclr_b => "NONE", - outdata_reg_a => "UNREGISTERED", - outdata_reg_b => "UNREGISTERED", - power_up_uninitialized => "FALSE", - widthad_a => 8, - widthad_b => 12, - width_a => 16, - width_b => 1, - width_byteena_a => 1, - width_byteena_b => 1, - wrcontrol_wraddress_reg_b => "CLOCK1" - ) - PORT MAP ( - clocken0 => enable_a, - clocken1 => enable_b, - wren_a => wren_a, - clock0 => clock_a, - wren_b => wren_b, - clock1 => clock_b, - address_a => address_a, - address_b => address_b, - data_a => data_a, - data_b => data_b, - q_a => sub_wire0, - q_b => sub_wire1 - ); - - - -END SYN; - --- ============================================================ --- CNX file retrieval info --- ============================================================ --- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" --- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" --- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" --- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" --- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" --- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" --- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" --- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" --- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1" --- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "1" --- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" --- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" --- Retrieval info: PRIVATE: CLRdata NUMERIC "0" --- Retrieval info: PRIVATE: CLRq NUMERIC "0" --- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" --- Retrieval info: PRIVATE: CLRrren NUMERIC "0" --- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" --- Retrieval info: PRIVATE: CLRwren NUMERIC "0" --- Retrieval info: PRIVATE: Clock NUMERIC "5" --- Retrieval info: PRIVATE: Clock_A NUMERIC "0" --- Retrieval info: PRIVATE: Clock_B NUMERIC "0" --- Retrieval info: PRIVATE: ECC NUMERIC "0" --- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" --- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" --- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1" --- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" --- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" --- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II" --- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" --- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" --- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" --- Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096" --- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1" --- Retrieval info: PRIVATE: MIFfilename STRING "initial_data.mif" --- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3" --- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" --- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" --- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" --- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" --- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" --- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" --- Retrieval info: PRIVATE: REGdata NUMERIC "1" --- Retrieval info: PRIVATE: REGq NUMERIC "0" --- Retrieval info: PRIVATE: REGrdaddress NUMERIC "0" --- Retrieval info: PRIVATE: REGrren NUMERIC "0" --- Retrieval info: PRIVATE: REGwraddress NUMERIC "1" --- Retrieval info: PRIVATE: REGwren NUMERIC "1" --- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" --- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" --- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" --- Retrieval info: PRIVATE: VarWidth NUMERIC "1" --- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16" --- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "1" --- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16" --- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "1" --- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" --- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1" --- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" --- Retrieval info: PRIVATE: enable NUMERIC "1" --- Retrieval info: PRIVATE: rden NUMERIC "0" --- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1" --- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "NORMAL" --- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "NORMAL" --- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" --- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" --- Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1" --- Retrieval info: CONSTANT: INIT_FILE STRING "initial_data.mif" --- Retrieval info: CONSTANT: INIT_FILE_LAYOUT STRING "PORT_A" --- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II" --- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" --- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" --- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "4096" --- Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT" --- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" --- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" --- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED" --- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" --- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" --- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" --- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "12" --- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" --- Retrieval info: CONSTANT: WIDTH_B NUMERIC "1" --- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" --- Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1" --- Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1" --- Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL address_a[7..0] --- Retrieval info: USED_PORT: address_b 0 0 12 0 INPUT NODEFVAL address_b[11..0] --- Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT NODEFVAL clock_a --- Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL clock_b --- Retrieval info: USED_PORT: data_a 0 0 16 0 INPUT NODEFVAL data_a[15..0] --- Retrieval info: USED_PORT: data_b 0 0 1 0 INPUT NODEFVAL data_b[0..0] --- Retrieval info: USED_PORT: enable_a 0 0 0 0 INPUT VCC enable_a --- Retrieval info: USED_PORT: enable_b 0 0 0 0 INPUT VCC enable_b --- Retrieval info: USED_PORT: q_a 0 0 16 0 OUTPUT NODEFVAL q_a[15..0] --- Retrieval info: USED_PORT: q_b 0 0 1 0 OUTPUT NODEFVAL q_b[0..0] --- Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT VCC wren_a --- Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT VCC wren_b --- Retrieval info: CONNECT: @data_a 0 0 16 0 data_a 0 0 16 0 --- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0 --- Retrieval info: CONNECT: q_a 0 0 16 0 @q_a 0 0 16 0 --- Retrieval info: CONNECT: q_b 0 0 1 0 @q_b 0 0 1 0 --- Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0 --- Retrieval info: CONNECT: @data_b 0 0 1 0 data_b 0 0 1 0 --- Retrieval info: CONNECT: @address_b 0 0 12 0 address_b 0 0 12 0 --- Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0 --- Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0 --- Retrieval info: CONNECT: @clocken0 0 0 0 0 enable_a 0 0 0 0 --- Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0 --- Retrieval info: CONNECT: @clocken1 0 0 0 0 enable_b 0 0 0 0 --- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.vhd TRUE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.inc FALSE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.cmp TRUE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.bsf TRUE FALSE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_inst.vhd FALSE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_waveforms.html TRUE --- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_wave*.jpg FALSE --- Retrieval info: LIB_FILE: altera_mf diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Response_Receiver.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Response_Receiver.vhd deleted file mode 100644 index 7b195b6..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Card_Response_Receiver.vhd +++ /dev/null @@ -1,308 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - -------------------------------------------------------------------------------------- --- This module looks at the data on the CMD line and waits to receive a response. --- It begins examining the data lines when the i_begin signal is asserted. It then --- waits for a first '0'. It then proceeds to store as many bits as are required by --- the response packet. Each message bit passes through the CRC7 circuit so that --- the CRC check sum can be verified at the end of transmission. The circuit then produces --- the o_data and o_CRC_passed outputs to indicate the message received and if the CRC --- check passed. --- --- If for some reason the requested response does not arrive within 56 clock cycles --- then the circuit will produce a '1' on the o_timeout output. In such a case the --- o_data should be ignored. --- --- In case of a response that is not 001, 010, 011 or 110, the circuit expects --- no response. --- --- A signal o_done is asserted when the circuit has completed response retrieval. In --- a case when a response is not expected, just wait for the CD Card to process the --- command. This is done by waiting 8 (=PROCESSING_DELAY) clock cycles. --- --- NOTES/REVISIONS: -------------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; - -entity Altera_UP_SD_Card_Response_Receiver is - generic ( - TIMEOUT : std_logic_vector(7 downto 0) := "00111000"; - BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000"; - PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000" - ); - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_begin : in std_logic; - i_scan_pulse : in std_logic; - i_datain : in std_logic; - i_wait_cmd_busy : in std_logic; - i_response_type : in std_logic_vector(2 downto 0); - o_data : out std_logic_vector(127 downto 0); - o_CRC_passed : out std_logic; - o_timeout : out std_logic; - o_done : out std_logic - ); -end entity; - -architecture rtl of Altera_UP_SD_Card_Response_Receiver is - - component Altera_UP_SD_CRC7_Generator - port - ( - i_clock : in std_logic; - i_enable : in std_logic; - i_reset_n : in std_logic; - i_shift : in std_logic; - i_datain : in std_logic; - o_dataout : out std_logic; - o_crcout : out std_logic_vector(6 downto 0) - ); - end component; - -- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state - -- of the switches. - type state_type is (s_WAIT_BEGIN, s_WAIT_END, s_WAIT_PROCESSING_DELAY, s_WAIT_BUSY, s_WAIT_BUSY_END, s_WAIT_BEGIN_DEASSERT); - - -- Register to hold the current state - signal current_state : state_type; - signal next_state : state_type; - - -- Local wires - -- REGISTERED - signal registered_data_input : std_logic_vector(127 downto 0); - signal response_incoming : std_logic; - signal counter, timeout_counter : std_logic_vector(7 downto 0); - signal crc_shift, keep_reading_bits, shift_crc_bits : std_logic; - -- UNREGISTERED - signal limit, limit_minus_1 : std_logic_vector(7 downto 0); - signal check_crc : std_logic; - signal CRC_bits : std_logic_vector(6 downto 0); - signal start_reading_bits, operation_complete, enable_crc_unit : std_logic; -begin - -- Control FSM. Begin operation when i_begin is raised, then wait for the operation to end and i_begin to be deasserted. - state_regs: process(i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - current_state <= s_WAIT_BEGIN; - elsif (rising_edge(i_clock)) then - current_state <= next_state; - end if; - end process; - - state_transitions: process(current_state, i_begin, operation_complete, timeout_counter, i_wait_cmd_busy, i_scan_pulse, i_datain) - begin - case current_state is - when s_WAIT_BEGIN => - if (i_begin = '1') then - next_state <= s_WAIT_END; - else - next_state <= s_WAIT_BEGIN; - end if; - - when s_WAIT_END => - if (operation_complete = '1') then - if (timeout_counter = TIMEOUT) then - next_state <= s_WAIT_BEGIN_DEASSERT; - else - next_state <= s_WAIT_PROCESSING_DELAY; - end if; - - else - next_state <= s_WAIT_END; - end if; - - when s_WAIT_PROCESSING_DELAY => - if (timeout_counter = PROCESSING_DELAY) then - if (i_wait_cmd_busy = '1') then - next_state <= s_WAIT_BUSY; - else - next_state <= s_WAIT_BEGIN_DEASSERT; - end if; - else - next_state <= s_WAIT_PROCESSING_DELAY; - end if; - - when s_WAIT_BUSY => - if ((i_scan_pulse = '1') and (i_datain = '0')) then - next_state <= s_WAIT_BUSY_END; - else - if (timeout_counter = BUSY_WAIT) then - -- If the card did not become busy, then it would not have raised the optional busy signal. - -- In such a case, proceeed further as the command has finished correctly. - next_state <= s_WAIT_BEGIN_DEASSERT; - else - next_state <= s_WAIT_BUSY; - end if; - end if; - - when s_WAIT_BUSY_END => - if ((i_scan_pulse = '1') and (i_datain = '1')) then - next_state <= s_WAIT_BEGIN_DEASSERT; - else - next_state <= s_WAIT_BUSY_END; - end if; - - when s_WAIT_BEGIN_DEASSERT => - if (i_begin = '1') then - next_state <= s_WAIT_BEGIN_DEASSERT; - else - next_state <= s_WAIT_BEGIN; - end if; - when others => - next_state <= s_WAIT_BEGIN; - end case; - end process; - - -- Store the response as it appears on the i_datain line. - received_data_buffer: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - registered_data_input <= (OTHERS=>'0'); - elsif (rising_edge(i_clock)) then - -- Only read new data and update the counter value when the scan pulse is high. - if (i_scan_pulse = '1') then - if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then - registered_data_input(127 downto 1) <= registered_data_input(126 downto 0); - registered_data_input(0) <= i_datain; - end if; - end if; - end if; - end process; - - -- Counter received bits - data_read_counter: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - counter <= (OTHERS=>'0'); - elsif (rising_edge(i_clock)) then - -- Reset he counter every time you being reading the response. - if (current_state = s_WAIT_BEGIN) then - counter <= (OTHERS => '0'); - end if; - -- Update the counter value when the scan pulse is high. - if (i_scan_pulse = '1') then - if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then - counter <= counter + '1'; - end if; - end if; - end if; - end process; - operation_complete <= '1' when (((counter = limit) and (not (limit = "00000000"))) or - (timeout_counter = TIMEOUT) or - ((timeout_counter = PROCESSING_DELAY) and (limit = "00000000"))) else '0'; - - -- Count the number of scan pulses before the response is received. If the counter - -- exceeds TIMEOUT value, then an error must have occured when the SD card received a message. - timeout_counter_control: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - timeout_counter <= (OTHERS=>'0'); - elsif (rising_edge(i_clock)) then - -- Reset the counter every time you begin reading the response. - if ((current_state = s_WAIT_BEGIN) or ((current_state = s_WAIT_END) and (operation_complete = '1') and (not (timeout_counter = TIMEOUT)))) then - timeout_counter <= (OTHERS => '0'); - end if; - -- Update the counter value when the scan pulse is high. - if (i_scan_pulse = '1') then - if (((start_reading_bits = '0') and (keep_reading_bits = '0') and (current_state = s_WAIT_END) and (not (timeout_counter = TIMEOUT))) or - (current_state = s_WAIT_PROCESSING_DELAY) or (current_state = s_WAIT_BUSY)) then - timeout_counter <= timeout_counter + '1'; - end if; - end if; - end if; - end process; - - -- Enable data storing only after you see the first 0. - read_enable_logic: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - keep_reading_bits <= '0'; - elsif (rising_edge(i_clock)) then - if (i_scan_pulse = '1') then - if ((start_reading_bits = '1') or ((keep_reading_bits = '1') and (not (counter = limit_minus_1)))) then - keep_reading_bits <= '1'; - else - keep_reading_bits <= '0'; - end if; - end if; - end if; - end process; - start_reading_bits <= '1' when ((current_state = s_WAIT_END) and (i_datain = '0') and - (counter = "00000000") and (not (limit = "00000000"))) else '0'; - - -- CRC7 checker. - crc_checker: Altera_UP_SD_CRC7_Generator PORT MAP - ( - i_clock => i_clock, - i_reset_n => i_reset_n, - i_enable => enable_crc_unit, - i_shift => shift_crc_bits, - i_datain => registered_data_input(7), - o_crcout => CRC_bits - ); - enable_crc_unit <= '1' when ((i_scan_pulse = '1') and (current_state = s_WAIT_END)) else '0'; - - -- Clear CRC7 registers before processing the response bits - crc_control_register: process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - shift_crc_bits <= '1'; - elsif (rising_edge(i_clock)) then - -- Reset he counter every time you being reading the response. - if (current_state = s_WAIT_BEGIN) then - -- clear the CRC7 contents before you process the next message. - shift_crc_bits <= '1'; - end if; - -- Only read new data and update the counter value when the scan pulse is high. - if (i_scan_pulse = '1') then - if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then - if (counter = "00000111") then - -- Once the 7-bits of the CRC checker have been cleared you can process the message and - -- compute its CRC bits to verify the validity of the transmission. - shift_crc_bits <= '0'; - end if; - end if; - end if; - end if; - end process; - - -- Indicate the number of bits to expect in the response packet. - limit <= "00110000" when ((i_response_type = "001") or - (i_response_type = "011") or - (i_response_type = "110")) else - "10001000" when (i_response_type = "010") else - "00000000"; -- No response - limit_minus_1 <= - "00101111" when ((i_response_type = "001") or - (i_response_type = "011") or - (i_response_type = "110")) else - "10000111" when (i_response_type = "010") else - "00000000"; -- No response - - check_crc <= '1' when ((i_response_type = "001") or (i_response_type = "110")) else '0'; - - -- Generate Circuit outputs - o_data <= (registered_data_input(127 downto 1) & '1') when (i_response_type = "010") else - (CONV_STD_LOGIC_VECTOR(0, 96) & registered_data_input(39 downto 8)); - - o_CRC_passed <= '1' when ((check_crc = '0') or - ((registered_data_input(0) = '1') and (CRC_bits = registered_data_input(7 downto 1)))) else '0'; - - o_timeout <= '1' when (timeout_counter = TIMEOUT) else '0'; - o_done <= '1' when (current_state = s_WAIT_BEGIN_DEASSERT) else '0'; -end rtl; \ No newline at end of file diff --git a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Signal_Trigger.vhd b/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Signal_Trigger.vhd deleted file mode 100644 index 7529de8..0000000 --- a/ip/altera_up_sd_card_avalon_interface_mod/hdl/Altera_UP_SD_Signal_Trigger.vhd +++ /dev/null @@ -1,57 +0,0 @@ --- (C) 2001-2015 Altera Corporation. All rights reserved. --- Your use of Altera Corporation's design tools, logic functions and other --- software and tools, and its AMPP partner logic functions, and any output --- files any of the foregoing (including device programming or simulation --- files), and any associated documentation or information are expressly subject --- to the terms and conditions of the Altera Program License Subscription --- Agreement, Altera MegaCore Function License Agreement, or other applicable --- license agreement, including, without limitation, that your use is for the --- sole purpose of programming logic devices manufactured by Altera and sold by --- Altera or its authorized distributors. Please refer to the applicable --- agreement for further details. - - ---------------------------------------------------------------------------------------- --- This module generates a trigger pulse every time it sees a transition --- from 0 to 1 on signal i_signal. --- --- NOTES/REVISIONS: ---------------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity Altera_UP_SD_Signal_Trigger is - - port - ( - i_clock : in std_logic; - i_reset_n : in std_logic; - i_signal : in std_logic; - o_trigger : out std_logic - ); - -end entity; - -architecture rtl of Altera_UP_SD_Signal_Trigger is - - -- Local wires - -- REGISTERED - signal local_reg : std_logic; -begin - - process (i_clock, i_reset_n) - begin - if (i_reset_n = '0') then - local_reg <= '0'; - else - if (rising_edge(i_clock)) then - local_reg <= i_signal; - end if; - end if; - end process; - - o_trigger <= '1' when ((local_reg = '0') and (i_signal = '1')) - else '0'; -end rtl; \ No newline at end of file