summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authordanicampora <danicampora@gmail.com>2015-02-22 17:31:26 +0100
committerdanicampora <danicampora@gmail.com>2015-02-22 17:50:50 +0100
commit33ddb566a7565b4fba4a68939d43bcdb5f132836 (patch)
treebd348fd647ca26de8e05b18e411bcf7323a09a8c
parent5c047b97f2e41b51f8314f6ee06788b1d9246dbf (diff)
downloadmicropython-33ddb566a7565b4fba4a68939d43bcdb5f132836.tar.gz
micropython-33ddb566a7565b4fba4a68939d43bcdb5f132836.zip
cc3200: Remove dependencies from FreeRTOS.
Use the simplelink wrappers instead. This is one step further towards having a single module for the cc3200 and the cc3100.
-rw-r--r--cc3200/fatfs/src/drivers/sflash_diskio.c31
-rw-r--r--cc3200/ftp/ftp.c1
-rw-r--r--cc3200/ftp/updater.c12
-rw-r--r--cc3200/hal/cc3200_hal.h3
-rw-r--r--cc3200/main.c1
-rw-r--r--cc3200/misc/FreeRTOSHooks.c4
-rw-r--r--cc3200/mods/modpyb.c3
-rw-r--r--cc3200/mods/modwlan.c37
-rw-r--r--cc3200/mods/modwlan.h7
-rw-r--r--cc3200/mods/pybsd.c2
-rw-r--r--cc3200/mptask.c1
-rw-r--r--cc3200/serverstask.c1
-rw-r--r--cc3200/simplelink/cc_pal.c5
-rw-r--r--cc3200/simplelink/oslib/osi_freertos.c7
-rw-r--r--cc3200/simplelink/user.h1
-rw-r--r--cc3200/telnet/telnet.c9
-rw-r--r--cc3200/util/hash.c57
-rw-r--r--cc3200/util/hash.h26
18 files changed, 91 insertions, 117 deletions
diff --git a/cc3200/fatfs/src/drivers/sflash_diskio.c b/cc3200/fatfs/src/drivers/sflash_diskio.c
index 54343487a2..f463376795 100644
--- a/cc3200/fatfs/src/drivers/sflash_diskio.c
+++ b/cc3200/fatfs/src/drivers/sflash_diskio.c
@@ -10,12 +10,6 @@
#include "debug.h"
#include "modwlan.h"
-#ifdef USE_FREERTOS
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-#endif
-
#define SFLASH_TIMEOUT_MAX_MS 5500
#define SFLASH_WAIT_TIME_MS 5
@@ -38,18 +32,15 @@ static bool sflash_access (_u32 mode, _i32 (* sl_FsFunction)(_i32 FileHdl, _u32
bool retval = false;
// wlan must be enabled in order to access the serial flash
-#ifdef USE_FREERTOS
- xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
-#endif
+ sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
+
if (0 == sl_FsOpen(sflash_block_name, mode, NULL, &fileHandle)) {
if (SFLASH_BLOCK_SIZE == sl_FsFunction (fileHandle, 0, sflash_block_cache, SFLASH_BLOCK_SIZE)) {
retval = true;
}
sl_FsClose (fileHandle, NULL, NULL, 0);
}
-#ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
-#endif
+ sl_LockObjUnlock (&wlan_LockObj);
return retval;
}
@@ -64,16 +55,12 @@ DRESULT sflash_disk_init (void) {
// Proceed to format the memory if not done yet
for (int i = 0; i < SFLASH_BLOCK_COUNT; i++) {
print_block_name (i);
- #ifdef USE_FREERTOS
- xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
- #endif
+ sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
// Create the block file if it doesn't exist
if (sl_FsGetInfo(sflash_block_name, 0, &FsFileInfo) < 0) {
if (!sl_FsOpen(sflash_block_name, FS_MODE_OPEN_CREATE(SFLASH_BLOCK_SIZE, 0), NULL, &fileHandle)) {
sl_FsClose(fileHandle, NULL, NULL, 0);
- #ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
- #endif
+ sl_LockObjUnlock (&wlan_LockObj);
memset(sflash_block_cache, 0xFF, SFLASH_BLOCK_SIZE);
if (!sflash_access(FS_MODE_OPEN_WRITE, sl_FsWrite)) {
return RES_ERROR;
@@ -81,15 +68,11 @@ DRESULT sflash_disk_init (void) {
}
else {
// Unexpected failure while creating the file
- #ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
- #endif
+ sl_LockObjUnlock (&wlan_LockObj);
return RES_ERROR;
}
}
- #ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
- #endif
+ sl_LockObjUnlock (&wlan_LockObj);
}
sflash_init_done = true;
sflash_prblock = UINT32_MAX;
diff --git a/cc3200/ftp/ftp.c b/cc3200/ftp/ftp.c
index f43818fe19..dee29a39b5 100644
--- a/cc3200/ftp/ftp.c
+++ b/cc3200/ftp/ftp.c
@@ -31,7 +31,6 @@
#include "py/mpconfig.h"
#include MICROPY_HAL_H
#include "py/obj.h"
-#include "osi.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
diff --git a/cc3200/ftp/updater.c b/cc3200/ftp/updater.c
index 1fda9f62e2..2e240c7226 100644
--- a/cc3200/ftp/updater.c
+++ b/cc3200/ftp/updater.c
@@ -60,9 +60,7 @@ bool updater_check_path (void *path) {
bool updater_start (void) {
_u32 AccessModeAndMaxSize = FS_MODE_OPEN_WRITE;
SlFsFileInfo_t FsFileInfo;
-#ifdef USE_FREERTOS
- xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
-#endif
+ sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
if (0 != sl_FsGetInfo((_u8 *)updater_data.path, 0, &FsFileInfo)) {
// file doesn't exist, create it
AccessModeAndMaxSize = FS_MODE_OPEN_CREATE(updater_data.fsize, 0);
@@ -71,9 +69,7 @@ bool updater_start (void) {
updater_data.foffset = 0;
return true;
}
-#ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
-#endif
+ sl_LockObjUnlock (&wlan_LockObj);
return false;
}
@@ -115,7 +111,5 @@ void updater_finnish (void) {
}
}
updater_data.fhandle = -1;
-#ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
-#endif
+ sl_LockObjUnlock (&wlan_LockObj);
}
diff --git a/cc3200/hal/cc3200_hal.h b/cc3200/hal/cc3200_hal.h
index 71b6442391..5ce93edd2a 100644
--- a/cc3200/hal/cc3200_hal.h
+++ b/cc3200/hal/cc3200_hal.h
@@ -39,6 +39,9 @@
#define HAL_SYSTICK_PERIOD_US 1000U
#define UTILS_DELAY_US_TO_COUNT(us) (((us) * HAL_FCPU_MHZ) / 3)
+#define HAL_NVIC_INT_CTRL_REG (*((volatile uint32_t *) 0xE000ED04 ) )
+#define HAL_VECTACTIVE_MASK (0x1FUL)
+
/******************************************************************************
DEFINE TYPES
******************************************************************************/
diff --git a/cc3200/main.c b/cc3200/main.c
index 54d3025ba1..f07479fdde 100644
--- a/cc3200/main.c
+++ b/cc3200/main.c
@@ -32,7 +32,6 @@
#include MICROPY_HAL_H
#include "mptask.h"
#include "simplelink.h"
-#include "osi.h"
#include "debug.h"
/******************************************************************************
diff --git a/cc3200/misc/FreeRTOSHooks.c b/cc3200/misc/FreeRTOSHooks.c
index cfaae73108..a052f0dabc 100644
--- a/cc3200/misc/FreeRTOSHooks.c
+++ b/cc3200/misc/FreeRTOSHooks.c
@@ -36,8 +36,6 @@
#include "osi.h"
-#ifdef USE_FREERTOS
-
//*****************************************************************************
//
//! \brief Application defined idle task hook
@@ -115,5 +113,3 @@ void vApplicationTickHook( void )
{
HAL_IncrementTick();
}
-
-#endif //USE_FREERTOS
diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c
index 80a4f74aca..4cfeeec910 100644
--- a/cc3200/mods/modpyb.c
+++ b/cc3200/mods/modpyb.c
@@ -59,12 +59,13 @@
#include "pybi2c.h"
#include "pybsd.h"
#include "utils.h"
+#include "gccollect.h"
#ifdef DEBUG
extern OsiTaskHandle mpTaskHandle;
extern OsiTaskHandle svTaskHandle;
-extern TaskHandle_t xSimpleLinkSpawnTaskHndl;
+extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
#endif
/// \module pyb - functions related to the pyboard
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index e27aa84cea..9cab92188d 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -37,17 +37,10 @@
#include "modwlan.h"
#include "pybioctl.h"
#include "pybuart.h"
-#include "osi.h"
#include "debug.h"
#include "serverstask.h"
#include "mpexception.h"
-#ifdef USE_FREERTOS
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-#endif
-
/******************************************************************************
DEFINE TYPES
@@ -88,7 +81,6 @@ typedef struct _wlan_obj_t {
uint8_t macAddr[SL_MAC_ADDR_LEN];
uint8_t ssid_name[33];
uint8_t bssid[6];
- bool servers_enabled;
// IPVv4 data
uint32_t ip;
@@ -152,7 +144,7 @@ STATIC wlan_obj_t wlan_obj;
/******************************************************************************
DECLARE EXPORTED DATA
******************************************************************************/
-SemaphoreHandle_t xWlanSemaphore = NULL;
+OsiLockObj_t wlan_LockObj;
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
@@ -355,11 +347,7 @@ void wlan_init0 (void) {
wlan_obj.mode = -1;
wlan_obj.base.type = NULL;
memset (wlan_obj.macAddr, 0, SL_MAC_ADDR_LEN);
-#ifdef USE_FREERTOS
- if (NULL == xWlanSemaphore) {
- xWlanSemaphore = xSemaphoreCreateBinary();
- }
-#endif
+ ASSERT(OSI_OK == sl_LockObjCreate(&wlan_LockObj, "WlanLock"));
wlan_initialize_data ();
}
@@ -369,9 +357,7 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
if (mode == ROLE_STA || mode == ROLE_AP || mode == ROLE_P2P) {
if (wlan_obj.mode < 0) {
wlan_obj.mode = sl_Start(0, 0, 0);
- #ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
- #endif
+ sl_LockObjUnlock (&wlan_LockObj);
}
// get the mac address
@@ -492,9 +478,7 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
void wlan_sl_disable (void) {
if (wlan_obj.mode >= 0) {
- #ifdef USE_FREERTOS
- xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
- #endif
+ sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
wlan_obj.mode = -1;
sl_Stop(SL_STOP_TIMEOUT);
}
@@ -543,14 +527,10 @@ STATIC void wlan_initialize_data (void) {
STATIC void wlan_reenable (SlWlanMode_t mode) {
// Stop and start again
wlan_obj.mode = -1;
-#ifdef USE_FREERTOS
- xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
-#endif
+ sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
sl_Stop(SL_STOP_TIMEOUT);
wlan_obj.mode = sl_Start(0, 0, 0);
-#ifdef USE_FREERTOS
- xSemaphoreGive (xWlanSemaphore);
-#endif
+ sl_LockObjUnlock (&wlan_LockObj);
ASSERT (wlan_obj.mode == mode);
}
@@ -647,7 +627,8 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
SlWlanMode_t mode = mp_obj_get_int(args[0]);
// Stop all other processes using the wlan engine
- if ( (wlan_obj.servers_enabled = servers_are_enabled()) ) {
+ bool servers_enabled;
+ if ( (servers_enabled = servers_are_enabled()) ) {
wlan_servers_stop();
}
if (mode == ROLE_AP) {
@@ -667,7 +648,7 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
}
// Start the servers again
- if (wlan_obj.servers_enabled) {
+ if (servers_enabled) {
servers_enable ();
}
} else if (wlan_obj.mode < 0) {
diff --git a/cc3200/mods/modwlan.h b/cc3200/mods/modwlan.h
index 7a84f2a511..3143d4063d 100644
--- a/cc3200/mods/modwlan.h
+++ b/cc3200/mods/modwlan.h
@@ -48,12 +48,7 @@ typedef enum
/******************************************************************************
DECLARE PUBLIC DATA
******************************************************************************/
-#ifdef USE_FREERTOS
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-extern SemaphoreHandle_t xWlanSemaphore;
-#endif
+extern _SlLockObj_t wlan_LockObj;
/******************************************************************************
DECLARE PUBLIC FUNCTIONS
diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c
index 269c65ad56..c9d6512b21 100644
--- a/cc3200/mods/pybsd.c
+++ b/cc3200/mods/pybsd.c
@@ -40,7 +40,7 @@
#include "pybpin.h"
#include "pybsd.h"
#include "ff.h"
-#include "osi.h"
+#include "simplelink.h"
#include "debug.h"
#include "mpexception.h"
diff --git a/cc3200/mptask.c b/cc3200/mptask.c
index acab12eaea..5bfb274143 100644
--- a/cc3200/mptask.c
+++ b/cc3200/mptask.c
@@ -43,7 +43,6 @@
#include "gccollect.h"
#include "gchelper.h"
#include "readline.h"
-#include "osi.h"
#include "mptask.h"
#include "mperror.h"
#include "simplelink.h"
diff --git a/cc3200/serverstask.c b/cc3200/serverstask.c
index f942e2f679..af28058fd2 100644
--- a/cc3200/serverstask.c
+++ b/cc3200/serverstask.c
@@ -30,7 +30,6 @@
#include "py/mpconfig.h"
#include MICROPY_HAL_H
#include "py/misc.h"
-#include "osi.h"
#include "simplelink.h"
#include "serverstask.h"
#include "modwlan.h"
diff --git a/cc3200/simplelink/cc_pal.c b/cc3200/simplelink/cc_pal.c
index 5043d50a03..be90104407 100644
--- a/cc3200/simplelink/cc_pal.c
+++ b/cc3200/simplelink/cc_pal.c
@@ -57,11 +57,6 @@
#include <interrupt.h>
#include <utils.h>
-//OSLib includes
-#if defined(SL_PLATFORM_MULTI_THREADED)
-#include <osi.h>
-#endif
-
#define REG_INT_MASK_SET 0x400F7088
#define REG_INT_MASK_CLR 0x400F708C
diff --git a/cc3200/simplelink/oslib/osi_freertos.c b/cc3200/simplelink/oslib/osi_freertos.c
index e8b617f846..8684d8f5db 100644
--- a/cc3200/simplelink/oslib/osi_freertos.c
+++ b/cc3200/simplelink/oslib/osi_freertos.c
@@ -176,12 +176,7 @@ OsiReturnVal_e osi_SyncObjSignal(OsiSyncObj_t* pSyncObj)
return OSI_INVALID_PARAMS;
}
- if(pdTRUE != xSemaphoreGive( *pSyncObj ))
- {
- //In case of Semaphore, you are expected to get this if multiple sem
- // give is called before sem take
- return OSI_OK;
- }
+ xSemaphoreGive( *pSyncObj );
return OSI_OK;
}
diff --git a/cc3200/simplelink/user.h b/cc3200/simplelink/user.h
index 82cc420ce4..3f6a691c4e 100644
--- a/cc3200/simplelink/user.h
+++ b/cc3200/simplelink/user.h
@@ -66,6 +66,7 @@ extern "C" {
#include <string.h>
#include "cc_pal.h"
+#include "debug.h"
/*!
\def MAX_CONCURRENT_ACTIONS
diff --git a/cc3200/telnet/telnet.c b/cc3200/telnet/telnet.c
index 6ed97cc0ed..7d11df913b 100644
--- a/cc3200/telnet/telnet.c
+++ b/cc3200/telnet/telnet.c
@@ -447,10 +447,8 @@ static void telnet_parse_input (uint8_t *str, int16_t *len) {
static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len) {
int32_t retries = 0;
-#ifdef USE_FREERTOS
// abort sending if we happen to be within interrupt context
- if ((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0) {
-#endif
+ if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0) {
do {
_i16 result = sl_Send(sd, pBuf, len, 0);
if (result > 0) {
@@ -461,11 +459,10 @@ static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len)
}
HAL_Delay (TELNET_WAIT_TIME_MS);
} while (++retries <= TELNET_TX_RETRIES_MAX);
-#ifdef USE_FREERTOS
- } else {
+ }
+ else {
// TODO: blink the BLD
}
-#endif
return false;
}
diff --git a/cc3200/util/hash.c b/cc3200/util/hash.c
index a7afdf9f2f..acd1475552 100644
--- a/cc3200/util/hash.c
+++ b/cc3200/util/hash.c
@@ -1,3 +1,29 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * 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.
+ */
+
#include "std.h"
#include <stdint.h>
#include <stdbool.h>
@@ -11,34 +37,21 @@
#include "prcm.h"
#include "shamd5.h"
#include "hash.h"
+#include "simplelink.h"
-#ifdef USE_FREERTOS
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-#endif
+static _SlLockObj_t hash_LockObj;
-#ifdef USE_FREERTOS
-static SemaphoreHandle_t xShamd5Semaphore = NULL;
-#endif
void HASH_Init (void) {
// Enable the Data Hashing and Transform Engine
MAP_PRCMPeripheralClkEnable(PRCM_DTHE, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
-#ifdef USE_FREERTOS
- vSemaphoreCreateBinary(xShamd5Semaphore);
-#endif
+ sl_LockObjCreate(&hash_LockObj, "HashLock");
}
-
-
void HASH_SHAMD5Start (uint32_t algo, uint32_t blocklen) {
-
-#ifdef USE_FREERTOS
- xSemaphoreTake (xShamd5Semaphore, portMAX_DELAY);
-#endif
-
+ sl_LockObjLock (&hash_LockObj, SL_OS_WAIT_FOREVER);
+ // reset the perihperal before starting any new operation
MAP_PRCMPeripheralReset(PRCM_DTHE);
// wait until the context is ready
@@ -62,11 +75,9 @@ void HASH_SHAMD5Update (uint8_t *data, uint32_t datalen) {
}
void HASH_SHAMD5Read (uint8_t *hash) {
- // wait for the output to be ready.
+ // wait for the output to be ready
while((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) == 0);
- // read the result.
+ // read the result
MAP_SHAMD5ResultRead(SHAMD5_BASE, hash);
-#ifdef USE_FREERTOS
- xSemaphoreGive (xShamd5Semaphore);
-#endif
+ sl_LockObjUnlock (&hash_LockObj);
}
diff --git a/cc3200/util/hash.h b/cc3200/util/hash.h
index d131584611..edea1e3fce 100644
--- a/cc3200/util/hash.h
+++ b/cc3200/util/hash.h
@@ -1,3 +1,29 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * 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.
+ */
+
#ifndef HASH_H_
#define HASH_H_