NtdLpc

NtdLpc — LPC default bootloader protocol

Synopsis

struct              NtdLpc;
struct              NtdLpcClass;
NtdLpc *            ntd_lpc_new                         (void);
NtdLpc *            ntd_lpc_new_with_device             (const gchar *device);
gboolean            ntd_lpc_config_by_name              (NtdLpc *lpc,
                                                         const gchar *name);
gboolean            ntd_lpc_config_by_device_id         (NtdLpc *lpc,
                                                         guint32 device_id);
void                ntd_lpc_set_name                    (NtdLpc *lpc,
                                                         const gchar *name);
const gchar *       ntd_lpc_get_name                    (NtdLpc *lpc);
void                ntd_lpc_set_buffer_address          (NtdLpc *lpc,
                                                         gulong address);
gulong              ntd_lpc_get_buffer_address          (NtdLpc *lpc);
void                ntd_lpc_set_buffer_size             (NtdLpc *lpc,
                                                         guint size);
guint               ntd_lpc_get_buffer_size             (NtdLpc *lpc);
void                ntd_lpc_set_chunk_size              (NtdLpc *lpc,
                                                         guint chunk_size);
guint               ntd_lpc_get_chunk_size              (NtdLpc *lpc);
void                ntd_lpc_set_frequency               (NtdLpc *lpc,
                                                         guint frequency);
guint               ntd_lpc_get_frequency               (NtdLpc *lpc);
void                ntd_lpc_set_flash_table             (NtdLpc *lpc,
                                                         const gchar *flash_table);
const gchar *       ntd_lpc_get_flash_table             (NtdLpc *lpc);
gsize               ntd_lpc_get_flash_size              (NtdLpc *lpc);
gboolean            ntd_lpc_command                     (NtdLpc *lpc,
                                                         const gchar *format,
                                                         ...);
gboolean            ntd_lpc_command_valist              (NtdLpc *lpc,
                                                         const gchar *format,
                                                         va_list var_args);
gboolean            ntd_lpc_encode                      (NtdLpc *lpc,
                                                         gconstpointer data,
                                                         guint nbytes);
gpointer            ntd_lpc_decode                      (NtdLpc *lpc,
                                                         guint nbytes);
gchar *             ntd_lpc_read_line                   (NtdLpc *lpc);
gboolean            ntd_lpc_answered_OK                 (NtdLpc *lpc);
gboolean            ntd_lpc_answered_0                  (NtdLpc *lpc);
gboolean            ntd_lpc_answered_data               (NtdLpc *lpc,
                                                         gchar **p_data,
                                                         gulong *p_checksum);
gint                ntd_lpc_map_address                 (NtdLpc *lpc,
                                                         gulong address);
guint               ntd_lpc_ram_to_flash                (NtdLpc *lpc,
                                                         gulong ram,
                                                         gulong flash,
                                                         guint size);

Object Hierarchy

  GObject
   +----NtdIsp
         +----NtdLpc

Properties

  "buffer-address"           gulong                : Read / Write
  "buffer-size"              guint                 : Read / Write
  "chunk-size"               guint                 : Read / Write
  "flash-table"              gchar*                : Read / Write
  "frequency"                guint                 : Read / Write
  "name"                     gchar*                : Read / Write

Description

To download a program on the LPC the local SRAM must be used as a mid-step. This complicates things a bit because when downloading big programs more steps are needed. Furthermore, the available RAM buffer can be smaller than a flash sector (!), so multiple download on the same sector can be possibly needed. Another complication is flash sectors don't necessarily have the same size, so the "flash-table" property is provided.

Hence, to be able to use it, the buffer must be configured with ntd_lpc_set_buffer_address() and ntd_lpc_set_buffer_size() and the mapping of the flash memory specified with ntd_lpc_set_flash_table().

Alternatively, if the device id is yet known by the program, a call to ntd_isp_probe() will do that for you by directly querying the device.

Details

struct NtdLpc

struct NtdLpc;

All fields are private and should not be used directly. Use its public methods instead.


struct NtdLpcClass

struct NtdLpcClass {
};

ntd_lpc_new ()

NtdLpc *            ntd_lpc_new                         (void);

Creates a new generic NtdLpc instance.

Returns :

the newly created object

ntd_lpc_new_with_device ()

NtdLpc *            ntd_lpc_new_with_device             (const gchar *device);

Creates a new default NtdLpc instance and binds it to a NtdSerial device automatically configured with sensible defaults.

