From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- peripherals/hsmc4/hsmc4.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 peripherals/hsmc4/hsmc4.c (limited to 'peripherals/hsmc4/hsmc4.c') diff --git a/peripherals/hsmc4/hsmc4.c b/peripherals/hsmc4/hsmc4.c new file mode 100644 index 0000000..350da99 --- /dev/null +++ b/peripherals/hsmc4/hsmc4.c @@ -0,0 +1,247 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "hsmc4.h" + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ +/// Store value of current read only HSMC4_CTRL register. +static unsigned int hsmc4Ctrl; + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller has terminated the command. +/// read mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_CommandDone(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_CMDDONE) == AT91C_HSMC4_CMDDONE); +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/// Sets the mode of the HSMC4 to one of the following values: +/// - AT91C_HSMC4_PAGESIZE +/// - AT91C_HSMC4_WSPARE +/// - AT91C_HSMC4_RSPARE +/// - AT91C_HSMC4_EDGECTRL +/// - AT91C_HSMC4_RBEDGE +/// - AT91C_HSMC4_DTOCYC +/// - AT91C_HSMC4_DTOMUL +/// \param mode mode. +//------------------------------------------------------------------------------ +void HSMC4_SetMode(unsigned int mode) +{ + AT91C_BASE_HSMC4->HSMC4_CFG = mode; +} + +//----------------------------------------------------------------------------- +/// Reset the HSMC4 Nand flash controll host. +//----------------------------------------------------------------------------- +void HSMC4_ResetNfc(void) +{ + //Disable all the HSMC4 interrupts + AT91C_BASE_HSMC4 -> HSMC4_IDR = 0xFFFFFFFF; + AT91C_BASE_HSMC4 -> HSMC4_CTRL = 0; + hsmc4Ctrl = 0; +} + +//----------------------------------------------------------------------------- +/// Enable NAND flsah controller host through the APB interface. +//----------------------------------------------------------------------------- +void HSMC4_EnableNfc(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_NFCEN; + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; +} + +//----------------------------------------------------------------------------- +/// Acticated and perform a data transfer between the Host and a Nand Flash. +//----------------------------------------------------------------------------- +void HSMC4_EnableNfcHost(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_HOSTEN; + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; +} + +//----------------------------------------------------------------------------- +/// Enable host transfer data from the internal SRAM to the memory device. +//----------------------------------------------------------------------------- +void HSMC4_EnableHostTransfer(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_HOSTWR; + // The HOSTWR field can be modified if the host controller is not busy. + while((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; + while((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); +} + +//----------------------------------------------------------------------------- +/// Enables the host main controller reads both main and spare area in read mode. +//----------------------------------------------------------------------------- +void HSMC4_EnableSpareRead(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG |= AT91C_HSMC4_RSPARE; +} + +//----------------------------------------------------------------------------- +/// The host main controller skips spare area in read mode. +//----------------------------------------------------------------------------- +void HSMC4_DisableSpareRead(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG &= 0xFFFFFDFF; +} + +//----------------------------------------------------------------------------- +/// Enables the host main controller writes both main and spare area in write +/// mode. +//----------------------------------------------------------------------------- +void HSMC4_EnableSpareWrite(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG |= AT91C_HSMC4_WSPARE; +} + +//----------------------------------------------------------------------------- +/// The host main controller skips spare area in write mode. +//----------------------------------------------------------------------------- +void HSMC4_DisableSpareWrite(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG &= 0xFFFFFEFF; +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller reads both main and spare area in +/// read mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isSpareRead(void) +{ + return (((AT91C_BASE_HSMC4->HSMC4_CFG) >> 9) & 0x1); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller writes both main and spare area in +/// write mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isSpareWrite(void) +{ + return (((AT91C_BASE_HSMC4->HSMC4_CFG) >> 8) & 0x1); +} + + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller has terminated the data transmission. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_TransferComplete(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_XFRDONE) == AT91C_HSMC4_XFRDONE); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if edge has been detected on the Ready/Busy line. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isReadyBusy(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_RBEDGE0) == AT91C_HSMC4_RBEDGE0); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the Controller is activated and accesses the memory device. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isNfcBusy(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the ecc is ready +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isEccReady(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_ECCRDY) == AT91C_HSMC4_ECCRDY); +} + +//----------------------------------------------------------------------------- +/// Returns the current status register of the HSMC4 peripheral. This +/// resets the internal value of the status register, so further read may yield +/// different values. +//----------------------------------------------------------------------------- +unsigned int HSMC4_GetStatus(void) +{ + return AT91C_BASE_HSMC4->HSMC4_SR; +} + +//------------------------------------------------------------------------------ +// HOST command functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Returns 1 if the host controller is busy. +/// otherwise returns 0. +//------------------------------------------------------------------------------ +unsigned char HSMC4_isHostBusy(void) +{ + return (((*((volatile unsigned int *) (CMD_BASE_ADDR + AT91C_HSMC4_HOSTCMD))) & 0x8000000) == 0x8000000); +} + +//------------------------------------------------------------------------------ +/// Uses the HOST nandflash conntroller to send a command to the NFC +/// \param cmd command to send. +/// \param addressCycle address cycle when command access id decoded. +/// \param cycle0 address at first cycle. +//------------------------------------------------------------------------------ +void HSMC4_SendCommand (unsigned int cmd, unsigned int addressCycle, unsigned int cycle0) +{ + volatile unsigned int *pCommandAddress; + // Wait until host controller is not busy. + while(HSMC4_isHostBusy()); + // Send the command plus the ADDR_CYCLE + pCommandAddress = (volatile unsigned int *) (cmd + CMD_BASE_ADDR); + AT91C_BASE_HSMC4->HSMC4_ADDR = cycle0; + *pCommandAddress = addressCycle; + while( !HSMC4_CommandDone()); +} + + -- cgit v1.2.3