 // Файл аппаратной абстрации: функции системы, SPI
 // v 1.1 от 16/04/19
 // Автор: Сычев А.

 // НЕ ТРЕБУЕТ МОДИФИКАЦИИ! см. AT45DBXXX_import.h для переопределения 

#if defined(AT45DB321D_LOWLEVEL) || defined(AT45DB321D_APILEVEL)

#ifndef AT45DBXXX_HAL_H
#define AT45DBXXX_HAL_H
 
        #include "drivers\flash\common\AT45DBXXX_TYP.h"    // типы
        #include "drivers\flash\config\AT45DBXXX_import.h" // программная прослойка: прототипы функций обмена по SSP                 
        
        /* уровень аппаратной абстракции: системные функции     */
        /*      - внутр. процедура -            - функция системы - */        
      //#define __FLASH_WAITns(_10ns)             __imp_sys_delayns(_10ns)       // ожидание, в 10ках наносекунд
        #define __FLASH_WAITus(_1us)              __imp_sys_delayus(_1us)        // ожидание, в микросекундах

        #if AT45DBXXX_NO_MS_DELAYS == 1
        #define __FLASH_WAITms(_1ms)              __int_sys_delayms(_1ms)        // ожидание, в миллисекундах (внутр. функция)      
        #else
        #define __FLASH_WAITms(_1ms)              __imp_sys_delayms(_1ms)        // ожидание, в миллисекундах        
        #endif

        #define __FLASH_SMART_GETTIMER()          __imp_sys_gettimer()           //__imp_sys_gettimer()           // возвращает количество тиков системы с момента запуска в миллисекундах
        #define __FLASH_COPYMEMORY(dst,src,cnt)   __imp_sys_memset(dst,src,cnt)  // копирование блока памяти (memcpy)
        #define __FLASH_MOVEMEMORY(dst,src,cnt)   __imp_sys_memmove(dst,src,cnt) // перемещение блока памяти (memmove)
        #define __FLASH_ZEROMEMORY(dst,cnt)       __imp_sys_memzero(dst,cnt)     // обнуление блока памяти (memset)
        #define __FLASH_SETMEMORY(dst,byte,cnt)   __imp_sys_memset(dst,byte,cnt) // заполнение блока памяти (memset)

        /* уровень аппаратной абстракции: встроенные функции     */
        /*      - внутр. процедура -         - встроенная функция - */        
        #if AT45DB321D_DONTUSESMARTDELAY
        #define __FLASH_SMART_WAITms(_1ms)        __imp_sys_delayms(_1ms)
        #else
        #define __FLASH_SMART_WAITms(_1ms)        __flash_smart_waitms(_1ms) // ожидание, в миллисекундах с проверкой состояния flash. 
        #endif 

        #ifdef  AT45DB321D_POWER_MANAGEMENT
        #define __FLASH_POWER_ON()                __imp_flash_poweron()
        #define __FLASH_POWER_OFF()               __imp_flash_poweroff()
        #endif

        #ifdef  AT45DB321D_RESET_MANAGEMENT
        #define __FLASH_RESET_ASSERT()            __imp_flash_reset_assert()      // установить сигнал сброса
        #define __FLASH_RESET_RELEASE()           __imp_flash_reset_release()     // снять сигнал сброса
        #endif

        #define __FLASH_LOCK()                    __imp_utl_mutex_lock()
        #define __FLASH_UNLOCK()                  __imp_utl_mutex_unlock()
      //#define __FLASH_IS_IRQ()                  __imp_utl_isirq_context()
      //#define __FLASH_IS_TSK()                  (!__FLASH_IS_IRQ())

        /* уровень аппаратной абстракции: функции обмена по SSP     */
        /*      - внутр. процедура -         - польз. функция SSP - */
        #define __FLASH_HAL_CS_HI()             __imp_ssp_cshi()               // #CS в состояние 1 (HiLogicLevel)
        #define __FLASH_HAL_CS_LO()             __imp_ssp_cslo()               // #CS в состояние 0 (LoLogicLevel) 
        // __FLASH_HAL_EX: wb - write buffer ptr, rb - read buffer pointer, cnt - amount of bytes to exchange
        #define __FLASH_HAL_EX(wb,rb,cnt)       __imp_ssp_io( (__FLASH_BYTE*)(wb),(__FLASH_BYTE*)(rb),(__FLASH_DWORD)(cnt) )  // обмен по SSP (SPI) в обе стороны

        // UPDATED: 16.04.19
        #ifndef __imp_ssp_ro // read-only      
        #define __FLASH_HAL_RD(rb,cnt)          __imp_ssp_io( 0,(__FLASH_BYTE*)(rb),(__FLASH_DWORD)(cnt) )  // обмен по SSP (SPI): прием от flash-чипа
        #else
        #define __FLASH_HAL_RD(rb,cnt)          __imp_ssp_ro( (__FLASH_BYTE*)(rb),(__FLASH_DWORD)(cnt) )  // обмен по SSP (SPI): прием от flash-чипа
        #endif
        #ifndef __imp_ssp_wo // write-only       
        #define __FLASH_HAL_WR(wb,cnt)          __imp_ssp_io( (__FLASH_BYTE*)(wb),0,(__FLASH_DWORD)(cnt) )  // обмен по SSP (SPI): запись во flash-чип
        #else
        #define __FLASH_HAL_WR(wb,cnt)          __imp_ssp_wo( (__FLASH_BYTE*)(wb),(__FLASH_DWORD)(cnt) )  // обмен по SSP (SPI): запись во flash-чип
        #endif

        // UPDATED: 16.04.19
        #ifdef  __imp_ssp_wo_rev // write-only
          #define __FLASH_HAL_WR_REV(wb,cnt)      __imp_ssp_wo_rev( (__FLASH_BYTE*)(wb),(__FLASH_DWORD)(cnt) )  // запись по SSP (SPI): запись команды в обратном порядке следования
        #else
          #ifdef  __imp_ssp_io_rev
          #define __FLASH_HAL_WR_REV(wb,cnt)      __imp_ssp_io_rev( (__FLASH_BYTE*)(wb),              0,(__FLASH_DWORD)(cnt) )  // запись по SSP (SPI): запись команды в обратном порядке следования
          #else
          #ifdef AT45DB321D_LOWLEVEL
          #warning Внимание! Производительность снижена из-за отсутствия функции передачи данных по SPI в обратном порядке!
          #endif
          #define __FLASH_HAL_WR_REV(wb,cnt)      __int_ssp_io_rev( (__FLASH_BYTE*)(wb),                (__FLASH_DWORD)(cnt) )  // инверсия порядка байт + запись по SSP (SPI): запись команды 
          #endif
        #endif  
        // за счет инвертированного порядка битов в командах микросхем AT45DB321D требуется передача
        // _команды_ в обратном порядке байт
        #define __FLASH_HAL_WRCMD(wb,cnt)         __FLASH_HAL_WR_REV(wb,cnt)

#endif
#else
#error FLASH HAL: вы подключили заголовочный файл для низкоуровневых операций.
#error FLASH HAL: используйте файл AT45DB321_API.h
#endif