|
@@ -15,6 +15,15 @@
|
|
|
" send_data" x "_%=: \n" \
|
|
" send_data" x "_%=: \n" \
|
|
|
" str %[tmp1], [%[out_port_bop]] \n"
|
|
" str %[tmp1], [%[out_port_bop]] \n"
|
|
|
|
|
|
|
|
|
|
+// Read data from SCSI port, set REQ high, store data to d at bit offset b
|
|
|
|
|
+#define ASM_RECV_DATA(d, b, x) \
|
|
|
|
|
+" recv_data" x "_%=: \n" \
|
|
|
|
|
+" ldr %[tmp1], [%[in_port_istat]] \n" \
|
|
|
|
|
+" mov %[tmp2], %[req_high_bop] \n" \
|
|
|
|
|
+" str %[tmp2], [%[out_port_bop]] \n" \
|
|
|
|
|
+" ubfx %[tmp1], %[tmp1], %[data_in_shift], #8 \n" \
|
|
|
|
|
+" bfi %[" d "], %[tmp1], #" b ", #8 \n"
|
|
|
|
|
+
|
|
|
// Wait for ACK to be high, set REQ low, wait ACK low
|
|
// Wait for ACK to be high, set REQ low, wait ACK low
|
|
|
#define ASM_HANDSHAKE(x) \
|
|
#define ASM_HANDSHAKE(x) \
|
|
|
" ldr %[tmp2], [%[ack_pin_bb]] \n" \
|
|
" ldr %[tmp2], [%[ack_pin_bb]] \n" \
|
|
@@ -52,13 +61,12 @@
|
|
|
|
|
|
|
|
// Send bytes to SCSI bus using the asynchronous handshake mechanism
|
|
// Send bytes to SCSI bus using the asynchronous handshake mechanism
|
|
|
// Takes 4 bytes at a time for sending from buf.
|
|
// Takes 4 bytes at a time for sending from buf.
|
|
|
-// Returns the next buffer pointer.
|
|
|
|
|
void scsi_accel_asm_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag)
|
|
void scsi_accel_asm_send(const uint32_t *buf, uint32_t num_words, volatile int *resetFlag)
|
|
|
{
|
|
{
|
|
|
volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT);
|
|
volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT);
|
|
|
const uint32_t *byte_lookup = g_scsi_out_byte_to_bop;
|
|
const uint32_t *byte_lookup = g_scsi_out_byte_to_bop;
|
|
|
- uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + 12 * 4;
|
|
|
|
|
- uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)out_port_bop) - APB1_BUS_BASE) * 32 + (9 + 16) * 4;
|
|
|
|
|
|
|
+ uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4;
|
|
|
|
|
+ uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)out_port_bop) - APB1_BUS_BASE) * 32 + (SCSI_OUT_REQ_IDX + 16) * 4;
|
|
|
register uint32_t tmp1 = 0;
|
|
register uint32_t tmp1 = 0;
|
|
|
register uint32_t tmp2 = 0;
|
|
register uint32_t tmp2 = 0;
|
|
|
register uint32_t data = 0;
|
|
register uint32_t data = 0;
|
|
@@ -96,5 +104,49 @@ void scsi_accel_asm_send(const uint32_t *buf, uint32_t num_words, volatile int *
|
|
|
[reset_flag] "r" (resetFlag)
|
|
[reset_flag] "r" (resetFlag)
|
|
|
: /* Clobber */ );
|
|
: /* Clobber */ );
|
|
|
|
|
|
|
|
|
|
+ SCSI_RELEASE_DATA_REQ();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Read bytes from SCSI bus using asynchronous handshake mechanism
|
|
|
|
|
+// Takes 4 bytes at a time.
|
|
|
|
|
+void scsi_accel_asm_recv(uint32_t *buf, uint32_t num_words, volatile int *resetFlag)
|
|
|
|
|
+{
|
|
|
|
|
+ volatile uint32_t *out_port_bop = (volatile uint32_t*)&GPIO_BOP(SCSI_OUT_PORT);
|
|
|
|
|
+ volatile uint32_t *in_port_istat = (volatile uint32_t*)&GPIO_ISTAT(SCSI_IN_PORT);
|
|
|
|
|
+ uint32_t ack_pin_bb = PERIPH_BB_BASE + (((uint32_t)&GPIO_ISTAT(SCSI_ACK_PORT)) - APB1_BUS_BASE) * 32 + SCSI_IN_ACK_IDX * 4;
|
|
|
|
|
+ uint32_t req_pin_bb = PERIPH_BB_BASE + (((uint32_t)out_port_bop) - APB1_BUS_BASE) * 32 + (SCSI_OUT_REQ_IDX + 16) * 4;
|
|
|
|
|
+ register uint32_t tmp1 = 0;
|
|
|
|
|
+ register uint32_t tmp2 = 0;
|
|
|
|
|
+ register uint32_t data = 0;
|
|
|
|
|
+
|
|
|
|
|
+ asm volatile (
|
|
|
|
|
+ "inner_loop_%=: \n" \
|
|
|
|
|
+ ASM_HANDSHAKE("0")
|
|
|
|
|
+ ASM_RECV_DATA("data", "0", "0")
|
|
|
|
|
+
|
|
|
|
|
+ ASM_HANDSHAKE("8")
|
|
|
|
|
+ ASM_RECV_DATA("data", "8", "8")
|
|
|
|
|
+
|
|
|
|
|
+ ASM_HANDSHAKE("16")
|
|
|
|
|
+ ASM_RECV_DATA("data", "16", "16")
|
|
|
|
|
+
|
|
|
|
|
+ ASM_HANDSHAKE("24")
|
|
|
|
|
+ ASM_RECV_DATA("data", "24", "24")
|
|
|
|
|
+
|
|
|
|
|
+ " mvn %[data], %[data] \n" \
|
|
|
|
|
+ " str %[data], [%[buf]], #4 \n" \
|
|
|
|
|
+ " subs %[num_words], %[num_words], #1 \n" \
|
|
|
|
|
+ " bne inner_loop_%= \n"
|
|
|
|
|
+ : /* Output */ [tmp1] "+l" (tmp1), [tmp2] "+l" (tmp2), [data] "+r" (data),
|
|
|
|
|
+ [buf] "+r" (buf), [num_words] "+r" (num_words)
|
|
|
|
|
+ : /* Input */ [ack_pin_bb] "r" (ack_pin_bb),
|
|
|
|
|
+ [req_pin_bb] "r" (req_pin_bb),
|
|
|
|
|
+ [out_port_bop] "r"(out_port_bop),
|
|
|
|
|
+ [in_port_istat] "r" (in_port_istat),
|
|
|
|
|
+ [reset_flag] "r" (resetFlag),
|
|
|
|
|
+ [data_in_shift] "I" (SCSI_IN_SHIFT),
|
|
|
|
|
+ [req_high_bop] "I" (SCSI_OUT_REQ)
|
|
|
|
|
+ : /* Clobber */ );
|
|
|
|
|
+
|
|
|
SCSI_RELEASE_DATA_REQ();
|
|
SCSI_RELEASE_DATA_REQ();
|
|
|
}
|
|
}
|