diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index 26e018c..7d3ba94 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -220,6 +220,7 @@ void pcm_rec_dma_stop(void) } +#if 0 /* C */ void INT_I2SIN(void) { register int status; @@ -255,6 +256,70 @@ void INT_I2SIN(void) } } } +#else /* ASM */ +void INT_I2SIN(void) __attribute__((naked)); +void INT_I2SIN(void) +{ + asm volatile( + " str lr, [sp, #-4]! \n" + + " ldr r0, =0xC8090008 @ I2SIN_RAW_STATUS \n" + " ldrb r1, [r0, #4] @ I2SIN_STATUS \n" + " strb r1, [r0, #8] @ I2SIN_CLEAR \n" + + " ldr r2, =rec_size \n" + " ldr r3, =rec_start_addr \n" + + " ldrb r1, [r0] \n" + " tst r1, #(1<<5) @ test fifo pop empty \n" + " bne 3f @no_samples \n" + + " ldr r1, [r2] @ test if rec_size == 0 \n" + " cmp r1, #0 \n" + " beq 4f @rec_size_null \n" + + " ldr r12, [r3] @ load rec_start_addr \n" + " ldr lr, [r2] @ load rec_size \n" + + "1: @loop \n" + " ldr r1, [r0, #0xC] @ read I2SIN_DATA \n" + " str r1, [r12], #4 @ store samples \n" + + " sub lr, lr, #4 @ decrement rec_size \n" + " beq 2f @end_loop @ exit loop if rec_size is 0 \n" + + " ldrb r1, [r0] @ I2SIN_RAW_STATUS \n" + " tst r1, #(1<<5) @ test fifo pop empty \n" + " beq 1b @loop \n" + + "2: @end_loop \n" + " str r12, [r3] @ store new rec_start_addr \n" + " str lr, [r2] @ store new rec_size \n" + + "3: @no_samples \n" + " ldr r0, [r2] @ return if rec_size > 0 \n" + " cmp r0, #0 \n" + " bne 6f @ret \n" + + "4: @rec_size_null \n" + " ldr r3, =pcm_callback_more_ready \n" + " ldr r3, [r3] \n" + " cmp r3, #0 \n" + " beq 5f @stop_record \n" + " mov lr, pc \n" + " bx r3 \n" + " cmp r0, #0 \n" + " bge 6f @ret \n" + + "5: @stop_record \n" + " bl pcm_rec_dma_stop \n" + " bl pcm_rec_dma_stopped_callback \n" + + "6: @ret \n" + " ldr pc, [sp], #4 \n" + : : : "r0", "r1", "r2", "r3", "r12", "lr"); +} +#endif void pcm_rec_dma_start(void *addr, size_t size)