Skip to content

Instantly share code, notes, and snippets.

@GMMan
Created August 4, 2022 06:01
Show Gist options
  • Save GMMan/634b23dec4ef82ec0f50cbe32f08eb6c to your computer and use it in GitHub Desktop.
Save GMMan/634b23dec4ef82ec0f50cbe32f08eb6c to your computer and use it in GitHub Desktop.
GPCE4 Test Program

GPCE4 Test Program

Entry

Before powering on the MCU, raise TEST pin high, configure wait states, select the test to run, and configure any inputs.

Test mode selection

Determines whether MCU starts in test mode.

Input

  • TEST: 1 = test mode, 0 = normal mode

Output

  • None

Wait states

Configures wait states. See C_Wait_State_Reg of P_Wait_Ctrl.

Input

  • IOA[7]: 1 = set wait state, 0 = use default (C_Wait_State_3Cycles)
  • IOA[3:0]: number of cycles

Output

  • None

Test selection

Selects the test to run.

Input

  • IOB[4:0]: test index
    • 0x00: SRAM test and sleep mode test
    • 0x01: GPIO test
    • 0x02: LVD test
    • 0x03: DAC test
    • 0x04: ADC test
    • 0x05: IRQ test
    • 0x06: SPI test
    • 0x07: System clock test
    • 0x08: ROM test
    • 0x09: Timer test
    • 0x0a: Reserved
    • 0x0b: Reserved
    • 0x0c: Set all GPIOs high
    • 0x0d: Set all GPIOs low
    • 0x0e: USB test
    • Other values will result in pins being resampled until valid

Output

  • IOB[15:8]: value read from IOB[7:0] when test selection valid

Note: the following values will cause MCU to enter busy loop:

  • IOB[15:12]: 0xa
  • IOB[7:0]: 0x0f, 0xa5, 0x1f, 0x35, 0x5a, 0x3f, 0x2f, 0x2c

Tests

0x00: SRAM test and sleep mode test

Checks SRAM, then enters sleep mode.

Input

  • None

Output

  • IOB[15:8]
    • After SRAM test: 0x80 if success, 0xf0 if failure
    • After sleep mode test: 0xc0 until system enters sleep

0x01: GPIO test

Checks GPIO port can be written to and read from, both using push-pull and pull up/down.

Input

  • None

Output

  • IOB[15:8]: 0xc1 if success, 0xf1 if failure

Note: IOB[0] is not checked due to being set to enter this test

0x02: LVD test

Tests LVD reset.

Input

  • IOA[10:8]: value to set C_LVD_Ctrl to in P_Reset_LVD_Ctrl

Output

  • IOB[15:8]: bits 8-15 of P_Reset_LVD_Ctrl

Note: hold same values on IOA and IOB and dip VDD below configured LVD value, then back up. C_LVD_Status_Flag should be set after the restart.

0x03: DAC test

Tests DAC output.

Input

  • IOA[11:8]: value to set C_PP_Gain_Sel to in P_PPAMP_Ctrl
  • IOA[15:0]: after gain select, value to convert by DAC

Output:

  • AUDP, AUDN: Converted analog output

Note: DAC conversion is run repeatedly

0x04: ADC test

Tests ADC conversion.

Input

  • IOA[15]: C_ADC_PGA_Disable or C_ADC_PGA_Enable in P_ADC_PGA_Ctrl
  • IOA[12:8]: value to set C_ADC_PGA_Gain_Sel to in P_ADC_PGA_Ctrl
  • IOA[3]: input select, 0 = ADC channel, 1 = MIC
  • IOA[2:0]: ADC channel select, see C_ADC_Manual_AN* of P_ADC_Ctrl
  • MICP, MICN, IOB[7:0]: ADC input

Output

  • IOA[15:4]: converted data from P_ADC_Data
  • IOB[15]: pulsed after conversion latched to IOA

Note: ADC conversion is run repeatedly

0x05: IRQ test

Tests IRQs.

Input

  • IOA[8]: EXT1 trigger rising edge
  • IOA[6]: EXT2 trigger rising edge

Output

  • IOC[15]: high when Timer A (8KHz) interrupt triggers
  • IOC[14]: high when Timer B (4KHz) interrupt triggers
  • IOC[13]: high when Timer C (2KHz) interrupt triggers
  • IOC[8]: high when SPI2 interrupt triggers
  • IOC[7]: high when SPI interrupt triggers
  • IOC[4]: high when KEY interrupt triggers
  • IOC[1]: high when EXT1 interrupt triggers
  • IOC[0]: high when EXT2 interrupt triggers
  • IOB[13]: high when 4096Hz interrupt triggers
  • IOB[12]: high when 2048Hz interrupt triggers
  • IOB[11]: high when 512Hz interrupt triggers
  • IOB[10]: high when 64Hz interrupt triggers
  • IOB[9]: high when 16Hz interrupt triggers
  • IOB[8]: high when 2Hz interrupt triggers

0x06: SPI test

Tests SPI loopback mode.

Input

  • None

Output

  • IOB[15:8]: 0xc6 if success, 0xf6 if failure

0x07: System clock test

Tests system clock settings.

Input

  • IOA[15:8]: value to set lower 8 bits of P_System_Clock to

Output

  • IOB[15]: toggled in a loop

0x08: ROM test

Tests ROM/OTP read.

Input

  • None

Output

  • IOB[15]: toggled in a loop
  • IOB[15:8]: 0xf8 if failure

