diff options
Diffstat (limited to 'arm9/lib/NitroSDK/include/CARD_common.h')
-rw-r--r-- | arm9/lib/NitroSDK/include/CARD_common.h | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/arm9/lib/NitroSDK/include/CARD_common.h b/arm9/lib/NitroSDK/include/CARD_common.h new file mode 100644 index 00000000..1ae31b7a --- /dev/null +++ b/arm9/lib/NitroSDK/include/CARD_common.h @@ -0,0 +1,233 @@ +#ifndef POKEDIAMOND_CARD_COMMON_H +#define POKEDIAMOND_CARD_COMMON_H + +#include "nitro/types.h" +#include "OS_thread.h" +#include "OS_system.h" +#include "MI_dma.h" +#include "PXI_fifo.h" + +#define CARD_PXI_COMMAND_MASK 0x3f +#define CARD_PXI_COMMAND_PULLED_OUT 0x0011 +#define CARD_PXI_COMMAND_TERMINATE 0x0001 + +#define CARD_THREAD_PRIORITY_DEFAULT 4 + +#define CARD_BACKUP_TYPE_DEVICE_SHIFT 0 +#define CARD_BACKUP_TYPE_DEVICE_MASK 0xFF +#define CARD_BACKUP_TYPE_DEVICE_EEPROM 1 +#define CARD_BACKUP_TYPE_DEVICE_FLASH 2 +#define CARD_BACKUP_TYPE_DEVICE_FRAM 3 +#define CARD_BACKUP_TYPE_SIZEBIT_SHIFT 8 +#define CARD_BACKUP_TYPE_SIZEBIT_MASK 0xFF +#define CARD_BACKUP_TYPE_VENDER_SHIFT 16 +#define CARD_BACKUP_TYPE_DEFINE(type, size, vender) \ + (((CARD_BACKUP_TYPE_DEVICE_ ## type) << CARD_BACKUP_TYPE_DEVICE_SHIFT) | \ + ((size) << CARD_BACKUP_TYPE_SIZEBIT_SHIFT) | \ + ((vender) << CARD_BACKUP_TYPE_VENDER_SHIFT)) + +#define ALIGN_MASK(a) ((a) - 1) +#define CARD_ALIGN_HI_BIT(n) (((u32)(n)) & ~ALIGN_MASK(CARD_ROM_PAGE_SIZE)) +#define CARD_ALIGN_LO_BIT(n) (((u32)(n)) & ALIGN_MASK(CARD_ROM_PAGE_SIZE)) + +#define CARD_BACKUP_CAPS_AVAILABLE (u32)(CARD_BACKUP_CAPS_READ - 1) +#define CARD_BACKUP_CAPS_READ (u32)(1 << CARD_REQ_READ_BACKUP) +#define CARD_BACKUP_CAPS_WRITE (u32)(1 << CARD_REQ_WRITE_BACKUP) +#define CARD_BACKUP_CAPS_PROGRAM (u32)(1 << CARD_REQ_PROGRAM_BACKUP) +#define CARD_BACKUP_CAPS_VERIFY (u32)(1 << CARD_REQ_VERIFY_BACKUP) +#define CARD_BACKUP_CAPS_ERASE_PAGE (u32)(1 << CARD_REQ_ERASE_PAGE_BACKUP) +#define CARD_BACKUP_CAPS_ERASE_SECTOR (u32)(1 << CARD_REQ_ERASE_SECTOR_BACKUP) +#define CARD_BACKUP_CAPS_ERASE_CHIP (u32)(1 << CARD_REQ_ERASE_CHIP_BACKUP) + +typedef enum +{ + CARD_BACKUP_TYPE_EEPROM_4KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 9, 0), + CARD_BACKUP_TYPE_EEPROM_64KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 13, 0), + CARD_BACKUP_TYPE_EEPROM_512KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 16, 0), + CARD_BACKUP_TYPE_FLASH_2MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 18, 0), + CARD_BACKUP_TYPE_FLASH_4MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 19, 0), + CARD_BACKUP_TYPE_FLASH_8MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 20, 0), + CARD_BACKUP_TYPE_FRAM_256KBITS = CARD_BACKUP_TYPE_DEFINE(FRAM, 15, 0), + CARD_BACKUP_TYPE_NOT_USE = 0 +} CARDBackupType; + +typedef enum +{ + CARD_RESULT_SUCCESS = 0, + CARD_RESULT_FAILURE, + CARD_RESULT_INVALID_PARAM, + CARD_RESULT_UNSUPPORTED, + CARD_RESULT_TIMEOUT, + CARD_RESULT_ERROR, + CARD_RESULT_NO_RESPONSE, + CARD_RESULT_CANCELED +} CARDResult; + +typedef enum +{ + CARD_TARGET_NONE, + CARD_TARGET_ROM, + CARD_TARGET_BACKUP +} CARDTargetMode; + +typedef enum +{ + CARD_REQ_INIT = 0, + CARD_REQ_ACK, + CARD_REQ_IDENTIFY, + CARD_REQ_READ_ID, + CARD_REQ_READ_ROM, + CARD_REQ_WRITE_ROM, + CARD_REQ_READ_BACKUP, + CARD_REQ_WRITE_BACKUP, + CARD_REQ_PROGRAM_BACKUP, + CARD_REQ_VERIFY_BACKUP, + CARD_REQ_ERASE_PAGE_BACKUP, + CARD_REQ_ERASE_SECTOR_BACKUP, + CARD_REQ_ERASE_CHIP_BACKUP, + CARD_REQ_MAX +} CARDRequest; + +typedef enum +{ + CARD_REQUEST_MODE_RECV, + CARD_REQUEST_MODE_SEND, + CARD_REQUEST_MODE_SEND_VERIFY, + CARD_REQUEST_MODE_SPECIAL +} CARDRequestMode; + +enum +{ + CARD_STAT_INIT = (1 << 0), + CARD_STAT_INIT_CMD = (1 << 1), + CARD_STAT_BUSY = (1 << 2), + CARD_STAT_TASK = (1 << 3), + CARD_STAT_RECV = (1 << 4), + CARD_STAT_REQ = (1 << 5), + CARD_STAT_CANCEL = (1 << 6) +}; + +typedef s32 CARDiOwner; + +typedef struct CARDiCommandArg +{ + CARDResult result; + CARDBackupType type; + u32 id; + u32 src; + u32 dest; + u32 len; + + struct + { + u32 total_size; + u32 sect_size; + u32 page_size; + u32 addr_width; + u32 program_page; + u32 write_page; + u32 write_page_total; + u32 erase_chip; + u32 erase_chip_total; + u32 erase_sector; + u32 erase_sector_total; + u32 erase_page; + u8 initial_status; + u8 padding1[3]; + u32 caps; + u8 padding2[16]; + } spec; +} CARDiCommandArg; + +typedef struct CARDiCommon +{ + CARDiCommandArg *cmd; + s32 command; + + volatile CARDiOwner lock_owner; + volatile s32 lock_ref; + OSThreadQueue lock_queue[1]; + CARDTargetMode lock_target; + + u32 src; + u32 dst; + u32 len; + u32 dma; + CARDRequest req_type; + s32 req_retry; + CARDRequestMode req_mode; + MIDmaCallback callback; + void *callback_arg; + void (*task_func) (struct CARDiCommon *); + + OSThread thread[1]; + OSThread *cur_th; + + u32 priority; + OSThreadQueue busy_q[1]; + + volatile u32 flag; + + u8 dummy[8]; + + u8 backup_cache_page_buf[256] ALIGN(32); +} CARDiCommon; + +static inline void CARDi_EndTask(CARDiCommon *p, BOOL is_own_task) +{ + const MIDmaCallback func = p->callback; + void *const arg = p->callback_arg; + + { + OSIntrMode bak_psr = OS_DisableInterrupts(); + + p->flag &= ~(CARD_STAT_BUSY | CARD_STAT_TASK | CARD_STAT_CANCEL); + OS_WakeupThread(p->busy_q); + if ((p->flag & CARD_STAT_RECV) != 0) + { + OS_WakeupThreadDirect(p->thread); + } + (void)OS_RestoreInterrupts(bak_psr); + } + + if (is_own_task && func) + { + (*func)(arg); + } +} + +static inline void CARDi_WaitTask(CARDiCommon *p, MIDmaCallback callback, void *callback_arg) +{ + OSIntrMode bak_psr = OS_DisableInterrupts(); + while ((p->flag & CARD_STAT_BUSY) != 0) + { + OS_SleepThread(p->busy_q); + } + p->flag |= CARD_STAT_BUSY; + p->callback = callback; + p->callback_arg = callback_arg; + (void)OS_RestoreInterrupts(bak_psr); +} + +void CARDi_SetTask(void (*task) (CARDiCommon *)); +void CARDi_InitCommon(void); +BOOL CARD_IsEnabled(void); +void CARD_CheckEnabled(void); +void CARD_Enable(BOOL enable); +BOOL CARDi_WaitAsync(void); +BOOL CARDi_TryWaitAsync(void); +CARDResult CARD_GetResultCode(void); +void CARD_LockRom(u16 lock_id); +void CARD_UnlockRom(u16 lock_id); +void CARD_LockBackup(u16 lock_id); +void CARD_UnlockBackup(u16 lock_id); + +#define CARD_RETRY_COUNT_MAX 10 + +static inline void CARDi_SendPxi(u32 data) +{ + while (PXI_SendWordByFifo(PXI_FIFO_TAG_FS, data, TRUE) < 0) + ; +} + +#endif //POKEDIAMOND_CARD_COMMON_H |