# AM13E2x BSL CLI Tool - Usage Guide

## Overview

The BSL (Bootstrap Loader) CLI tool (`bsl_cli_am13e2.py`) is a Python script for programming firmware to AM13E2x devices over UART using the ROM bootloader.

## Before You Begin - Quick Checklist

**Check your COM port** in Device Manager (e.g., COM21)
**Edit `bsl_cli_am13e2.py` line 21** - Set `DEFAULT_PORT = "COM21"` (or your port)
**Install Python packages**: `pip install pyserial pyelftools`
**Have CCS installed** - Needed to flash main.c helper (one-time)
**Read the "Quick Start Guide"** below for step-by-step instructions

## Hardware Setup

### Required Hardware
- AM13E2 LaunchPad
- USB cable

### UART Connections
- **Using XDS110 (LaunchPad):** Application UART backchannel (COM21 by default)

## Script Configuration (Before First Use)

### Step 1: Find Your COM Port

Check which COM port your device is using:

**Windows:**
1. Open **Device Manager** (Win+X → Device Manager)
2. Expand **Ports (COM & LPT)**
3. Look for **"XDS110 Class Application/User UART (COMxx)"**
4. Note the COM port number (e.g., COM21)

### Step 2: Configure DEFAULT_PORT in Script

Open `bsl_cli_am13e2.py` in a text editor and find this section near the top (lines 17-21):

```python
# ---------------------------------------------------------------------------
# Configuration defaults
# ---------------------------------------------------------------------------
DEFAULT_BAUD_RATE = 9600
SERIAL_TIMEOUT = 5

# Serial port – set this to your BSL UART COM port (XDS110 Application UART)
DEFAULT_PORT = "COM21"
```

**Change line 21 `DEFAULT_PORT` to match your COM port:**

```python
DEFAULT_PORT = "COM21"
```

**Note:** You can override this at runtime using `--port`:
```bash
python bsl_cli_am13e2.py --port COM23 --no-invoke flash firmware.out
```

### Step 3: Verify Python Dependencies

Ensure required Python packages are installed:

```bash
pip install pyserial pyelftools
```

**Required packages:**
- `pyserial` - For UART communication
- `pyelftools` - For reading ELF (.out) files

### Configuration Summary

| Setting | Location | Default | Description |
|---------|----------|---------|-------------|
| **COM Port** | Line 21 | `"COM21"` | UART serial port (XDS110 or USB-UART) |
| **Baud Rate** | Line 17 | `9600` | UART communication speed |
| **Timeout** | Line 18 | `5` | Serial timeout (seconds) |

**Visual Guide - What to Edit:**

```python
# File: bsl_cli_am13e2.py
# Lines 17-21

DEFAULT_BAUD_RATE = 9600        # ← Line 17: Change if needed (usually keep 9600)
SERIAL_TIMEOUT = 5              # ← Line 18: Change if needed (usually keep 5)

# Serial port – set this to your BSL UART COM port
DEFAULT_PORT = "COM21"          # ← Line 21: CHANGE THIS to your COM port!
```

**After configuration, you're ready to use the tool!**

## Supported File Formats

The tool supports multiple firmware file formats:

| Format | Extension | Description | Notes |
|--------|-----------|-------------|-------|
| **ELF** | `.out` | TI CCS output format | **Recommended** - Direct from build |
| **Intel HEX** | `.hex` | Intel HEX format | Standard hex format |
| **TI-TXT** | `.txt` | TI text format | Legacy format |
| **Binary** | `.bin` | Raw binary | Requires `--address` parameter |

## Quick Start Guide

### Step 1: One-Time Setup - Flash main.c

Before you can use the BSL tool, you must flash the `main.c` helper program **once**:

1. **Open CCS (Code Composer Studio)**
2. **Import the project:**
   - File → Import → CCS Projects
   - Select: `hello_world_am13e230x_lp_m33_nortos_ti_arm_clang`
3. **Build the project:**
   - Right-click project → Build Project
4. **Flash main.c:**
   - Click the **Debug** button (bug icon)
   - Wait for it to halt at `main()`
   - Click **Resume** (or F8)
   - Device will **immediately enter BSL mode** (debugger will disconnect)
5. **Terminate debug session:**
   - Click **Terminate** button (red square)

