XCF (Xilinx platfrom flash) support.
[fw/openocd] / src / flash / nor / stm32f1x.c
index 105bd79c0873ab31e64932639b2151f796bab74c..d44670768b6045880205e24464c963525514a578 100644 (file)
@@ -19,9 +19,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -130,7 +128,7 @@ struct stm32x_flash_bank {
 
 static int stm32x_mass_erase(struct flash_bank *bank);
 static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id);
-static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
+static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
                uint32_t offset, uint32_t count);
 
 /* flash bank stm32x <base> <size> 0 0 <target#>
@@ -561,7 +559,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
        return stm32x_write_options(bank);
 }
 
-static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
+static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
                uint32_t offset, uint32_t count)
 {
        struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
@@ -620,7 +618,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
                        &write_algorithm) != ERROR_OK) {
                LOG_WARNING("no working area available, can't do block memory writes");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       };
+       }
 
        retval = target_write_buffer(target, write_algorithm->address,
                        sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
@@ -639,7 +637,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
                        LOG_WARNING("no large enough working area available, can't do block memory writes");
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
-       };
+       }
 
        init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* count (halfword-16bit) */
@@ -692,7 +690,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
        return retval;
 }
 
-static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
+static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
                uint32_t offset, uint32_t count)
 {
        struct target *target = bank->target;
@@ -720,7 +718,7 @@ static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
                }
                LOG_INFO("odd number of bytes to write, padding with 0xff");
                buffer = memcpy(new_buffer, buffer, count);
-               buffer[count++] = 0xff;
+               new_buffer[count++] = 0xff;
        }
 
        uint32_t words_remaining = count / 2;
@@ -894,7 +892,7 @@ static int stm32x_probe(struct flash_bank *bank)
                stm32x_info->ppage_size = 4;
                max_flash_size_in_kb = 128;
                break;
-       case 0x422: /* stm32f30x */
+       case 0x422: /* stm32f302/3xb/c */
                page_size = 2048;
                stm32x_info->ppage_size = 2;
                max_flash_size_in_kb = 256;
@@ -902,6 +900,14 @@ static int stm32x_probe(struct flash_bank *bank)
                stm32x_info->option_offset = 6;
                stm32x_info->default_rdp = 0x55AA;
                break;
+       case 0x446: /* stm32f303xD/E */
+               page_size = 2048;
+               stm32x_info->ppage_size = 2;
+               max_flash_size_in_kb = 512;
+               stm32x_info->user_data_offset = 16;
+               stm32x_info->option_offset = 6;
+               stm32x_info->default_rdp = 0x55AA;
+               break;
        case 0x428: /* value line High density */
                page_size = 2048;
                stm32x_info->ppage_size = 4;
@@ -921,8 +927,18 @@ static int stm32x_probe(struct flash_bank *bank)
                stm32x_info->option_offset = 6;
                stm32x_info->default_rdp = 0x55AA;
                break;
+       case 0x438: /* stm32f33x */
+       case 0x439: /* stm32f302x6/8 */
+               page_size = 2048;
+               stm32x_info->ppage_size = 2;
+               max_flash_size_in_kb = 64;
+               stm32x_info->user_data_offset = 16;
+               stm32x_info->option_offset = 6;
+               stm32x_info->default_rdp = 0x55AA;
+               break;
        case 0x440: /* stm32f05x */
        case 0x444: /* stm32f03x */
+       case 0x445: /* stm32f04x */
                page_size = 1024;
                stm32x_info->ppage_size = 4;
                max_flash_size_in_kb = 64;
@@ -931,9 +947,10 @@ static int stm32x_probe(struct flash_bank *bank)
                stm32x_info->default_rdp = 0x55AA;
                break;
        case 0x448: /* stm32f07x */
+       case 0x442: /* stm32f09x */
                page_size = 2048;
                stm32x_info->ppage_size = 4;
-               max_flash_size_in_kb = 128;
+               max_flash_size_in_kb = 256;
                stm32x_info->user_data_offset = 16;
                stm32x_info->option_offset = 6;
                stm32x_info->default_rdp = 0x55AA;
@@ -1022,6 +1039,21 @@ COMMAND_HANDLER(stm32x_handle_part_id_command)
 }
 #endif
 
+static const char *get_stm32f0_revision(uint16_t rev_id)
+{
+       const char *rev_str = NULL;
+
+       switch (rev_id) {
+       case 0x1000:
+               rev_str = "1.0";
+               break;
+       case 0x2000:
+               rev_str = "2.0";
+               break;
+       }
+       return rev_str;
+}
+
 static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
 {
        uint32_t dbgmcu_idcode;
@@ -1116,7 +1148,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                break;
 
        case 0x422:
-               device_str = "STM32F30x";
+               device_str = "STM32F302xB/C";
 
                switch (rev_id) {
                case 0x1000:
@@ -1175,48 +1207,64 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                }
                break;
 
-       case 0x444:
-               device_str = "STM32F03x";
+       case 0x438:
+               device_str = "STM32F33x";
 
                switch (rev_id) {
                case 0x1000:
-                       rev_str = "1.0";
-                       break;
-
-               case 0x2000:
-                       rev_str = "2.0";
+                       rev_str = "A";
                        break;
                }
                break;
 
-       case 0x440:
-               device_str = "STM32F05x";
+       case 0x439:
+               device_str = "STM32F302x6/8";
 
                switch (rev_id) {
                case 0x1000:
-                       rev_str = "1.0";
+                       rev_str = "A";
                        break;
 
-               case 0x2000:
-                       rev_str = "2.0";
+               case 0x1001:
+                       rev_str = "Z";
                        break;
                }
                break;
 
-       case 0x448:
-               device_str = "STM32F07x";
+       case 0x444:
+               device_str = "STM32F03x";
+               rev_str = get_stm32f0_revision(rev_id);
+               break;
+
+       case 0x440:
+               device_str = "STM32F05x";
+               rev_str = get_stm32f0_revision(rev_id);
+               break;
+
+       case 0x445:
+               device_str = "STM32F04x";
+               rev_str = get_stm32f0_revision(rev_id);
+               break;
 
+       case 0x446:
+               device_str = "STM32F303xD/E";
                switch (rev_id) {
                case 0x1000:
-                       rev_str = "1.0";
-                       break;
-
-               case 0x2000:
-                       rev_str = "2.0";
+                       rev_str = "A";
                        break;
                }
                break;
 
+       case 0x448:
+               device_str = "STM32F07x";
+               rev_str = get_stm32f0_revision(rev_id);
+               break;
+
+       case 0x442:
+               device_str = "STM32F09x";
+               rev_str = get_stm32f0_revision(rev_id);
+               break;
+
        default:
                snprintf(buf, buf_size, "Cannot identify target as a STM32F0/1/3\n");
                return ERROR_FAIL;
@@ -1433,12 +1481,12 @@ COMMAND_HANDLER(stm32x_handle_options_write_command)
                else if (strcmp("HWWDG", CMD_ARGV[0]) == 0)
                        optionbyte &= ~(1 << 0);
                else if (strcmp("NORSTSTOP", CMD_ARGV[0]) == 0)
-                       optionbyte &= ~(1 << 1);
-               else if (strcmp("RSTSTNDBY", CMD_ARGV[0]) == 0)
+                       optionbyte |= (1 << 1);
+               else if (strcmp("RSTSTOP", CMD_ARGV[0]) == 0)
                        optionbyte &= ~(1 << 1);
                else if (strcmp("NORSTSTNDBY", CMD_ARGV[0]) == 0)
-                       optionbyte &= ~(1 << 2);
-               else if (strcmp("RSTSTOP", CMD_ARGV[0]) == 0)
+                       optionbyte |= (1 << 2);
+               else if (strcmp("RSTSTNDBY", CMD_ARGV[0]) == 0)
                        optionbyte &= ~(1 << 2);
                else if (stm32x_info->has_dual_banks) {
                        if (strcmp("BOOT0", CMD_ARGV[0]) == 0)