0x09: Timer test

Tests timer A and associated interrupt.

Input

  • None

Output

  • IOC[15]: toggled when timer triggers

0x0a: Reserved

Does nothing.

Input

  • None

Output

  • None

0x0b: Reserved

Does nothing.

Input

  • None

Output

  • None

0x0c: Set all GPIOs high

Sets all GPIO pins high.

Input

  • None

Output

  • IOA[15:0], IOB[15:0], IOC[15:0]: set high

0x0d: Set all GPIOs low

Sets all GPIO pins low.

Input

  • None

Output

  • IOA[15:0], IOB[15:0], IOC[15:0]: set low

0x0e: USB test

Currently unknown due to lack of documentation of related registers.

Input

  • Unknown

Output

  • Unknown

Notes

Init details

  • Set system clock to 48MHz
  • Reset IOA to input pull low
  • Disable SPI interfaces
  • Disable ADC
  • IOA7 + IOA0-3: wait state config, IOA7 high to set P_Wait_control to IOA0-3, otherwise 3 by default
  • IOB0-4: test select
    • IOB0-7 value latched into IOB8-15 on acceptance
    • Rechecks if value not in range

Test details

Results are typically output on IOB8-15

  • 0: SRAM test and sleep mode test
    • SRAM test
      • Write 0x55aa to all SRAM (0x17ff down to 0x0000), then read back and verify value is as written
      • Repeat above with value being 0xaa55
      • Sets IOB to 0x8000 if success, 0xf000 if failure
    • Sleep mode test
      • Turn off 32KHz sleep (system reset after wake)
      • Unmask all I/O wakeup bits
      • Enable key IRQ
      • Enter sleep mode
      • Set IOB to 0xc000
  • 1: GPIO test
    • Set all IO to output
    • Write 0x55aa to each port
    • Confirm each port reads the same, output 0xf100 on IOB if failure
      • IOB0 is ignored since it's probably still latched test select at this point
    • Repeat above with 0xaa55
    • Repeat all of the above with all IO set to input with pull instead
    • Output 0xc100 on success
    • Uses *6
  • 2: LVD test
    • Read IOA8-10 and write into C_LVD_Ctrl of P_Reset_LVD_Ctrl
    • Repeatedly output reset status flags (top 8 bits of P_Reset_LVD_Ctrl) on IOB8-15
  • 3: DAC test
    • Enable DAC and channel 1 and 2
    • Read IOA8-11 to set gain in P_PPAMP_Ctrl, also set CH1/2 mix and push-pull enable
    • Repeatedly sample IOA and write to DAC CH1/2 data
  • 4: ADC test
    • Read IOA8-15 and set to P_ADC_PGA_Ctrl
    • If IOB3 set, IOB0-3 select manual channel, otherwise mic selected
    • Repeatedly sample ADC data, and set upper 12 bits to IOA4-15, and pulse IOB15 after each conversion
  • 5: IRQ test
    • Set IOA0-7 and IOC0-15 to output, set all IO low
    • Set system clock 48MHz, C_Sleep_RTC_SLP_Work, C_RTC_Mode_Strong
    • Clear timebase
    • Set timers to use PLL
    • Set timer A to 8KHz
    • Set timer B to 4KHz
    • Set timer C to 2KHz
    • Clear P_IO_Ctrl
    • Reset and enable SPI/SPI2
    • Enable SPI/SPI2 interrupt and set FIFO level to 2
    • Write 0x4020 to SPI/SPI2
    • Turn on SPI, timer, key, ext, and periodic interrupts (basically all IRQs)
    • Reset interrupt status
    • IRQ handling
      • Timer A: one shot set IOC15 high
      • Timer B: one shot set IOC14 high
      • Timer C: one shot set IOC13 high
      • SPI: one shot set IOC7 high, disable SPI interrupt
      • SPI2: one shot set IOC8 high, disable SPI interrupt
      • Key: one shot set IOC4 high
      • EXT1/2: set IOC1/0 high accordingly
      • 4096Hz: set IOB13 high
      • 2048Hz: set IOB12 high
      • 512Hz: set IOB11 high
      • 64Hz: set IOB10 high
      • 16Hz: set IOB9 high
      • 2Hz: set IOB8 high
  • 6: SPI test
    • Reset SPI/SPI2
    • Set enable, C_SPI_LBM_Enable, auto CS, and /16 prescaler for SPI and SPI2
    • Send to both SPI and SPI2, values from 0x00 to 0xff, and read back after each TX
      • If mismatch, output 0xf600 to IOB
    • Output 0xc600 if success
    • Uses *4
  • 7: External crystal test
    • Read IOA8-15 into P_System_Clock (PLL not available, mostly only SYSCLK prescaler is applicable)
    • Repeatedly toggle IOB15
  • 8: ROM test
    • Calculate ROM checksum
    • Repeatedly calculate ROM checksum and compare with initial value, toggling IOB15 after each iteration
    • If checksum mismatch, output 0xf800 on IOB
    • Uses *1
  • 9: Timer test
    • Set timer A source to PLL
    • Set timer A to 16kHz
    • Clear P_IO_Ctrl
    • Turn on timer A IRQ
    • Toggles IOC15 every time IRQ triggers
    • Uses *2
  • 10: Reserved
  • 11: Reserved
  • 12: Set all GPIOs high
  • 13: Set all GPIOs low
  • 14: USB test
    • Dunno what this does
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment