mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 05:32:47 +00:00
Merge ARM11 spi and ARM9 spicard drivers
Also centralize device IDs into SPI.h
This commit is contained in:
parent
48d8c48d12
commit
d2f596e7a3
@ -24,9 +24,7 @@
|
|||||||
#include <hid_map.h>
|
#include <hid_map.h>
|
||||||
|
|
||||||
#include "hw/codec.h"
|
#include "hw/codec.h"
|
||||||
#include "hw/spi.h"
|
#include <spi.h>
|
||||||
|
|
||||||
#define CODEC_SPI_DEV 3
|
|
||||||
|
|
||||||
#define CPAD_THRESH_X (750)
|
#define CPAD_THRESH_X (750)
|
||||||
#define CPAD_THRESH_Y (150)
|
#define CPAD_THRESH_Y (150)
|
||||||
@ -44,7 +42,7 @@ static void CODEC_WriteRead(u32 *txb, u8 txl, u32 *rxb, u8 rxl)
|
|||||||
xfers[1].len = rxl;
|
xfers[1].len = rxl;
|
||||||
xfers[1].read = true;
|
xfers[1].read = true;
|
||||||
|
|
||||||
SPI_DoXfer(CODEC_SPI_DEV, xfers, 2);
|
SPI_DoXfer(SPI_DEV_CODEC, xfers, 2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CODEC_RegSelect(u8 reg)
|
static void CODEC_RegSelect(u8 reg)
|
||||||
@ -58,7 +56,7 @@ static void CODEC_RegSelect(u8 reg)
|
|||||||
xfer.len = 2;
|
xfer.len = 2;
|
||||||
xfer.read = false;
|
xfer.read = false;
|
||||||
|
|
||||||
SPI_DoXfer(CODEC_SPI_DEV, &xfer, 1);
|
SPI_DoXfer(SPI_DEV_CODEC, &xfer, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 CODEC_RegRead(u8 reg)
|
static u8 CODEC_RegRead(u8 reg)
|
||||||
@ -86,7 +84,7 @@ static void CODEC_RegWrite(u8 reg, u8 val)
|
|||||||
xfer.len = 2;
|
xfer.len = 2;
|
||||||
xfer.read = false;
|
xfer.read = false;
|
||||||
|
|
||||||
SPI_DoXfer(CODEC_SPI_DEV, &xfer, 1);
|
SPI_DoXfer(SPI_DEV_CODEC, &xfer, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CODEC_RegMask(u8 reg, u8 mask0, u8 mask1)
|
static void CODEC_RegMask(u8 reg, u8 mask0, u8 mask1)
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include "hw/spi.h"
|
#include <spi.h>
|
||||||
#include "hw/nvram.h"
|
#include "hw/nvram.h"
|
||||||
|
|
||||||
#define NVRAM_SPI_DEV 1
|
|
||||||
|
|
||||||
// returns manuf id, memory type and size
|
// returns manuf id, memory type and size
|
||||||
// size = (1 << id[2]) ?
|
// size = (1 << id[2]) ?
|
||||||
// apparently unreliable on some Sanyo chips?
|
// apparently unreliable on some Sanyo chips?
|
||||||
@ -51,7 +49,7 @@ static u32 NVRAM_SendStatusCommand(u32 cmd, u32 width)
|
|||||||
xfer[1].read = true;
|
xfer[1].read = true;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
SPI_DoXfer(NVRAM_SPI_DEV, xfer, 2);
|
SPI_DoXfer(SPI_DEV_NVRAM, xfer, 2, true);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,5 +89,5 @@ void NVRAM_Read(u32 address, u32 *buffer, u32 len)
|
|||||||
xfer[1].len = len;
|
xfer[1].len = len;
|
||||||
xfer[1].read = true;
|
xfer[1].read = true;
|
||||||
|
|
||||||
SPI_DoXfer(NVRAM_SPI_DEV, xfer, 2);
|
SPI_DoXfer(SPI_DEV_NVRAM, xfer, 2, true);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include "hw/spi.h"
|
#include <spi.h>
|
||||||
|
|
||||||
#define NVRAM_SR_WIP BIT(0) // work in progress / busy
|
#define NVRAM_SR_WIP BIT(0) // work in progress / busy
|
||||||
#define NVRAM_SR_WEL BIT(1) // write enable latch
|
#define NVRAM_SR_WEL BIT(1) // write enable latch
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "hw/gpulcd.h"
|
#include "hw/gpulcd.h"
|
||||||
#include "hw/i2c.h"
|
#include "hw/i2c.h"
|
||||||
#include "hw/mcu.h"
|
#include "hw/mcu.h"
|
||||||
#include "hw/spi.h"
|
#include <spi.h>
|
||||||
|
|
||||||
#include "system/sections.h"
|
#include "system/sections.h"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "spicard.h"
|
#include <spi.h>
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
// declarations for actual implementations
|
// declarations for actual implementations
|
||||||
@ -103,19 +103,27 @@ const CardType FLASH_256KB_2_INFRARED = FlashInfraredTypes + 1;
|
|||||||
const CardType FLASH_512KB_1_INFRARED = FlashInfraredTypes + 2;
|
const CardType FLASH_512KB_1_INFRARED = FlashInfraredTypes + 2;
|
||||||
const CardType FLASH_512KB_2_INFRARED = FlashInfraredTypes + 3;
|
const CardType FLASH_512KB_2_INFRARED = FlashInfraredTypes + 3;
|
||||||
|
|
||||||
int SPIWriteRead(CardType type, void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize) {
|
#define REG_CFG9_CARDCTL *((vu16*)0x1000000C)
|
||||||
const u32 headerFooterVal = 0;
|
#define CARDCTL_SPICARD (1u<<8)
|
||||||
bool b = type->infrared;
|
|
||||||
|
|
||||||
SPICARD_init();
|
int SPIWriteRead(CardType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize) {
|
||||||
|
u32 headerFooterVal = 0;
|
||||||
|
|
||||||
if (b) {
|
REG_CFG9_CARDCTL |= CARDCTL_SPICARD;
|
||||||
SPICARD_writeRead(NSPI_CLK_1MHz, &headerFooterVal, NULL, 1, 0, false);
|
|
||||||
|
if (type->infrared) {
|
||||||
|
SPI_XferInfo irXfer = { &headerFooterVal, 1, false };
|
||||||
|
SPI_DoXfer(SPI_DEV_CART_IR, &irXfer, 1, false);
|
||||||
}
|
}
|
||||||
SPICARD_writeRead(NSPI_CLK_4MHz, cmd, answer, cmdSize, answerSize, false);
|
|
||||||
SPICARD_writeRead(NSPI_CLK_4MHz, data, NULL, dataSize, 0, true);
|
|
||||||
|
|
||||||
SPICARD_deinit();
|
SPI_XferInfo transfers[3] = {
|
||||||
|
{ (u8*) cmd, cmdSize, false },
|
||||||
|
{ answer, answerSize, true },
|
||||||
|
{ (u8*) data, dataSize, false },
|
||||||
|
};
|
||||||
|
SPI_DoXfer(SPI_DEV_CART_FLASH, transfers, 3, true);
|
||||||
|
|
||||||
|
REG_CFG9_CARDCTL &= ~CARDCTL_SPICARD;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ const CardType FLASH_256KB_2_INFRARED;
|
|||||||
const CardType FLASH_512KB_1_INFRARED;
|
const CardType FLASH_512KB_1_INFRARED;
|
||||||
const CardType FLASH_512KB_2_INFRARED;
|
const CardType FLASH_512KB_2_INFRARED;
|
||||||
|
|
||||||
int SPIWriteRead(CardType type, void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize);
|
int SPIWriteRead(CardType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize);
|
||||||
int SPIWaitWriteEnd(CardType type);
|
int SPIWaitWriteEnd(CardType type);
|
||||||
int SPIEnableWriting(CardType type);
|
int SPIEnableWriting(CardType type);
|
||||||
int SPIReadJEDECIDAndStatusReg(CardType type, u32* id, u8* statusReg);
|
int SPIReadJEDECIDAndStatusReg(CardType type, u32* id, u8* statusReg);
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of fastboot 3DS
|
|
||||||
* Copyright (C) 2019 derrek, profi200
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "spicard.h"
|
|
||||||
#include "delay.h"
|
|
||||||
|
|
||||||
#define REG_CFG9_CARDCTL *((vu16*)0x1000000C)
|
|
||||||
|
|
||||||
#define SPICARD_REGS_BASE 0x1000D800
|
|
||||||
#define REG_NSPI_CNT *((vu32*)(SPICARD_REGS_BASE + 0x00))
|
|
||||||
#define REG_NSPI_DONE *((vu32*)(SPICARD_REGS_BASE + 0x04))
|
|
||||||
#define REG_NSPI_BLKLEN *((vu32*)(SPICARD_REGS_BASE + 0x08))
|
|
||||||
#define REG_NSPI_FIFO *((vu32*)(SPICARD_REGS_BASE + 0x0C))
|
|
||||||
#define REG_NSPI_STATUS *((vu32*)(SPICARD_REGS_BASE + 0x10))
|
|
||||||
#define REG_NSPI_AUTOPOLL *((vu32*)(SPICARD_REGS_BASE + 0x14))
|
|
||||||
#define REG_NSPI_INT_MASK *((vu32*)(SPICARD_REGS_BASE + 0x18))
|
|
||||||
#define REG_NSPI_INT_STAT *((vu32*)(SPICARD_REGS_BASE + 0x1C))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline void nspiWaitBusy(void)
|
|
||||||
{
|
|
||||||
while(REG_NSPI_CNT & NSPI_CNT_ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void nspiWaitFifoBusy(void)
|
|
||||||
{
|
|
||||||
while(REG_NSPI_STATUS & NSPI_STATUS_BUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPICARD_init(void)
|
|
||||||
{
|
|
||||||
REG_CFG9_CARDCTL |= 1u<<8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPICARD_deinit(void)
|
|
||||||
{
|
|
||||||
REG_CFG9_CARDCTL &= ~(1u<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool _SPICARD_autoPollBit(u32 params)
|
|
||||||
{
|
|
||||||
REG_NSPI_AUTOPOLL = NSPI_AUTOPOLL_START | params;
|
|
||||||
|
|
||||||
u32 res;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
__wfi();
|
|
||||||
res = REG_NSPI_INT_STAT;
|
|
||||||
} while(!(res & (NSPI_INT_AP_TIMEOUT | NSPI_INT_AP_SUCCESS)));
|
|
||||||
REG_NSPI_INT_STAT = res; // Aknowledge
|
|
||||||
|
|
||||||
return (res & NSPI_INT_AP_TIMEOUT) == 0; // Timeout error
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SPICARD_writeRead(NspiClk clk, const void *in, void *out, u32 inSize, u32 outSize, bool done)
|
|
||||||
{
|
|
||||||
const u32 cntParams = NSPI_CNT_ENABLE | NSPI_CNT_BUS_1BIT | clk;
|
|
||||||
|
|
||||||
REG_CFG9_CARDCTL |= 1u<<8;
|
|
||||||
|
|
||||||
u32 buf;
|
|
||||||
char *in_ = (char *) in;
|
|
||||||
char *out_ = (char *) out;
|
|
||||||
|
|
||||||
if(in_)
|
|
||||||
{
|
|
||||||
REG_NSPI_BLKLEN = inSize;
|
|
||||||
REG_NSPI_CNT = cntParams | NSPI_CNT_DIRE_WRITE;
|
|
||||||
|
|
||||||
u32 counter = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if((counter & 31) == 0) nspiWaitFifoBusy();
|
|
||||||
memcpy(&buf, in_, min(4, inSize - counter));
|
|
||||||
REG_NSPI_FIFO = buf;
|
|
||||||
counter += 4;
|
|
||||||
in_ += 4;
|
|
||||||
} while(counter < inSize);
|
|
||||||
|
|
||||||
nspiWaitBusy();
|
|
||||||
}
|
|
||||||
if(out_)
|
|
||||||
{
|
|
||||||
REG_NSPI_BLKLEN = outSize;
|
|
||||||
REG_NSPI_CNT = cntParams | NSPI_CNT_DIRE_READ;
|
|
||||||
|
|
||||||
u32 counter = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if((counter & 31) == 0) nspiWaitFifoBusy();
|
|
||||||
buf = REG_NSPI_FIFO;
|
|
||||||
memcpy(out_, &buf, min(4, outSize - counter));
|
|
||||||
counter += 4;
|
|
||||||
out_ += 4;
|
|
||||||
} while(counter < outSize);
|
|
||||||
|
|
||||||
nspiWaitBusy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(done) REG_NSPI_DONE = NSPI_DONE;
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of fastboot 3DS
|
|
||||||
* Copyright (C) 2019 derrek, profi200
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
|
|
||||||
// REG_NSPI_CNT
|
|
||||||
#define NSPI_CNT_BUS_1BIT (0u)
|
|
||||||
#define NSPI_CNT_BUS_4BIT (1u<<12)
|
|
||||||
#define NSPI_CNT_DIRE_READ (0u)
|
|
||||||
#define NSPI_CNT_DIRE_WRITE (1u<<13)
|
|
||||||
#define NSPI_CNT_ENABLE (1u<<15)
|
|
||||||
|
|
||||||
// REG_NSPI_DONE
|
|
||||||
#define NSPI_DONE (0u)
|
|
||||||
|
|
||||||
// REG_NSPI_STATUS
|
|
||||||
#define NSPI_STATUS_BUSY (1u)
|
|
||||||
|
|
||||||
// REG_NSPI_AUTOPOLL
|
|
||||||
#define NSPI_AUTOPOLL_START (1u<<31)
|
|
||||||
|
|
||||||
// REG_NSPI_INT_MASK Bit set = disabled.
|
|
||||||
// REG_NSPI_INT_STAT Status and aknowledge.
|
|
||||||
#define NSPI_INT_TRANSF_END (1u) // Fires on (each?) auto poll try aswell
|
|
||||||
#define NSPI_INT_AP_SUCCESS (1u<<1) // Auto poll
|
|
||||||
#define NSPI_INT_AP_TIMEOUT (1u<<2) // Auto poll
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NSPI_CLK_512KHz = 0u,
|
|
||||||
NSPI_CLK_1MHz = 1u,
|
|
||||||
NSPI_CLK_2MHz = 2u,
|
|
||||||
NSPI_CLK_4MHz = 3u,
|
|
||||||
NSPI_CLK_8MHz = 4u,
|
|
||||||
NSPI_CLK_16MHz = 5u
|
|
||||||
} NspiClk;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Activates the SPI bus. Use after some cartridge interface has been initialized.
|
|
||||||
*/
|
|
||||||
void SPICARD_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deactivates the SPI bus.
|
|
||||||
*/
|
|
||||||
void SPICARD_deinit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Automatically polls a bit of the command response. Use with the macro below.
|
|
||||||
*
|
|
||||||
* @param[in] params The parameters. Use the macro below.
|
|
||||||
*
|
|
||||||
* @return Returns false on failure/timeout and true on success.
|
|
||||||
*/
|
|
||||||
bool _SPICARD_autoPollBit(u32 params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Writes and/or reads data to/from a SPI device.
|
|
||||||
*
|
|
||||||
* @param[in] clk The clock frequency to use.
|
|
||||||
* @param[in] in Input data pointer for write.
|
|
||||||
* @param out Output data pointer for read.
|
|
||||||
* @param[in] inSize Input size. Must be <= 0x1FFFFF.
|
|
||||||
* @param[in] outSize Output size. Must be <= 0x1FFFFF.
|
|
||||||
* @param[in] done Set to true if this is the last transfer (chip select).
|
|
||||||
*/
|
|
||||||
void SPICARD_writeRead(NspiClk clk, const void *in, void *out, u32 inSize, u32 outSize, bool done);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Automatically polls a bit of the command response.
|
|
||||||
*
|
|
||||||
* @param[in] cmd The command.
|
|
||||||
* @param[in] timeout The timeout. Must be 0-15. Tries = 31<<NspiClk + timeout.
|
|
||||||
* @param[in] off The bit offset. Must be 0-7.
|
|
||||||
* @param[in] bitSet Poll for a set ur unset bit.
|
|
||||||
*
|
|
||||||
* @return Returns false on failure/timeout and true on success.
|
|
||||||
*/
|
|
||||||
#define SPICARD_autoPollBit(cmd, timeout, off, bitSet) _SPICARD_autoPollBit((bitSet)<<30 | (off)<<24 | (timeout)<<16 | (cmd))
|
|
@ -21,7 +21,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include "hw/spi.h"
|
#include "spi.h"
|
||||||
|
|
||||||
#define REG_CFG_SPI_CNT ((vu16*)0x101401C0)
|
#define REG_CFG_SPI_CNT ((vu16*)0x101401C0)
|
||||||
|
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#define REG_SPI_BUS0 (0x10160800)
|
#define REG_SPI_BUS0 (0x10160800)
|
||||||
#define REG_SPI_BUS1 (0x10142800)
|
#define REG_SPI_BUS1 (0x10142800)
|
||||||
#define REG_SPI_BUS2 (0x10143800)
|
#define REG_SPI_BUS2 (0x10143800)
|
||||||
|
#define REG_SPI_CARD (0x1000D800)
|
||||||
|
|
||||||
#define REG_SPI_CONTROL 0x00
|
#define REG_SPI_CONTROL 0x00
|
||||||
#define REG_SPI_DONE 0x04
|
#define REG_SPI_DONE 0x04
|
||||||
@ -56,6 +57,8 @@ static struct {
|
|||||||
{REG_SPI_BUS0, SPI_CONTROL_RATE(0) | SPI_CONTROL_CS(1)}, // NVRAM
|
{REG_SPI_BUS0, SPI_CONTROL_RATE(0) | SPI_CONTROL_CS(1)}, // NVRAM
|
||||||
{REG_SPI_BUS0, SPI_CONTROL_RATE(0) | SPI_CONTROL_CS(2)},
|
{REG_SPI_BUS0, SPI_CONTROL_RATE(0) | SPI_CONTROL_CS(2)},
|
||||||
{REG_SPI_BUS1, SPI_CONTROL_RATE(5) | SPI_CONTROL_CS(0)}, // CODEC
|
{REG_SPI_BUS1, SPI_CONTROL_RATE(5) | SPI_CONTROL_CS(0)}, // CODEC
|
||||||
|
{REG_SPI_CARD, SPI_CONTROL_RATE(3) | SPI_CONTROL_CS(0)}, // Gamecard flash chip
|
||||||
|
{REG_SPI_CARD, SPI_CONTROL_RATE(1) | SPI_CONTROL_CS(0)}, // Gamecard IR chip
|
||||||
// TODO: complete this table
|
// TODO: complete this table
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,9 +77,10 @@ static void SPI_Done(u32 bus)
|
|||||||
REG_SPI(bus, REG_SPI_DONE) = 0;
|
REG_SPI(bus, REG_SPI_DONE) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SPI_SingleXfer(u32 reg, u32 bus, u32 *buffer, u32 len, bool read)
|
static void SPI_SingleXfer(u32 reg, u32 bus, void *buffer, u32 len, bool read)
|
||||||
{
|
{
|
||||||
u32 pos = 0;
|
u32 pos = 0;
|
||||||
|
bool aligned = ((u32)buffer % 4 == 0) && (len % 4 == 0);
|
||||||
|
|
||||||
REG_SPI(bus, REG_SPI_BLKLEN) = len;
|
REG_SPI(bus, REG_SPI_BLKLEN) = len;
|
||||||
REG_SPI(bus, REG_SPI_CONTROL) = reg |
|
REG_SPI(bus, REG_SPI_CONTROL) = reg |
|
||||||
@ -88,17 +92,28 @@ static void SPI_SingleXfer(u32 reg, u32 bus, u32 *buffer, u32 len, bool read)
|
|||||||
if ((pos % SPI_FIFO_WIDTH) == 0)
|
if ((pos % SPI_FIFO_WIDTH) == 0)
|
||||||
SPI_WaitFIFO(bus);
|
SPI_WaitFIFO(bus);
|
||||||
|
|
||||||
|
if(aligned) {
|
||||||
if (read) {
|
if (read) {
|
||||||
buffer[pos / 4] = REG_SPI(bus, REG_SPI_FIFO);
|
((u32*)buffer)[pos / 4] = REG_SPI(bus, REG_SPI_FIFO);
|
||||||
} else {
|
} else {
|
||||||
REG_SPI(bus, REG_SPI_FIFO) = buffer[pos / 4];
|
REG_SPI(bus, REG_SPI_FIFO) = ((u32*)buffer)[pos / 4];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (read) {
|
||||||
|
u32 tmp = REG_SPI(bus, REG_SPI_FIFO);
|
||||||
|
memcpy((u8 *) buffer + pos, &tmp, min(4, len - pos));
|
||||||
|
} else {
|
||||||
|
u32 tmp;
|
||||||
|
memcpy(&tmp, (u8 *) buffer + pos, min(4, len - pos));
|
||||||
|
REG_SPI(bus, REG_SPI_FIFO) = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += 4;
|
pos += 4;
|
||||||
} while(pos < len);
|
} while(pos < len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfers, u32 xfer_cnt)
|
int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfers, u32 xfer_cnt, bool done)
|
||||||
{
|
{
|
||||||
u32 bus, reg;
|
u32 bus, reg;
|
||||||
|
|
||||||
@ -116,7 +131,9 @@ int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfers, u32 xfer_cnt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SPI_WaitBusy(bus);
|
SPI_WaitBusy(bus);
|
||||||
|
if(done) {
|
||||||
SPI_Done(bus);
|
SPI_Done(bus);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -20,13 +20,18 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
#define SPI_DEV_NVRAM 1
|
||||||
|
#define SPI_DEV_CODEC 3
|
||||||
|
#define SPI_DEV_CART_FLASH 4
|
||||||
|
#define SPI_DEV_CART_IR 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 *buf;
|
void *buf;
|
||||||
u32 len;
|
u32 len;
|
||||||
bool read;
|
bool read;
|
||||||
} SPI_XferInfo;
|
} SPI_XferInfo;
|
||||||
|
|
||||||
int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfer, u32 xfer_cnt);
|
int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfer, u32 xfer_cnt, bool done);
|
||||||
|
|
||||||
void SPI_Init(void);
|
void SPI_Init(void);
|
||||||
void SPI_Deinit(void);
|
void SPI_Deinit(void);
|
Loading…
x
Reference in New Issue
Block a user