PageSourceSearch

https://jcalado.com/posts/gm950-programming-cable/

html jcalado.com collected 2026-09-24 13:45:52 UTC 38,110 bytes, 259 lines download raw bytes

1<!DOCTYPE html><html lang="en" data-theme="auto" data-dark-theme="github-dark" data-light-theme="github-light" data-theme-mode="light-dark-auto" data-theme-hash="02d6740b" style="--theme-font: JetBrains Mono Variable;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);" data-astro-cid-ju4pidww><head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1.0" name="viewport"><meta name="generator" content="Astro v7.3.2"><meta name="title" content="A DIY Programming Cable for the Motorola GM950 - jcalado.com"><meta name="description" content="Building a cheap USB programming cable for the Motorola GM950 with a USB-TTL module, one diode and one resistor"><meta name="author" content="Joel Calado"><meta property="og:title" content="A DIY Programming Cable for the Motorola GM950 - jcalado.com"><meta property="og:description" content="Building a cheap USB programming cable for the Motorola GM950 with a USB-TTL module, one diode and one resistor"><meta property="og:url" content="http://jcalado.com/posts/gm950-programming-cable"><meta property="og:type" content="article"><meta property="og:image" content="http://jcalado.com/social-cards/gm950-programming-cable.png"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="A DIY Programming Cable for the Motorola GM950 - jcalado.com"><meta name="twitter:description" content="Building a cheap USB programming cable for the Motorola GM950 with a USB-TTL module, one diode and one resistor"><meta name="twitter:image" content="http://jcalado.com/social-cards/gm950-programming-cable.png"><meta name="keywords" content="development, blog, ham radio, amateur-radio, motorola, diy, electronics, radio-programming, hardware"><link rel="canonical" href="https://jcalado.com/posts/gm950-programming-cable"><link rel="sitemap" href="/sitemap-index.xml"><link rel="icon" href="/favicon.svg" type="image/svg+xml"><link rel="alternate" type="application/rss+xml" title="jcalado.com" href="https://jcalado.com/rss.xml"><title>A DIY Programming Cable for the Motorola GM950 - jcalado.com</title><style>:root[data-theme="github-light"] {
2--theme-foreground: #1c2333;
3--theme-background: #f3ecd8;
4--theme-accent: #b6242a;
5--theme-heading1: #1c2333;
6--theme-heading2: #1c2333;
7--theme-heading3: #1c2333;
8--theme-heading4: #1c2333;
9--theme-heading5: #1c2333;
10--theme-heading6: #1c2333;
11--theme-list: #1c2333;
12--theme-italic: #24292e;
13--theme-link: #b6242a;
14--theme-separator: #1c2333;
15--theme-note: #0366d6;
16--theme-tip: #28a745;
17--theme-important: #5a32a3;
18--theme-caution: #dbab09;
19--theme-warning: #d73a49;
20--theme-blue: #1f4ea0;
21--theme-green: #3d6630;
22--theme-red: #b6242a;
23--theme-yellow: #8a6a00;
24--theme-magenta: #8a1750;
25--theme-cyan: #0c6a73;
26}
27:root[data-theme="github-dark"] {
28--theme-foreground: #dbc99a;
29--theme-background: #0e1217;
30--theme-accent: #f4c95d;
31--theme-heading1: #f4c95d;
32--theme-heading2: #f4c95d;
33--theme-heading3: #f4c95d;
34--theme-heading4: #f4c95d;
35--theme-heading5: #f4c95d;
36--theme-heading6: #f4c95d;
37--theme-list: #dbc99a;
38--theme-italic: #e1e4e8;
39--theme-link: #ff8d7a;
40--theme-separator: #dbc99a;
41--theme-note: #2188ff;
42--theme-tip: #34d058;
43--theme-important: #b392f0;
44--theme-caution: #ffea7f;
45--theme-warning: #ea4a5a;
46--theme-blue: #7ab9ff;
47--theme-green: #a3d977;
48--theme-red: #ff8d7a;
49--theme-yellow: #f4c95d;
50--theme-magenta: #ff5fc8;
51--theme-cyan: #7eddd8;
52}</style>
52<script>
53  ;(function loadTheme() {
54    const pageDefaultTheme = document.documentElement.getAttribute('data-theme')
55    const pageDarkTheme = document.documentElement.getAttribute('data-dark-theme')
56    const pageLightTheme = document.documentElement.getAttribute('data-light-theme')
57    const pageThemeHash = document.documentElement.getAttribute('data-theme-hash')
58    if (!pageDefaultTheme || !pageDarkTheme || !pageLightTheme || !pageThemeHash) {
59      throw new Error('Theme attributes are required.')
60    }
61    const getStoredTheme = () => localStorage.getItem('data-theme')
62    let storedTheme = getStoredTheme()
63    const storedThemeHash = localStorage.getItem('data-theme-hash')
64    const themeHashMatches = storedThemeHash === pageThemeHash
65
66    if (!storedTheme || !storedThemeHash || !themeHashMatches) {
67      // Should be the first time loading the website
68      localStorage.setItem('data-theme', pageDefaultTheme)
69      localStorage.setItem('data-theme-hash', pageThemeHash)
70    }
71
72    if (
73      themeHashMatches &&
74      storedTheme &&
75      storedTheme !== 'auto' &&
76      storedTheme !== pageDefaultTheme
77    ) {
78      // The stored theme is different from the default theme, apply it
79      document.documentElement.setAttribute('data-theme', storedTheme)
80    } else if (pageDefaultTheme === 'auto' || storedTheme === 'auto') {
81      // If the default or stored theme is 'auto', apply the system preference
82      const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)')
83      document.documentElement.setAttribute(
84        'data-theme',
85        prefersDarkScheme.matches ? pageDarkTheme : pageLightTheme,
86      )
87      prefersDarkScheme.addEventListener('change', (e) => {
88        if (getStoredTheme() === 'auto') {
89          const newTheme = e.matches ? pageDarkTheme : pageLightTheme
90          document.documentElement.setAttribute('data-theme', newTheme)
91        }
92      })
93    }
94  })()
95</script>
95<script>
96  ;(function () {
97    const root = document.documentElement
98
99    try {
100      if (localStorage.getItem('animations') === 'off') {
101        root.setAttribute('data-animations', 'off')
102      }
103    } catch {}
104
105    const motionOff = () =>
106      root.getAttribute('data-animations') === 'off' ||
107      window.matchMedia('(prefers-reduced-motion: reduce)').matches
108
109    // Paginated routes look like /posts, /posts/2, /tags/foo, /tags/foo/2.
110    const pageNum = (path) => Number((path.match(/\/(\d+)\/?$/) || [])[1] || 1)
111    const section = (path) => path.replace(/\/\d+\/?$/, '') || '/'
112
113    function direction(fromUrl, toUrl) {
114      try {
115        const from = new URL(fromUrl)
116        const to = new URL(toUrl)
117        if (section(from.pathname) !== section(to.pathname)) return null
118        const a = pageNum(from.pathname)
119        const b = pageNum(to.pathname)
120        return a === b ? null : b > a ? 'older' : 'newer'
121      } catch {
122        return null
123      }
124    }
125
126    // Both documents must add the type independently, so the same decision is
127    // made on the way out and on the way in.
128    function tag(viewTransition, fromUrl, toUrl) {
129      if (!viewTransition) return
130      // `ready` rejects with "Transition was skipped" whenever the transition
131      // is dropped -- by skipTransition() below, or by the browser itself.
132      // Nothing awaits it, so catch it rather than leaking an unhandled
133      // rejection into the console on every such navigation.
134      viewTransition.ready.catch(function () {})
135      if (motionOff()) return viewTransition.skipTransition()
136      if (!fromUrl || !toUrl) return
137      const d = direction(fromUrl, toUrl)
138      if (d) viewTransition.types.add(d)
139    }
140
141    window.addEventListener('pageswap', (e) => {
142      const from = e.activation && e.activation.from
143      tag(e.viewTransition, from && from.url, e.activation && e.activation.entry.url)
144    })
145
146    window.addEventListener('pagereveal', (e) => {
147      // Navigation API; absent in some engines, in which case we simply fall
148      // back to the undirected default animation.
149      const act = window.navigation && window.navigation.activation
150      const from = act && act.from
151      tag(e.viewTransition, from && from.url, act && act.entry.url)
152    })
153  })()
154</script>
154<link rel="stylesheet" href="/_astro/Layout.D3aeZgTd.css"><style>li[data-astro-cid-hgduawhh].active-heading a[data-astro-cid-hgduawhh]{color:var(--theme-accent);font-weight:600}iframe.giscus-frame{margin-block:32px}button[data-astro-cid-doictzoz].scroll-up{opacity:1;transition:transform .3s ease-in-out,opacity .5s cubic-bezier(.4,0,.2,1),background-color .15s cubic-bezier(.4,0,.2,1);transform:translateY(0)}button[data-astro-cid-doictzoz].scroll-up:not(.active){opacity:0;transform:translateY(10px)}
155@layer astro.images{:where([data-astro-image]){height:auto}:where([data-astro-image=full-width]){width:100%}:where([data-astro-image=constrained]){max-width:100%}[data-astro-image-fit=fill]{object-fit:fill}[data-astro-image-fit=contain]{object-fit:contain}[data-astro-image-fit=cover]{object-fit:cover}[data-astro-image-fit=scale-down]{object-fit:scale-down}[data-astro-image-pos=top]{object-position:top}[data-astro-image-pos=bottom]{object-position:bottom}[data-astro-image-pos=left]{object-position:left}[data-astro-image-pos=right]{object-position:right}[data-astro-image-pos=center]{object-position:center}[data-astro-image-pos=top-bottom]{object-position:top bottom}[data-astro-image-pos=top-left]{object-position:top left}[data-astro-image-pos=top-right]{object-position:top right}[data-astro-image-pos=top-center]{object-position:top center}[data-astro-image-pos=bottom-top]{object-position:bottom top}[data-astro-image-pos=bottom-left]{object-position:bottom left}[data-astro-image-pos=bottom-right]{object-position:bottom right}[data-astro-image-pos=bottom-center]{object-position:bottom center}[data-astro-image-pos=left-top]{object-position:left top}[data-astro-image-pos=left-bottom]{object-position:left bottom}[data-astro-image-pos=left-right]{object-position:left right}[data-astro-image-pos=left-center]{object-position:left center}[data-astro-image-pos=right-top]{object-position:right top}[data-astro-image-pos=right-bottom]{object-position:right bottom}[data-astro-image-pos=right-left]{object-position:right left}[data-astro-image-pos=right-center]{object-position:right center}[data-astro-image-pos=center-top]{object-position:center top}[data-astro-image-pos=center-bottom]{object-position:center bottom}[data-astro-image-pos=center-left]{object-position:center left}[data-astro-image-pos=center-right]{object-position:center right}}
156</style>
156<script type="module" src="/_astro/page.D6Rx8f8Z.js"></script>
156</head><body class="w-full m-0 bg-background text-foreground" style="--theme-font: JetBrains Mono Variable;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);" data-astro-cid-ju4pidww><div class="page-frame flex flex-col min-h-screen"><div id="boot-overlay" class="hidden fixed inset-0 z-[100] bg-background text-green font-mono text-sm p-6 transition-opacity duration-200 overflow-hidden"><div id="boot-output" class="space-y-0.5"></div><div class="mt-4 text-foreground/40 text-xs">press any key to skip</div></div>
156<script type="module" src="/_astro/BootSequence.astro_astro_type_script_index_0_lang.CTbjHhXa.js"></script>
156<main class="flex-1 px-3 py-4"><div class="max-w-3xl mx-auto w-full" style="--theme-font: JetBrains Mono Variable;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);" data-astro-cid-ju4pidww><header class="masthead font-mono not-prose" data-astro-cid-v3lsk6py><div class="border-double border-4 border-foreground px-4 py-4 sm:px-6 sm:py-6" style="background: color-mix(in oklab, var(--theme-foreground) 3%, transparent);" data-astro-cid-v3lsk6py><h1 aria-label="jcalado.com" class="zine-title text-accent text-center m-0" data-astro-cid-v3lsk6py>jcalado</h1><p class="mt-3 text-center text-foreground/70 text-xs sm:text-sm uppercase tracking-widest" data-astro-cid-v3lsk6py>an irregular zine on software · radio · side-projects</p><p class="mt-2 text-center text-foreground text-xs sm:text-sm uppercase tracking-widest flex flex-wrap justify-center gap-x-3 gap-y-1" data-astro-cid-v3lsk6py><span data-astro-cid-v3lsk6py><span class="text-foreground/45" data-astro-cid-v3lsk6py>entry</span> 21</span><span aria-hidden="true" class="text-foreground/30" data-astro-cid-v3lsk6py>·</span><span data-astro-cid-v3lsk6py>SEPT 2026</span><span aria-hidden="true" class="text-foreground/30" data-astro-cid-v3lsk6py>·</span><span class="text-accent" data-astro-cid-v3lsk6py>CT7BLE / PT</span></p></div><nav class="flex flex-wrap items-baseline gap-x-2 gap-y-2 mt-4 text-sm" data-astro-cid-v3lsk6py><a href="/" class="no-underline text-foreground hover:text-accent tracking-wide" data-astro-cid-v3lsk6py>[home]</a><a href="/about" class="no-underline text-foreground hover:text-accent tracking-wide" data-astro-cid-v3lsk6py>[about]</a><a href="/posts" class="no-underline text-foreground hover:text-accent tracking-wide" data-astro-cid-v3lsk6py>[archive]</a><a href="https://github.com/jcalado" class="no-underline text-foreground hover:text-accent tracking-wide" data-astro-cid-v3lsk6py>[github]</a><span class="hidden sm:inline flex-1 mx-2 border-b border-dotted border-foreground
156/35 -translate-y-[3px]" aria-hidden="true" data-astro-cid-v3lsk6py></span><site-search class="ms-auto" id="search" data-trailing-slashes="false"><button class="hover:text-accent flex cursor-pointer items-center justify-center rounded-md" aria-keyshortcuts="Control+K Meta+K" data-open-modal disabled><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-6 text-accent"><path d="m21 21-4.34-4.34" /><circle cx="11" cy="11" r="8" /></svg><span class="sr-only">Open Search</span></button><dialog aria-label="search" class="text-foreground! bg-background max-h-5/6 min-h-48 w-7/8 sm:w-5/6 max-w-xl border-double! border-4 border-accent/30 shadow-sm backdrop:backdrop-blur-sm open:flex mx-auto mt-10 sm:mt-16 mb-auto rounded-xl"><div class="dialog-frame flex grow flex-col gap-4 p-6 pt-6 max-w-full"><button class="cursor-pointer fixed top-2 right-2 rounded-full" data-close-modal><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-6 text-accent/50"><circle cx="12" cy="12" r="10" /><path d="m15 9-6 6" /><path d="m9 9 6 6" /></svg></button><div class="search-container"><div id="pagefind-search" class="max-w-full"></div></div></div></dialog></site-search>
156<script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.DkoIW2g_.js"></script>
156<button id="animations-toggle" class="motion-toggle block cursor-pointer" aria-label="Toggle animations" data-astro-cid-ttqbc2xx><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-motion-on size-6 text-accent" data-astro-cid-ttqbc2xx="true"><path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" /></svg><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-motion-off size-6 text-accent" data-astro-cid-ttqbc2xx="true"><path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" opacity="0.45" /><path d="m2 2 20 20" /></svg><span class="sr-only" data-astro-cid-ttqbc2xx>Toggle animations</span></button>
156<script type="module">var e=document.getElementById(`animations-toggle`),t=document.documentElement,n=()=>t.getAttribute(`data-animations`)===`off`,r=()=>{e?.setAttribute(`aria-pressed`,n()?`false`:`true`),e?.setAttribute(`title`,n()?`Animations off`:`Animations on`)};r(),e?.addEventListener(`click`,()=>{let e=n()?`on`:`off`;e===`off`?t.setAttribute(`data-animations`,`off`):t.removeAttribute(`data-animations`);try{localStorage.setItem(`animations`,e)}catch{}r()});</script>
156<button id="theme-change-button" class="block ml-auto cursor-pointer" data-light="github-light" data-dark="github-dark" aria-label="Toggle light/dark mode"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden size-6 text-accent" id="icon-light"><circle cx="12" cy="12" r="4" /><path d="M12 2v2" /><path d="M12 20v2" /><path d="m4.93 4.93 1.41 1.41" /><path d="m17.66 17.66 1.41 1.41" /><path d="M2 12h2" /><path d="M20 12h2" /><path d="m6.34 17.66-1.41 1.41" /><path d="m19.07 4.93-1.41 1.41" /></svg><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden size-6 text-accent" id="icon-dark"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" /></svg></button>
156<script type="module" src="/_astro/LightDarkAutoButton.astro_astro_type_script_index_0_lang.CUe0N-Ha.js"></script>
156</nav><div class="mt-3 h-1 border-y border-foreground" aria-hidden="true" data-astro-cid-v3lsk6py></div></header><div class="py-4" style="--theme-font: JetBrains Mono Variable;--ec-frm-frameBoxShdCssVal: none;--ec-frm-edTabBrdRad: 0;--ec-frm-edTabBarBrdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);--ec-brdCol: color-mix(in srgb, var(--theme-foreground), 10%, transparent);" data-astro-cid-ju4pidww><article class="max-w-full py-7.5" data-pagefind-body><h1 id="gm950-programming-cable" class="text-heading1 mt-2 mb-3" style="view-transition-name:post-gm950-programming-cable;view-transition-class:post-title">A DIY Programming Cable for the Motorola GM950</h1><pre class="font-mono text-xs leading-5 mb-3 text-foreground/45 whitespace-pre-wrap"># date         : 2026-08-17
157# reading_time : 4 min read</pre><div class="mb-6"><aside class="font-mono text-xs"><div class="flex items-baseline gap-2 text-foreground/45 uppercase tracking-widest mb-1"><span>filed under</span><span class="flex-1 border-b border-dotted border-foreground
157/25 -translate-y-[3px]" aria-hidden="true"></span></div><p class="text-foreground/85"><a href="/tags/amateur-radio" class="hover:text-accent no-underline" style="view-transition-name:tag-amateur-radio;view-transition-class:tag-label">amateur-radio</a><span class="text-foreground/30"> · </span><a href="/tags/radio-programming" class="hover:text-accent no-underline" style="view-transition-name:tag-radio-programming;view-transition-class:tag-label">radio-programming</a><span class="text-foreground/30"> · </span><a href="/tags/motorola" class="hover:text-accent no-underline" style="view-transition-name:tag-motorola;view-transition-class:tag-label">motorola</a><span class="text-foreground/30"> · </span><a href="/tags/diy" class="hover:text-accent no-underline" style="view-transition-name:tag-diy;view-transition-class:tag-label">diy</a><span class="text-foreground/30"> · </span><a href="/tags/electronics" class="hover:text-accent no-underline" style="view-transition-name:tag-electronics;view-transition-class:tag-label">electronics</a><span class="text-foreground/30"> · </span><a href="/tags/hardware" class="hover:text-accent no-underline" style="view-transition-name:tag-hardware;view-transition-class:tag-label">hardware</a></p></aside></div><div class="flex flex-col xl:gap-1 2xl:gap-18 xl:flex-row xl:items-start"><details open class="toc relative md:mx-2 xl:mx-0 text-foreground/90 text-sm bg-foreground
157/3 xl:bg-transparent border border-accent/20 xl:border-none px-4 py-4 mt-5 xl:mt-0 xl:w-full xl:sticky xl:top-10 xl:basis-[300px] 2xl:basis-[340px] xl:order-2 xl:shrink-0 xl:min-w-0 overflow-hidden"><summary class="font-mono text-foreground/60 cursor-pointer list-none marker:hidden marker:content-['']"><span class="text-accent">$</span> tree ./toc</summary><nav class="w-full mt-3"><div class="font-mono text-sm text-foreground/70 mb-1">.</div><ul class="flex flex-col"><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="The schematic" href="#the-schematic" data-astro-cid-hgduawhh>The schematic</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Why the diode" href="#why-the-diode" data-astro-cid-hgduawhh>Why the diode</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Finding the pins" href="#finding-the-pins" data-astro-cid-hgduawhh>Finding the pins</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Building it" href="#building-it" data-astro-cid-hgduawhh>Building it</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Before you plug it in" href="#before-you-plug-it-in" data-astro-cid-hgduawhh>Before you plug it in</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>├─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Drivers" href="#drivers" data-astro-cid-hgduawhh>Drivers</a></li><li class="flex items-baseline font-mono text-sm min-w-0" data-astro-cid-hgduawhh><span class="text-foreground/30 select-none whitespace-pre shrink-0" data-astro-cid-hgduawhh>└─ </span><a class="hover:text-accent text-foreground/85 no-underline truncate min-w-0 flex-1" title="Credit" href="#credit" data-astro-cid-hgduawhh>Credit</a></li></ul></nav></details>
157<script type="module">var e=document.querySelectorAll(`h2[id], h3[id], h4[id]`),t=document.querySelectorAll(`details.toc > nav > ul > li`);e.length===t.length&&e.length>0&&window.addEventListener(`scroll`,()=>{let n=window.scrollY,r=!1;for(let i=e.length-1;i>=0;i--){let a=e[i];!r&&n>a.offsetTop-75?(t[i].classList.add(`active-heading`),r=!0):t[i].classList.remove(`active-heading`)}});</script>
157<div class="mb-5 xl:min-w-full 2xl:min-w-full prose"><h1 id="a-diy-programming-cable-for-the-motorola-gm950">A DIY Programming Cable for the Motorola GM950<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#a-diy-programming-cable-for-the-motorola-gm950">  # a-diy-programming-cable-for-the-motorola-gm950</a></h1>
158<p>The GM950 is cheap at hamfests and indestructible, but it always arrives programmed for whatever commercial fleet it came out of — almost certainly not the channels you want. And with no VFO, there’s no way to key in a frequency from the front panel: reprogramming is the only option. The original Motorola RIB costs more than the radio.</p>
159<p>It speaks a simple single-wire serial protocol, so you can build a working cable from a USB-to-TTL module, a 1N4148 and a 1K resistor.</p>
160<h2 id="the-schematic">The schematic<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#the-schematic">  # the-schematic</a></h2>
161<img src="/_astro/cable-schematic.B2eA2vRn_20USgJ.svg" alt="DIY programming cable schematic for the Motorola GM950" loading="lazy" decoding="async" width="900" height="420">
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192<table><thead><tr><th>From</th><th>To</th><th>Notes</th></tr></thead><tbody><tr><td>RJ45 pin 2 (DATA)</td><td>TTL <code>RXD</code></td><td>Direct</td></tr><tr><td>RJ45 pin 2 (DATA)</td><td>TTL <code>TXD</code></td><td>Through D1 (1N4148), <strong>anode on the radio side</strong></td></tr><tr><td>RJ45 pin 5</td><td>TTL <code>GND</code></td><td>Common ground</td></tr><tr><td>RJ45 pin 6</td><td>RJ45 pin 8</td><td>Through R1 (1K) — puts the radio in programming mode</td></tr></tbody></table>
193<p>Pins 1, 3, 4 and 7 stay unconnected, as do <code>3V3</code>, <code>5V</code> and <code>DTR</code> on the module. The radio powers itself.</p>
194<h2 id="why-the-diode">Why the diode<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#why-the-diode">  # why-the-diode</a></h2>
195<p>Pin 2 is a <strong>single bidirectional data line</strong> — the radio transmits and receives on the same wire. The TTL module’s <code>TXD</code> is push-pull, driving both high and low. Wire it straight through and the moment the radio answers you have two output stages fighting.</p>
196<p>D1 makes <code>TXD</code> behave like an open-collector output. Anode on the radio side, cathode on <code>TXD</code>:</p>
197<ul>
198<li><code>TXD</code> <strong>low</strong> → diode conducts, pulls the line low (~0.7 V, still a valid logic low).</li>
199<li><code>TXD</code> <strong>high</strong> → diode reverse-biased, effectively gone. The radio drives the line freely.</li>
200</ul>
201<p><code>RXD</code> taps the same wire, so the adapter hears its own transmissions echo back. Normal for a single-wire bus.</p>
202<p>Get the diode backwards and nothing works — first thing to check if the cable comes out dead.</p>
203<h2 id="finding-the-pins">Finding the pins<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#finding-the-pins">  # finding-the-pins</a></h2>
204<p>The easiest source of an RJ45 connector is a patch cable with one end cut off. Almost all of them are wired <strong>T568B</strong>:</p>
205<img src="/_astro/rj45-t568b-pinout.DbFNttcg_1KKzdq.svg" alt="RJ45 T-568B pinout, viewed from the contact side with the latch away from the viewer" loading="lazy" decoding="async" width="640" height="760">
206<p>Which gives us the four wires we care about:</p>
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237<table><thead><tr><th>Pin</th><th>T568B colour</th><th>Function</th></tr></thead><tbody><tr><td>2</td><td>Orange</td><td>DATA</td></tr><tr><td>5</td><td>White/Blue</td><td>GND</td></tr><tr><td>6</td><td>Green</td><td>Bridge via 1K</td></tr><tr><td>8</td><td>Brown</td><td>Bridge via 1K</td></tr></tbody></table>
238<p>Two things to watch. The view above is from the <strong>contact side with the latch facing away</strong> — flip the plug over and the numbering reverses. And T568<strong>A</strong> swaps the orange and green pairs, so pins 2 and 6 land on different colours. Buzz it out with a meter before you commit; it takes a minute.</p>
239<h2 id="building-it">Building it<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#building-it">  # building-it</a></h2>
240<ol>
241<li>Use an <strong>RJ45 female</strong> jack, or the cut patch cable from above.</li>
242<li>Solder the 1K between pins 6 and 8 right at the connector. Use a real resistor, not a wire link.</li>
243<li>Run pin 2, pin 2 (via the diode) and pin 5 out to the module. Put the diode near the module end — on a 1N4148 the black band is the cathode, and it goes to <code>TXD</code>.</li>
244<li>Heatshrink everything.</li>
245</ol>
246<p>Pin order on USB-TTL modules isn’t standardised and clone silkscreens sometimes lie. <strong>Wire by label, not position.</strong></p>
247<h2 id="before-you-plug-it-in">Before you plug it in<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#before-you-plug-it-in">  # before-you-plug-it-in</a></h2>
248<ul>
249<li>Continuity from pin 5 to <code>GND</code>; ~1K between pins 6 and 8.</li>
250<li>Diode check pin 2 → <code>TXD</code>: forward drop one way, open the other.</li>
251<li><strong>Nothing</strong> on <code>5V</code> or <code>3V3</code>. Check twice — 5 V into an accessory pin turns a cheap radio into a paperweight.</li>
252</ul>
253<h2 id="drivers">Drivers<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#drivers">  # drivers</a></h2>
254<p>I used a <strong>Prolific PL2303</strong> module, and it didn’t come up on Windows 11 — the in-box driver refuses to load for older and counterfeit PL2303 chips, so the port shows up flagged in Device Manager and never enumerates. The fix is the legacy driver collection at <a href="https://github.com/theAmberLion/Prolific" rel="noreferrer noopener" target="_blank">theAmberLion/Prolific</a>: v3.8.38.2 for newer (usually black) cables, v3.3.2.105 for older (usually grey) ones. Extract it, then point Device Manager’s <em>Update driver → Have disk…</em> at the folder.</p>
255<p>If you’d rather skip the hassle, a CP2102 or FTDI module works just as well here and both are still supported out of the box.</p>
256<p>Then point your programming software at the module’s COM port and <strong>read the codeplug before changing anything</strong>. That original file is your only way back.</p>
257<h2 id="credit">Credit<a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#credit">  # credit</a></h2>
258<p>The circuit isn’t mine — thanks to <strong>Rui Barreiros, CT7BPM</strong>, for the design.</p></div></div>
258<div class="font-mono text-xs text-foreground/40 mt-10 pt-4 border-t border-accent/15">── EOF ── (642 words · 4 min read)</div></article><div class="flex flex-col sm:flex-row items-center justify-around sm:gap-5 max-w-full mb-6 py-10 bg-accent/8 p-4 rounded-xl"><img src="/_astro/avatar.CnwxojJF_24EYS3.webp" srcset="/_astro/avatar.CnwxojJF_ZrUEC2.webp 288w" alt="My avatar" loading="lazy" decoding="async" width="144" height="144" class="rounded-full border-8 border-accent/15 size-36 aspect-square box-content shrink-0"><div><div class="m-4 max-w-full prose"><p>Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.</p></div></div></div><section><div class="flex gap-3 items-center my-4"><hr class="flex-1 bg-accent h-0.5 border-none"><span class="shrink-0 whitespace-nowrap">More Posts</span><hr class="flex-1 bg-accent h-0.5 border-none"></div><article class="py-3 group [&amp;+&amp;]:border-t [&amp;+&amp;]:border-dashed [&amp;+&amp;]:border-foreground/15"><a href="/posts/vox-apps-ios-macos-goal" class="block no-underline"><div class="flex items-baseline gap-3 font-mono text-sm"><span class="text-foreground group-hover:text-accent font-semibold" style="view-transition-name:post-vox-apps-ios-macos-goal;view-transition-class:post-title">Bringing my ham radio apps to iOS and macOS: help me get there</span><span class="flex-1 hidden sm:block border-b border-dotted border-foreground
258/25 -translate-y-[3px]" aria-hidden="true"></span><span class="text-foreground/55 shrink-0 hidden sm:flex gap-3 text-xs uppercase tracking-wider"><span>05 JUL</span><span class="text-yellow">4.6K</span></span></div><p class="mt-1 text-foreground/75 text-sm sm:pl-[3.5ch] max-w-prose">VoxDMR and VoxLink run on Android and the desktop today. The one platform I can&#39;t reach is Apple&#39;s — building for iOS and macOS needs a Mac, an Apple Developer membership, and real iPhone/iPad…</p><p class="mt-1 text-foreground/45 font-mono text-xs sm:pl-[3.5ch]"><span class="text-accent/70">&gt;</span> <span>amateur-radio</span><span class="text-foreground/25"> · </span><span>voxdmr</span><span class="text-foreground/25"> · </span><span>voxlink</span><span class="text-foreground/25"> · </span><span>echolink</span><span class="text-foreground/25"> · </span><span>ios</span><span class="text-foreground/25"> · </span><span>macos</span><span class="text-foreground/25"> · </span><span>ptt</span><span class="text-foreground/25"> · </span><span>open-source</span></p></a></article></section><button hidden class="scroll-up size-11 fixed flex items-center justify-center bg-background z-100 bottom-3 right-3 rounded-full border-2 border-accent/20 hover:bg-accent/10 md:size-12 md:bottom-5 md:right-5 lg:size-13 lg:bottom-6 lg:right-6" data-astro-cid-doictzoz><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-accent/50 size-8 lg:size-9" data-astro-cid-doictzoz="true"><path d="m18 15-6-6-6 6" /></svg></button>
258<script type="module">function e(e,t,n){let r=n=>{n.target===e&&n.propertyName===t&&(e.setAttribute(`hidden`,`true`),e.removeEventListener(`transitionend`,r))};return{show(){e.removeEventListener(`transitionend`,r),e.removeAttribute(`hidden`),e.offsetHeight,e.classList.add(n)},hide(){e.addEventListener(`transitionend`,r),e.classList.remove(n)}}}function t(){let t=document.querySelector(`button.scroll-up`),n=document.querySelector(`h1`),r=n?n.offsetTop:0;if(!t){console.warn(`Scroll up button not found in the document.`);return}t.addEventListener(`click`,()=>{window.scrollTo({top:r,behavior:`smooth`})});let i=document.querySelector(`article div.prose`);if(!i){console.warn(`Prose element not found in the article.`);return}let a=e(t,`opacity`,`active`);new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?a.show():a.hide()})},{rootMargin:`0px 0px -95% 0px`}).observe(i)}t();</script>
258</div><footer class="font-mono text-xs text-foreground/70 mt-12 pt-6" data-astro-cid-jo6i4kqk><div class="mb-4 h-1 border-y border-foreground" aria-hidden="true" data-astro-cid-jo6i4kqk></div><div class="flex items-baseline gap-3 mb-3 text-accent uppercase tracking-widest" data-astro-cid-jo6i4kqk><span data-astro-cid-jo6i4kqk>[ COLOPHON ]</span><span class="flex-1 border-b border-dotted border-foreground/30 -translate-y-[3px]" aria-hidden="true" data-astro-cid-jo6i4kqk></span><span class="text-foreground/50" data-astro-cid-jo6i4kqk>EOF</span></div><dl class="grid grid-cols-1 sm:grid-cols-[8rem_1fr] gap-y-1 gap-x-4 leading-6" data-astro-cid-jo6i4kqk><dt class="text-foreground/45 uppercase tracking-wider" data-astro-cid-jo6i4kqk>editor</dt><dd data-astro-cid-jo6i4kqk>Joel Calado &mdash; CT7BLE / PT</dd><dt class="text-foreground/45 uppercase tracking-wider" data-astro-cid-jo6i4kqk>imprint</dt><dd data-astro-cid-jo6i4kqk>jcalado.com &middot; self-published &middot; 2026</dd><dt class="text-foreground/45 uppercase tracking-wider" data-astro-cid-jo6i4kqk>typeset</dt><dd data-astro-cid-jo6i4kqk>JetBrains Mono &middot; built with <a class="underline hover:text-accent" href="https://astro.build" data-astro-cid-jo6i4kqk>Astro</a></dd><dt class="text-foreground/45 uppercase tracking-wider" data-astro-cid-jo6i4kqk>contact</dt><dd class="contact-line" data-astro-cid-jo6i4kqk><div class="flex flex-wrap items-center gap-x-4 gap-y-1"><a href="https://github.com/jcalado" target="_blank" rel="noopener noreferrer" class="social-link"><span class="sr-only">GitHub</span><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" /><path d="M9 18c-4.51 2-5-2-7-2" /></svg></a><a href="https://masto.pt/@jcalado" target="_blank" rel="noopener noreferrer" class="social-link"><span class="sr-only">Mastodon</span><svg width="24" height="24" viewBox="0 0 24 24" class="size-4"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M15.5 21.5c-10.5 2.5 -12.5 -2.5 -12.5 -8.5v-3c0 -6 2.5 -7 7 -7h4c4.5 0 7 1.5 7 5.5v4c0 6.5 -10 4 -13.5 4c-1 0 -1.5 7 8 5Z" /><path d="M7 13.5l0 -5.5c0 0 0.5 -2 2.5 -2c2 0 2.5 2 2.5 2l0 2.5l0 -2.5c0 0 0.5 -2 2.5 -2c2 0 2.5 2 2.5 2l0 5.5" /></g></svg></a><a href="https://x.com/jcalado" target="_blank" rel="noopener noreferrer" class="social-link"><span class="sr-only">Twitter</span><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" /></svg></a><a href="/cdn-cgi/l/email-protection#127f77527871737e73767d3c717d7f" target="_blank" rel="noopener noreferrer" class="social-link"><span class="sr-only">Email</span><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" /><rect x="2" y="4" width="20" height="16" rx="2" /></svg></a><a href="/rss.xml" class="social-link"><span class="sr-only">RSS</span><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M4 11a9 9 0 0 1 9 9" /><path d="M4 4a16 16 0 0 1 16 16" /><circle cx="5" cy="19" r="1" /></svg></a></div></dd></dl><p class="mt-6 text-foreground/40 text-center" data-astro-cid-jo6i4kqk>&mdash; thanks for reading &mdash;</p></footer></div></main></div>
vendor: 108 bytes, line 258
258<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
258<script type="module" src="/_astro/Layout.astro_astro_type_script_index_0_lang.D0VCjD4d.js"></script>
258<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"a16e5d769e854b329b64c43e09c89a13","r":1,"spa":2}' crossorigin="anonymous"></script>
258
259</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.