**What main.c does:**
```c
// Writes SYSCTL registers to invoke BSL mode
SYSCTL_RESETLEVEL = 0x00000002;  // BOOTLOADERENTRY
SYSCTL_RESETCMD = 0xE4000001;    // KEY + GO
// Device resets into BSL mode with UART configured
```

### Step 2: Flash Your Firmware

After main.c is running and device is in BSL mode:

```bash
python bsl_cli_am13e2.py --no-invoke flash your_firmware.out
```

**Full sequence:**
```bash
# Flash ELF file (most common)
python bsl_cli_am13e2.py --no-invoke flash gpio_output_toggle.out

# Flash with verbose output
python bsl_cli_am13e2.py --verbose --no-invoke flash firmware.out
```

### Step 3: For Subsequent Updates

**IMPORTANT:** After the first BSL flash, your application overwrites main.c. To flash again:

**Option A: Re-flash main.c (Repeat Step 1)**
1. Flash main.c again using CCS
2. Run BSL script with `--no-invoke`

**Option B: Add BSL Entry to Your Application**
Add this code to your firmware to enter BSL on command:
```c
void enter_bsl_mode(void) {
    SYSCTL_RESETLEVEL = 0x00000002;  // BOOTLOADERENTRY
    SYSCTL_RESETCMD = 0xE4000001;    // KEY + GO
    // Device will reset into BSL mode
}
```
Trigger this function via GPIO, UART command, or button press.

## Complete Workflow Diagram

```
┌─────────────────────────────────────────────────────────┐
│ FIRST TIME SETUP                                        │
├─────────────────────────────────────────────────────────┤
│ 1. Build project in CCS                                 │
│ 2. Flash main.c using CCS Debug                         │
│ 3. Device enters BSL mode (debugger disconnects)       │
│ 4. Terminate debug session in CCS                      │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│ FLASH FIRMWARE VIA BSL                                  │
├─────────────────────────────────────────────────────────┤
│ python bsl_cli_am13e2.py --no-invoke flash app.out     │
│                                                         │
│ This will:                                              │
│ - Connect to BSL                                        │
│ - Unlock BSL                                            │
│ - Mass erase flash                                      │
│ - Program your firmware                                 │
│ - Start application                                     │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│ APPLICATION RUNNING                                     │
│ (main.c is now gone, replaced by your app)             │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│ TO FLASH AGAIN: Choose one method                      │
├─────────────────────────────────────────────────────────┤
│ Method 1: Re-flash main.c in CCS (go back to top)      │
│ Method 2: Trigger BSL entry from your application      │
└─────────────────────────────────────────────────────────┘
```

## Command Reference

### Global Options

```bash
python bsl_cli_am13e2.py [OPTIONS] COMMAND [ARGS]
```

| Option | Short | Description | Default |
|--------|-------|-------------|---------|
| `--port PORT` | `-p` | Serial port (e.g., COM21, COM23) | COM21 |
| `--baud BAUD` | `-b` | Baud rate | 9600 |
| `--no-invoke` | - | Skip BSL invocation (use after main.c) | False |
| `--manual-invoke` | - | Prompt for manual BSL invocation | False |
| `--wait` | - | Wait for COM port (unplug/replug) | False |
| `--verbose` | `-v` | Show detailed TX/RX output | False |

### Commands

#### 1. `flash` - Flash Firmware (Full Sequence)

Flash firmware with complete sequence: connect → unlock → erase → program → start

```bash
python bsl_cli_am13e2.py --no-invoke flash <file> [OPTIONS]
```

**Arguments:**
- `file` - Firmware file (.out, .hex, .txt, or .bin)
- `--address ADDR` - Start address for .bin files (hex format, e.g., 0x0)
- `--password PASS` - 32-byte password as hex string (default: all 0xFF)

**Examples:**
```bash
# Flash ELF file
python bsl_cli_am13e2.py --no-invoke flash firmware.out

# Flash HEX file with verbose output
python bsl_cli_am13e2.py -v --no-invoke flash firmware.hex

# Flash binary at specific address
python bsl_cli_am13e2.py --no-invoke flash firmware.bin --address 0x1000

# Use different COM port
python bsl_cli_am13e2.py --port COM23 --no-invoke flash firmware.out
```

#### 2. `connect` - Test BSL Connection

Test connection to BSL without programming:

```bash
python bsl_cli_am13e2.py --no-invoke connect
```

