Difference between revisions of "CH32V307"

From Stm32World Wiki
Jump to navigation Jump to search
Line 10: Line 10:
  
 
== Development Notes ==
 
== Development Notes ==
=== DAC ===
+
* [[CH32V307-DAC]]
 
 
* The output impedance is a concern. Without the Output Buffer enabled, >100kohm impedance for the load is needed. Even WITH Output Buffer enabled, a 1kohm load is not really possible, both high and low end of range is not reached, which is a bit strange. 10kohm hasn't been tested yet, but datasheet indicates that a 5kohm load should be fine.
 
 
 
* For fastest write to DAC output, this is used;
 
<nowiki>
 
DAC->RD12BDHR = dac_value1 + (dac_value2 << 16);
 
</nowiki>
 
 
 
* Simple initialization is;
 
<nowiki>
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
 
 
 
    DAC_InitTypeDef DAC_InitType={0};
 
    DAC_InitType.DAC_Trigger=DAC_Trigger_None;
 
    DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
 
    DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Enable;
 
    DAC_Init(DAC_Channel_1,&DAC_InitType);
 
    DAC_Init(DAC_Channel_2,&DAC_InitType);
 
 
 
    DAC_Cmd(DAC_Channel_1, ENABLE);
 
    DAC_Cmd(DAC_Channel_2, ENABLE);
 
</nowiki>
 
 
 
=== Execution Speed ===
 
While executing some tests, I noticed that an extra layer of function call added much more time than should be the case.
 
 
 
In the '''TIM7_IRQHandler''' I did
 
<nowiki>
 
__attribute__((interrupt("WCH-Interrupt-fast"))) void TIM7_IRQHandler() {
 
    GET_INT_SP();
 
    rt_interrupt_enter();
 
    GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);
 
    GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_RESET);
 
    set_testpoint(0);
 
    clear_testpoint(0);
 
    demiurge_tick();
 
    TIM7->INTFR = 0;
 
    rt_interrupt_leave();
 
    FREE_INT_SP();
 
}
 
</nowiki>
 
 
 
and the '''set_testpoint(0)''' and '''clear_testpoint(0)''' functions as follows;
 
 
 
<nowiki>
 
void set_testpoint(int point)
 
{
 
    GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);
 
}
 
void clear_testpoint(int point)
 
{
 
    GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_RESET);
 
}
 
</nowiki>
 
 
 
It is clear that there is literally only one extra call. In assembler we can see that the compiler has not inlined any of this code;
 
 
 
 
 
  21                    __attribute__((interrupt("WCH-Interrupt-fast"))) void TIM7_IRQHandler() {
 
  22 002c 73110134          GET_INT_SP();
 
  23                        rt_interrupt_enter();
 
  33                            csrrw sp,mscratch,sp
 
  34                    # 0 "" 2
 
  35                    #NO_APP
 
  36 0030 37140140              li      s0,1073811456
 
  37 0034 97000000              call    rt_interrupt_enter
 
  37      E7800000
 
  38 003c 13050480              addi    a0,s0,-2048
 
  39 0040 0546                  li      a2,1
 
  40 0042 93050008              li      a1,128
 
  41 0046 97000000              call    GPIO_WriteBit
 
  41      E7800000
 
  42 004e 0146                  li      a2,0
 
  43 0050 93050008              li      a1,128
 
  44 0054 13050480              addi    a0,s0,-2048
 
  45 0058 97000000              call    GPIO_WriteBit
 
  45      E7800000
 
  46 0060 0145                  li      a0,0
 
  47 0062 97000000              call    set_testpoint
 
  47      E7800000
 
  48 006a 0145                  li      a0,0
 
  49 006c 97000000              call    clear_testpoint
 
  49      E7800000
 
  50 0074 97000000              call    demiurge_tick
 
  50      E7800000
 
  51 007c B7170040              li      a5,1073745920
 
  52 0080 23980740              sh      zero,1040(a5)
 
  53 0084 97000000              call    rt_interrupt_leave
 
  53      E7800000
 
-------
 
  29                    set_testpoint:
 
  30 0000 17030000              call    t0,__riscv_save_0
 
  30      E7020300
 
  31 0008 37150140              li      a0,1073811456
 
  32 000c 0546                  li      a2,1
 
  33 000e 93050008              li      a1,128
 
  34 0012 13050580              addi    a0,a0,-2048
 
  35 0016 97000000              call    GPIO_WriteBit
 
  35      E7800000
 
  36 001e 17030000              tail    __riscv_restore_0
 
  36      67000300
 
  38                            .section        .text.clear_testpoint,"ax",@progbits
 
  39                            .align  1
 
  40                            .globl  clear_testpoint
 
  42                    clear_testpoint:
 
  43 0000 17030000              call    t0,__riscv_save_0
 
  43      E7020300
 
  44 0008 37150140              li      a0,1073811456
 
  45 000c 0146                  li      a2,0
 
  46 000e 93050008              li      a1,128
 
  47 0012 13050580              addi    a0,a0,-2048
 
  48 0016 97000000              call    GPIO_WriteBit
 
  48      E7800000
 
  49 001e 17030000              tail    __riscv_restore_0
 
  49      67000300
 
 
 
 
 
But on the oscilloscope, I get a 70ns pulse first and a 220ns pulse there after. So why does
 
 
 
  46 0060 0145                  li      a0,0
 
  47 0062 97000000              call    set_testpoint
 
 
 
 
 
take 150ns to execute?  For the '''GPIO_WriteBit''' we have 5 32-bit and 1 16-bit instruction, and inside '''GPIO_WriteBit''' we get 3 assembly instructions. At 144MHz, each fetch cycle is ~7ns, so 7*9 = 63ns which is very close to what I observe. So the
 
 
 
  li a0,0
 
  call set_testpoint
 
 
 
should only take 14 or maybe 21 ns, not 150ns!!!
 
 
 
'''So why is this happening??'''
 
 
 
Hypotheses
 
# Different memory types, fetch happening at different speeds. Perhaps because the code is inside a IRQ Handler.
 
# Because it is Saturday and was raining earlier.
 

Revision as of 08:29, 3 July 2022