Analyzing and duplicating the behavior of a PIC12

Enhanced mid-range devices. PIC12F1xxx and PIC16F1xxx

Analyzing and duplicating the behavior of a PIC12

Postby logicalness » Tue Jan 15, 2019 12:57 pm

Hello everyone!

Short disclaimer before you invest your time reading my post: In this post I ask for information about analyzing clock and data lines on a PIC12 which appears to be configured for synchronous EUSART. I am not interested in, or asking how to read a CP protected chip. I'm just interested in learning how to analyze PIC12 behavior using a logic analyzer and developing what I observe on a brand new chip.

I've recently pulled apart a child's toy and noticed a chip which I believe is a PIC12F1572, or extremely similar. The chip is an 8 pin, surface mount chip and unmarked, but a video posted online with the developers showed a prototype of the PCB with an 8-pin chip marked "F1572" with a Microchip logo.

The toy communicates to a "base station" that powers on the device and the user can make LEDs flicker. Based on the relatively simple nature of the toy, the PIC12F1572's 3 PWMs as well as logic analyzer captures all lead me to believe this is a rather reasonable assumption.

So I wired up my logic analyzer to an SOIC clip, seated it to the target chip and powered on the toy. The following captures show only one segment of the power-on activity. It does not show the data transmitted during the full start-up capture, or interacting with the toy.

Figure 1: Capture at power-on. Appears to be synchronous serial communication from the chip. Pin 7 on the chip appears to be the clock, and Pin 6, the data line. This is consistent with PIC12F1572 documentation on EUSART mode. There's a constant clock "tick" around 44kHz, which speeds up to ~9.8kHz during data transfer. The clock is idle low, while the data line is idle high.
Image


Figure 2: This image shows the first communications chatter.
Image


Figure 3: This image shows the frequency of the periodic "ticks" on the clock line.
Image


Figure 4: This image shows the frequency of the clock during data transfer. Notice how the data line drops low prior to the clock. There's an elongated tick at the beginning and end of this transmission on the clock.
Image


Figure 5: This image shows my version of the chip (not the original shown in Figures 1-4). Notice how my chip attempts to send the same data, but the data line is idle low. Also, there's a "drift" in the clock line where the frequency appears to shift. When I capture this on a bread board I don't get this - when I write my code to a new chip on the toy's PCB, I do.
Image


Figure 6: This image shows my version of the chip with more time. I've added this image to show a contrast between Figure 1 where the original chip has a constant "chirp" on the clock line - my version does not.
Image

Here's a link to all images on one page: Imgur: https://imgur.com/a/NrTObUL

Here is my code which attempts to replicate the synchronous EUSART data transfer seen in the logic analyzer captures shown in these images.

Code: Select all
#include <xc.h>

#define _XTAL_FREQ 16000000   // Oscillator frequency.

#pragma config FOSC = INTOSC  // INTOSC oscillator: I/O function on CLKIN pin.
#pragma config WDTE = OFF     // Watchdog Timer off.
#pragma config PWRTE = OFF    // Power-up Timer enbable.
#pragma config MCLRE = ON     // MCLR/VPP pin function is MCLR.
#pragma config CP = OFF       // Program memory code protection disabled.
#pragma config BOREN = ON     // Brown-out Reset enabled.
#pragma config CLKOUTEN = OFF // CLKOUT function is disabled; I/O or oscillator
                              // function on the CLKOUT pin.
#pragma config WRT = OFF      // Flash Memory Write protection off.
#pragma config STVREN = ON    // Stack Overflow or Underflow will cause a Reset.
#pragma config BORV = LO      // Brown-out Reset Voltage (Vbor), low trip point
                              // selected.
#pragma config LVP = OFF      // High-voltage on MCLR/VPP must be used for
                              // programming.

#include <stdio.h>
#include <stdlib.h>