**Output:**
- Connection status
- BSL interface locked to UART

#### 3. `get-id` - Get Device Identity

Retrieve device information:

```bash
python bsl_cli_am13e2.py --no-invoke get-id
```

**Output:**
- Device identity data (24+ bytes)
- BSL buffer size
- Firmware version info

#### 4. `unlock` - Unlock BSL

Unlock BSL with password (required before erase/program):

```bash
python bsl_cli_am13e2.py --no-invoke unlock [--password PASS]
```

**Arguments:**
- `--password` - 32-byte (64 hex chars) password (default: all 0xFF)

#### 5. `erase` - Mass Erase Flash

Erase entire main flash memory:

```bash
python bsl_cli_am13e2.py --no-invoke erase [--password PASS]
```

**Note:** Requires unlock first (or use default password)

#### 6. `read` - Read Memory

Read memory from device:

```bash
python bsl_cli_am13e2.py --no-invoke read <address> <length>
```

**Arguments:**
- `address` - Start address (hex, e.g., 0x00000000)
- `length` - Number of bytes to read

**Example:**
```bash
# Read 256 bytes from flash start
python bsl_cli_am13e2.py --no-invoke read 0x00000000 256
```

#### 7. `verify` - Verify Programmed Firmware

Verify firmware using CRC:

```bash
python bsl_cli_am13e2.py --no-invoke verify <file> [--address ADDR]
```

**Arguments:**
- `file` - Firmware file to verify against
- `--address` - Start address for .bin files

#### 8. `start-app` - Start Application

Exit BSL mode and start the application:

```bash
python bsl_cli_am13e2.py --no-invoke start-app
```

#### 9. `factory-reset` - Factory Reset

Perform factory reset (if enabled):

```bash
python bsl_cli_am13e2.py --no-invoke factory-reset [--password PASS]
```

## Common Usage Scenarios

### Scenario 1: Development - Frequent Flashing

**Setup once:**
1. Flash main.c using CCS

**Every firmware update:**
```bash
# Build in CCS
# Device still in BSL mode from last flash
python bsl_cli_am13e2.py --no-invoke flash Debug/myapp.out

# For next update, re-flash main.c first
```

### Scenario 2: Field Updates
Add BSL entry function to your application which is trigger when update is requested:

```c
// In your application code

void check_for_firmware_update(void) {
    // Check GPIO, UART command, etc.
    if (update_requested) {
        // Enter BSL mode for update
        SYSCTL_RESETLEVEL = 0x00000002;
        SYSCTL_RESETCMD = 0xE4000001;
        // Device will reset into BSL
    }
}
```

Then flash updates remotely:
```bash
python bsl_cli_am13e2.py --no-invoke flash new_firmware.out
```

## Troubleshooting

### Problem: "No ACK received for connection command"

**Causes:**
- Device not in BSL mode
- Wrong COM port
- Debugger still connected
- Wrong baud rate

**Solutions:**
1. **Re-flash main.c** using CCS (see Step 1)
2. **Terminate debug session** in CCS completely
3. **Press RESET button** on LaunchPad
4. **Verify COM port**: Check Device Manager
5. **Try different baud rate**: `--baud 115200`
6. **Use verbose mode**: `--verbose` to see TX/RX

### Problem: "Invalid address/length alignment"

**Cause:** BSL requires 16-byte aligned addresses and lengths

**Solution:** The tool automatically handles alignment for .out files. If using .bin files, ensure your start address is 16-byte aligned.

### Problem: "Device info received but programming fails"

**Causes:**
- BSL locked
- Incorrect password
- Flash protection enabled

**Solutions:**
1. Use default unlock: Tool does this automatically
2. Specify password: `--password <64 hex chars>`
3. Check for flash protection in device config

### Problem: "COM port not found"

**Solutions:**
1. **Check Device Manager** for XDS110 COM port number
2. **Specify port manually**: `--port COM23`
3. **Re-connect USB cable**
4. **Update XDS110 drivers**

### Problem: "CCS won't connect to device"

**Solutions:**
1. **Power cycle**: Unplug USB, wait 5 sec, plug back in
2. **Press RESET button** on LaunchPad
3. **Check Target Configuration**: View → Target Configurations
4. **Close other tools** that might be using the debugger

### Problem: "Error -6305 PRSC module failed to write to a router register"

