From 5fe913c88d8c1781de336cca3949142bd9fc370d Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 14 Mar 2018 19:08:00 +0100 Subject: i2s driver added; new amd trap entry vector added --- code/fe310/eos/trap_entry.S | 398 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 code/fe310/eos/trap_entry.S (limited to 'code/fe310/eos/trap_entry.S') diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S new file mode 100644 index 0000000..1c164d3 --- /dev/null +++ b/code/fe310/eos/trap_entry.S @@ -0,0 +1,398 @@ +#include "encoding.h" +#include "sifive/bits.h" + +#define MCAUSE_INT 0x80000000 +#define MCAUSE_EXT (MCAUSE_INT | IRQ_M_EXT) +#define MCAUSE_TIMER (MCAUSE_INT | IRQ_M_TIMER) + +#define PLIC_PRIORITY 0x0C000000 +#define PLIC_THRESHOLD 0x0C200000 +#define PLIC_CLAIM 0x0C200004 + +#define PWM0_CTRL_ADDR 0x10015000 +#define PWM1_CTRL_ADDR 0x10025000 +#define PWM2_CTRL_ADDR 0x10035000 + +#define PWM_CFG 0x00 +#define PWM_COUNT 0x08 + +#define PWM_CFG_CMP0IP 0x10000000 +#define PWM_CFG_CMP1IP 0x20000000 +#define PWM_CFG_CMP2IP 0x40000000 +#define PWM_CFG_CMP3IP 0x80000000 + +#define GPIO_CTRL_ADDR 0x10012000 +#define GPIO_INPUT_VAL 0x00 + +#define INT_PWM0_BASE 40 +#define INT_PWM1_BASE 44 +#define INT_PWM2_BASE 48 + +#define I2S_PWM_CTRL_ADDR_CK PWM1_CTRL_ADDR +#define I2S_PWM_CTRL_ADDR_WS PWM2_CTRL_ADDR + +#include "i2s_def.h" +#include "evt_def.h" +#include "msgq_def.h" + + .section .data.entry + .align 2 + +.global eos_trap_entry +eos_trap_entry: + addi sp, sp, -4*REGBYTES + + STORE x8, 0*REGBYTES(sp) + STORE x9, 1*REGBYTES(sp) + STORE x18, 2*REGBYTES(sp) + STORE x19, 3*REGBYTES(sp) + + csrr x8, mcause + li x18, MCAUSE_EXT + bne x8, x18, handler + li x18, PLIC_CLAIM + lw x9, 0(x18) + li x18, I2S_IRQ_SD_ID + beq x9, x18, handler_sd + li x18, I2S_IRQ_CK_ID + beq x9, x18, handler_ck + li x18, I2S_IRQ_WS_ID + beq x9, x18, handler_ws + li x18, I2S_IRQ_CI_ID + beq x9, x18, handler_ci + j handler + +handler_sd: + # read mic value -> x8 + li x18, GPIO_CTRL_ADDR + lw x8, GPIO_INPUT_VAL(x18) + + # set bit as ws pwm counter/ck period - sd volume -> x9 + li x18, I2S_PWM_CTRL_ADDR_WS + lw x9, PWM_COUNT(x18) + la x18, _eos_i2s_ck_period + lw x19, 0(x18) + divu x9, x9, x19 + la x18, _eos_i2s_mic_volume + lw x19, 0(x18) + sub x9, x9, x19 + + # disable sd irq + li x18, PLIC_PRIORITY + sw x0, 4*I2S_IRQ_SD_ID(x18) + + addi sp, sp, -1*REGBYTES + STORE x20, 0*REGBYTES(sp) + + # bit <= 0 -> exit + bge x0, x9, handler_sd_exit + + # sample |= sd gpio value << (32 - bit) -> x8 + # sample_mask |= 1 << (32 - bit) -> x20 + li x18, (0x1 << I2S_PIN_SD) + and x8, x8, x18 + srli x8, x8, I2S_PIN_SD + li x18, 32 + sub x19, x18, x9 + sll x8, x8, x19 + li x20, 1 + sll x20, x20, x19 + la x18, sd_sample_mask + lw x19, 0(x18) + or x19, x19, x20 + sw x19, 0(x18) + mv x20, x19 + la x18, sd_sample + lw x19, 0(x18) + or x19, x19, x8 + sw x19, 0(x18) + mv x8, x19 + + # bit < I2S_SMPL_WIDTH -> exit + li x18, I2S_SMPL_WIDTH + blt x9, x18, handler_sd_exit + + # disable ck irq + li x18, PLIC_PRIORITY + sw x0, 4*I2S_IRQ_CK_ID(x18) + + # reset irq mask + li x18, PLIC_THRESHOLD + sw x0, 0(x18) + + # reset sample / sample_mask + la x18, sd_sample + sw x0, 0(x18) + la x18, sd_sample_mask + sw x0, 0(x18) + + # correct for missed bits + la x18, sd_sample_save + li x19, 0x80000000 + srai x19, x19, I2S_SMPL_WIDTH-1 + and x20, x20, x19 + beq x19, x20, 0f + lw x8, 0(x18) +0: + sw x8, 0(x18) + srai x8, x8, 32-I2S_SMPL_WIDTH + + # aLaw encode -> x8 + li x18, 0x800 + li x19, 7 + bgez x8, 1f + neg x8, x8 + lui x9, 0x80000 + or x8, x8, x9 +1: + and x9, x8, x18 + beq x9, x18, 2f + beqz x19, 2f + srli x18, x18, 1 + addi x19, x19, -1 + j 1b +2: + mv x9, x19 + bnez x9, 3f + addi x9, x9, 1 +3: + sra x8, x8, x9 + li x9, 0x8000000f + and x8, x8, x9 + slli x19, x19, 4 + or x8, x8, x19 + bgez x8, 4f + ori x8, x8, 0x80 + +4: + xori x8, x8, 0x55 + andi x8, x8, 0xff + + # push to mic but + la x9, _eos_i2s_mic_buf + lhu x18, I2S_ABUF_OFF_IDXR(x9) + lhu x19, I2S_ABUF_OFF_IDXW(x9) + lhu x20, I2S_ABUF_OFF_SIZE(x9) + + sub x18, x19, x18 + beq x18, x20, handler_sd_exit + + addi x20, x20, -1 + and x20, x20, x19 + lw x18, I2S_ABUF_OFF_ARRAY(x9) + add x20, x20, x18 + sb x8, 0(x20) + + addi x19, x19, 1 + sh x19, I2S_ABUF_OFF_IDXW(x9) + + # push to event queue + la x9, _eos_i2s_mic_wm + lhu x20, 0(x9) + beqz x20, handler_sd_exit + + la x9, _eos_i2s_mic_buf + lhu x18, I2S_ABUF_OFF_IDXR(x9) + sub x18, x19, x18 + bne x18, x20, handler_sd_exit + + la x9, _eos_event_q + lbu x18, MSGQ_OFF_IDXR(x9) + lbu x19, MSGQ_OFF_IDXW(x9) + lbu x20, MSGQ_OFF_SIZE(x9) + + sub x18, x19, x18 + beq x18, x20, handler_sd_exit + + addi x20, x20, -1 + and x20, x20, x19 + li x18, MSGQ_ITEM_SIZE + mul x20, x20, x18 + lw x18, MSGQ_OFF_ARRAY(x9) + add x20, x20, x18 + li x18, (EOS_EVT_AUDIO | I2S_EVT_MIC) + sb x18, 0(x20) + + addi x19, x19, 1 + sb x19, MSGQ_OFF_IDXW(x9) + j handler_sd_exit + +handler_sd_exit: + LOAD x20, 0*REGBYTES(sp) + addi sp, sp, 1*REGBYTES + + # complete + li x18, I2S_IRQ_SD_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +handler_ck: + # enable sd irq + li x18, PLIC_PRIORITY + li x19, I2S_IRQ_SD_PRIORITY + sw x19, 4*I2S_IRQ_SD_ID(x18) + + # complete + li x18, I2S_IRQ_CK_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +handler_ws: + # enable wsc irq + li x18, PLIC_PRIORITY + li x19, I2S_IRQ_CI_PRIORITY + sw x19, 4*I2S_IRQ_CI_ID(x18) + + # complete + li x18, I2S_IRQ_WS_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +handler_ci: + # disable wsc/enable ck irq + li x18, PLIC_PRIORITY + sw x0, 4*I2S_IRQ_CI_ID(x18) + li x19, I2S_IRQ_CK_PRIORITY + sw x19, 4*I2S_IRQ_CK_ID(x18) + + # set irq mask + li x18, PLIC_THRESHOLD + li x19, I2S_IRQ_MASK + sw x19, 0(x18) + + # complete + li x18, I2S_IRQ_CI_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +trap_exit_data: + # Remain in M-mode after mret + li x18, MSTATUS_MPP + csrs mstatus, x18 + + LOAD x8, 0*REGBYTES(sp) + LOAD x9, 1*REGBYTES(sp) + LOAD x18, 2*REGBYTES(sp) + LOAD x19, 3*REGBYTES(sp) + + addi sp, sp, 4*REGBYTES + mret + +handler: + lui x18, %hi(trap_entry_text) + addi x18, x18, %lo(trap_entry_text) + jalr x0, x18 + + .align 4 + +sd_sample: + .word 0 +sd_sample_save: + .word 0 +sd_sample_mask: + .word 0 + + .section .text.entry + .align 2 + +trap_entry_text: + addi sp, sp, -28*REGBYTES + + STORE x1, 0*REGBYTES(sp) + STORE x2, 1*REGBYTES(sp) + STORE x3, 2*REGBYTES(sp) + STORE x4, 3*REGBYTES(sp) + STORE x5, 4*REGBYTES(sp) + STORE x6, 5*REGBYTES(sp) + STORE x7, 6*REGBYTES(sp) + STORE x10, 7*REGBYTES(sp) + STORE x11, 8*REGBYTES(sp) + STORE x12, 9*REGBYTES(sp) + STORE x13, 10*REGBYTES(sp) + STORE x14, 11*REGBYTES(sp) + STORE x15, 12*REGBYTES(sp) + STORE x16, 13*REGBYTES(sp) + STORE x17, 14*REGBYTES(sp) + STORE x20, 15*REGBYTES(sp) + STORE x21, 16*REGBYTES(sp) + STORE x22, 17*REGBYTES(sp) + STORE x23, 18*REGBYTES(sp) + STORE x24, 19*REGBYTES(sp) + STORE x25, 20*REGBYTES(sp) + STORE x26, 21*REGBYTES(sp) + STORE x27, 22*REGBYTES(sp) + STORE x28, 23*REGBYTES(sp) + STORE x29, 24*REGBYTES(sp) + STORE x30, 25*REGBYTES(sp) + STORE x31, 26*REGBYTES(sp) + + li x18, MCAUSE_TIMER + beq x8, x18, handle_timer + li x18, MCAUSE_EXT + beq x8, x18, handle_ext + mv a0, x8 + call _exit + +handle_timer: + call eos_timer_handle + j trap_exit_text + +handle_ext: + mv a0, x9 + call eos_intr_handle + li x18, PLIC_CLAIM + sw a0, 0(x18) + j trap_exit_text + +trap_exit_text: + # Remain in M-mode after mret + li t0, MSTATUS_MPP + csrs mstatus, t0 + + LOAD x1, 0*REGBYTES(sp) + LOAD x2, 1*REGBYTES(sp) + LOAD x3, 2*REGBYTES(sp) + LOAD x4, 3*REGBYTES(sp) + LOAD x5, 4*REGBYTES(sp) + LOAD x6, 5*REGBYTES(sp) + LOAD x7, 6*REGBYTES(sp) + LOAD x10, 7*REGBYTES(sp) + LOAD x11, 8*REGBYTES(sp) + LOAD x12, 9*REGBYTES(sp) + LOAD x13, 10*REGBYTES(sp) + LOAD x14, 11*REGBYTES(sp) + LOAD x15, 12*REGBYTES(sp) + LOAD x16, 13*REGBYTES(sp) + LOAD x17, 14*REGBYTES(sp) + LOAD x20, 15*REGBYTES(sp) + LOAD x21, 16*REGBYTES(sp) + LOAD x22, 17*REGBYTES(sp) + LOAD x23, 18*REGBYTES(sp) + LOAD x24, 19*REGBYTES(sp) + LOAD x25, 20*REGBYTES(sp) + LOAD x26, 21*REGBYTES(sp) + LOAD x27, 22*REGBYTES(sp) + LOAD x28, 23*REGBYTES(sp) + LOAD x29, 24*REGBYTES(sp) + LOAD x30, 25*REGBYTES(sp) + LOAD x31, 26*REGBYTES(sp) + + LOAD x8, 28*REGBYTES(sp) + LOAD x9, 29*REGBYTES(sp) + LOAD x18, 30*REGBYTES(sp) + LOAD x19, 31*REGBYTES(sp) + + addi sp, sp, 32*REGBYTES + mret -- cgit v1.2.3