device :

path to the device to use

Returns :

the newly created object

ntd_lpc_config_by_name ()

gboolean            ntd_lpc_config_by_name              (NtdLpc *lpc,
                                                         const gchar *name);

ntd_lpc_config_by_device_id ()

gboolean            ntd_lpc_config_by_device_id         (NtdLpc *lpc,
                                                         guint32 device_id);

ntd_lpc_set_name ()

void                ntd_lpc_set_name                    (NtdLpc *lpc,
                                                         const gchar *name);

Sets a new name on lpc. If name is found in the internal (hard-coded) database, lpc is also configured with the default parameters for that device.

lpc :

a NtdLpc

name :

device name (such as "LPC2148")

ntd_lpc_get_name ()

const gchar *       ntd_lpc_get_name                    (NtdLpc *lpc);

Gets the name bound to lpc. The string is internally owned and must not be freed or modified.

lpc :

a NtdLpc

Returns :

the name bound to this lpc instance

ntd_lpc_set_buffer_address ()

void                ntd_lpc_set_buffer_address          (NtdLpc *lpc,
                                                         gulong address);

Sets the starting address of the biggest buffer available for downloading.

While downloading on LPC based devices, data cannot be directly sent to the flash. It must be instead written to a RAM space before (or to whatever available on the lpc device) by using the ISP write command ("W to size") and then moved to flash with the copy to flash command ("C to from size").

This command, in conjunction with ntd_lpc_set_buffer_size(), is used to identify the address and extension of the temporary buffer to use as destination of the "W" command (and, consequently, the source of the "C" command).

Some things to keep in mind:

  • the buffer must be contiguous;

  • all the memory must be addressable by the "W" command;

  • check the "C" command documentation to know if some special restrictions apply to some RAM memory;

  • the first 512 bytes of the base RAM memory should be considered reserved by the ISP program itself.

  • the last bunch of bytes, usually up to 256, can be possibly used by the ISP as stack for its commands.

An example: although LPC2148 is able to address 40 KB of RAM, the last 8 KB are not contiguous and can be reserved for USB purposes. This makes them unavailable for the "W" command. Considering the first 512 bytes and the last 256 bytes are reserved, a proper way to initialize the buffer for this device would be:

1
2
ntd_lpc_set_buffer_address(lpc, 0x40000000UL + 512);
ntd_lpc_set_buffer_size(lpc, 40*1024 - 8*1024 - 512 - 256);

To be able to use ntd_isp_download(), the flash memory map must be known. This would require a call to ntd_lpc_set_flash_table().

ntd_isp_probe() does this for you by querying the device id with the "J" command and setting the properties stored in an hard-coded list.

lpc :

a NtdLpc instance

address :

the new address

ntd_lpc_get_buffer_address ()

gulong              ntd_lpc_get_buffer_address          (NtdLpc *lpc);

Gets the base ram address of lpc.

lpc :

a NtdLpc instance

Returns :

the base RAM address

ntd_lpc_set_buffer_size ()

void                ntd_lpc_set_buffer_size             (NtdLpc *lpc,
                                                         guint size);

Sets the new size of biggest contiguous buffer available for lpc to size.

This value is used by write operations ("W ..."): check ntd_lpc_set_buffer_address() for details.

lpc :

a NtdLpc instance

size :

size, in bytes, of the biggest RAM buffer available

ntd_lpc_get_buffer_size ()

guint               ntd_lpc_get_buffer_size             (NtdLpc *lpc);

Gets the size, in bytes, of the biggest buffer of lpc. Check ntd_lpc_set_buffer_address() for details on what this buffer is intended to be.

lpc :

a NtdLpc instance

Returns :

the buffer size.

ntd_lpc_set_chunk_size ()

void                ntd_lpc_set_chunk_size              (NtdLpc *lpc,
                                                         guint chunk_size);

Sets the chunk size of lpc to chunk_size.

This option specifies the width (in bytes) of the largest block that can be moved with a single operation by this chip.

lpc :

a NtdLpc instance

chunk_size :

the new address

ntd_lpc_get_chunk_size ()

guint               ntd_lpc_get_chunk_size              (NtdLpc *lpc);

Gets the chunk size of lpc.

lpc :

a NtdLpc instance

Returns :

the chunk size

ntd_lpc_set_frequency ()

void                ntd_lpc_set_frequency               (NtdLpc *lpc,
                                                         guint frequency);

Sets the frequency of lpc to frequency.