void init_pic() {
    ANSELA = 0;             // Analog off.
    OSCCON = 0b01111010;    // 16 Mhz clock, int. oscillator block (see page 55)
   
    // 16 MHz oscillator, 9600 bps (see page 187 for calculation)
    SPBRGH = 0x00;  // BRG high byte
    SPBRGL = 0x19;  // BRG low byte
}

void init_uart() {
    // Synchronous Master Transmission Setup  (page 196)
    BAUDCONbits.BRG16 = 1;
   
    // Configure EUSART for synchronous master operation (page 196)
    TXSTAbits.CSRC = 1;     // configure as master
    TXSTAbits.TX9 = 0;      // 8-bit transmission (as opposed to 9-bit)
    TXSTAbits.TXEN = 1;     // transmit enabled
    TXSTAbits.SYNC = 1;     // synchronous operation
   
    RCSTAbits.SPEN = 1;     // enable EUSART (serial port enabled)
    RCSTAbits.RX9 = 0;      // 8-bit reception (as opposed to 9-bit)
    RCSTAbits.SREN = 0;     // disable single receive
   
    BAUDCONbits.SCKP = 0;   // set the clock idle state to low
   
    // The following lines are used to mimic what we see on the logic analyzer
    LATAbits.LATA4 = 1;     // Sets RA4 high
}

void send_byte(unsigned char byte) {
  // Wait until no char is being held for transmission in the TXREG.
  while (!PIR1bits.TXIF) {
    continue;
  }
  // Write the byte to the transmission register.
  TXREG = byte;
}

int main() {
   
    // Initialize the PIC
    init_pic();
    init_uart();
   
    // Send loop
    while (1) {
        __delay_ms(43);

        send_byte(0xE1);
        send_byte(0x48);
        send_byte(0x80);
        send_byte(0xF0);
        send_byte(0x42);
       
        __delay_ms(1000);

        send_byte(0xE1);
        send_byte(0x08);
        send_byte(0x80);
        send_byte(0xF0);
        send_byte(0x02);
       
        __delay_ms(4000);
    }
   
    return (EXIT_SUCCESS);
}


I wrote my code to a brand new PIC12F1572 on a breadboard using the Pickit 3 and MPLAB X. I then connected my logic analyzer and supplied 5V from my own powered USB port (not the Pickit 3) and captured the power on activity.

Here's what I noticed:
• My data line idles low while the target chip's data line idles high.
• When my chip "talks" the clock and data lines are completely in sync, but on the target, the data line drops low before the clock even ticks high.
• My clock is very consistent in frequency, whereas the target chip's clock line has a longer start and end "chirps" which a consistent frequency in between.

So finally, my questions:
1. Is it possible (in code) to switch the idle state of the EUSART data line to high instead of low? I know this is possible on the clock by setting `BAUDCONbits.SCKP = 1` but I can't find any indication the same is possible with the data line.
2. How could it be possible for the data line to activate before the clock line? Do you think this is just a poor capture? I captured at 12 Mhz which is close to the upper range on my very cheap budget logic analyzer (currently budgeting for a Saleae).
3. What would cause the clock to have longer chirps at the start and end of the data transfer as seen in Figure 4 (the start is shown).
4. When I write my code to the PIC12 the clock only activates when data is being sent. However, on the target chip, there's this periodic chirp when no data is being transferred. This is shown in Figures 2 and 3.
5. Figure 5 shows a "drift" in the clock line - any idea what would cause this? It happens when I write my code to the chip on the PCB, not on my breadboard.

Thanks so much for your time and help!
logicalness
 
Posts: 1
Joined: Tue Jan 15, 2019 5:35 am

Re: Analyzing and duplicating the behavior of a PIC12

Postby jtemples » Sun Jan 20, 2019 10:08 pm

You've assumed they're using the UART, but they're probably just bit-banging a proprietary protocol which is coincidentally on the UART pins.
jtemples
Verified identity
 
Posts: 181
Joined: Sun May 25, 2014 2:23 am
Location: The 805
PIC experience: Professional 5+ years with MCHP products


Return to 14-Bit Core (enhanced)

Who is online

Users browsing this forum: No registered users and 1 guest