**Error Message:**
```
Error connecting to the target:
(Error -6305) PRSC module failed to write to a router register.
(Emulation package 20.4.0.3756)
```

**This error occurs when the debug interface is in a bad state. Follow these steps to recover:**

**Quick Recovery Procedure:**

1. **Open CCS Scripts Menu**
   - Click on **"Scripts"** in the top menu bar

2. **Navigate to DSSM Commands**
   - Click on **"DSSM commands"**

3. **Perform Factory Reset**
   - Click on **"DSSM_factoryReset"**
   - This will reset the device to factory version.

4.   **Perform NRST Reset**                                                                                                         
   - In CCS menu: Run → Reset → System Reset.                                                                                        
   - Or use the NRST button on hardware.

5. **Try Connecting Again**
   - Attempt to connect to the device in CCS
   - The error should be resolved

## BSL Protocol Details

### Communication Settings
- **Baud Rate:** 9600 (default), configurable
- **Data Bits:** 8
- **Parity:** None
- **Stop Bits:** 1
- **Flow Control:** None

### Memory Alignment Requirements
- **Address alignment:** 16 bytes
- **Length alignment:** 16 bytes
- **Reason:** BSL flash programming operates on 16-byte blocks

### Packet Structure
```
[Header] [Length] [Command] [Data...] [CRC16]
   1B       1B       1B       0-N B      2B
```

### BSL Entry Methods

| Method | Pros | Cons | Use Case |
|--------|------|------|----------|
| **main.c helper** | Configures UART properly | Must re-flash each time | Development |
| **Application trigger** | Remote updates possible | Must add code to app | Production/field updates |

## Advanced Options

### Custom Passwords

If BSL is password-protected:

```bash
# 32-byte (64 hex characters) password
python bsl_cli_am13e2.py --no-invoke unlock \
  --password 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF
```

### Wait for Device Connection

Useful for automated testing:

```bash
# Script will wait for COM port to appear
python bsl_cli_am13e2.py --wait --no-invoke flash firmware.out
```

### Manual BSL Invocation with Prompt

For guided operation:

```bash
python bsl_cli_am13e2.py --manual-invoke flash firmware.out
```

The tool will prompt you to manually activate BSL mode.

## Error Codes

### BSL Error Codes

| Code | Meaning | Solution |
|------|---------|----------|
| 0x00 | Success | - |
| 0x01 | BSL locked | Unlock BSL first |
| 0x02 | Password error | Check password |
| 0x04 | Unknown command | Update BSL tool |
| 0x05 | Invalid memory range | Check address |
| 0x0A | Invalid alignment | Tool handles automatically |
| 0xF0 | Flash command failed | Check flash protection |

### UART Error Codes

| Code | Meaning | Solution |
|------|---------|----------|
| 0x00 | ACK (no error) | - |
| 0x51 | Header incorrect | Check connection |
| 0x52 | Checksum incorrect | Retry or check cable |
| 0x53 | Packet size zero | Tool issue, report bug |
| 0x54 | Packet size too large | Reduce chunk size |

## Tips and Best Practices

### Development Workflow

1. **Keep main.c project open** in CCS for quick re-flashing
2. **Use .out files directly** - no conversion needed
3. **Use verbose mode** during debugging: `--verbose`
4. **Create a script** for repetitive flashing:

```bash
@echo off
echo Flashing firmware...
python bsl_cli_am13e2.py --no-invoke flash Debug\myapp.out
if %errorlevel% neq 0 (
    echo Flash failed! Re-flash main.c and try again.
) else (
    echo Flash successful!
)
```


## FAQ

**Q: Do I need to flash main.c every time?**
A: Yes, unless you add BSL entry code to your application.

**Q: Can I use this over network/remote connection?**
A: Not directly, but you can forward the COM port over network using tools like `com0com` or `hub4com`.

**Q: What if my device has custom BSL?**
A: This tool is for ROM BSL only. Custom BSL may have different protocol.

**Q: Can I flash multiple devices simultaneously?**
A: Yes, run multiple instances with different `--port` parameters.

**Q: How do I know which COM port to use?**
A: Check Windows Device Manager → Ports (COM & LPT) → "XDS110 Class Application/User UART"

**Q: Why does it fail after flashing once?**
A: Your new firmware overwrote main.c. Re-flash main.c to enter BSL mode again.