The frequency is required (or only reccomended?) by the communication protocol and its value will be sent (if not 0) after the synchronization step. No idea what it will be used for, though...

lpc :

a NtdLpc instance

frequency :

the new frequency

ntd_lpc_get_frequency ()

guint               ntd_lpc_get_frequency               (NtdLpc *lpc);

Gets the current set frequency on lpc.

lpc :

a NtdLpc instance

Returns :

the frequency, in kHz

ntd_lpc_set_flash_table ()

void                ntd_lpc_set_flash_table             (NtdLpc *lpc,
                                                         const gchar *flash_table);

Sets a new flash table on lpc.

The flash table is a '\0' terminated array of char (such as normal ASCII text) but where every character specifies the size, in KiB, of the sector at that index. For example, an array such as "\x04\x08\x08" specifies that the lpc chip has 3 flash sectors, the first one of 4KiB and the others of 8KiB.

lpc :

a NtdLpc

flash_table :

name (informational)

ntd_lpc_get_flash_table ()

const gchar *       ntd_lpc_get_flash_table             (NtdLpc *lpc);

Gets the flash table of lpc. The array is internally owned and must not be freed or modified.

lpc :

a NtdLpc

Returns :

the flash table array

ntd_lpc_get_flash_size ()

gsize               ntd_lpc_get_flash_size              (NtdLpc *lpc);

Gets the flash size of lpc.

lpc :

a NtdLpc

Returns :

the flash size, in bytes.

ntd_lpc_command ()

gboolean            ntd_lpc_command                     (NtdLpc *lpc,
                                                         const gchar *format,
                                                         ...);

ntd_lpc_command_valist ()

gboolean            ntd_lpc_command_valist              (NtdLpc *lpc,
                                                         const gchar *format,
                                                         va_list var_args);

ntd_lpc_encode ()

gboolean            ntd_lpc_encode                      (NtdLpc *lpc,
                                                         gconstpointer data,
                                                         guint nbytes);

ntd_lpc_decode ()

gpointer            ntd_lpc_decode                      (NtdLpc *lpc,
                                                         guint nbytes);

ntd_lpc_read_line ()

gchar *             ntd_lpc_read_line                   (NtdLpc *lpc);

ntd_lpc_answered_OK ()

gboolean            ntd_lpc_answered_OK                 (NtdLpc *lpc);

ntd_lpc_answered_0 ()

gboolean            ntd_lpc_answered_0                  (NtdLpc *lpc);

ntd_lpc_answered_data ()

gboolean            ntd_lpc_answered_data               (NtdLpc *lpc,
                                                         gchar **p_data,
                                                         gulong *p_checksum);

ntd_lpc_map_address ()

gint                ntd_lpc_map_address                 (NtdLpc *lpc,
                                                         gulong address);

Converts address to a sector number basing the process on the "flash-table" property of lpc.

lpc :

a NtdLpc instance

address :

the address to map

Returns :

the sector number address belongs to or -1 if out of range.

ntd_lpc_ram_to_flash ()

guint               ntd_lpc_ram_to_flash                (NtdLpc *lpc,
                                                         gulong ram,
                                                         gulong flash,
                                                         guint size);

Copies size bytes from ram to flash.

size should be greather or equal than "chunk-size", if not it is adjusted accordingly. Furthermore, size will be forcibly rounded up to a 256 boundary value.

lpc :

a NtdLpc

ram :

source address (must be 4 byte boundary)

flash :

destination address (must be 256 byte boundary)

size :

size of the buffer to copy

Returns :

the number of bytes effectively copied, or 0 on errors.

Property Details

The "buffer-address" property

  "buffer-address"           gulong                : Read / Write

Starting address (usually in the SRAM space) of the biggest contiguous buffer available for downloading.


The "buffer-size" property

  "buffer-size"              guint                 : Read / Write

Size, in bytes, of the buffer starting at buffer-address.

Default value: 0


The "chunk-size" property

  "chunk-size"               guint                 : Read / Write

Size, in bytes, of the largest chunk that can be copied to flash in a single command.

Default value: 0


The "flash-table" property

  "flash-table"              gchar*                : Read / Write

A \0 terminated array of bytes specifying the size, in KiB, of every flash sector.

Default value: NULL


The "frequency" property

  "frequency"                guint                 : Read / Write

Crystal frequency, in kHz, at which the part is running.

Default value: 14746


The "name" property

  "name"                     gchar*                : Read / Write

The informal name of this chip.

Default value: NULL