Skip to content

CH32V003J4M6 to stops reporting MCU UID after Arduino upload, bricking chip. #194

@beehphy

Description

@beehphy

Uploading a seemingly benign arduino sketch causes CH32V003J4M6 to stop reporting MCU UID. This exact file has been repeated twice, bricking both chips. The circuit is just the chip and a bypass cap with +5V, GND, SWO lines connected WCH-LinkE v1.0.
After upload of INO file the WCH-LinkUtility 2.40 cannot communicate with the chip. The log in in WCH-LinkUtility says:

Begin to set chip type...
Failed,the chip type is not matched or status of chip is wrong!

Seems like adding the analogWrite() in the setup function was the only change to cause bricking.

Full Arduino sketch:

void TIMx_PWM(u16 ClkPrescaler, u16 Period, u16 PwmCount, u16 Timer, u16 Channel)
{
  TIM_OCInitTypeDef       TIM_OCInitStructure = {0};
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};

  TIM_TypeDef *TIMx;
  if      (Timer == 1) {
    TIMx = TIM1;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  }
  else if (Timer == 2) {
    TIMx = TIM2;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  }
  else {
      return;  //fail, cannot proceed
  }

  TIM_TimeBaseInitStructure.TIM_Period = Period;
  TIM_TimeBaseInitStructure.TIM_Prescaler = ClkPrescaler;
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStructure);

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = PwmCount;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  switch(Channel){
      case 1:
      TIM_OC1Init(TIMx, &TIM_OCInitStructure);
      break;

      case 2:
      TIM_OC2Init(TIMx, &TIM_OCInitStructure);
      break;

      case 3:
      TIM_OC3Init(TIMx, &TIM_OCInitStructure);
      break;

      case 4:
      TIM_OC4Init(TIMx, &TIM_OCInitStructure);
      break;
  }

  TIM_CtrlPWMOutputs(TIM1, ENABLE);
  switch(Channel){
  case 1:
      TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Disable);
      break;

  case 2:
      TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Disable);
      break;

  case 3:
      TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Disable);
      break;

  case 4:
      TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Disable);
      break;
  }
  TIM_ARRPreloadConfig(TIMx, ENABLE);
  TIM_SelectOutputTrigger(TIMx, TIM_TRGOSource_Update);
  TIM_Cmd(TIMx, ENABLE);
}

void pinSetup(GPIO_TypeDef *port, uint32_t pin, GPIOMode_TypeDef mode) {
    if (pin == 0) printf("Pin setup Bonk\r\n");

    u32 BitMask = 0;
    while ( (1&(pin >> BitMask)) != 0x1 ) {  //solve the pin number based on the mask
        if (BitMask == 20) {
            printf("Pin setup Lost, 0x%x\r\n", pin);
            break;
        }
        BitMask++;
    }

    if ( port == GPIOA_BASE) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
    }
    if ( port == GPIOC_BASE) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
    }


    GPIO_InitTypeDef  GPIO_InitStructure = {0};  //blank structure
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = pin;
    GPIO_InitStructure.GPIO_Mode = mode;
    GPIO_Init(port, &GPIO_InitStructure);  //make active
}

void setup() {
  Serial.begin(115200);

  analogWrite(PC4,128);  //this line seems to be the problem
  //I was having prblems getting the PWM output going. 
  //I added the analogWrite hoping to poke the pin configuration into opperation

  pinSetup(GPIOC, GPIO_Pin_4 ,GPIO_Mode_AF_PP);
  TIMx_PWM(1,200,20,TIM1,4);
}

int i = 0;

void loop() {
  Serial.print(i++);
  delay(100);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions