X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Flpc2900.c;h=0d961e47f8bb81e2fbb5e8517638cf4667e4db3c;hb=1cbe3ec6f105e35e641293cd7e62e6fefac1b271;hp=fd265bd7ddeb85fc41aa9a6127a22ab044dc4f77;hpb=fb59ec739a3ae79937020dc2fe5413be0e73e8d3;p=openocd.git diff --git a/src/flash/lpc2900.c b/src/flash/lpc2900.c index fd265bd7dd..0d961e47f8 100644 --- a/src/flash/lpc2900.c +++ b/src/flash/lpc2900.c @@ -24,10 +24,10 @@ #include "image.h" - -#include "lpc2900.h" +#include "flash.h" #include "binarybuffer.h" #include "armv4_5.h" +#include "algorithm.h" /* 1024 bytes */ @@ -129,7 +129,7 @@ /** * Private data for \c lpc2900 flash driver. */ -typedef struct lpc2900_flash_bank_s +struct lpc2900_flash_bank { /** * Holds the value read from CHIPID register. @@ -168,17 +168,17 @@ typedef struct lpc2900_flash_bank_s */ uint32_t max_ram_block; -} lpc2900_flash_bank_t; +}; -static uint32_t lpc2900_wait_status(flash_bank_t *bank, uint32_t mask, int timeout); -static void lpc2900_setup(struct flash_bank_s *bank); -static uint32_t lpc2900_is_ready(struct flash_bank_s *bank); -static uint32_t lpc2900_read_security_status(struct flash_bank_s *bank); -static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank, +static uint32_t lpc2900_wait_status(struct flash_bank *bank, uint32_t mask, int timeout); +static void lpc2900_setup(struct flash_bank *bank); +static uint32_t lpc2900_is_ready(struct flash_bank *bank); +static uint32_t lpc2900_read_security_status(struct flash_bank *bank); +static uint32_t lpc2900_run_bist128(struct flash_bank *bank, uint32_t addr_from, uint32_t addr_to, uint32_t (*signature)[4] ); -static uint32_t lpc2900_address2sector(struct flash_bank_s *bank, uint32_t offset); +static uint32_t lpc2900_address2sector(struct flash_bank *bank, uint32_t offset); static uint32_t lpc2900_calc_tr( uint32_t clock, uint32_t time ); @@ -194,12 +194,12 @@ static uint32_t lpc2900_calc_tr( uint32_t clock, uint32_t time ); * @param[in] mask Mask to be used for INT_STATUS * @param[in] timeout Timeout in ms */ -static uint32_t lpc2900_wait_status( flash_bank_t *bank, +static uint32_t lpc2900_wait_status( struct flash_bank *bank, uint32_t mask, int timeout ) { uint32_t int_status; - target_t *target = bank->target; + struct target *target = bank->target; do @@ -228,10 +228,10 @@ static uint32_t lpc2900_wait_status( flash_bank_t *bank, * * @param bank Pointer to the flash bank descriptor */ -static void lpc2900_setup( struct flash_bank_s *bank ) +static void lpc2900_setup( struct flash_bank *bank ) { uint32_t fcra; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; /* Power up the flash block */ @@ -251,9 +251,9 @@ static void lpc2900_setup( struct flash_bank_s *bank ) * Must have been successfully probed. * Must be halted. */ -static uint32_t lpc2900_is_ready( struct flash_bank_s *bank ) +static uint32_t lpc2900_is_ready( struct flash_bank *bank ) { - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; if( lpc2900_info->chipid != EXPECTED_CHIPID ) { @@ -275,7 +275,7 @@ static uint32_t lpc2900_is_ready( struct flash_bank_s *bank ) * * @param bank Pointer to the flash bank descriptor */ -static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank ) +static uint32_t lpc2900_read_security_status( struct flash_bank *bank ) { uint32_t status; if( (status = lpc2900_is_ready( bank )) != ERROR_OK ) @@ -283,7 +283,7 @@ static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank ) return status; } - target_t *target = bank->target; + struct target *target = bank->target; /* Enable ISS access */ target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS); @@ -356,12 +356,12 @@ static uint32_t lpc2900_read_security_status( struct flash_bank_s *bank ) * @param addr_to * @param signature */ -static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank, +static uint32_t lpc2900_run_bist128(struct flash_bank *bank, uint32_t addr_from, uint32_t addr_to, uint32_t (*signature)[4] ) { - target_t *target = bank->target; + struct target *target = bank->target; /* Clear END_OF_MISR interrupt status */ target_write_u32( target, INT_CLR_STATUS, INTSRC_END_OF_MISR ); @@ -393,7 +393,7 @@ static uint32_t lpc2900_run_bist128(struct flash_bank_s *bank, * @param bank Pointer to the flash bank descriptor * @param offset Offset address relative to bank start */ -static uint32_t lpc2900_address2sector( struct flash_bank_s *bank, +static uint32_t lpc2900_address2sector( struct flash_bank *bank, uint32_t offset ) { uint32_t address = bank->base + offset; @@ -424,7 +424,7 @@ static uint32_t lpc2900_address2sector( struct flash_bank_s *bank, * @param pagenum Page number (0...7) * @param page Page array (FLASH_PAGE_SIZE bytes) */ -static int lpc2900_write_index_page( struct flash_bank_s *bank, +static int lpc2900_write_index_page( struct flash_bank *bank, int pagenum, uint8_t (*page)[FLASH_PAGE_SIZE] ) { @@ -436,7 +436,7 @@ static int lpc2900_write_index_page( struct flash_bank_s *bank, } /* Get target, and check if it's halted */ - target_t *target = bank->target; + struct target *target = bank->target; if( target->state != TARGET_HALTED ) { LOG_ERROR( "Target not halted" ); @@ -444,7 +444,7 @@ static int lpc2900_write_index_page( struct flash_bank_s *bank, } /* Private info */ - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; /* Enable flash block and set the correct CRA clock of 66 kHz */ lpc2900_setup( bank ); @@ -537,14 +537,14 @@ COMMAND_HANDLER(lpc2900_handle_signature_command) uint32_t signature[4]; - if( argc < 1 ) + if( CMD_ARGC < 1 ) { LOG_WARNING( "Too few arguments. Call: lpc2900 signature " ); return ERROR_FLASH_BANK_INVALID; } - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; @@ -564,7 +564,7 @@ COMMAND_HANDLER(lpc2900_handle_signature_command) return status; } - command_print( cmd_ctx, "signature: 0x%8.8" PRIx32 + command_print( CMD_CTX, "signature: 0x%8.8" PRIx32 ":0x%8.8" PRIx32 ":0x%8.8" PRIx32 ":0x%8.8" PRIx32, @@ -583,21 +583,21 @@ COMMAND_HANDLER(lpc2900_handle_signature_command) */ COMMAND_HANDLER(lpc2900_handle_read_custom_command) { - if( argc < 2 ) + if( CMD_ARGC < 2 ) { return ERROR_COMMAND_SYNTAX_ERROR; } - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; lpc2900_info->risky = 0; /* Get target, and check if it's halted */ - target_t *target = bank->target; + struct target *target = bank->target; if( target->state != TARGET_HALTED ) { LOG_ERROR( "Target not halted" ); @@ -623,7 +623,7 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_command) /* Try and open the file */ struct fileio fileio; - const char *filename = args[1]; + const char *filename = CMD_ARGV[1]; int ret = fileio_open( &fileio, filename, FILEIO_WRITE, FILEIO_BINARY ); if( ret != ERROR_OK ) { @@ -631,7 +631,7 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_command) return ret; } - uint32_t nwritten; + size_t nwritten; ret = fileio_write( &fileio, sizeof(customer), (const uint8_t *)customer, &nwritten ); if( ret != ERROR_OK ) @@ -654,29 +654,29 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_command) */ COMMAND_HANDLER(lpc2900_handle_password_command) { - if (argc < 2) + if (CMD_ARGC < 2) { return ERROR_COMMAND_SYNTAX_ERROR; } - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; #define ISS_PASSWORD "I_know_what_I_am_doing" - lpc2900_info->risky = !strcmp( args[1], ISS_PASSWORD ); + lpc2900_info->risky = !strcmp( CMD_ARGV[1], ISS_PASSWORD ); if( !lpc2900_info->risky ) { - command_print(cmd_ctx, "Wrong password (use '%s')", ISS_PASSWORD); + command_print(CMD_CTX, "Wrong password (use '%s')", ISS_PASSWORD); return ERROR_COMMAND_ARGUMENT_INVALID; } - command_print(cmd_ctx, + command_print(CMD_CTX, "Potentially dangerous operation allowed in next command!"); return ERROR_OK; @@ -689,28 +689,28 @@ COMMAND_HANDLER(lpc2900_handle_password_command) */ COMMAND_HANDLER(lpc2900_handle_write_custom_command) { - if (argc < 2) + if (CMD_ARGC < 2) { return ERROR_COMMAND_SYNTAX_ERROR; } - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; /* Check if command execution is allowed. */ if( !lpc2900_info->risky ) { - command_print( cmd_ctx, "Command execution not allowed!" ); + command_print( CMD_CTX, "Command execution not allowed!" ); return ERROR_COMMAND_ARGUMENT_INVALID; } lpc2900_info->risky = 0; /* Get target, and check if it's halted */ - target_t *target = bank->target; + struct target *target = bank->target; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -718,13 +718,13 @@ COMMAND_HANDLER(lpc2900_handle_write_custom_command) } /* The image will always start at offset 0 */ - image_t image; + struct image image; image.base_address_set = 1; image.base_address = 0; image.start_address_set = 0; - const char *filename = args[1]; - const char *type = (argc >= 3) ? args[2] : NULL; + const char *filename = CMD_ARGV[1]; + const char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL; retval = image_open(&image, filename, type); if (retval != ERROR_OK) { @@ -755,7 +755,7 @@ COMMAND_HANDLER(lpc2900_handle_write_custom_command) /* Page 4 */ uint32_t offset = ISS_CUSTOMER_START1 % FLASH_PAGE_SIZE; memset( page, 0xff, FLASH_PAGE_SIZE ); - uint32_t size_read; + size_t size_read; retval = image_read_section( &image, 0, 0, ISS_CUSTOMER_SIZE1, &page[offset], &size_read); if( retval != ERROR_OK ) @@ -799,23 +799,23 @@ COMMAND_HANDLER(lpc2900_handle_write_custom_command) */ COMMAND_HANDLER(lpc2900_handle_secure_sector_command) { - if (argc < 3) + if (CMD_ARGC < 3) { return ERROR_COMMAND_SYNTAX_ERROR; } /* Get the bank descriptor */ - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; /* Check if command execution is allowed. */ if( !lpc2900_info->risky ) { - command_print( cmd_ctx, "Command execution not allowed! " + command_print( CMD_CTX, "Command execution not allowed! " "(use 'password' command first)"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -823,13 +823,13 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command) /* Read sector range, and do a sanity check. */ int first, last; - COMMAND_PARSE_NUMBER(int, args[1], first); - COMMAND_PARSE_NUMBER(int, args[2], last); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last); if( (first >= bank->num_sectors) || (last >= bank->num_sectors) || (first > last) ) { - command_print( cmd_ctx, "Illegal sector range" ); + command_print( CMD_CTX, "Illegal sector range" ); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -878,7 +878,7 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command) } } - command_print( cmd_ctx, + command_print( CMD_CTX, "Sectors security will become effective after next power cycle"); /* Update the sector security status */ @@ -898,23 +898,23 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command) */ COMMAND_HANDLER(lpc2900_handle_secure_jtag_command) { - if (argc < 1) + if (CMD_ARGC < 1) { return ERROR_COMMAND_SYNTAX_ERROR; } /* Get the bank descriptor */ - flash_bank_t *bank; - int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); if (ERROR_OK != retval) return retval; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; /* Check if command execution is allowed. */ if( !lpc2900_info->risky ) { - command_print( cmd_ctx, "Command execution not allowed! " + command_print( CMD_CTX, "Command execution not allowed! " "(use 'password' command first)"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -948,85 +948,82 @@ COMMAND_HANDLER(lpc2900_handle_secure_jtag_command) /*********************** Flash interface functions **************************/ +static const struct command_registration lpc2900_exec_command_handlers[] = { + { + .name = "signature", + .handler = &lpc2900_handle_signature_command, + .mode = COMMAND_EXEC, + .usage = "", + .help = "print device signature of flash bank", + }, + { + .name = "read_custom", + .handler = &lpc2900_handle_read_custom_command, + .mode = COMMAND_EXEC, + .usage = " ", + .help = "read customer information from index sector to file", + }, + { + .name = "password", + .handler = &lpc2900_handle_password_command, + .mode = COMMAND_EXEC, + .usage = " ", + .help = "enter password to enable 'dangerous' options", + }, + { + .name = "write_custom", + .handler = &lpc2900_handle_write_custom_command, + .mode = COMMAND_EXEC, + .usage = " []", + .help = "write customer info from file to index sector", + }, + { + .name = "secure_sector", + .handler = &lpc2900_handle_secure_sector_command, + .mode = COMMAND_EXEC, + .usage = " ", + .help = "activate sector security for a range of sectors", + }, + { + .name = "secure_jtag", + .handler = &lpc2900_handle_secure_jtag_command, + .mode = COMMAND_EXEC, + .usage = " ", + .help = "activate JTAG security", + }, + COMMAND_REGISTRATION_DONE +}; +static const struct command_registration lpc2900_command_handlers[] = { + { + .name = "lpc2900", + .mode = COMMAND_ANY, + .help = "LPC2900 flash command group", + .chain = lpc2900_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; /** * Register private command handlers. */ -static int lpc2900_register_commands(struct command_context_s *cmd_ctx) +static int lpc2900_register_commands(struct command_context *cmd_ctx) { - command_t *lpc2900_cmd = register_command(cmd_ctx, NULL, "lpc2900", - NULL, COMMAND_ANY, NULL); - - register_command( - cmd_ctx, - lpc2900_cmd, - "signature", - lpc2900_handle_signature_command, - COMMAND_EXEC, - " | " - "print device signature of flash bank"); - - register_command( - cmd_ctx, - lpc2900_cmd, - "read_custom", - lpc2900_handle_read_custom_command, - COMMAND_EXEC, - " | " - "read customer information from index sector to file"); - - register_command( - cmd_ctx, - lpc2900_cmd, - "password", - lpc2900_handle_password_command, - COMMAND_EXEC, - " | " - "enter password to enable 'dangerous' options"); - - register_command( - cmd_ctx, - lpc2900_cmd, - "write_custom", - lpc2900_handle_write_custom_command, - COMMAND_EXEC, - " [] | " - "write customer info from file to index sector"); - - register_command( - cmd_ctx, - lpc2900_cmd, - "secure_sector", - lpc2900_handle_secure_sector_command, - COMMAND_EXEC, - " | " - "activate sector security for a range of sectors"); - - register_command( - cmd_ctx, - lpc2900_cmd, - "secure_jtag", - lpc2900_handle_secure_jtag_command, - COMMAND_EXEC, - " | " - "activate JTAG security"); - - return ERROR_OK; + return register_commands(cmd_ctx, NULL, lpc2900_command_handlers); } /// Evaluate flash bank command. FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command) { - lpc2900_flash_bank_t *lpc2900_info; + struct lpc2900_flash_bank *lpc2900_info; - if (argc < 6) + if (CMD_ARGC < 6) { LOG_WARNING("incomplete flash_bank LPC2900 configuration"); return ERROR_FLASH_BANK_INVALID; } - lpc2900_info = malloc(sizeof(lpc2900_flash_bank_t)); + lpc2900_info = malloc(sizeof(struct lpc2900_flash_bank)); bank->driver_priv = lpc2900_info; /* Get flash clock. @@ -1034,7 +1031,7 @@ FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command) * (if clock too slow), or for erase time (clock too fast). */ uint32_t clk_sys_fmc; - COMMAND_PARSE_NUMBER(u32, args[6], clk_sys_fmc); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], clk_sys_fmc); lpc2900_info->clk_sys_fmc = clk_sys_fmc * 1000; uint32_t clock_limit; @@ -1070,13 +1067,13 @@ FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command) * @param first First sector to be erased * @param last Last sector (including) to be erased */ -static int lpc2900_erase(struct flash_bank_s *bank, int first, int last) +static int lpc2900_erase(struct flash_bank *bank, int first, int last) { uint32_t status; int sector; int last_unsecured_sector; - target_t *target = bank->target; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct target *target = bank->target; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; status = lpc2900_is_ready(bank); @@ -1177,7 +1174,7 @@ static int lpc2900_erase(struct flash_bank_s *bank, int first, int last) -static int lpc2900_protect(struct flash_bank_s *bank, int set, int first, int last) +static int lpc2900_protect(struct flash_bank *bank, int set, int first, int last) { /* This command is not supported. * "Protection" in LPC2900 terms is handled transparently. Sectors will @@ -1199,14 +1196,14 @@ static int lpc2900_protect(struct flash_bank_s *bank, int set, int first, int la * @param offset Start address (relative to bank start) * @param count Number of bytes to be programmed */ -static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer, +static int lpc2900_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { uint8_t page[FLASH_PAGE_SIZE]; uint32_t status; uint32_t num_bytes; - target_t *target = bank->target; - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; + struct target *target = bank->target; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; int sector; int retval; @@ -1294,7 +1291,7 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer, /* Try working area allocation. Start with a large buffer, and try with reduced size if that fails. */ - working_area_t *warea; + struct working_area *warea; uint32_t buffer_size = lpc2900_info->max_ram_block - 1 * KiB; while( (retval = target_alloc_working_area(target, buffer_size + target_code_size, @@ -1313,8 +1310,8 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer, if( warea ) { - reg_param_t reg_params[5]; - armv4_5_algorithm_t armv4_5_info; + struct reg_param reg_params[5]; + struct armv4_5_algorithm armv4_5_info; /* We can use target mode. Download the algorithm. */ retval = target_write_buffer( target, @@ -1548,10 +1545,10 @@ static int lpc2900_write(struct flash_bank_s *bank, uint8_t *buffer, * * @param bank Pointer to the flash bank descriptor */ -static int lpc2900_probe(struct flash_bank_s *bank) +static int lpc2900_probe(struct flash_bank *bank) { - lpc2900_flash_bank_t *lpc2900_info = bank->driver_priv; - target_t *target = bank->target; + struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; + struct target *target = bank->target; int i = 0; uint32_t offset; @@ -1751,7 +1748,7 @@ static int lpc2900_probe(struct flash_bank_s *bank) * * @param bank Pointer to the flash bank descriptor */ -static int lpc2900_erase_check(struct flash_bank_s *bank) +static int lpc2900_erase_check(struct flash_bank *bank) { uint32_t status = lpc2900_is_ready(bank); if (status != ERROR_OK) @@ -1809,7 +1806,7 @@ static int lpc2900_erase_check(struct flash_bank_s *bank) * * @param bank Pointer to the flash bank descriptor */ -static int lpc2900_protect_check(struct flash_bank_s *bank) +static int lpc2900_protect_check(struct flash_bank *bank) { return lpc2900_read_security_status(bank); } @@ -1822,7 +1819,7 @@ static int lpc2900_protect_check(struct flash_bank_s *bank) * @param buf Buffer to take the string * @param buf_size Maximum number of characters that the buffer can take */ -static int lpc2900_info(struct flash_bank_s *bank, char *buf, int buf_size) +static int lpc2900_info(struct flash_bank *bank, char *buf, int buf_size) { snprintf(buf, buf_size, "lpc2900 flash driver"); @@ -1830,7 +1827,7 @@ static int lpc2900_info(struct flash_bank_s *bank, char *buf, int buf_size) } -flash_driver_t lpc2900_flash = +struct flash_driver lpc2900_flash = { .name = "lpc2900", .register_commands = lpc2900_register_commands,