[WIP] Voice IND
[osmocom-bb.git] / src / target / firmware / calypso / tpu.c
index f0172e2..0b60292 100644 (file)
 #include <calypso/tpu.h>
 #include <calypso/tsp.h>
 
+/* Using TPU_DEBUG you will send special HLDC messages to the host PC
+ * containing the full TPU RAM content at the time you call tpu_enable() */
+//#define TPU_DEBUG
+
 #define BASE_ADDR_TPU  0xffff1000
 #define TPU_REG(x)     (BASE_ADDR_TPU+(x))
 
@@ -66,6 +70,51 @@ enum tpu_int_ctrl_bits {
        ICTRL_DSP_FRAME_FORCE   = (1 << 3),
 };
 
+static uint16_t *tpu_ptr = (uint16_t *)BASE_ADDR_TPU_RAM;
+
+#ifdef TPU_DEBUG
+#include <comm/sercomm.h>
+#include <layer1/sync.h>
+static void tpu_ram_read_en(int enable)
+{
+       uint16_t reg;
+
+       reg = readw(TPU_REG(TPU_CTRL));
+       if (enable)
+               reg |= TPU_CTRL_MCU_RAM_ACC;
+       else
+               reg &= ~TPU_CTRL_MCU_RAM_ACC;
+       writew(reg, TPU_REG(TPU_CTRL));
+}
+
+static void tpu_debug(void)
+{
+       uint16_t *tpu_base = (uint16_t *)BASE_ADDR_TPU_RAM;
+       unsigned int tpu_size = tpu_ptr - tpu_base;
+       struct msgb *msg = sercomm_alloc_msgb(tpu_size*2);
+       uint16_t *data;
+       uint32_t *fn;
+       uint16_t reg;
+       int i;
+
+       /* prepend tpu memory dump with frame number */
+       fn = (uint32_t *) msgb_put(msg, sizeof(fn));
+       *fn = l1s.current_time.fn;
+
+       tpu_ram_read_en(1);
+
+       data = (uint16_t *) msgb_put(msg, tpu_size*2);
+       for (i = 0; i < tpu_size; i ++)
+               data[i] = tpu_base[i];
+
+       tpu_ram_read_en(0);
+
+       sercomm_sendmsg(SC_DLCI_DEBUG, msg);
+}
+#else
+static void tpu_debug(void) { }
+#endif
+
 #define BIT_SET        1
 #define BIT_CLEAR 0
 
@@ -117,6 +166,9 @@ void tpu_enable(int active)
        uint16_t reg = readw(TPU_REG(TPU_CTRL));
 
        printd("tpu_enable(%u)\n", active);
+
+       tpu_debug();
+
        if (active)
                reg |= TPU_CTRL_EN;
        else
@@ -142,7 +194,7 @@ void tpu_enable(int active)
 #endif
 }
 
-/* Enable or Disable the clock of teh TPU Module */
+/* Enable or Disable the clock of the TPU Module */
 void tpu_clk_enable(int active)
 {
        uint16_t reg = readw(TPU_REG(TPU_CTRL));
@@ -180,8 +232,6 @@ int tpu_dsp_fameirq_pending(void)
        return 0;
 }
 
-static uint16_t *tpu_ptr;
-
 void tpu_rewind(void)
 {
        dputs("tpu_rewind()\n");
@@ -190,7 +240,7 @@ void tpu_rewind(void)
 
 void tpu_enqueue(uint16_t instr)
 {
-       printd("tpu_enqueue(tpu_ptr=%p, instr=0x%04x\n", tpu_ptr, instr);
+       printd("tpu_enqueue(tpu_ptr=%p, instr=0x%04x)\n", tpu_ptr, instr);
        *tpu_ptr++ = instr;
        if (tpu_ptr > (uint16_t *) TPU_RAM_END)
                puts("TPU enqueue beyond end of TPU memory\n");
@@ -198,9 +248,17 @@ void tpu_enqueue(uint16_t instr)
 
 void tpu_init(void)
 {
-       /* Get TPU out of reset */
+       uint16_t *ptr;
+
+       /* Put TPU into Reset and enable clock */
        tpu_reset(1);
        tpu_clk_enable(1);
+
+       /* set all TPU RAM to zero */
+       for (ptr = (uint16_t *) BASE_ADDR_TPU_RAM; ptr < (uint16_t *) TPU_RAM_END; ptr++)
+               *ptr = 0x0000;
+
+       /* Get TPU out of reset */
        tpu_reset(0);
        /* Disable all interrupts */
        writeb(0x7, TPU_REG(INT_CTRL));
@@ -274,9 +332,9 @@ uint16_t tpu_get_synchro(void)
 }
 
 /* add two numbers, modulo 5000, and ensure the result is positive */
-uint16_t add_mod5000(uint16_t a, uint16_t b)
+uint16_t add_mod5000(int16_t a, int16_t b)
 {
-       int32_t sum = (uint32_t)a + (uint32_t)b;
+       int32_t sum = (int32_t)a + (int32_t)b;
 
        sum %= 5000;