From 4720e5e9fee9b94a9f1e55448ecbf551737eeae3 Mon Sep 17 00:00:00 2001
From: Jim Mussared <jim.mussared@gmail.com>
Date: Mon, 2 Mar 2020 22:35:22 +1100
Subject: [PATCH] all: Use MP_ERROR_TEXT for all error messages.

---

Updated for Pycopy.

Change-Id: I9e3f72bfe7decf38e3db78d46dc421779e4a4f21
Signed-off-by: Paul Sokolovsky <pfalcon@users.sourceforge.net>
---
 drivers/dht/dht.c                             |  2 +-
 examples/natmod/features1/features1.c         |  2 +-
 examples/natmod/features2/main.c              |  2 +-
 examples/natmod/ure/ure.c                     |  2 +-
 extmod/machine_i2c.c                          | 10 +--
 extmod/machine_mem.c                          |  2 +-
 extmod/machine_spi.c                          | 10 +--
 extmod/modbluetooth.c                         | 28 +++---
 extmod/modframebuf.c                          |  2 +-
 extmod/modlwip.c                              |  6 +-
 extmod/moduasyncio.c                          |  4 +-
 extmod/modubinascii.c                         |  6 +-
 extmod/moducryptolib.c                        | 14 +--
 extmod/moductypes.c                           | 10 +--
 extmod/moduheapq.c                            |  4 +-
 extmod/modujson.c                             |  2 +-
 extmod/modure.c                               |  4 +-
 extmod/modussl_axtls.c                        |  4 +-
 extmod/modussl_mbedtls.c                      |  4 +-
 extmod/modutimeq.c                            |  6 +-
 extmod/moduzlib.c                             |  2 +-
 extmod/network_cyw43.c                        | 14 +--
 extmod/uos_dupterm.c                          |  2 +-
 extmod/vfs_posix_file.c                       |  2 +-
 lib/embed/abort_.c                            |  2 +-
 lib/netutils/netutils.c                       |  2 +-
 ports/cc3200/application.mk                   | 13 ++-
 ports/cc3200/hal/cc3200_hal.c                 |  1 -
 ports/cc3200/misc/mpexception.c               | 39 --------
 ports/cc3200/misc/mpexception.h               | 34 -------
 ports/cc3200/misc/mpirq.c                     |  3 +-
 ports/cc3200/mods/modmachine.c                |  3 +-
 ports/cc3200/mods/modnetwork.c                |  1 -
 ports/cc3200/mods/moduhashlib.c               |  1 -
 ports/cc3200/mods/moduos.c                    |  1 -
 ports/cc3200/mods/modusocket.c                |  1 -
 ports/cc3200/mods/modussl.c                   |  3 +-
 ports/cc3200/mods/modutime.c                  |  3 +-
 ports/cc3200/mods/modwlan.c                   | 21 +++--
 ports/cc3200/mods/pybadc.c                    |  9 +-
 ports/cc3200/mods/pybi2c.c                    |  1 -
 ports/cc3200/mods/pybpin.c                    | 21 +++--
 ports/cc3200/mods/pybrtc.c                    |  7 +-
 ports/cc3200/mods/pybsd.c                     |  1 -
 ports/cc3200/mods/pybsleep.c                  |  1 -
 ports/cc3200/mods/pybspi.c                    |  5 +-
 ports/cc3200/mods/pybtimer.c                  | 13 ++-
 ports/cc3200/mods/pybuart.c                   |  5 +-
 ports/cc3200/mods/pybwdt.c                    |  3 +-
 ports/cc3200/mpthreadport.c                   |  2 +-
 ports/cc3200/serverstask.c                    |  5 +-
 ports/cc3200/telnet/telnet.c                  |  1 -
 ports/esp32/esp32_rmt.c                       |  6 +-
 ports/esp32/machine_adc.c                     | 10 +--
 ports/esp32/machine_dac.c                     |  8 +-
 ports/esp32/machine_hw_spi.c                  | 22 ++---
 ports/esp32/machine_i2c.c                     |  2 +-
 ports/esp32/machine_pin.c                     | 16 ++--
 ports/esp32/machine_pwm.c                     |  8 +-
 ports/esp32/machine_rtc.c                     |  2 +-
 ports/esp32/machine_sdcard.c                  |  4 +-
 ports/esp32/machine_touchpad.c                |  8 +-
 ports/esp32/machine_uart.c                    | 10 +--
 ports/esp32/machine_wdt.c                     |  2 +-
 ports/esp32/modesp32.c                        | 10 +--
 ports/esp32/modmachine.c                      |  4 +-
 ports/esp32/modnetwork.c                      | 54 ++++++------
 ports/esp32/modutime.c                        |  2 +-
 ports/esp32/mpthreadport.c                    |  2 +-
 ports/esp32/network_lan.c                     | 14 +--
 ports/esp32/network_ppp.c                     | 12 +--
 ports/esp8266/esp_mphal.c                     |  2 +-
 ports/esp8266/machine_adc.c                   |  2 +-
 ports/esp8266/machine_hspi.c                  |  4 +-
 ports/esp8266/machine_pin.c                   |  8 +-
 ports/esp8266/machine_pwm.c                   |  2 +-
 ports/esp8266/machine_rtc.c                   |  8 +-
 ports/esp8266/machine_uart.c                  | 10 +--
 ports/esp8266/modesp.c                        |  8 +-
 ports/esp8266/modmachine.c                    |  2 +-
 ports/esp8266/modnetwork.c                    | 16 ++--
 ports/esp8266/modutime.c                      |  2 +-
 .../boards/microbit/modules/microbitdisplay.c |  8 +-
 .../boards/microbit/modules/microbitimage.c   | 32 +++----
 ports/nrf/drivers/bluetooth/ble_drv.c         | 26 +++---
 ports/nrf/modules/board/led.c                 |  2 +-
 ports/nrf/modules/machine/adc.c               |  4 +-
 ports/nrf/modules/machine/i2c.c               |  2 +-
 ports/nrf/modules/machine/pin.c               |  6 +-
 ports/nrf/modules/machine/pwm.c               |  4 +-
 ports/nrf/modules/machine/rtcounter.c         |  4 +-
 ports/nrf/modules/machine/spi.c               |  6 +-
 ports/nrf/modules/machine/timer.c             |  8 +-
 ports/nrf/modules/machine/uart.c              |  4 +-
 ports/nrf/modules/music/modmusic.c            |  8 +-
 .../modules/ubluepy/ubluepy_characteristic.c  |  2 +-
 ports/nrf/modules/ubluepy/ubluepy_service.c   |  6 +-
 ports/nrf/modules/ubluepy/ubluepy_uuid.c      |  4 +-
 ports/nrf/modules/uos/microbitfs.c            |  4 +-
 ports/nrf/modules/uos/moduos.c                |  2 +-
 ports/pic16bit/modpybled.c                    |  2 +-
 ports/pic16bit/modpybswitch.c                 |  2 +-
 ports/stm32/accel.c                           |  4 +-
 ports/stm32/adc.c                             | 16 ++--
 ports/stm32/dac.c                             |  8 +-
 ports/stm32/extint.c                          | 14 +--
 ports/stm32/lcd.c                             |  2 +-
 ports/stm32/led.c                             |  2 +-
 ports/stm32/machine_adc.c                     |  2 +-
 ports/stm32/machine_i2c.c                     |  6 +-
 ports/stm32/machine_spi.c                     |  2 +-
 ports/stm32/machine_timer.c                   |  2 +-
 ports/stm32/machine_uart.c                    | 16 ++--
 ports/stm32/modmachine.c                      |  4 +-
 ports/stm32/modnetwork.c                      |  4 +-
 ports/stm32/modnwcc3k.c                       |  4 +-
 ports/stm32/modpyb.c                          |  2 +-
 ports/stm32/modusocket.c                      |  2 +-
 ports/stm32/modutime.c                        |  2 +-
 ports/stm32/mpthreadport.c                    |  2 +-
 ports/stm32/network_lan.c                     | 10 +--
 ports/stm32/network_wiznet5k.c                | 10 +--
 ports/stm32/pin.c                             | 10 +--
 ports/stm32/pyb_can.c                         | 10 +--
 ports/stm32/pyb_i2c.c                         | 18 ++--
 ports/stm32/pyb_spi.c                         |  2 +-
 ports/stm32/rtc.c                             |  6 +-
 ports/stm32/sdcard.c                          | 10 +--
 ports/stm32/servo.c                           |  4 +-
 ports/stm32/spi.c                             |  6 +-
 ports/stm32/timer.c                           | 34 +++----
 ports/stm32/usb.c                             |  8 +-
 ports/stm32/wdt.c                             |  6 +-
 ports/teensy/led.c                            |  2 +-
 ports/teensy/main.c                           |  2 +-
 ports/teensy/servo.c                          |  4 +-
 ports/teensy/timer.c                          | 28 +++---
 ports/teensy/uart.c                           |  8 +-
 ports/unix/modffi.c                           |  8 +-
 ports/unix/modjni.c                           | 32 +++----
 ports/unix/modmachine.c                       |  2 +-
 ports/unix/modusocket.c                       |  2 +-
 ports/zephyr/machine_i2c.c                    |  8 +-
 ports/zephyr/machine_pin.c                    |  6 +-
 ports/zephyr/modzsensor.c                     |  2 +-
 ports/zephyr/zephyr_storage.c                 | 10 +--
 py/argcheck.c                                 | 18 ++--
 py/bc.c                                       | 16 ++--
 py/binary.c                                   |  2 +-
 py/builtinevex.c                              |  2 +-
 py/builtinimport.c                            | 14 +--
 py/compile.c                                  | 88 +++++++++----------
 py/emitinlinethumb.c                          | 32 +++----
 py/emitinlinextensa.c                         | 22 ++---
 py/emitnative.c                               | 38 ++++----
 py/lexer.c                                    |  2 +-
 py/modbuiltins.c                              | 14 +--
 py/modmath.c                                  |  8 +-
 py/modmicropython.c                           |  2 +-
 py/modstruct.c                                |  8 +-
 py/modthread.c                                |  2 +-
 py/nativeglue.c                               | 14 +--
 py/obj.c                                      | 42 ++++-----
 py/objarray.c                                 |  6 +-
 py/objcomplex.c                               |  6 +-
 py/objdeque.c                                 |  4 +-
 py/objdict.c                                  |  4 +-
 py/objfloat.c                                 |  4 +-
 py/objgenerator.c                             |  8 +-
 py/objint.c                                   | 16 ++--
 py/objint_longlong.c                          |  6 +-
 py/objint_mpz.c                               | 12 +--
 py/objlist.c                                  |  2 +-
 py/objnamedtuple.c                            | 10 +--
 py/objobject.c                                |  8 +-
 py/objrange.c                                 |  2 +-
 py/objset.c                                   |  2 +-
 py/objslice.c                                 |  2 +-
 py/objstr.c                                   | 78 ++++++++--------
 py/objstringio.c                              |  2 +-
 py/objstrunicode.c                            |  8 +-
 py/objtuple.c                                 |  2 +-
 py/objtype.c                                  | 30 +++----
 py/parse.c                                    |  8 +-
 py/parsenum.c                                 | 12 +--
 py/persistentcode.c                           |  6 +-
 py/qstr.c                                     |  2 +-
 py/runtime.c                                  | 76 ++++++++--------
 py/sequence.c                                 |  2 +-
 py/stream.c                                   |  2 +-
 py/vm.c                                       |  6 +-
 191 files changed, 819 insertions(+), 915 deletions(-)
 delete mode 100644 ports/cc3200/misc/mpexception.c
 delete mode 100644 ports/cc3200/misc/mpexception.h

diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c
index 70371cc013..81754ac15f 100644
--- a/drivers/dht/dht.c
+++ b/drivers/dht/dht.c
@@ -45,7 +45,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
     mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
 
     if (bufinfo.len < 5) {
-        mp_raise_ValueError("buffer too small");
+        mp_raise_ValueError(MP_ERROR_TEXT("buffer too small"));
     }
 
     // issue start command
diff --git a/examples/natmod/features1/features1.c b/examples/natmod/features1/features1.c
index 1bfbe50b95..f865f1887c 100644
--- a/examples/natmod/features1/features1.c
+++ b/examples/natmod/features1/features1.c
@@ -45,7 +45,7 @@ STATIC mp_int_t fibonacci_helper(mp_int_t x) {
 STATIC mp_obj_t fibonacci(mp_obj_t x_in) {
     mp_int_t x = mp_obj_get_int(x_in);
     if (x < 0) {
-        mp_raise_ValueError("can't compute negative Fibonacci number");
+        mp_raise_ValueError(MP_ERROR_TEXT("can't compute negative Fibonacci number"));
     }
     return mp_obj_new_int(fibonacci_helper(x));
 }
diff --git a/examples/natmod/features2/main.c b/examples/natmod/features2/main.c
index de83bf2bed..1a39700dc4 100644
--- a/examples/natmod/features2/main.c
+++ b/examples/natmod/features2/main.c
@@ -52,7 +52,7 @@ STATIC mp_obj_t productf(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_o
     mp_buffer_info_t bufinfo;
     mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_RW);
     if (bufinfo.typecode != 'f') {
-        mp_raise_ValueError("expecting float array");
+        mp_raise_ValueError(MP_ERROR_TEXT("expecting float array"));
     }
 
     // Compute product, store result back in first element of array
diff --git a/examples/natmod/ure/ure.c b/examples/natmod/ure/ure.c
index ca1383583a..00ca2e9eb4 100644
--- a/examples/natmod/ure/ure.c
+++ b/examples/natmod/ure/ure.c
@@ -15,7 +15,7 @@ void mp_stack_check(void) {
     // Assumes descending stack on target
     volatile char dummy;
     if (stack_top - &dummy >= STACK_LIMIT) {
-        mp_raise_msg(&mp_type_RuntimeError, "maximum recursion depth exceeded");
+        mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("maximum recursion depth exceeded"));
     }
 }
 
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index 32ec3dd4db..14cba96236 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -327,7 +327,7 @@ STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, s
             extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
             return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, n_kw, args);
             #else
-            mp_raise_ValueError("invalid I2C peripheral");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid I2C peripheral"));
             #endif
         }
         --n_args;
@@ -367,7 +367,7 @@ STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
     if (i2c_p->start == NULL) {
-        mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
     }
     int ret = i2c_p->start(self);
     if (ret != 0) {
@@ -381,7 +381,7 @@ STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
     if (i2c_p->stop == NULL) {
-        mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
     }
     int ret = i2c_p->stop(self);
     if (ret != 0) {
@@ -395,7 +395,7 @@ STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
     if (i2c_p->read == NULL) {
-        mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
     }
 
     // get the buffer to read into
@@ -419,7 +419,7 @@ STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
     if (i2c_p->write == NULL) {
-        mp_raise_msg(&mp_type_OSError, "I2C operation not supported");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
     }
 
     // get the buffer to write from
diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c
index 88fa53006f..a1494bd51a 100644
--- a/extmod/machine_mem.c
+++ b/extmod/machine_mem.c
@@ -42,7 +42,7 @@
 STATIC uintptr_t machine_mem_get_addr(mp_obj_t addr_o, uint align) {
     uintptr_t addr = mp_obj_int_get_truncated(addr_o);
     if ((addr & (align - 1)) != 0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("address %08x is not aligned to %d bytes"), addr, align);
     }
     return addr;
 }
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
index f16ec269e3..a7f96573a7 100644
--- a/extmod/machine_spi.c
+++ b/extmod/machine_spi.c
@@ -52,7 +52,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
             extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
             return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, n_kw, args);
             #else
-            mp_raise_ValueError("invalid SPI peripheral");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid SPI peripheral"));
             #endif
         }
         --n_args;
@@ -119,7 +119,7 @@ STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp
     mp_buffer_info_t dest;
     mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
     if (src.len != dest.len) {
-        mp_raise_ValueError("buffers must be the same length");
+        mp_raise_ValueError(MP_ERROR_TEXT("buffers must be the same length"));
     }
     mp_machine_spi_transfer(self, src.len, src.buf, dest.buf);
     return mp_const_none;
@@ -202,15 +202,15 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
     self->spi.polarity = args[ARG_polarity].u_int;
     self->spi.phase = args[ARG_phase].u_int;
     if (args[ARG_bits].u_int != 8) {
-        mp_raise_ValueError("bits must be 8");
+        mp_raise_ValueError(MP_ERROR_TEXT("bits must be 8"));
     }
     if (args[ARG_firstbit].u_int != MICROPY_PY_MACHINE_SPI_MSB) {
-        mp_raise_ValueError("firstbit must be MSB");
+        mp_raise_ValueError(MP_ERROR_TEXT("firstbit must be MSB"));
     }
     if (args[ARG_sck].u_obj == MP_OBJ_NULL
         || args[ARG_mosi].u_obj == MP_OBJ_NULL
         || args[ARG_miso].u_obj == MP_OBJ_NULL) {
-        mp_raise_ValueError("must specify all of sck/mosi/miso");
+        mp_raise_ValueError(MP_ERROR_TEXT("must specify all of sck/mosi/miso"));
     }
     self->spi.sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj);
     self->spi.mosi = mp_hal_get_pin_obj(args[ARG_mosi].u_obj);
diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c
index 5b4f698cc6..6c59d05c48 100644
--- a/extmod/modbluetooth.c
+++ b/extmod/modbluetooth.c
@@ -91,7 +91,7 @@ STATIC mp_obj_t bluetooth_uuid_make_new(const mp_obj_type_t *type, size_t n_args
         self->type = MP_BLUETOOTH_UUID_TYPE_16;
         mp_int_t value = mp_obj_get_int(all_args[0]);
         if (value > 65535) {
-            mp_raise_ValueError("invalid UUID");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid UUID"));
         }
         self->data[0] = value & 0xff;
         self->data[1] = (value >> 8) & 0xff;
@@ -112,12 +112,12 @@ STATIC mp_obj_t bluetooth_uuid_make_new(const mp_obj_type_t *type, size_t n_args
                     continue;
                 }
                 if (!unichar_isxdigit(c)) {
-                    mp_raise_ValueError("invalid char in UUID");
+                    mp_raise_ValueError(MP_ERROR_TEXT("invalid char in UUID"));
                 }
                 c = unichar_xdigit_value(c);
                 uuid_i--;
                 if (uuid_i < 0) {
-                    mp_raise_ValueError("UUID too long");
+                    mp_raise_ValueError(MP_ERROR_TEXT("UUID too long"));
                 }
                 if (uuid_i % 2 == 0) {
                     // lower nibble
@@ -128,7 +128,7 @@ STATIC mp_obj_t bluetooth_uuid_make_new(const mp_obj_type_t *type, size_t n_args
                 }
             }
             if (uuid_i > 0) {
-                mp_raise_ValueError("UUID too short");
+                mp_raise_ValueError(MP_ERROR_TEXT("UUID too short"));
             }
         }
     }
@@ -283,7 +283,7 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map
     if (kwargs->used == 0) {
         // Get config value
         if (n_args != 2) {
-            mp_raise_TypeError("must query one param");
+            mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
         }
 
         switch (mp_obj_str_get_qstr(args[1])) {
@@ -295,12 +295,12 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map
             case MP_QSTR_rxbuf:
                 return mp_obj_new_int(self->ringbuf.size);
             default:
-                mp_raise_ValueError("unknown config param");
+                mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
         }
     } else {
         // Set config value(s)
         if (n_args != 1) {
-            mp_raise_TypeError("can't specify pos and kw args");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
         }
 
         for (size_t i = 0; i < kwargs->alloc; ++i) {
@@ -341,7 +341,7 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map
                         break;
                     }
                     default:
-                        mp_raise_ValueError("unknown config param");
+                        mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
                 }
             }
         }
@@ -361,7 +361,7 @@ STATIC mp_obj_t bluetooth_ble_irq(size_t n_args, const mp_obj_t *pos_args, mp_ma
     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
     mp_obj_t callback = args[ARG_handler].u_obj;
     if (callback != mp_const_none && !mp_obj_is_callable(callback)) {
-        mp_raise_ValueError("invalid callback");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid callback"));
     }
 
     // Update the callback.
@@ -414,7 +414,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bluetooth_ble_gap_advertise_obj, 1, bluetooth_
 
 STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t characteristics_in, uint16_t **handles, size_t *num_handles) {
     if (!mp_obj_is_type(uuid_in, &bluetooth_uuid_type)) {
-        mp_raise_ValueError("invalid service UUID");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid service UUID"));
     }
     mp_obj_bluetooth_uuid_t *service_uuid = MP_OBJ_TO_PTR(uuid_in);
 
@@ -451,11 +451,11 @@ STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t character
         mp_obj_get_array(characteristic_obj, &characteristic_len, &characteristic_items);
 
         if (characteristic_len < 2 || characteristic_len > 3) {
-            mp_raise_ValueError("invalid characteristic tuple");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid characteristic tuple"));
         }
         mp_obj_t uuid_obj = characteristic_items[0];
         if (!mp_obj_is_type(uuid_obj, &bluetooth_uuid_type)) {
-            mp_raise_ValueError("invalid characteristic UUID");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid characteristic UUID"));
         }
 
         (*handles)[handle_index++] = 0xffff;
@@ -487,7 +487,7 @@ STATIC int bluetooth_gatts_register_service(mp_obj_t uuid_in, mp_obj_t character
                 mp_obj_get_array_fixed_n(descriptor_obj, 2, &descriptor_items);
                 mp_obj_t desc_uuid_obj = descriptor_items[0];
                 if (!mp_obj_is_type(desc_uuid_obj, &bluetooth_uuid_type)) {
-                    mp_raise_ValueError("invalid descriptor UUID");
+                    mp_raise_ValueError(MP_ERROR_TEXT("invalid descriptor UUID"));
                 }
 
                 descriptor_uuids[descriptor_index] = MP_OBJ_TO_PTR(desc_uuid_obj);
@@ -567,7 +567,7 @@ STATIC mp_obj_t bluetooth_ble_gap_connect(size_t n_args, const mp_obj_t *args) {
     mp_buffer_info_t bufinfo = {0};
     mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
     if (bufinfo.len != 6) {
-        mp_raise_ValueError("invalid addr");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid addr"));
     }
     mp_int_t scan_duration_ms = MP_BLUETOOTH_CONNECT_DEFAULT_SCAN_DURATION_MS;
     if (n_args == 4) {
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index 951cbcd571..2753acc271 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -300,7 +300,7 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
         case FRAMEBUF_GS8:
             break;
         default:
-            mp_raise_ValueError("invalid format");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
     }
 
     return MP_OBJ_FROM_PTR(o);
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 40848b5196..7cc9fdb720 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -144,15 +144,15 @@ STATIC mp_obj_t lwip_slip_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw,
 
     ip_addr_t iplocal, ipremote;
     if (!ipaddr_aton(mp_obj_str_get_str(args[1]), &iplocal)) {
-        mp_raise_ValueError("not a valid local IP");
+        mp_raise_ValueError(MP_ERROR_TEXT("not a valid local IP"));
     }
     if (!ipaddr_aton(mp_obj_str_get_str(args[2]), &ipremote)) {
-        mp_raise_ValueError("not a valid remote IP");
+        mp_raise_ValueError(MP_ERROR_TEXT("not a valid remote IP"));
     }
 
     struct netif *n = &lwip_slip_obj.lwip_netif;
     if (netif_add(n, &iplocal, IP_ADDR_BROADCAST, &ipremote, NULL, slipif_init, ip_input) == NULL) {
-        mp_raise_ValueError("out of memory");
+        mp_raise_ValueError(MP_ERROR_TEXT("out of memory"));
     }
     netif_set_up(n);
     netif_set_default(n);
diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c
index a1aecc5d47..01ec582946 100644
--- a/extmod/moduasyncio.c
+++ b/extmod/moduasyncio.c
@@ -112,7 +112,7 @@ STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
     mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
     mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
     if (head == NULL) {
-        mp_raise_msg(&mp_type_IndexError, "empty heap");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
     }
     self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
     return MP_OBJ_FROM_PTR(head);
@@ -173,7 +173,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
     // Can't cancel self (not supported yet).
     mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
     if (self_in == cur_task) {
-        mp_raise_msg(&mp_type_RuntimeError, "cannot cancel self");
+        mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("cannot cancel self"));
     }
     // If Task waits on another task then forward the cancel to the one it's waiting on.
     while (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(self->data)), MP_OBJ_FROM_PTR(&task_type))) {
diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c
index 8d1544b34e..5f441b58ae 100644
--- a/extmod/modubinascii.c
+++ b/extmod/modubinascii.c
@@ -79,7 +79,7 @@ STATIC mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
     mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
 
     if ((bufinfo.len & 1) != 0) {
-        mp_raise_ValueError("odd-length string");
+        mp_raise_ValueError(MP_ERROR_TEXT("odd-length string"));
     }
     vstr_t vstr;
     vstr_init_len(&vstr, bufinfo.len / 2);
@@ -90,7 +90,7 @@ STATIC mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
         if (unichar_isxdigit(hex_ch)) {
             hex_byte += unichar_xdigit_value(hex_ch);
         } else {
-            mp_raise_ValueError("non-hex digit found");
+            mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found"));
         }
         if (i & 1) {
             hex_byte <<= 4;
@@ -158,7 +158,7 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
     }
 
     if (nbits) {
-        mp_raise_ValueError("incorrect padding");
+        mp_raise_ValueError(MP_ERROR_TEXT("incorrect padding"));
     }
 
     return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c
index b15f10c23b..9ea24c9fd1 100644
--- a/extmod/moducryptolib.c
+++ b/extmod/moducryptolib.c
@@ -225,7 +225,7 @@ STATIC mp_obj_t ucryptolib_aes_make_new(const mp_obj_type_t *type, size_t n_args
             break;
 
         default:
-            mp_raise_ValueError("mode");
+            mp_raise_ValueError(MP_ERROR_TEXT("mode"));
     }
 
     mp_obj_aes_t *o = m_new_obj_var(mp_obj_aes_t, struct ctr_params, !!is_ctr_mode(block_mode));
@@ -237,7 +237,7 @@ STATIC mp_obj_t ucryptolib_aes_make_new(const mp_obj_type_t *type, size_t n_args
     mp_buffer_info_t keyinfo;
     mp_get_buffer_raise(args[0], &keyinfo, MP_BUFFER_READ);
     if (32 != keyinfo.len && 16 != keyinfo.len) {
-        mp_raise_ValueError("key");
+        mp_raise_ValueError(MP_ERROR_TEXT("key"));
     }
 
     mp_buffer_info_t ivinfo;
@@ -246,10 +246,10 @@ STATIC mp_obj_t ucryptolib_aes_make_new(const mp_obj_type_t *type, size_t n_args
         mp_get_buffer_raise(args[2], &ivinfo, MP_BUFFER_READ);
 
         if (16 != ivinfo.len) {
-            mp_raise_ValueError("IV");
+            mp_raise_ValueError(MP_ERROR_TEXT("IV"));
         }
     } else if (o->block_mode == UCRYPTOLIB_MODE_CBC || is_ctr_mode(o->block_mode)) {
-        mp_raise_ValueError("IV");
+        mp_raise_ValueError(MP_ERROR_TEXT("IV"));
     }
 
     if (is_ctr_mode(block_mode)) {
@@ -274,7 +274,7 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
     mp_get_buffer_raise(in_buf, &in_bufinfo, MP_BUFFER_READ);
 
     if (!is_ctr_mode(self->block_mode) && in_bufinfo.len % 16 != 0) {
-        mp_raise_ValueError("blksize % 16");
+        mp_raise_ValueError(MP_ERROR_TEXT("blksize % 16"));
     }
 
     vstr_t vstr;
@@ -284,7 +284,7 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
     if (out_buf != MP_OBJ_NULL) {
         mp_get_buffer_raise(out_buf, &out_bufinfo, MP_BUFFER_WRITE);
         if (out_bufinfo.len < in_bufinfo.len) {
-            mp_raise_ValueError("output too small");
+            mp_raise_ValueError(MP_ERROR_TEXT("output too small"));
         }
         out_buf_ptr = out_bufinfo.buf;
     } else {
@@ -301,7 +301,7 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
         if ((encrypt && self->key_type == AES_KEYTYPE_DEC) ||
             (!encrypt && self->key_type == AES_KEYTYPE_ENC)) {
 
-            mp_raise_ValueError("can't encrypt & decrypt");
+            mp_raise_ValueError(MP_ERROR_TEXT("can't encrypt & decrypt"));
         }
     }
 
diff --git a/extmod/moductypes.c b/extmod/moductypes.c
index 68241ed161..8520602851 100644
--- a/extmod/moductypes.c
+++ b/extmod/moductypes.c
@@ -140,7 +140,7 @@ typedef struct _mp_obj_uctypes_struct_t {
 } mp_obj_uctypes_struct_t;
 
 STATIC NORETURN void syntax_error(void) {
-    mp_raise_TypeError("syntax error in uctypes descriptor");
+    mp_raise_TypeError(MP_ERROR_TEXT("syntax error in uctypes descriptor"));
 }
 
 STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@@ -270,7 +270,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
             // but scalar structure field is lowered into native Python int, so all
             // type info is lost. So, we cannot say if it's scalar type description,
             // or such lowered scalar.
-            mp_raise_TypeError("Cannot unambiguously get sizeof scalar");
+            mp_raise_TypeError(MP_ERROR_TEXT("Cannot unambiguously get sizeof scalar"));
         }
         syntax_error();
     }
@@ -514,7 +514,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
         && !mp_obj_is_type(self->desc, &mp_type_ordereddict)
         #endif
         ) {
-        mp_raise_TypeError("struct: no fields");
+        mp_raise_TypeError(MP_ERROR_TEXT("struct: no fields"));
     }
 
     mp_uint_t val_type;
@@ -655,7 +655,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
     } else {
         // load / store
         if (!mp_obj_is_type(self->desc, &mp_type_tuple)) {
-            mp_raise_TypeError("struct: cannot index");
+            mp_raise_TypeError(MP_ERROR_TEXT("struct: cannot index"));
         }
 
         mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
@@ -669,7 +669,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
             uint val_type = GET_TYPE(arr_sz, VAL_TYPE_BITS);
             arr_sz &= VALUE_MASK(VAL_TYPE_BITS);
             if (index >= arr_sz) {
-                mp_raise_msg(&mp_type_IndexError, "struct: index out of range");
+                mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("struct: index out of range"));
             }
 
             if (t->len == 2) {
diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c
index 0ba955ed2a..187c104743 100644
--- a/extmod/moduheapq.c
+++ b/extmod/moduheapq.c
@@ -33,7 +33,7 @@
 
 STATIC mp_obj_list_t *uheapq_get_heap(mp_obj_t heap_in) {
     if (!mp_obj_is_type(heap_in, &mp_type_list)) {
-        mp_raise_TypeError("heap must be a list");
+        mp_raise_TypeError(MP_ERROR_TEXT("heap must be a list"));
     }
     return MP_OBJ_TO_PTR(heap_in);
 }
@@ -81,7 +81,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush);
 STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
     mp_obj_list_t *heap = uheapq_get_heap(heap_in);
     if (heap->len == 0) {
-        mp_raise_msg(&mp_type_IndexError, "empty heap");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
     }
     mp_obj_t item = heap->items[0];
     heap->len -= 1;
diff --git a/extmod/modujson.c b/extmod/modujson.c
index 048a19aa7f..3a196ee0cc 100644
--- a/extmod/modujson.c
+++ b/extmod/modujson.c
@@ -295,7 +295,7 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
     return stack_top;
 
 fail:
-    mp_raise_ValueError("syntax error in JSON");
+    mp_raise_ValueError(MP_ERROR_TEXT("syntax error in JSON"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
 
diff --git a/extmod/modure.c b/extmod/modure.c
index 0e065366fc..987596537f 100644
--- a/extmod/modure.c
+++ b/extmod/modure.c
@@ -235,7 +235,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
         mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte *)subj.begin, caps[0] - subj.begin);
         mp_obj_list_append(retval, s);
         if (self->re.sub > 0) {
-            mp_raise_NotImplementedError("Splitting with sub-captures");
+            mp_raise_NotImplementedError(MP_ERROR_TEXT("Splitting with sub-captures"));
         }
         subj.begin = caps[1];
         if (maxsplit > 0 && --maxsplit == 0) {
@@ -403,7 +403,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
     int error = re1_5_compilecode(&o->re, re_str);
     if (error != 0) {
     error:
-        mp_raise_ValueError("Error in regex");
+        mp_raise_ValueError(MP_ERROR_TEXT("Error in regex"));
     }
     #if MICROPY_PY_URE_DEBUG
     if (flags & FLAG_DEBUG) {
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index f102f6ada3..7b0e3cbcbc 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -82,13 +82,13 @@ STATIC mp_obj_ssl_socket_t *ussl_socket_new(mp_obj_t sock, struct ssl_args *args
         const byte *data = (const byte *)mp_obj_str_get_data(args->key.u_obj, &len);
         int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL);
         if (res != SSL_OK) {
-            mp_raise_ValueError("invalid key");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid key"));
         }
 
         data = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &len);
         res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL);
         if (res != SSL_OK) {
-            mp_raise_ValueError("invalid cert");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid cert"));
         }
     }
 
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
index 4f8b1a9909..e62843809a 100644
--- a/extmod/modussl_mbedtls.c
+++ b/extmod/modussl_mbedtls.c
@@ -230,9 +230,9 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
     if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
         mp_raise_OSError(MP_ENOMEM);
     } else if (ret == MBEDTLS_ERR_PK_BAD_INPUT_DATA) {
-        mp_raise_ValueError("invalid key");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid key"));
     } else if (ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA) {
-        mp_raise_ValueError("invalid cert");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid cert"));
     } else {
         mp_raise_OSError(MP_EIO);
     }
diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c
index 352a9ac69a..15bd2d22c5 100644
--- a/extmod/modutimeq.c
+++ b/extmod/modutimeq.c
@@ -159,7 +159,7 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
     mp_obj_t heap_in = args[0];
     mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
     if (heap->len == heap->alloc) {
-        mp_raise_msg(&mp_type_IndexError, "queue overflow");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("queue overflow"));
     }
 
     struct qentry *item = heap->free;
@@ -181,7 +181,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_ut
 STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
     mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
     if (heap->len == 0) {
-        mp_raise_msg(&mp_type_IndexError, "empty heap");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
     }
     mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
     if (!mp_obj_is_type(list_ref, &mp_type_list) || ret->len < 3) {
@@ -242,7 +242,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_remove_obj, mod_utimeq_remove);
 STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) {
     mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
     if (heap->len == 0) {
-        mp_raise_msg(&mp_type_IndexError, "empty heap");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
     }
 
     struct qentry *item = heap->heap[0];
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 3e17595973..ec8fe4f06d 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -80,7 +80,7 @@ STATIC unsigned handle_dict_opt(mp_obj_decompio_t *o) {
         int dict_code = uzlib_zlib_parse_header(&o->decomp);
         if (dict_code < 0) {
         header_error:
-            mp_raise_ValueError("compression header");
+            mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
         }
         if (o->dict_opt == 0) {
             o->dict_opt = dict_code + 8;
diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c
index dac49c61b8..86cdeee9ca 100644
--- a/extmod/network_cyw43.c
+++ b/extmod/network_cyw43.c
@@ -196,7 +196,7 @@ STATIC mp_obj_t network_cyw43_scan(size_t n_args, const mp_obj_t *pos_args, mp_m
     int scan_res = cyw43_wifi_scan(self->cyw, &opts, MP_OBJ_TO_PTR(res), network_cyw43_scan_cb);
 
     if (scan_res < 0) {
-        mp_raise_msg(&mp_type_OSError, "STA must be active");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("STA must be active"));
     }
 
     // Wait for scan to finish, with a 10s timeout
@@ -279,7 +279,7 @@ STATIC mp_obj_t network_cyw43_status(size_t n_args, const mp_obj_t *args) {
         case MP_QSTR_stations: {
             // return list of connected stations
             if (self->itf != CYW43_ITF_AP) {
-                mp_raise_ValueError("AP required");
+                mp_raise_ValueError(MP_ERROR_TEXT("AP required"));
             }
             int num_stas;
             uint8_t macs[32 * 6];
@@ -295,7 +295,7 @@ STATIC mp_obj_t network_cyw43_status(size_t n_args, const mp_obj_t *args) {
         }
     }
 
-    mp_raise_ValueError("unknown status param");
+    mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_cyw43_status_obj, 1, 2, network_cyw43_status);
 
@@ -316,7 +316,7 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
     if (kwargs->used == 0) {
         // Get config value
         if (n_args != 2) {
-            mp_raise_TypeError("must query one param");
+            mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
         }
 
         switch (mp_obj_str_get_qstr(args[1])) {
@@ -354,12 +354,12 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
                 return MP_OBJ_NEW_SMALL_INT(nw_get_le32(buf) / 4);
             }
             default:
-                mp_raise_ValueError("unknown config param");
+                mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
         }
     } else {
         // Set config value(s)
         if (n_args != 1) {
-            mp_raise_TypeError("can't specify pos and kw args");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
         }
 
         for (size_t i = 0; i < kwargs->alloc; ++i) {
@@ -420,7 +420,7 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
                         break;
                     }
                     default:
-                        mp_raise_ValueError("unknown config param");
+                        mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
                 }
             }
         }
diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c
index 8b6e865463..ad706d5246 100644
--- a/extmod/uos_dupterm.c
+++ b/extmod/uos_dupterm.c
@@ -179,7 +179,7 @@ STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) {
     }
 
     if (idx < 0 || idx >= MICROPY_PY_OS_DUPTERM) {
-        mp_raise_ValueError("invalid dupterm index");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid dupterm index"));
     }
 
     mp_obj_t previous_obj = MP_STATE_VM(dupterm_objs[idx]);
diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c
index 5a564a8ec0..b75e812d8a 100644
--- a/extmod/vfs_posix_file.c
+++ b/extmod/vfs_posix_file.c
@@ -47,7 +47,7 @@ typedef struct _mp_obj_vfs_posix_file_t {
 #ifdef MICROPY_CPYTHON_COMPAT
 STATIC void check_fd_is_open(const mp_obj_vfs_posix_file_t *o) {
     if (o->fd < 0) {
-        mp_raise_ValueError("I/O operation on closed file");
+        mp_raise_ValueError(MP_ERROR_TEXT("I/O operation on closed file"));
     }
 }
 #else
diff --git a/lib/embed/abort_.c b/lib/embed/abort_.c
index 2fba0de4ea..3051eae81e 100644
--- a/lib/embed/abort_.c
+++ b/lib/embed/abort_.c
@@ -3,5 +3,5 @@
 NORETURN void abort_(void);
 
 NORETURN void abort_(void) {
-    mp_raise_msg(&mp_type_RuntimeError, "abort() called");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("abort() called"));
 }
diff --git a/lib/netutils/netutils.c b/lib/netutils/netutils.c
index 917cd83310..40fbd5bca3 100644
--- a/lib/netutils/netutils.c
+++ b/lib/netutils/netutils.c
@@ -79,7 +79,7 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian
         } else if (i > 0 && s < s_top && *s == '.') {
             s++;
         } else {
-            mp_raise_ValueError("invalid arguments");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments"));
         }
     }
 }
diff --git a/ports/cc3200/application.mk b/ports/cc3200/application.mk
index c926fda10c..86ea3c7309 100644
--- a/ports/cc3200/application.mk
+++ b/ports/cc3200/application.mk
@@ -73,7 +73,6 @@ APP_MISC_SRC_C = $(addprefix misc/,\
 	help.c \
 	mpirq.c \
 	mperror.c \
-	mpexception.c \
 	)
 
 APP_MODS_SRC_C = $(addprefix mods/,\
@@ -112,12 +111,12 @@ APP_CC3100_SRC_C = $(addprefix drivers/cc3100/src/,\
 APP_SL_SRC_C = $(addprefix simplelink/,\
 	oslib/osi_freertos.c \
 	cc_pal.c \
-	) 
+	)
 
 APP_TELNET_SRC_C = $(addprefix telnet/,\
 	telnet.c \
 	)
-	
+
 APP_UTIL_SRC_C = $(addprefix util/,\
 	cryptohash.c \
 	fifo.c \
@@ -125,18 +124,18 @@ APP_UTIL_SRC_C = $(addprefix util/,\
 	random.c \
 	socketfifo.c \
 	)
-	
+
 APP_UTIL_SRC_S = $(addprefix util/,\
 	sleeprestore.s \
 	)
-	
+
 APP_MAIN_SRC_C = \
 	main.c \
 	mptask.c \
 	mpthreadport.c \
 	serverstask.c \
 	fatfs_port.c \
-	
+
 APP_LIB_SRC_C = $(addprefix lib/,\
 	oofatfs/ff.c \
 	oofatfs/ffunicode.c \
@@ -148,7 +147,7 @@ APP_LIB_SRC_C = $(addprefix lib/,\
 	utils/interrupt_char.c \
 	utils/sys_stdio_mphal.c \
 	)
-	
+
 APP_STM_SRC_C = $(addprefix ports/stm32/,\
 	bufhelper.c \
 	irq.c \
diff --git a/ports/cc3200/hal/cc3200_hal.c b/ports/cc3200/hal/cc3200_hal.c
index 526874f33b..bdb7d33d4a 100644
--- a/ports/cc3200/hal/cc3200_hal.c
+++ b/ports/cc3200/hal/cc3200_hal.c
@@ -45,7 +45,6 @@
 #include "systick.h"
 #include "prcm.h"
 #include "pin.h"
-#include "mpexception.h"
 #include "telnet.h"
 #include "pybuart.h"
 #include "utils.h"
diff --git a/ports/cc3200/misc/mpexception.c b/ports/cc3200/misc/mpexception.c
deleted file mode 100644
index 72d4a155fa..0000000000
--- a/ports/cc3200/misc/mpexception.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- * Copyright (c) 2015 Daniel Campora
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdint.h>
-#include <string.h>
-
-#include "mpexception.h"
-
-
-/******************************************************************************
-DECLARE EXPORTED DATA
- ******************************************************************************/
-const char mpexception_value_invalid_arguments[]    = "invalid argument(s) value";
-const char mpexception_num_type_invalid_arguments[] = "invalid argument(s) num/type";
-const char mpexception_uncaught[]                   = "uncaught exception";
diff --git a/ports/cc3200/misc/mpexception.h b/ports/cc3200/misc/mpexception.h
deleted file mode 100644
index e84a1edb21..0000000000
--- a/ports/cc3200/misc/mpexception.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- * Copyright (c) 2015 Daniel Campora
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
-#define MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
-
-extern const char mpexception_value_invalid_arguments[];
-extern const char mpexception_num_type_invalid_arguments[];
-extern const char mpexception_uncaught[];
-
-#endif // MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
diff --git a/ports/cc3200/misc/mpirq.c b/ports/cc3200/misc/mpirq.c
index d54e7465b1..a4144def5a 100644
--- a/ports/cc3200/misc/mpirq.c
+++ b/ports/cc3200/misc/mpirq.c
@@ -33,7 +33,6 @@
 #include "inc/hw_types.h"
 #include "interrupt.h"
 #include "pybsleep.h"
-#include "mpexception.h"
 #include "mperror.h"
 #include "mpirq.h"
 
@@ -112,7 +111,7 @@ void mp_irq_remove (const mp_obj_t parent) {
 
 uint mp_irq_translate_priority (uint priority) {
     if (priority < 1 || priority > MP_ARRAY_SIZE(mp_irq_priorities)) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     return mp_irq_priorities[priority - 1];
 }
diff --git a/ports/cc3200/mods/modmachine.c b/ports/cc3200/mods/modmachine.c
index 9e49e23436..f70b399c07 100644
--- a/ports/cc3200/mods/modmachine.c
+++ b/ports/cc3200/mods/modmachine.c
@@ -47,7 +47,6 @@
 #include "FreeRTOS.h"
 #include "portable.h"
 #include "task.h"
-#include "mpexception.h"
 #include "random.h"
 #include "pybadc.h"
 #include "pybi2c.h"
@@ -125,7 +124,7 @@ STATIC mp_obj_t machine_main(mp_obj_t main) {
     if (mp_obj_is_str(main)) {
         MP_STATE_PORT(machine_config_main) = main;
     } else {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     return mp_const_none;
 }
diff --git a/ports/cc3200/mods/modnetwork.c b/ports/cc3200/mods/modnetwork.c
index 37dffe731f..e8a70e0a84 100644
--- a/ports/cc3200/mods/modnetwork.c
+++ b/ports/cc3200/mods/modnetwork.c
@@ -29,7 +29,6 @@
 #include "py/mperrno.h"
 #include "py/mphal.h"
 #include "modnetwork.h"
-#include "mpexception.h"
 #include "serverstask.h"
 #include "simplelink.h"
 
diff --git a/ports/cc3200/mods/moduhashlib.c b/ports/cc3200/mods/moduhashlib.c
index 96f5149273..fc11569b7f 100644
--- a/ports/cc3200/mods/moduhashlib.c
+++ b/ports/cc3200/mods/moduhashlib.c
@@ -41,7 +41,6 @@
 #include "prcm.h"
 #include "shamd5.h"
 #include "cryptohash.h"
-#include "mpexception.h"
 
 
 /******************************************************************************
diff --git a/ports/cc3200/mods/moduos.c b/ports/cc3200/mods/moduos.c
index 4c9d4a87a7..53521fe66c 100644
--- a/ports/cc3200/mods/moduos.c
+++ b/ports/cc3200/mods/moduos.c
@@ -40,7 +40,6 @@
 #include "extmod/vfs.h"
 #include "extmod/vfs_fat.h"
 #include "random.h"
-#include "mpexception.h"
 #include "version.h"
 #include "pybsd.h"
 #include "pybuart.h"
diff --git a/ports/cc3200/mods/modusocket.c b/ports/cc3200/mods/modusocket.c
index 286b1fb02b..5dac0a0102 100644
--- a/ports/cc3200/mods/modusocket.c
+++ b/ports/cc3200/mods/modusocket.c
@@ -38,7 +38,6 @@
 #include "lib/netutils/netutils.h"
 #include "modnetwork.h"
 #include "modusocket.h"
-#include "mpexception.h"
 
 /******************************************************************************/
 // The following set of macros and functions provide a glue between the CC3100
diff --git a/ports/cc3200/mods/modussl.c b/ports/cc3200/mods/modussl.c
index 9a9dc95a45..09a1a31857 100644
--- a/ports/cc3200/mods/modussl.c
+++ b/ports/cc3200/mods/modussl.c
@@ -33,7 +33,6 @@
 #include "py/runtime.h"
 #include "modnetwork.h"
 #include "modusocket.h"
-#include "mpexception.h"
 
 /******************************************************************************
  DEFINE CONSTANTS
@@ -133,7 +132,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_
     mp_raise_OSError(_errno);
 
 arg_error:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 0, mod_ssl_wrap_socket);
 
diff --git a/ports/cc3200/mods/modutime.c b/ports/cc3200/mods/modutime.c
index 13750f96b5..a729d62f9c 100644
--- a/ports/cc3200/mods/modutime.c
+++ b/ports/cc3200/mods/modutime.c
@@ -42,7 +42,6 @@
 #include "prcm.h"
 #include "systick.h"
 #include "pybrtc.h"
-#include "mpexception.h"
 #include "utils.h"
 
 /// \module time - time related functions
@@ -109,7 +108,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
 
     // localtime generates a tuple of len 8. CPython uses 9, so we accept both.
     if (len < 8 || len > 9) {
-        mp_raise_TypeError(mpexception_num_type_invalid_arguments);
+        mp_raise_TypeError(MP_ERROR_TEXT("invalid argument(s) num/type"));
     }
 
     return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c
index d6f7638c70..7aa8f0e2c4 100644
--- a/ports/cc3200/mods/modwlan.c
+++ b/ports/cc3200/mods/modwlan.c
@@ -45,7 +45,6 @@
 #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
 #include "serverstask.h"
 #endif
-#include "mpexception.h"
 #include "mpirq.h"
 #include "pybsleep.h"
 #include "antenna.h"
@@ -589,7 +588,7 @@ STATIC void wlan_reset (void) {
 
 STATIC void wlan_validate_mode (uint mode) {
     if (mode != ROLE_STA && mode != ROLE_AP) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
@@ -600,7 +599,7 @@ STATIC void wlan_set_mode (uint mode) {
 
 STATIC void wlan_validate_ssid_len (uint32_t len) {
     if (len > MODWLAN_SSID_LEN_MAX) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
@@ -633,7 +632,7 @@ STATIC void wlan_validate_security (uint8_t auth, const char *key, uint8_t len)
     return;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
@@ -656,7 +655,7 @@ STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
 
 STATIC void wlan_validate_channel (uint8_t channel) {
     if (channel < 1 || channel > 11) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
@@ -668,7 +667,7 @@ STATIC void wlan_set_channel (uint8_t channel) {
 #if MICROPY_HW_ANTENNA_DIVERSITY
 STATIC void wlan_validate_antenna (uint8_t antenna) {
     if (antenna != ANTENNA_TYPE_INTERNAL && antenna != ANTENNA_TYPE_EXTERNAL) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
@@ -964,7 +963,7 @@ STATIC mp_obj_t wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
     if (status == MODWLAN_ERROR_TIMEOUT) {
         mp_raise_OSError(MP_ETIMEDOUT);
     } else if (status == MODWLAN_ERROR_INVALID_PARAMS) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     return mp_const_none;
 }
@@ -1040,7 +1039,7 @@ STATIC mp_obj_t wlan_ifconfig(size_t n_args, const mp_obj_t *pos_args, mp_map_t
             // check for the correct string
             const char *mode = mp_obj_str_get_str(args[1].u_obj);
             if (strcmp("dhcp", mode)) {
-                mp_raise_ValueError(mpexception_value_invalid_arguments);
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
             }
 
             // only if we are not in AP mode
@@ -1154,7 +1153,7 @@ STATIC mp_obj_t wlan_mac(size_t n_args, const mp_obj_t *args) {
         mp_buffer_info_t bufinfo;
         mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
         if (bufinfo.len != 6) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         }
         memcpy(self->mac, bufinfo.buf, SL_MAC_ADDR_LEN);
         sl_NetCfgSet(SL_MAC_ADDRESS_SET, 1, SL_MAC_ADDR_LEN, (_u8 *)self->mac);
@@ -1190,7 +1189,7 @@ STATIC mp_obj_t wlan_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
     return _irq;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
 
@@ -1219,7 +1218,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
 //
 //        // the call to sl_NetAppSet corrupts the input string URN=args[1], so we copy into a local buffer
 //        if (len > MAX_DEVICE_URN_LEN) {
-//            mp_raise_ValueError(mpexception_value_invalid_arguments);
+//            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 //        }
 //        strcpy(urn, p);
 //
diff --git a/ports/cc3200/mods/pybadc.c b/ports/cc3200/mods/pybadc.c
index c73b8c149a..fbdd393cd2 100644
--- a/ports/cc3200/mods/pybadc.c
+++ b/ports/cc3200/mods/pybadc.c
@@ -47,7 +47,6 @@
 #include "pybpin.h"
 #include "pybsleep.h"
 #include "pins.h"
-#include "mpexception.h"
 
 
 /******************************************************************************
@@ -153,7 +152,7 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
 
     // check the number of bits
     if (args[1].u_int != 12) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 
     // setup the object
@@ -172,7 +171,7 @@ STATIC mp_obj_t adc_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args);
     // check the number of bits
     if (args[0].u_int != 12) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     pyb_adc_init(pos_args[0]);
     return mp_const_none;
@@ -205,11 +204,11 @@ STATIC mp_obj_t adc_channel(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
     if (args[0].u_obj != MP_OBJ_NULL) {
         ch_id = mp_obj_get_int(args[0].u_obj);
         if (ch_id >= PYB_ADC_NUM_CHANNELS) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         } else if (args[1].u_obj != mp_const_none) {
             uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
             if (ch_id != pin_ch_id) {
-                mp_raise_ValueError(mpexception_value_invalid_arguments);
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
             }
         }
     } else {
diff --git a/ports/cc3200/mods/pybi2c.c b/ports/cc3200/mods/pybi2c.c
index d08627fa49..5310176091 100644
--- a/ports/cc3200/mods/pybi2c.c
+++ b/ports/cc3200/mods/pybi2c.c
@@ -41,7 +41,6 @@
 #include "prcm.h"
 #include "i2c.h"
 #include "pybi2c.h"
-#include "mpexception.h"
 #include "pybsleep.h"
 #include "utils.h"
 #include "pybpin.h"
diff --git a/ports/cc3200/mods/pybpin.c b/ports/cc3200/mods/pybpin.c
index 3872f70c5f..fd2f032e8d 100644
--- a/ports/cc3200/mods/pybpin.c
+++ b/ports/cc3200/mods/pybpin.c
@@ -44,7 +44,6 @@
 #include "mpirq.h"
 #include "pins.h"
 #include "pybsleep.h"
-#include "mpexception.h"
 #include "mperror.h"
 
 
@@ -142,7 +141,7 @@ pin_obj_t *pin_find(mp_obj_t user_obj) {
         return pin_obj;
     }
 
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint strength) {
@@ -182,7 +181,7 @@ uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type)
             return pin_o->af_list[i].unit;
         }
     }
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit) {
@@ -192,13 +191,13 @@ uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit)
             return pin_o->af_list[i].type;
         }
     }
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
     int8_t af = pin_obj_find_af(pin, fn, unit, type);
     if (af < 0) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     return af;
 }
@@ -423,18 +422,18 @@ STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t prio
 STATIC void pin_validate_mode (uint mode) {
     if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT && mode != PIN_TYPE_OD &&
         mode != GPIO_DIR_MODE_ALT && mode != GPIO_DIR_MODE_ALT_OD) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 STATIC void pin_validate_pull (uint pull) {
     if (pull != PIN_TYPE_STD && pull != PIN_TYPE_STD_PU && pull != PIN_TYPE_STD_PD) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
 STATIC void pin_validate_drive(uint strength) {
     if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 }
 
@@ -447,7 +446,7 @@ STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8
             return;
         }
     }
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC uint8_t pin_get_value (const pin_obj_t* self) {
@@ -588,7 +587,7 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, size_t n_args, const mp_obj
     return mp_const_none;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -895,7 +894,7 @@ STATIC mp_obj_t pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
     return _irq;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_irq_obj, 1, pin_irq);
 
diff --git a/ports/cc3200/mods/pybrtc.c b/ports/cc3200/mods/pybrtc.c
index a8e001efb4..f0704eecda 100644
--- a/ports/cc3200/mods/pybrtc.c
+++ b/ports/cc3200/mods/pybrtc.c
@@ -41,7 +41,6 @@
 #include "simplelink.h"
 #include "modnetwork.h"
 #include "modwlan.h"
-#include "mpexception.h"
 
 /// \moduleref pyb
 /// \class RTC - real time clock
@@ -201,7 +200,7 @@ STATIC uint pyb_rtc_datetime_s_us(const mp_obj_t datetime, uint32_t *seconds) {
 
     // verify the tuple
     if (len < 3 || len > 8) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
 
     tm.tm_year = mp_obj_get_int(items[0]);
@@ -370,7 +369,7 @@ STATIC mp_obj_t pyb_rtc_alarm(size_t n_args, const mp_obj_t *pos_args, mp_map_t
     if (mp_obj_is_type(args[1].u_obj, &mp_type_tuple)) { // datetime tuple given
         // repeat cannot be used with a datetime tuple
         if (repeat) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         }
         f_mseconds = pyb_rtc_datetime_s_us (args[1].u_obj, &f_seconds) / 1000;
     } else { // then it must be an integer
@@ -452,7 +451,7 @@ STATIC mp_obj_t pyb_rtc_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
     return _irq;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_irq_obj, 1, pyb_rtc_irq);
 
diff --git a/ports/cc3200/mods/pybsd.c b/ports/cc3200/mods/pybsd.c
index e5a6e2624d..817127634d 100644
--- a/ports/cc3200/mods/pybsd.c
+++ b/ports/cc3200/mods/pybsd.c
@@ -42,7 +42,6 @@
 #include "sdhost.h"
 #include "sd_diskio.h"
 #include "pybsd.h"
-#include "mpexception.h"
 #include "pybsleep.h"
 #include "pybpin.h"
 #include "pins.h"
diff --git a/ports/cc3200/mods/pybsleep.c b/ports/cc3200/mods/pybsleep.c
index 09b3253338..da2eeff80f 100644
--- a/ports/cc3200/mods/pybsleep.c
+++ b/ports/cc3200/mods/pybsleep.c
@@ -49,7 +49,6 @@
 #include "modwlan.h"
 #include "osi.h"
 #include "debug.h"
-#include "mpexception.h"
 #include "mperror.h"
 #include "sleeprestore.h"
 #include "serverstask.h"
diff --git a/ports/cc3200/mods/pybspi.c b/ports/cc3200/mods/pybspi.c
index 27591e4f4c..61b1a6bd11 100644
--- a/ports/cc3200/mods/pybspi.c
+++ b/ports/cc3200/mods/pybspi.c
@@ -40,7 +40,6 @@
 #include "prcm.h"
 #include "spi.h"
 #include "pybspi.h"
-#include "mpexception.h"
 #include "pybsleep.h"
 #include "pybpin.h"
 #include "pins.h"
@@ -213,7 +212,7 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *arg
     return mp_const_none;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 static const mp_arg_t pyb_spi_init_args[] = {
@@ -351,7 +350,7 @@ STATIC mp_obj_t pyb_spi_write_readinto (mp_obj_t self, mp_obj_t writebuf, mp_obj
         // get the read buffer
         mp_get_buffer_raise(readbuf, &bufinfo_read, MP_BUFFER_WRITE);
         if (bufinfo_read.len != bufinfo_write.len) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         }
     }
 
diff --git a/ports/cc3200/mods/pybtimer.c b/ports/cc3200/mods/pybtimer.c
index ea795b8480..b5cf594d74 100644
--- a/ports/cc3200/mods/pybtimer.c
+++ b/ports/cc3200/mods/pybtimer.c
@@ -47,7 +47,6 @@
 #include "pins.h"
 #include "mpirq.h"
 #include "pybsleep.h"
-#include "mpexception.h"
 
 
 /// \moduleref pyb
@@ -221,7 +220,7 @@ STATIC uint32_t compute_prescaler_period_and_match_value(pyb_timer_channel_obj_t
     return prescaler;
 
 error:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC void timer_init (pyb_timer_obj_t *tim) {
@@ -317,7 +316,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, size_t n_args, const
     return mp_const_none;
 
 error:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@@ -438,7 +437,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
     return ch;
 
 error:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_obj, 2, pyb_timer_channel);
 
@@ -558,7 +557,7 @@ STATIC mp_obj_t pyb_timer_channel_freq(size_t n_args, const mp_obj_t *args) {
         // set
         int32_t _frequency = mp_obj_get_int(args[1]);
         if (_frequency <= 0) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         }
         ch->frequency = _frequency;
         ch->period = 1000000 / _frequency;
@@ -577,7 +576,7 @@ STATIC mp_obj_t pyb_timer_channel_period(size_t n_args, const mp_obj_t *args) {
         // set
         int32_t _period = mp_obj_get_int(args[1]);
         if (_period <= 0) {
-            mp_raise_ValueError(mpexception_value_invalid_arguments);
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
         }
         ch->period = _period;
         ch->frequency = 1000000 / _period;
@@ -710,7 +709,7 @@ STATIC mp_obj_t pyb_timer_channel_irq(size_t n_args, const mp_obj_t *pos_args, m
     return _irq;
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_irq_obj, 1, pyb_timer_channel_irq);
 
diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c
index 35c0de9f95..98adf1c398 100644
--- a/ports/cc3200/mods/pybuart.c
+++ b/ports/cc3200/mods/pybuart.c
@@ -45,7 +45,6 @@
 #include "pybuart.h"
 #include "mpirq.h"
 #include "pybsleep.h"
-#include "mpexception.h"
 #include "osi.h"
 #include "utils.h"
 #include "pin.h"
@@ -431,7 +430,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *a
     return mp_const_none;
 
 error:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 
 STATIC const mp_arg_t pyb_uart_init_args[] = {
@@ -555,7 +554,7 @@ STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
     return uart_irq_new (self, trigger, priority, args[2].u_obj);
 
 invalid_args:
-    mp_raise_ValueError(mpexception_value_invalid_arguments);
+    mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
 
diff --git a/ports/cc3200/mods/pybwdt.c b/ports/cc3200/mods/pybwdt.c
index 4a9fafc4a9..8db096d6b5 100644
--- a/ports/cc3200/mods/pybwdt.c
+++ b/ports/cc3200/mods/pybwdt.c
@@ -40,7 +40,6 @@
 #include "prcm.h"
 #include "utils.h"
 #include "pybwdt.h"
-#include "mpexception.h"
 #include "mperror.h"
 
 
@@ -105,7 +104,7 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
     }
     uint timeout_ms = args[1].u_int;
     if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     if (pyb_wdt_obj.running) {
         mp_raise_OSError(MP_EPERM);
diff --git a/ports/cc3200/mpthreadport.c b/ports/cc3200/mpthreadport.c
index 27d2386ed6..d35dab2d15 100644
--- a/ports/cc3200/mpthreadport.c
+++ b/ports/cc3200/mpthreadport.c
@@ -132,7 +132,7 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
     TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void *), arg, 2, stack, tcb);
     if (id == NULL) {
         mp_thread_mutex_unlock(&thread_mutex);
-        mp_raise_msg(&mp_type_OSError, "can't create thread");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't create thread"));
     }
 
     // add thread to linked list of all threads
diff --git a/ports/cc3200/serverstask.c b/ports/cc3200/serverstask.c
index 1c7249ee68..517a7a2281 100644
--- a/ports/cc3200/serverstask.c
+++ b/ports/cc3200/serverstask.c
@@ -38,7 +38,6 @@
 #include "ftp.h"
 #include "pybwdt.h"
 #include "modusocket.h"
-#include "mpexception.h"
 #include "modnetwork.h"
 #include "modwlan.h"
 
@@ -184,7 +183,7 @@ void servers_close_socket (int16_t *sd) {
 
 void servers_set_login (char *user, char *pass) {
     if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) {
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX);
     memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX);
@@ -193,7 +192,7 @@ void servers_set_login (char *user, char *pass) {
 void servers_set_timeout (uint32_t timeout) {
     if (timeout < SERVERS_MIN_TIMEOUT_MS) {
         // timeout is too low
-        mp_raise_ValueError(mpexception_value_invalid_arguments);
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid argument(s) value"));
     }
     servers_data.timeout = timeout;
 }
diff --git a/ports/cc3200/telnet/telnet.c b/ports/cc3200/telnet/telnet.c
index 6c4c5cab49..401e8a8cc9 100644
--- a/ports/cc3200/telnet/telnet.c
+++ b/ports/cc3200/telnet/telnet.c
@@ -35,7 +35,6 @@
 #include "modwlan.h"
 #include "modusocket.h"
 #include "debug.h"
-#include "mpexception.h"
 #include "serverstask.h"
 #include "genhdr/mpversion.h"
 #include "irq.h"
diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c
index bacbde1f33..7998752661 100644
--- a/ports/esp32/esp32_rmt.c
+++ b/ports/esp32/esp32_rmt.c
@@ -61,7 +61,7 @@ typedef struct _esp32_rmt_obj_t {
 //        At least update the method in machine_time.c.
 STATIC esp_err_t check_esp_err(esp_err_t code) {
     if (code) {
-        mp_raise_msg(&mp_type_OSError, esp_err_to_name(code));
+        mp_raise_msg(&mp_type_OSError, (mp_rom_error_text_t)esp_err_to_name(code));
     }
 
     return code;
@@ -80,7 +80,7 @@ STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, siz
     mp_uint_t clock_div = args[2].u_int;
 
     if (clock_div < 1 || clock_div > 255) {
-        mp_raise_ValueError("clock_div must be between 1 and 255");
+        mp_raise_ValueError(MP_ERROR_TEXT("clock_div must be between 1 and 255"));
     }
 
     esp32_rmt_obj_t *self = m_new_obj_with_finaliser(esp32_rmt_obj_t);
@@ -189,7 +189,7 @@ STATIC mp_obj_t esp32_rmt_write_pulses(size_t n_args, const mp_obj_t *pos_args,
     mp_uint_t start = args[2].u_int;
 
     if (start < 0 || start > 1) {
-        mp_raise_ValueError("start must be 0 or 1");
+        mp_raise_ValueError(MP_ERROR_TEXT("start must be 0 or 1"));
     }
 
     size_t pulses_length = 0;
diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c
index db70b785a4..d23e622091 100644
--- a/ports/esp32/machine_adc.c
+++ b/ports/esp32/machine_adc.c
@@ -75,13 +75,13 @@ STATIC mp_obj_t madc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
         }
     }
     if (!self) {
-        mp_raise_ValueError("invalid Pin for ADC");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for ADC"));
     }
     esp_err_t err = adc1_config_channel_atten(self->adc1_id, ADC_ATTEN_0db);
     if (err == ESP_OK) {
         return MP_OBJ_FROM_PTR(self);
     }
-    mp_raise_ValueError("Parameter Error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
 }
 
 STATIC void madc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -104,7 +104,7 @@ STATIC mp_obj_t madc_read(mp_obj_t self_in) {
     madc_obj_t *self = self_in;
     int val = adc1_get_raw(self->adc1_id);
     if (val == -1) {
-        mp_raise_ValueError("Parameter Error");
+        mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
     }
     return MP_OBJ_NEW_SMALL_INT(val);
 }
@@ -117,7 +117,7 @@ STATIC mp_obj_t madc_atten(mp_obj_t self_in, mp_obj_t atten_in) {
     if (err == ESP_OK) {
         return mp_const_none;
     }
-    mp_raise_ValueError("Parameter Error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
 }
 MP_DEFINE_CONST_FUN_OBJ_2(madc_atten_obj, madc_atten);
 
@@ -125,7 +125,7 @@ STATIC mp_obj_t madc_width(mp_obj_t cls_in, mp_obj_t width_in) {
     adc_bits_width_t width = mp_obj_get_int(width_in);
     esp_err_t err = adc1_config_width(width);
     if (err != ESP_OK) {
-        mp_raise_ValueError("Parameter Error");
+        mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
     }
     switch (width) {
         case ADC_WIDTH_9Bit:
diff --git a/ports/esp32/machine_dac.c b/ports/esp32/machine_dac.c
index bb441c7da9..a1a91167a7 100644
--- a/ports/esp32/machine_dac.c
+++ b/ports/esp32/machine_dac.c
@@ -60,7 +60,7 @@ STATIC mp_obj_t mdac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
         }
     }
     if (!self) {
-        mp_raise_ValueError("invalid Pin for DAC");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for DAC"));
     }
 
     esp_err_t err = dac_output_enable(self->dac_id);
@@ -70,7 +70,7 @@ STATIC mp_obj_t mdac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
     if (err == ESP_OK) {
         return MP_OBJ_FROM_PTR(self);
     }
-    mp_raise_ValueError("Parameter Error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
 }
 
 STATIC void mdac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -82,14 +82,14 @@ STATIC mp_obj_t mdac_write(mp_obj_t self_in, mp_obj_t value_in) {
     mdac_obj_t *self = self_in;
     int value = mp_obj_get_int(value_in);
     if (value < 0 || value > 255) {
-        mp_raise_ValueError("Value out of range");
+        mp_raise_ValueError(MP_ERROR_TEXT("Value out of range"));
     }
 
     esp_err_t err = dac_output_voltage(self->dac_id, value);
     if (err == ESP_OK) {
         return mp_const_none;
     }
-    mp_raise_ValueError("Parameter Error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Parameter Error"));
 }
 MP_DEFINE_CONST_FUN_OBJ_2(mdac_write_obj, mdac_write);
 
diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c
index e7554e3809..f63b245983 100644
--- a/ports/esp32/machine_hw_spi.c
+++ b/ports/esp32/machine_hw_spi.c
@@ -64,21 +64,21 @@ STATIC machine_hw_spi_obj_t machine_hw_spi_obj[2];
 STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self) {
     switch (spi_bus_remove_device(self->spi)) {
         case ESP_ERR_INVALID_ARG:
-            mp_raise_msg(&mp_type_OSError, "invalid configuration");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("invalid configuration"));
             return;
 
         case ESP_ERR_INVALID_STATE:
-            mp_raise_msg(&mp_type_OSError, "SPI device already freed");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SPI device already freed"));
             return;
     }
 
     switch (spi_bus_free(self->host)) {
         case ESP_ERR_INVALID_ARG:
-            mp_raise_msg(&mp_type_OSError, "invalid configuration");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("invalid configuration"));
             return;
 
         case ESP_ERR_INVALID_STATE:
-            mp_raise_msg(&mp_type_OSError, "SPI bus already freed");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SPI bus already freed"));
             return;
     }
 
@@ -159,7 +159,7 @@ STATIC void machine_hw_spi_init_internal(
     }
 
     if (self->host != HSPI_HOST && self->host != VSPI_HOST) {
-        mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)");
+        mp_raise_ValueError(MP_ERROR_TEXT("SPI ID must be either HSPI(1) or VSPI(2)"));
     }
 
     if (changed) {
@@ -201,28 +201,28 @@ STATIC void machine_hw_spi_init_internal(
     ret = spi_bus_initialize(self->host, &buscfg, dma_chan);
     switch (ret) {
         case ESP_ERR_INVALID_ARG:
-            mp_raise_msg(&mp_type_OSError, "invalid configuration");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("invalid configuration"));
             return;
 
         case ESP_ERR_INVALID_STATE:
-            mp_raise_msg(&mp_type_OSError, "SPI host already in use");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SPI host already in use"));
             return;
     }
 
     ret = spi_bus_add_device(self->host, &devcfg, &self->spi);
     switch (ret) {
         case ESP_ERR_INVALID_ARG:
-            mp_raise_msg(&mp_type_OSError, "invalid configuration");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("invalid configuration"));
             spi_bus_free(self->host);
             return;
 
         case ESP_ERR_NO_MEM:
-            mp_raise_msg(&mp_type_OSError, "out of memory");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("out of memory"));
             spi_bus_free(self->host);
             return;
 
         case ESP_ERR_NOT_FOUND:
-            mp_raise_msg(&mp_type_OSError, "no free slots");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("no free slots"));
             spi_bus_free(self->host);
             return;
     }
@@ -241,7 +241,7 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui
     machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
     if (self->state == MACHINE_HW_SPI_STATE_DEINIT) {
-        mp_raise_msg(&mp_type_OSError, "transfer on deinitialized SPI");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("transfer on deinitialized SPI"));
         return;
     }
 
diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c
index 67dae9cb11..8362ed5e7b 100644
--- a/ports/esp32/machine_i2c.c
+++ b/ports/esp32/machine_i2c.c
@@ -130,7 +130,7 @@ mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_
     // Get I2C bus
     mp_int_t i2c_id = mp_obj_get_int(args[ARG_id].u_obj);
     if (!(I2C_NUM_0 <= i2c_id && i2c_id < I2C_NUM_MAX)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "I2C(%d) doesn't exist", i2c_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
     }
 
     // Get static peripheral object
diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c
index db853d0428..a55cc1f4ab 100644
--- a/ports/esp32/machine_pin.c
+++ b/ports/esp32/machine_pin.c
@@ -126,7 +126,7 @@ STATIC void machine_pin_isr_handler(void *arg) {
 
 gpio_num_t machine_pin_get_id(mp_obj_t pin_in) {
     if (mp_obj_get_type(pin_in) != &machine_pin_type) {
-        mp_raise_ValueError("expecting a pin");
+        mp_raise_ValueError(MP_ERROR_TEXT("expecting a pin"));
     }
     machine_pin_obj_t *self = pin_in;
     return self->id;
@@ -162,7 +162,7 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
     if (args[ARG_mode].u_obj != mp_const_none) {
         mp_int_t pin_io_mode = mp_obj_get_int(args[ARG_mode].u_obj);
         if (self->id >= 34 && (pin_io_mode & GPIO_MODE_DEF_OUTPUT)) {
-            mp_raise_ValueError("pin can only be input");
+            mp_raise_ValueError(MP_ERROR_TEXT("pin can only be input"));
         } else {
             gpio_set_direction(self->id, pin_io_mode);
         }
@@ -205,7 +205,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
         self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin];
     }
     if (self == NULL || self->base.type == NULL) {
-        mp_raise_ValueError("invalid pin");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
     }
 
     if (n_args > 1 || n_kw > 0) {
@@ -282,24 +282,24 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
             mp_int_t wake;
             if (mp_obj_get_int_maybe(wake_obj, &wake)) {
                 if (wake < 2 || wake > 7) {
-                    mp_raise_ValueError("bad wake value");
+                    mp_raise_ValueError(MP_ERROR_TEXT("bad wake value"));
                 }
             } else {
-                mp_raise_ValueError("bad wake value");
+                mp_raise_ValueError(MP_ERROR_TEXT("bad wake value"));
             }
 
             if (machine_rtc_config.wake_on_touch) { // not compatible
-                mp_raise_ValueError("no resources");
+                mp_raise_ValueError(MP_ERROR_TEXT("no resources"));
             }
 
             if (!RTC_IS_VALID_EXT_PIN(self->id)) {
-                mp_raise_ValueError("invalid pin for wake");
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for wake"));
             }
 
             if (machine_rtc_config.ext0_pin == -1) {
                 machine_rtc_config.ext0_pin = self->id;
             } else if (machine_rtc_config.ext0_pin != self->id) {
-                mp_raise_ValueError("no resources");
+                mp_raise_ValueError(MP_ERROR_TEXT("no resources"));
             }
 
             machine_rtc_config.ext0_level = trigger == GPIO_PIN_INTR_LOLEVEL ? 0 : 1;
diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c
index c98b26c691..c0eae3d0b8 100644
--- a/ports/esp32/machine_pwm.c
+++ b/ports/esp32/machine_pwm.c
@@ -145,7 +145,7 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
     }
     if (channel >= LEDC_CHANNEL_MAX) {
         if (avail == -1) {
-            mp_raise_ValueError("out of PWM channels");
+            mp_raise_ValueError(MP_ERROR_TEXT("out of PWM channels"));
         }
         channel = avail;
     }
@@ -163,7 +163,7 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
             .timer_sel = PWTIMER,
         };
         if (ledc_channel_config(&cfg) != ESP_OK) {
-            mp_raise_msg_varg(&mp_type_ValueError, "PWM not supported on pin %d", self->pin);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM not supported on pin %d"), self->pin);
         }
         chan_gpio[channel] = self->pin;
     }
@@ -173,7 +173,7 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
     if (tval != -1) {
         if (tval != timer_cfg.freq_hz) {
             if (!set_freq(tval)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "Bad frequency %d", tval);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Bad frequency %d"), tval);
             }
         }
     }
@@ -247,7 +247,7 @@ STATIC mp_obj_t esp32_pwm_freq(size_t n_args, const mp_obj_t *args) {
     // set
     int tval = mp_obj_get_int(args[1]);
     if (!set_freq(tval)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Bad frequency %d", tval);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Bad frequency %d"), tval);
     }
     return mp_const_none;
 }
diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c
index 073af79913..c776eaa8d3 100644
--- a/ports/esp32/machine_rtc.c
+++ b/ports/esp32/machine_rtc.c
@@ -154,7 +154,7 @@ STATIC mp_obj_t machine_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) {
         mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
 
         if (bufinfo.len > MICROPY_HW_RTC_USER_MEM_MAX) {
-            mp_raise_ValueError("buffer too long");
+            mp_raise_ValueError(MP_ERROR_TEXT("buffer too long"));
         }
         memcpy((char *)rtc_user_mem_data, (char *)bufinfo.buf, bufinfo.len);
         rtc_user_mem_len = bufinfo.len;
diff --git a/ports/esp32/machine_sdcard.c b/ports/esp32/machine_sdcard.c
index 4ae157178c..2c2f3bc4cd 100644
--- a/ports/esp32/machine_sdcard.c
+++ b/ports/esp32/machine_sdcard.c
@@ -177,7 +177,7 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
 
     int slot_num = arg_vals[ARG_slot].u_int;
     if (slot_num < 0 || slot_num > 3) {
-        mp_raise_ValueError("Slot number must be between 0 and 3 inclusive");
+        mp_raise_ValueError(MP_ERROR_TEXT("Slot number must be between 0 and 3 inclusive"));
     }
 
     // Slots 0 and 1 are native SD/MMC, slots 2 and 3 are SPI
@@ -253,7 +253,7 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
         if (width == 1 || width == 4 || (width == 8 && slot_num == 0)) {
             slot_config.width = width;
         } else {
-            mp_raise_ValueError("Width must be 1 or 4 (or 8 on slot 0)");
+            mp_raise_ValueError(MP_ERROR_TEXT("Width must be 1 or 4 (or 8 on slot 0)"));
         }
 
         DEBUG_printf("  Calling init_slot()");
diff --git a/ports/esp32/machine_touchpad.c b/ports/esp32/machine_touchpad.c
index 63c06d2680..44efac3756 100644
--- a/ports/esp32/machine_touchpad.c
+++ b/ports/esp32/machine_touchpad.c
@@ -68,7 +68,7 @@ STATIC mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
         }
     }
     if (!self) {
-        mp_raise_ValueError("invalid pin for touchpad");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for touchpad"));
     }
 
     static int initialized = 0;
@@ -81,7 +81,7 @@ STATIC mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
     if (err == ESP_OK) {
         return MP_OBJ_FROM_PTR(self);
     }
-    mp_raise_ValueError("Touch pad error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));
 }
 
 STATIC mp_obj_t mtp_config(mp_obj_t self_in, mp_obj_t value_in) {
@@ -91,7 +91,7 @@ STATIC mp_obj_t mtp_config(mp_obj_t self_in, mp_obj_t value_in) {
     if (err == ESP_OK) {
         return mp_const_none;
     }
-    mp_raise_ValueError("Touch pad error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));
 }
 MP_DEFINE_CONST_FUN_OBJ_2(mtp_config_obj, mtp_config);
 
@@ -102,7 +102,7 @@ STATIC mp_obj_t mtp_read(mp_obj_t self_in) {
     if (err == ESP_OK) {
         return MP_OBJ_NEW_SMALL_INT(value);
     }
-    mp_raise_ValueError("Touch pad error");
+    mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));
 }
 MP_DEFINE_CONST_FUN_OBJ_1(mtp_read_obj, mtp_read);
 
diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c
index 15d4068e98..c334e694b2 100644
--- a/ports/esp32/machine_uart.c
+++ b/ports/esp32/machine_uart.c
@@ -187,7 +187,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
             self->bits = 8;
             break;
         default:
-            mp_raise_ValueError("invalid data bits");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid data bits"));
             break;
     }
 
@@ -222,7 +222,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
             self->stop = 2;
             break;
         default:
-            mp_raise_ValueError("invalid stop bits");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid stop bits"));
             break;
     }
 
@@ -239,7 +239,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
 
     // set line inversion
     if (args[ARG_invert].u_int & ~UART_LINE_INV_MASK) {
-        mp_raise_ValueError("invalid inversion mask");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid inversion mask"));
     }
     self->invert = args[ARG_invert].u_int;
     uart_set_line_inverse(self->uart_num, self->invert);
@@ -251,13 +251,13 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
     // get uart id
     mp_int_t uart_num = mp_obj_get_int(args[0]);
     if (uart_num < 0 || uart_num >= UART_NUM_MAX) {
-        mp_raise_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", uart_num);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) does not exist"), uart_num);
     }
 
     // Attempts to use UART0 from Python has resulted in all sorts of fun errors.
     // FIXME: UART0 is disabled for now.
     if (uart_num == UART_NUM_0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "UART(%d) is disabled (dedicated to REPL)", uart_num);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) is disabled (dedicated to REPL)"), uart_num);
     }
 
     // Defaults
diff --git a/ports/esp32/machine_wdt.c b/ports/esp32/machine_wdt.c
index 5c4732f4b6..f0ec6928e0 100644
--- a/ports/esp32/machine_wdt.c
+++ b/ports/esp32/machine_wdt.c
@@ -58,7 +58,7 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args
     args[ARG_timeout].u_int /= 1000;
 
     if (args[ARG_timeout].u_int <= 0) {
-        mp_raise_ValueError("WDT timeout too short");
+        mp_raise_ValueError(MP_ERROR_TEXT("WDT timeout too short"));
     }
 
     mp_int_t rs_code = esp_task_wdt_init(args[ARG_timeout].u_int, true);
diff --git a/ports/esp32/modesp32.c b/ports/esp32/modesp32.c
index 0e0a7b7dbd..0ce3b957b3 100644
--- a/ports/esp32/modesp32.c
+++ b/ports/esp32/modesp32.c
@@ -46,9 +46,9 @@
 STATIC mp_obj_t esp32_wake_on_touch(const mp_obj_t wake) {
 
     if (machine_rtc_config.ext0_pin != -1) {
-        mp_raise_ValueError("no resources");
+        mp_raise_ValueError(MP_ERROR_TEXT("no resources"));
     }
-    //mp_raise_msg(&mp_type_RuntimeError, "touchpad wakeup not available for this version of ESP-IDF");
+    //mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("touchpad wakeup not available for this version of ESP-IDF"));
 
     machine_rtc_config.wake_on_touch = mp_obj_is_true(wake);
     return mp_const_none;
@@ -58,7 +58,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_wake_on_touch_obj, esp32_wake_on_touch);
 STATIC mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
 
     if (machine_rtc_config.wake_on_touch) {
-        mp_raise_ValueError("no resources");
+        mp_raise_ValueError(MP_ERROR_TEXT("no resources"));
     }
     enum {ARG_pin, ARG_level};
     const mp_arg_t allowed_args[] = {
@@ -74,7 +74,7 @@ STATIC mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_m
         gpio_num_t pin_id = machine_pin_get_id(args[ARG_pin].u_obj);
         if (pin_id != machine_rtc_config.ext0_pin) {
             if (!RTC_IS_VALID_EXT_PIN(pin_id)) {
-                mp_raise_ValueError("invalid pin");
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
             }
             machine_rtc_config.ext0_pin = pin_id;
         }
@@ -109,7 +109,7 @@ STATIC mp_obj_t esp32_wake_on_ext1(size_t n_args, const mp_obj_t *pos_args, mp_m
 
             gpio_num_t pin_id = machine_pin_get_id(elem[i]);
             if (!RTC_IS_VALID_EXT_PIN(pin_id)) {
-                mp_raise_ValueError("invalid pin");
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
                 break;
             }
             ext1_pins |= (1ll << pin_id);
diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c
index f2af502ba8..8d8df995c2 100644
--- a/ports/esp32/modmachine.c
+++ b/ports/esp32/modmachine.c
@@ -73,7 +73,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
         // set
         mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
         if (freq != 20 && freq != 40 && freq != 80 && freq != 160 && freq != 240) {
-            mp_raise_ValueError("frequency must be 20MHz, 40MHz, 80Mhz, 160MHz or 240MHz");
+            mp_raise_ValueError(MP_ERROR_TEXT("frequency must be 20MHz, 40MHz, 80Mhz, 160MHz or 240MHz"));
         }
         esp_pm_config_esp32_t pm;
         pm.max_freq_mhz = freq;
@@ -120,7 +120,7 @@ STATIC mp_obj_t machine_sleep_helper(wake_type_t wake_type, size_t n_args, const
 
     if (machine_rtc_config.wake_on_touch) {
         if (esp_sleep_enable_touchpad_wakeup() != ESP_OK) {
-            mp_raise_msg(&mp_type_RuntimeError, "esp_sleep_enable_touchpad_wakeup() failed");
+            mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("esp_sleep_enable_touchpad_wakeup() failed"));
         }
     }
 
diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c
index f486a0c6ad..85d2f1506d 100644
--- a/ports/esp32/modnetwork.c
+++ b/ports/esp32/modnetwork.c
@@ -60,45 +60,45 @@
 NORETURN void _esp_exceptions(esp_err_t e) {
     switch (e) {
         case ESP_ERR_WIFI_NOT_INIT:
-            mp_raise_msg(&mp_type_OSError, "Wifi Not Initialized");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Initialized"));
         case ESP_ERR_WIFI_NOT_STARTED:
-            mp_raise_msg(&mp_type_OSError, "Wifi Not Started");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Started"));
         case ESP_ERR_WIFI_NOT_STOPPED:
-            mp_raise_msg(&mp_type_OSError, "Wifi Not Stopped");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Stopped"));
         case ESP_ERR_WIFI_IF:
-            mp_raise_msg(&mp_type_OSError, "Wifi Invalid Interface");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Invalid Interface"));
         case ESP_ERR_WIFI_MODE:
-            mp_raise_msg(&mp_type_OSError, "Wifi Invalid Mode");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Invalid Mode"));
         case ESP_ERR_WIFI_STATE:
-            mp_raise_msg(&mp_type_OSError, "Wifi Internal State Error");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Internal State Error"));
         case ESP_ERR_WIFI_CONN:
-            mp_raise_msg(&mp_type_OSError, "Wifi Internal Error");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Internal Error"));
         case ESP_ERR_WIFI_NVS:
-            mp_raise_msg(&mp_type_OSError, "Wifi Internal NVS Error");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Internal NVS Error"));
         case ESP_ERR_WIFI_MAC:
-            mp_raise_msg(&mp_type_OSError, "Wifi Invalid MAC Address");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Invalid MAC Address"));
         case ESP_ERR_WIFI_SSID:
-            mp_raise_msg(&mp_type_OSError, "Wifi SSID Invalid");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi SSID Invalid"));
         case ESP_ERR_WIFI_PASSWORD:
-            mp_raise_msg(&mp_type_OSError, "Wifi Invalid Password");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Invalid Password"));
         case ESP_ERR_WIFI_TIMEOUT:
             mp_raise_OSError(MP_ETIMEDOUT);
         case ESP_ERR_WIFI_WAKE_FAIL:
-            mp_raise_msg(&mp_type_OSError, "Wifi Wakeup Failure");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Wakeup Failure"));
         case ESP_ERR_WIFI_WOULD_BLOCK:
-            mp_raise_msg(&mp_type_OSError, "Wifi Would Block");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Would Block"));
         case ESP_ERR_WIFI_NOT_CONNECT:
-            mp_raise_msg(&mp_type_OSError, "Wifi Not Connected");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Connected"));
         case ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:
-            mp_raise_msg(&mp_type_OSError, "TCP/IP Invalid Parameters");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP Invalid Parameters"));
         case ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:
-            mp_raise_msg(&mp_type_OSError, "TCP/IP IF Not Ready");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP IF Not Ready"));
         case ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED:
-            mp_raise_msg(&mp_type_OSError, "TCP/IP DHCP Client Start Failed");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP DHCP Client Start Failed"));
         case ESP_ERR_TCPIP_ADAPTER_NO_MEM:
             mp_raise_OSError(MP_ENOMEM);
         default:
-            mp_raise_msg_varg(&mp_type_RuntimeError, "Wifi Unknown Error 0x%04x", e);
+            mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Wifi Unknown Error 0x%04x"), e);
     }
 }
 
@@ -241,7 +241,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) {
 STATIC void require_if(mp_obj_t wlan_if, int if_no) {
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
     if (self->if_id != if_no) {
-        mp_raise_msg(&mp_type_OSError, if_no == WIFI_IF_STA ? "STA required" : "AP required");
+        mp_raise_msg(&mp_type_OSError, if_no == WIFI_IF_STA ? MP_ERROR_TEXT("STA required") : MP_ERROR_TEXT("AP required"));
     }
 }
 
@@ -262,7 +262,7 @@ STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) {
     } else if (idx == WIFI_IF_AP) {
         return MP_OBJ_FROM_PTR(&wlan_ap_obj);
     } else {
-        mp_raise_ValueError("invalid WLAN interface identifier");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid WLAN interface identifier"));
     }
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj, 0, 1, get_wlan);
@@ -429,7 +429,7 @@ STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
             return MP_OBJ_NEW_SMALL_INT(info.rssi);
         }
         default:
-            mp_raise_ValueError("unknown status param");
+            mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
     }
 
     return mp_const_none;
@@ -441,7 +441,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
     wifi_mode_t mode;
     ESP_EXCEPTIONS(esp_wifi_get_mode(&mode));
     if ((mode & WIFI_MODE_STA) == 0) {
-        mp_raise_msg(&mp_type_OSError, "STA must be active");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("STA must be active"));
     }
 
     mp_obj_t list = mp_obj_new_list(0, NULL);
@@ -540,7 +540,7 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
             // check for the correct string
             const char *mode = mp_obj_str_get_str(args[1]);
             if ((self->if_id != WIFI_IF_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) {
-                mp_raise_ValueError("invalid arguments");
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments"));
             }
             ESP_EXCEPTIONS(tcpip_adapter_dhcpc_start(self->if_id));
         }
@@ -552,7 +552,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig);
 
 STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
     if (n_args != 1 && kwargs->used != 0) {
-        mp_raise_TypeError("either pos or kw args are allowed");
+        mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed"));
     }
 
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -580,7 +580,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
                         mp_buffer_info_t bufinfo;
                         mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
                         if (bufinfo.len != 6) {
-                            mp_raise_ValueError("invalid buffer length");
+                            mp_raise_ValueError(MP_ERROR_TEXT("invalid buffer length"));
                         }
                         ESP_EXCEPTIONS(esp_wifi_set_mac(self->if_id, bufinfo.buf));
                         break;
@@ -647,7 +647,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
     // Get config
 
     if (n_args != 2) {
-        mp_raise_TypeError("can query only one param");
+        mp_raise_TypeError(MP_ERROR_TEXT("can query only one param"));
     }
 
     int req_if = -1;
@@ -720,7 +720,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
     return val;
 
 unknown:
-    mp_raise_ValueError("unknown config param");
+    mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
 }
 MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
 
diff --git a/ports/esp32/modutime.c b/ports/esp32/modutime.c
index 1b9e07f44e..0325bd4693 100644
--- a/ports/esp32/modutime.c
+++ b/ports/esp32/modutime.c
@@ -66,7 +66,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
 
     // localtime generates a tuple of len 8. CPython uses 9, so we accept both.
     if (len < 8 || len > 9) {
-        mp_raise_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len);
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9 (%d given)"), len);
     }
 
     return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c
index 7b391ad6be..f39c99b68d 100644
--- a/ports/esp32/mpthreadport.c
+++ b/ports/esp32/mpthreadport.c
@@ -137,7 +137,7 @@ void mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_size,
     BaseType_t result = xTaskCreatePinnedToCore(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, &th->id, MP_TASK_COREID);
     if (result != pdPASS) {
         mp_thread_mutex_unlock(&thread_mutex);
-        mp_raise_msg(&mp_type_OSError, "can't create thread");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't create thread"));
     }
 
     // adjust the stack_size to provide room to recover from hitting the limit
diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c
index c2365e6017..5aaabfa21e 100644
--- a/ports/esp32/network_lan.c
+++ b/ports/esp32/network_lan.c
@@ -111,7 +111,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
 
     if (args[ARG_id].u_obj != mp_const_none) {
         if (mp_obj_get_int(args[ARG_id].u_obj) != 0) {
-            mp_raise_ValueError("invalid LAN interface identifier");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid LAN interface identifier"));
         }
     }
 
@@ -120,11 +120,11 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
     self->phy_power_pin = args[ARG_power].u_obj == mp_const_none ? -1 : machine_pin_get_id(args[ARG_power].u_obj);
 
     if (args[ARG_phy_addr].u_int < 0x00 || args[ARG_phy_addr].u_int > 0x1f) {
-        mp_raise_ValueError("invalid phy address");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid phy address"));
     }
 
     if (args[ARG_phy_type].u_int != PHY_LAN8720 && args[ARG_phy_type].u_int != PHY_TLK110) {
-        mp_raise_ValueError("invalid phy type");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid phy type"));
     }
 
     if (args[ARG_clock_mode].u_int != -1 &&
@@ -133,7 +133,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         //args[ARG_clock_mode].u_int != ETH_CLOCK_GPIO0_OUT &&
         args[ARG_clock_mode].u_int != ETH_CLOCK_GPIO16_OUT &&
         args[ARG_clock_mode].u_int != ETH_CLOCK_GPIO17_OUT) {
-        mp_raise_ValueError("invalid clock mode");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid clock mode"));
     }
 
     eth_config_t config;
@@ -165,7 +165,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         self->active = false;
         self->initialized = true;
     } else {
-        mp_raise_msg(&mp_type_OSError, "esp_eth_init() failed");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("esp_eth_init() failed"));
     }
     return MP_OBJ_FROM_PTR(&lan_obj);
 }
@@ -178,12 +178,12 @@ STATIC mp_obj_t lan_active(size_t n_args, const mp_obj_t *args) {
         if (mp_obj_is_true(args[1])) {
             self->active = (esp_eth_enable() == ESP_OK);
             if (!self->active) {
-                mp_raise_msg(&mp_type_OSError, "ethernet enable failed");
+                mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ethernet enable failed"));
             }
         } else {
             self->active = !(esp_eth_disable() == ESP_OK);
             if (self->active) {
-                mp_raise_msg(&mp_type_OSError, "ethernet disable failed");
+                mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ethernet disable failed"));
             }
         }
     }
diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c
index c522914cac..9f3a99a903 100644
--- a/ports/esp32/network_ppp.c
+++ b/ports/esp32/network_ppp.c
@@ -128,7 +128,7 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
             self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self);
 
             if (self->pcb == NULL) {
-                mp_raise_msg(&mp_type_RuntimeError, "init failed");
+                mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("init failed"));
             }
             self->active = true;
         } else {
@@ -178,7 +178,7 @@ STATIC mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw
     ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
 
     if (!self->active) {
-        mp_raise_msg(&mp_type_OSError, "must be active");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("must be active"));
     }
 
     if (self->client_task_handle != NULL) {
@@ -191,7 +191,7 @@ STATIC mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw
         case PPPAUTHTYPE_CHAP:
             break;
         default:
-            mp_raise_ValueError("invalid auth");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid auth"));
     }
 
     if (parsed_args[ARG_authmode].u_int != PPPAUTHTYPE_NONE) {
@@ -200,17 +200,17 @@ STATIC mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw
         pppapi_set_auth(self->pcb, parsed_args[ARG_authmode].u_int, username_str, password_str);
     }
     if (pppapi_set_default(self->pcb) != ESP_OK) {
-        mp_raise_msg(&mp_type_OSError, "set default failed");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("set default failed"));
     }
 
     ppp_set_usepeerdns(self->pcb, true);
 
     if (pppapi_connect(self->pcb, 0) != ESP_OK) {
-        mp_raise_msg(&mp_type_OSError, "connect failed");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("connect failed"));
     }
 
     if (xTaskCreatePinnedToCore(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t *)&self->client_task_handle, MP_TASK_COREID) != pdPASS) {
-        mp_raise_msg(&mp_type_RuntimeError, "failed to create worker task");
+        mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to create worker task"));
     }
 
     return mp_const_none;
diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index d7113452b4..03676b9113 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -149,7 +149,7 @@ void ets_event_poll(void) {
 
 void __assert_func(const char *file, int line, const char *func, const char *expr) {
     printf("assert:%s:%d:%s: %s\n", file, line, func, expr);
-    mp_raise_msg(&mp_type_AssertionError, "C-level assert");
+    mp_raise_msg(&mp_type_AssertionError, MP_ERROR_TEXT("C-level assert"));
 }
 
 void mp_hal_signal_input(void) {
diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c
index b0b458acd4..471e14d8df 100644
--- a/ports/esp8266/machine_adc.c
+++ b/ports/esp8266/machine_adc.c
@@ -64,7 +64,7 @@ mp_obj_t machine_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, size_
         case 1:
             return &machine_adc_vdd3;
         default:
-            mp_raise_msg_varg(&mp_type_ValueError, "ADC(%d) doesn't exist", chn);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("ADC(%d) doesn't exist"), chn);
     }
 }
 
diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c
index 11c95a3e8a..7319194d76 100644
--- a/ports/esp8266/machine_hspi.c
+++ b/ports/esp8266/machine_hspi.c
@@ -127,13 +127,13 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob
         spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
         spi_clock(HSPI, 0, 0);
     } else if (self->baudrate > 40000000L) {
-        mp_raise_ValueError("impossible baudrate");
+        mp_raise_ValueError(MP_ERROR_TEXT("impossible baudrate"));
     } else {
         uint32_t divider = 40000000L / self->baudrate;
         uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1);
         uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even
         if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
-            mp_raise_ValueError("impossible baudrate");
+            mp_raise_ValueError(MP_ERROR_TEXT("impossible baudrate"));
         }
         self->baudrate = 80000000L / (prediv * cntdiv);
         spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c
index dcecea0b59..d997800d33 100644
--- a/ports/esp8266/machine_pin.c
+++ b/ports/esp8266/machine_pin.c
@@ -128,7 +128,7 @@ void pin_intr_handler(uint32_t status) {
 
 pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) {
     if (mp_obj_get_type(pin_in) != &pyb_pin_type) {
-        mp_raise_ValueError("expecting a pin");
+        mp_raise_ValueError(MP_ERROR_TEXT("expecting a pin"));
     }
     pyb_pin_obj_t *self = pin_in;
     return self;
@@ -283,7 +283,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, size_t n_args, cons
         // only pull-down seems to be supported by the hardware, and
         // we only expose pull-up behaviour in software
         if (pull != GPIO_PULL_NONE) {
-            mp_raise_ValueError("Pin(16) doesn't support pull");
+            mp_raise_ValueError(MP_ERROR_TEXT("Pin(16) doesn't support pull"));
         }
     } else {
         PIN_FUNC_SELECT(self->periph, self->func);
@@ -322,7 +322,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
         pin = (pyb_pin_obj_t *)&pyb_pin_obj[wanted_pin];
     }
     if (pin == NULL || pin->base.type == NULL) {
-        mp_raise_ValueError("invalid pin");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
     }
 
     if (n_args > 1 || n_kw > 0) {
@@ -388,7 +388,7 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
 
     if (self->phys_port >= 16) {
-        mp_raise_msg(&mp_type_OSError, "pin does not have IRQ capabilities");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("pin does not have IRQ capabilities"));
     }
 
     if (n_args > 1 || kw_args->used != 0) {
diff --git a/ports/esp8266/machine_pwm.c b/ports/esp8266/machine_pwm.c
index 53255806c0..edfa828c99 100644
--- a/ports/esp8266/machine_pwm.c
+++ b/ports/esp8266/machine_pwm.c
@@ -65,7 +65,7 @@ STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj
 
     int channel = pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func);
     if (channel == -1) {
-        mp_raise_msg_varg(&mp_type_ValueError, "PWM not supported on pin %d", self->pin->phys_port);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM not supported on pin %d"), self->pin->phys_port);
     }
 
     self->channel = channel;
diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c
index 3df2dfcaaf..1aa73f9b31 100644
--- a/ports/esp8266/machine_rtc.c
+++ b/ports/esp8266/machine_rtc.c
@@ -181,7 +181,7 @@ STATIC mp_obj_t pyb_rtc_memory(size_t n_args, const mp_obj_t *args) {
         mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
 
         if (bufinfo.len > MEM_USER_MAXLEN) {
-            mp_raise_ValueError("buffer too long");
+            mp_raise_ValueError(MP_ERROR_TEXT("buffer too long"));
         }
 
         len = bufinfo.len;
@@ -205,7 +205,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time
 
     // check we want alarm0
     if (mp_obj_get_int(alarm_id) != 0) {
-        mp_raise_ValueError("invalid alarm");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid alarm"));
     }
 
     // set expiry time (in microseconds)
@@ -219,7 +219,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_rtc_alarm_obj, pyb_rtc_alarm);
 STATIC mp_obj_t pyb_rtc_alarm_left(size_t n_args, const mp_obj_t *args) {
     // check we want alarm0
     if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
-        mp_raise_ValueError("invalid alarm");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid alarm"));
     }
 
     uint64_t now = pyb_rtc_get_us_since_2000();
@@ -242,7 +242,7 @@ STATIC mp_obj_t pyb_rtc_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
 
     // check we want alarm0
     if (args[ARG_trigger].u_int != 0) {
-        mp_raise_ValueError("invalid alarm");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid alarm"));
     }
 
     // set the wake value
diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c
index 735e01be19..a8ea5e38d3 100644
--- a/ports/esp8266/machine_uart.c
+++ b/ports/esp8266/machine_uart.c
@@ -107,7 +107,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
             self->bits = 8;
             break;
         default:
-            mp_raise_ValueError("invalid data bits");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid data bits"));
             break;
     }
 
@@ -143,7 +143,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
     } else if (tx == 15 && rx == 13) {
         system_uart_swap();
     } else {
-        mp_raise_ValueError("invalid tx/rx");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid tx/rx"));
     }
 
     // set stop bits
@@ -159,7 +159,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
             self->stop = 2;
             break;
         default:
-            mp_raise_ValueError("invalid stop bits");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid stop bits"));
             break;
     }
 
@@ -198,7 +198,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
     // get uart id
     mp_int_t uart_id = mp_obj_get_int(args[0]);
     if (uart_id != 0 && uart_id != 1) {
-        mp_raise_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", uart_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) does not exist"), uart_id);
     }
 
     // create instance
@@ -248,7 +248,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
     pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
     if (self->uart_id == 1) {
-        mp_raise_msg(&mp_type_OSError, "UART(1) can't read");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("UART(1) can't read"));
     }
 
     // make sure we want at least 1 char
diff --git a/ports/esp8266/modesp.c b/ports/esp8266/modesp.c
index 95566cd4fe..1047b42784 100644
--- a/ports/esp8266/modesp.c
+++ b/ports/esp8266/modesp.c
@@ -42,7 +42,7 @@
 
 #define MODESP_INCLUDE_CONSTANTS (1)
 
-void error_check(bool status, const char *msg) {
+void error_check(bool status, mp_rom_error_text_t msg) {
     if (!status) {
         mp_raise_msg(&mp_type_OSError, msg);
     }
@@ -120,7 +120,7 @@ STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, const mp_obj_t buf_in) {
     mp_buffer_info_t bufinfo;
     mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
     if (bufinfo.len & 0x3) {
-        mp_raise_ValueError("len must be multiple of 4");
+        mp_raise_ValueError(MP_ERROR_TEXT("len must be multiple of 4"));
     }
     ets_loop_iter(); // flash access takes time so run any pending tasks
     SpiFlashOpResult res = spi_flash_write(offset, bufinfo.buf, bufinfo.len);
@@ -289,7 +289,7 @@ void *esp_native_code_commit(void *buf, size_t len, void *reloc) {
     len = (len + 3) & ~3;
     if (esp_native_code_cur + len > esp_native_code_end) {
         mp_raise_msg_varg(&mp_type_MemoryError,
-            "memory allocation failed, allocating %u bytes for native code", (uint)len);
+            MP_ERROR_TEXT("memory allocation failed, allocating %u bytes for native code"), (uint)len);
     }
 
     void *dest;
@@ -342,7 +342,7 @@ STATIC mp_obj_t esp_set_native_code_location(mp_obj_t start_in, mp_obj_t len_in)
         esp_native_code_erased = esp_native_code_start;
         // memory-mapped flash is limited in extents to 1MByte
         if (esp_native_code_end > FLASH_END - FLASH_START) {
-            mp_raise_ValueError("flash location must be below 1MByte");
+            mp_raise_ValueError(MP_ERROR_TEXT("flash location must be below 1MByte"));
         }
     }
     return mp_const_none;
diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c
index bb7a780a35..b9573b1afb 100644
--- a/ports/esp8266/modmachine.c
+++ b/ports/esp8266/modmachine.c
@@ -64,7 +64,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
         // set
         mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
         if (freq != 80 && freq != 160) {
-            mp_raise_ValueError("frequency can only be either 80Mhz or 160MHz");
+            mp_raise_ValueError(MP_ERROR_TEXT("frequency can only be either 80Mhz or 160MHz"));
         }
         system_update_cpu_freq(freq);
         return mp_const_none;
diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c
index 7d27dceff7..cad53d912c 100644
--- a/ports/esp8266/modnetwork.c
+++ b/ports/esp8266/modnetwork.c
@@ -181,7 +181,7 @@ STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
                     return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi());
                 }
         }
-        mp_raise_ValueError("unknown status param");
+        mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
     }
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_status_obj, 1, 2, esp_status);
@@ -229,7 +229,7 @@ STATIC void esp_scan_cb(void *result, STATUS status) {
 STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
     require_if(self_in, STATION_IF);
     if ((wifi_get_opmode() & STATION_MODE) == 0) {
-        mp_raise_msg(&mp_type_OSError, "STA must be active");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("STA must be active"));
     }
     mp_obj_t list = mp_obj_new_list(0, NULL);
     esp_scan_list = &list;
@@ -246,7 +246,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
         ets_loop_iter();
     }
     if (list == MP_OBJ_NULL) {
-        mp_raise_msg(&mp_type_OSError, "scan failed");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("scan failed"));
     }
     return list;
 }
@@ -317,7 +317,7 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
             wifi_softap_dhcps_stop();
         }
         if (!wifi_set_ip_info(self->if_id, &info)) {
-            mp_raise_msg(&mp_type_OSError, "wifi_set_ip_info() failed");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("wifi_set_ip_info() failed"));
         }
         dns_setserver(0, &dns_addr);
         if (restart_dhcp_server) {
@@ -330,7 +330,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig)
 
 STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
     if (n_args != 1 && kwargs->used != 0) {
-        mp_raise_TypeError("either pos or kw args are allowed");
+        mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed"));
     }
 
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -357,7 +357,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
                         mp_buffer_info_t bufinfo;
                         mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
                         if (bufinfo.len != 6) {
-                            mp_raise_ValueError("invalid buffer length");
+                            mp_raise_ValueError(MP_ERROR_TEXT("invalid buffer length"));
                         }
                         wifi_set_macaddr(self->if_id, bufinfo.buf);
                         break;
@@ -427,7 +427,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
     // Get config
 
     if (n_args != 2) {
-        mp_raise_TypeError("can query only one param");
+        mp_raise_TypeError(MP_ERROR_TEXT("can query only one param"));
     }
 
     mp_obj_t val;
@@ -480,7 +480,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
     return val;
 
 unknown:
-    mp_raise_ValueError("unknown config param");
+    mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
 
diff --git a/ports/esp8266/modutime.c b/ports/esp8266/modutime.c
index 915f19302c..9e924121bb 100644
--- a/ports/esp8266/modutime.c
+++ b/ports/esp8266/modutime.c
@@ -88,7 +88,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
 
     // localtime generates a tuple of len 8. CPython uses 9, so we accept both.
     if (len < 8 || len > 9) {
-        mp_raise_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len);
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9 (%d given)"), len);
     }
 
     return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c
index 2d70817503..979a4ddd08 100644
--- a/ports/nrf/boards/microbit/modules/microbitdisplay.c
+++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c
@@ -305,7 +305,7 @@ static void draw_object(mp_obj_t obj) {
             async_stop();
         }
     } else {
-        MP_STATE_VM(mp_pending_exception) = mp_obj_new_exception_msg(&mp_type_TypeError, "not an image.");
+        MP_STATE_VM(mp_pending_exception) = mp_obj_new_exception_msg(&mp_type_TypeError, MP_ERROR_TEXT("not an image."));
         async_stop();
     }
 }
@@ -499,10 +499,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(microbit_display_clear_obj, microbit_display_clear_fun
 
 void microbit_display_set_pixel(microbit_display_obj_t *display, mp_int_t x, mp_int_t y, mp_int_t bright) {
     if (x < 0 || y < 0 || x > 4 || y > 4) {
-        mp_raise_ValueError("index out of bounds.");
+        mp_raise_ValueError(MP_ERROR_TEXT("index out of bounds."));
     }
     if (bright < 0 || bright > MAX_BRIGHTNESS) {
-        mp_raise_ValueError("brightness out of bounds.");
+        mp_raise_ValueError(MP_ERROR_TEXT("brightness out of bounds."));
     }
     display->image_buffer[x][y] = bright;
     display->brightnesses |= (1 << bright);
@@ -518,7 +518,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(microbit_display_set_pixel_obj, 4, 4, microb
 
 mp_int_t microbit_display_get_pixel(microbit_display_obj_t *display, mp_int_t x, mp_int_t y) {
     if (x < 0 || y < 0 || x > 4 || y > 4) {
-        mp_raise_ValueError("index out of bounds.");
+        mp_raise_ValueError(MP_ERROR_TEXT("index out of bounds."));
     }
     return display->image_buffer[x][y];
 }
diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c
index cc4719a3d9..56bd18c6ed 100644
--- a/ports/nrf/boards/microbit/modules/microbitimage.c
+++ b/ports/nrf/boards/microbit/modules/microbitimage.c
@@ -162,7 +162,7 @@ STATIC microbit_image_obj_t *image_from_parsed_str(const char *s, mp_int_t len)
         } else if ('c' >= '0' && c <= '9') {
             ++line_len;
         } else {
-            mp_raise_ValueError("Unexpected character in Image definition.");
+            mp_raise_ValueError(MP_ERROR_TEXT("Unexpected character in Image definition."));
         }
     }
     if (line_len) {
@@ -227,7 +227,7 @@ STATIC mp_obj_t microbit_image_make_new(const mp_obj_type_t *type_in, mp_uint_t
                     return image_from_parsed_str(str, len);
                 }
             } else {
-                mp_raise_TypeError("Image(s) takes a string.");
+                mp_raise_TypeError(MP_ERROR_TEXT("Image(s) takes a string."));
             }
         }
 
@@ -243,7 +243,7 @@ STATIC mp_obj_t microbit_image_make_new(const mp_obj_type_t *type_in, mp_uint_t
                 mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
 
                 if (w < 0 || h < 0 || (size_t)(w * h) != bufinfo.len) {
-                    mp_raise_ValueError("image data is incorrect size");
+                    mp_raise_ValueError(MP_ERROR_TEXT("image data is incorrect size"));
                 }
                 mp_int_t i = 0;
                 for (mp_int_t y = 0; y < h; y++) {
@@ -258,7 +258,7 @@ STATIC mp_obj_t microbit_image_make_new(const mp_obj_type_t *type_in, mp_uint_t
         }
 
         default: {
-            mp_raise_TypeError("Image() takes 0 to 3 arguments");
+            mp_raise_TypeError(MP_ERROR_TEXT("Image() takes 0 to 3 arguments"));
         }
     }
 }
@@ -351,19 +351,19 @@ mp_obj_t microbit_image_get_pixel(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in
     mp_int_t x = mp_obj_get_int(x_in);
     mp_int_t y = mp_obj_get_int(y_in);
     if (x < 0 || y < 0) {
-        mp_raise_ValueError("index cannot be negative");
+        mp_raise_ValueError(MP_ERROR_TEXT("index cannot be negative"));
     }
     if (x < imageWidth(self) && y < imageHeight(self)) {
         return MP_OBJ_NEW_SMALL_INT(imageGetPixelValue(self, x, y));
     }
-    mp_raise_ValueError("index too large");
+    mp_raise_ValueError(MP_ERROR_TEXT("index too large"));
 }
 MP_DEFINE_CONST_FUN_OBJ_3(microbit_image_get_pixel_obj, microbit_image_get_pixel);
 
 /* Raise an exception if not mutable */
 static void check_mutability(microbit_image_obj_t *self) {
     if (self->base.five) {
-        mp_raise_TypeError("image cannot be modified (try copying first)");
+        mp_raise_TypeError(MP_ERROR_TEXT("image cannot be modified (try copying first)"));
     }
 }
 
@@ -375,16 +375,16 @@ mp_obj_t microbit_image_set_pixel(mp_uint_t n_args, const mp_obj_t *args) {
     mp_int_t x = mp_obj_get_int(args[1]);
     mp_int_t y = mp_obj_get_int(args[2]);
     if (x < 0 || y < 0) {
-        mp_raise_ValueError("index cannot be negative");
+        mp_raise_ValueError(MP_ERROR_TEXT("index cannot be negative"));
     }
     mp_int_t bright = mp_obj_get_int(args[3]);
     if (bright < 0 || bright > MAX_BRIGHTNESS)
-        mp_raise_ValueError("brightness out of bounds.");
+        mp_raise_ValueError(MP_ERROR_TEXT("brightness out of bounds."));
     if (x < imageWidth(self) && y < imageHeight(self)) {
         greyscaleSetPixelValue(&(self->greyscale), x, y, bright);
         return mp_const_none;
     }
-    mp_raise_ValueError("index too large");
+    mp_raise_ValueError(MP_ERROR_TEXT("index too large"));
 }
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(microbit_image_set_pixel_obj, 4, 4, microbit_image_set_pixel);
 
@@ -393,7 +393,7 @@ mp_obj_t microbit_image_fill(mp_obj_t self_in, mp_obj_t n_in) {
     check_mutability(self);
     mp_int_t n = mp_obj_get_int(n_in);
     if (n < 0 || n > MAX_BRIGHTNESS) {
-        mp_raise_ValueError("brightness out of bounds.");
+        mp_raise_ValueError(MP_ERROR_TEXT("brightness out of bounds."));
     }
     greyscaleFill(&self->greyscale, n);
     return mp_const_none;
@@ -406,17 +406,17 @@ mp_obj_t microbit_image_blit(mp_uint_t n_args, const mp_obj_t *args) {
 
     mp_obj_t src = args[1];
     if (mp_obj_get_type(src) != &microbit_image_type) {
-        mp_raise_TypeError("expecting an image");
+        mp_raise_TypeError(MP_ERROR_TEXT("expecting an image"));
     }
     if (n_args == 7) {
-        mp_raise_TypeError("must specify both offsets");
+        mp_raise_TypeError(MP_ERROR_TEXT("must specify both offsets"));
     }
     mp_int_t x = mp_obj_get_int(args[2]);
     mp_int_t y = mp_obj_get_int(args[3]);
     mp_int_t w = mp_obj_get_int(args[4]);
     mp_int_t h = mp_obj_get_int(args[5]);
     if (w < 0 || h < 0) {
-        mp_raise_ValueError("size cannot be negative");
+        mp_raise_ValueError(MP_ERROR_TEXT("size cannot be negative"));
     }
     mp_int_t xdest;
     mp_int_t ydest;
@@ -608,7 +608,7 @@ microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_float_t f
 microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_int_t fval) {
 #endif
     if (fval < 0)
-        mp_raise_ValueError("Brightness multiplier must not be negative.");
+        mp_raise_ValueError(MP_ERROR_TEXT("Brightness multiplier must not be negative."));
     greyscale_t *result = greyscale_new(imageWidth(lhs), imageHeight(lhs));
     for (int x = 0; x < imageWidth(lhs); ++x) {
         for (int y = 0; y < imageWidth(lhs); ++y) {
@@ -628,7 +628,7 @@ microbit_image_obj_t *microbit_image_sum(microbit_image_obj_t *lhs, microbit_ima
     mp_int_t w = imageWidth(lhs);
     if (imageHeight(rhs) != h || imageWidth(lhs) != w) {
 // TODO: verify that image width in test above should really test (lhs != w)
-        mp_raise_ValueError("Images must be the same size.");
+        mp_raise_ValueError(MP_ERROR_TEXT("Images must be the same size."));
     }
     greyscale_t *result = greyscale_new(w, h);
     for (int x = 0; x < w; ++x) {
diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c
index 07f3b89aa5..7619dc0399 100644
--- a/ports/nrf/drivers/bluetooth/ble_drv.c
+++ b/ports/nrf/drivers/bluetooth/ble_drv.c
@@ -223,7 +223,7 @@ uint32_t ble_drv_stack_enable(void) {
     if ((err_code = sd_ble_gap_device_name_set(&sec_mode,
                                                (const uint8_t *)device_name,
                                                 strlen(device_name))) != 0) {
-        mp_raise_msg(&mp_type_OSError, "can't apply GAP parameters");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't apply GAP parameters"));
     }
 
     // set connection parameters
@@ -235,7 +235,7 @@ uint32_t ble_drv_stack_enable(void) {
     gap_conn_params.conn_sup_timeout  = BLE_CONN_SUP_TIMEOUT;
 
     if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) {
-        mp_raise_msg(&mp_type_OSError, "can't set PPCP parameters");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't set PPCP parameters"));
     }
 
     return err_code;
@@ -266,7 +266,7 @@ void ble_drv_address_get(ble_drv_addr_t * p_addr) {
 #endif
 
     if (err_code != 0) {
-        mp_raise_msg(&mp_type_OSError, "can't query for the device address");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't query for the device address"));
     }
 
     BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \
@@ -284,7 +284,7 @@ bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) {
     SD_TEST_OR_ENABLE();
 
     if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) {
-        mp_raise_msg(&mp_type_OSError, "can't add Vendor Specific 128-bit UUID");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Vendor Specific 128-bit UUID"));
     }
 
     return true;
@@ -303,7 +303,7 @@ bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
         if (sd_ble_gatts_service_add(p_service_obj->type,
                                      &uuid,
                                      &p_service_obj->handle) != 0) {
-            mp_raise_msg(&mp_type_OSError, "can't add Service");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Service"));
         }
     } else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) {
         BLE_DRIVER_LOG("adding service\n");
@@ -316,7 +316,7 @@ bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
         if (sd_ble_gatts_service_add(p_service_obj->type,
                                      &uuid,
                                      &p_service_obj->handle) != 0) {
-            mp_raise_msg(&mp_type_OSError, "can't add Service");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Service"));
         }
     }
     return true;
@@ -386,7 +386,7 @@ bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
                                         &char_md,
                                         &attr_char_value,
                                         &handles) != 0) {
-        mp_raise_msg(&mp_type_OSError, "can't add Characteristic");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Characteristic"));
     }
 
     // apply handles to object instance
@@ -413,7 +413,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
         if (sd_ble_gap_device_name_set(&sec_mode,
                                        p_adv_params->p_device_name,
                                        p_adv_params->device_name_len) != 0) {
-            mp_raise_msg(&mp_type_OSError, "can't apply device name in the stack");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't apply device name in the stack"));
         }
 
         BLE_DRIVER_LOG("Device name applied\n");
@@ -476,12 +476,12 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
                 uuid.uuid += p_service->p_uuid->value[1] << 8;
                 // calculate total size of uuids
                 if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
-                    mp_raise_msg(&mp_type_OSError, "can't encode UUID, to check length");
+                    mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID, to check length"));
                 }
 
                 // do encoding into the adv buffer
                 if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
-                    mp_raise_msg(&mp_type_OSError, "can't encode UUID into advertisment packet");
+                    mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID into advertisment packet"));
                 }
 
                 BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
@@ -524,12 +524,12 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
 
                 // calculate total size of uuids
                 if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
-                    mp_raise_msg(&mp_type_OSError, "can't encode UUID, to check length");
+                    mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID, to check length"));
                 }
 
                 // do encoding into the adv buffer
                 if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
-                    mp_raise_msg(&mp_type_OSError, "can't encode UUID into advertisment packet");
+                    mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID into advertisment packet"));
                 }
 
                 BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
@@ -553,7 +553,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
 
     if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
         if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
-            mp_raise_msg(&mp_type_OSError, "can't fit data into advertisment packet");
+            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't fit data into advertisment packet"));
         }
 
         memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len);
diff --git a/ports/nrf/modules/board/led.c b/ports/nrf/modules/board/led.c
index a7efafa366..cbfc330d63 100644
--- a/ports/nrf/modules/board/led.c
+++ b/ports/nrf/modules/board/led.c
@@ -151,7 +151,7 @@ STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_
 
     // check led number
     if (!(1 <= led_id && led_id <= NUM_LEDS)) {
-        mp_raise_ValueError("LED doesn't exist");
+        mp_raise_ValueError(MP_ERROR_TEXT("LED doesn't exist"));
     }
 
     // return static led object
diff --git a/ports/nrf/modules/machine/adc.c b/ports/nrf/modules/machine/adc.c
index fc5305e524..5a02dfc274 100644
--- a/ports/nrf/modules/machine/adc.c
+++ b/ports/nrf/modules/machine/adc.c
@@ -101,7 +101,7 @@ STATIC int adc_find(mp_obj_t id) {
         if (pin->adc_num & PIN_ADC1) {
             adc_idx = pin->adc_channel;
         } else {
-            mp_raise_ValueError("invalid Pin for ADC");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for ADC"));
         }
     }
 
@@ -109,7 +109,7 @@ STATIC int adc_find(mp_obj_t id) {
         && machine_adc_obj[adc_idx].id != (uint8_t)-1) {
         return adc_idx;
     }
-    mp_raise_ValueError("ADC doesn't exist");
+    mp_raise_ValueError(MP_ERROR_TEXT("ADC doesn't exist"));
 }
 
 /// \method __str__()
diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c
index 6ec902a833..799d46a142 100644
--- a/ports/nrf/modules/machine/i2c.c
+++ b/ports/nrf/modules/machine/i2c.c
@@ -80,7 +80,7 @@ STATIC int i2c_find(mp_obj_t id) {
     if (i2c_id >= 0 && i2c_id < MP_ARRAY_SIZE(machine_hard_i2c_obj)) {
         return i2c_id;
     }
-    mp_raise_ValueError("I2C doesn't exist");
+    mp_raise_ValueError(MP_ERROR_TEXT("I2C doesn't exist"));
 }
 
 STATIC void machine_hard_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
diff --git a/ports/nrf/modules/machine/pin.c b/ports/nrf/modules/machine/pin.c
index 64e85778b3..938f609303 100644
--- a/ports/nrf/modules/machine/pin.c
+++ b/ports/nrf/modules/machine/pin.c
@@ -150,7 +150,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
         pin_obj = mp_call_function_1(MP_STATE_PORT(pin_class_mapper), user_obj);
         if (pin_obj != mp_const_none) {
             if (!mp_obj_is_type(pin_obj, &pin_type)) {
-                mp_raise_ValueError("Pin.mapper didn't return a Pin object");
+                mp_raise_ValueError(MP_ERROR_TEXT("Pin.mapper didn't return a Pin object"));
             }
             if (pin_class_debug) {
                 printf("Pin.mapper maps ");
@@ -207,7 +207,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
         return pin_obj;
     }
 
-    mp_raise_ValueError("not a valid pin identifier");
+    mp_raise_ValueError(MP_ERROR_TEXT("not a valid pin identifier"));
 }
 
 /// \method __str__()
@@ -375,7 +375,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
                      NRF_GPIO_PIN_S0S1,
                      NRF_GPIO_PIN_NOSENSE);
     } else {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode);
     }
 
     return mp_const_none;
diff --git a/ports/nrf/modules/machine/pwm.c b/ports/nrf/modules/machine/pwm.c
index 195d47e6b1..a5a3be89b6 100644
--- a/ports/nrf/modules/machine/pwm.c
+++ b/ports/nrf/modules/machine/pwm.c
@@ -97,7 +97,7 @@ STATIC int hard_pwm_find(mp_obj_t id) {
         if (pwm_id >= 0 && pwm_id < MP_ARRAY_SIZE(machine_hard_pwm_obj)) {
             return pwm_id;
         }
-        mp_raise_ValueError("PWM doesn't exist");
+        mp_raise_ValueError(MP_ERROR_TEXT("PWM doesn't exist"));
     }
     return -1;
 }
@@ -249,7 +249,7 @@ STATIC mp_obj_t machine_hard_pwm_make_new(mp_arg_val_t *args) {
     if (args[ARG_period].u_obj != MP_OBJ_NULL) {
         self->p_config->period = mp_obj_get_int(args[ARG_period].u_obj);
     } else {
-        mp_raise_ValueError("PWM period must be within 16000 cycles");
+        mp_raise_ValueError(MP_ERROR_TEXT("PWM period must be within 16000 cycles"));
     }
 
     if (args[ARG_duty].u_obj != MP_OBJ_NULL) {
diff --git a/ports/nrf/modules/machine/rtcounter.c b/ports/nrf/modules/machine/rtcounter.c
index d51791905c..c06bb86d53 100644
--- a/ports/nrf/modules/machine/rtcounter.c
+++ b/ports/nrf/modules/machine/rtcounter.c
@@ -116,7 +116,7 @@ STATIC int rtc_find(mp_obj_t id) {
     if (rtc_id >= 0 && rtc_id < MP_ARRAY_SIZE(machine_rtc_obj)) {
         return rtc_id;
     }
-    mp_raise_ValueError("RTCounter doesn't exist");
+    mp_raise_ValueError(MP_ERROR_TEXT("RTCounter doesn't exist"));
 }
 
 STATIC void rtc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -162,7 +162,7 @@ STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s
     } else if (mp_obj_is_fun(args[ARG_callback].u_obj)) {
         config->callback = args[ARG_callback].u_obj;
     } else {
-        mp_raise_ValueError("callback must be a function");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be a function"));
     }
 
     // Periodic or one-shot
diff --git a/ports/nrf/modules/machine/spi.c b/ports/nrf/modules/machine/spi.c
index 4361a8f8f9..2510c27502 100644
--- a/ports/nrf/modules/machine/spi.c
+++ b/ports/nrf/modules/machine/spi.c
@@ -140,14 +140,14 @@ STATIC int spi_find(mp_obj_t id) {
             return 1;
         #endif
         }
-        mp_raise_ValueError("SPI doesn't exist");
+        mp_raise_ValueError(MP_ERROR_TEXT("SPI doesn't exist"));
     } else {
         // given an integer id
         int spi_id = mp_obj_get_int(id);
         if (spi_id >= 0 && spi_id < MP_ARRAY_SIZE(machine_hard_spi_obj)) {
             return spi_id;
         }
-        mp_raise_ValueError("SPI doesn't exist");
+        mp_raise_ValueError(MP_ERROR_TEXT("SPI doesn't exist"));
     }
 }
 
@@ -415,7 +415,7 @@ STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp
     mp_buffer_info_t dest;
     mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
     if (src.len != dest.len) {
-        mp_raise_ValueError("buffers must be the same length");
+        mp_raise_ValueError(MP_ERROR_TEXT("buffers must be the same length"));
     }
     spi_transfer(self, src.len, src.buf, dest.buf);
     return mp_const_none;
diff --git a/ports/nrf/modules/machine/timer.c b/ports/nrf/modules/machine/timer.c
index 00a3591185..c99713ef52 100644
--- a/ports/nrf/modules/machine/timer.c
+++ b/ports/nrf/modules/machine/timer.c
@@ -77,7 +77,7 @@ STATIC int timer_find(mp_obj_t id) {
     if (timer_id >= 0 && timer_id < MP_ARRAY_SIZE(machine_timer_obj)) {
         return timer_id;
     }
-    mp_raise_ValueError("Timer doesn't exist");
+    mp_raise_ValueError(MP_ERROR_TEXT("Timer doesn't exist"));
 }
 
 STATIC void timer_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) {
@@ -114,13 +114,13 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
 
 #if BLUETOOTH_SD
     if (timer_id == 0) {
-        mp_raise_ValueError("Timer reserved by Bluetooth LE stack");
+        mp_raise_ValueError(MP_ERROR_TEXT("Timer reserved by Bluetooth LE stack"));
     }
 #endif
 
 #if MICROPY_PY_MACHINE_SOFT_PWM
     if (timer_id == 1) {
-        mp_raise_ValueError("Timer reserved by ticker driver");
+        mp_raise_ValueError(MP_ERROR_TEXT("Timer reserved by ticker driver"));
     }
 #endif
 
@@ -131,7 +131,7 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
     } else if (args[ARG_callback].u_obj == mp_const_none) {
         machine_timer_callbacks[timer_id] = NULL;
     } else {
-        mp_raise_ValueError("callback must be a function");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be a function"));
     }
 
     // Timer peripheral usage:
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c
index 5f7daa91e9..1ff95e90d3 100644
--- a/ports/nrf/modules/machine/uart.c
+++ b/ports/nrf/modules/machine/uart.c
@@ -118,7 +118,7 @@ STATIC int uart_find(mp_obj_t id) {
     if (uart_id >= 0 && uart_id < MP_ARRAY_SIZE(machine_hard_uart_obj)) {
         return uart_id;
     }
-    mp_raise_ValueError("UART doesn't exist");
+    mp_raise_ValueError(MP_ERROR_TEXT("UART doesn't exist"));
 }
 
 STATIC void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context) {
@@ -215,7 +215,7 @@ STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_a
 
     // These baudrates are not supported, it seems.
     if (args[ARG_baudrate].u_int < 1200 || args[ARG_baudrate].u_int > 1000000) {
-        mp_raise_ValueError("UART baudrate not supported");
+        mp_raise_ValueError(MP_ERROR_TEXT("UART baudrate not supported"));
     }
 
     // Magic: calculate 'baudrate' register from the input number.
diff --git a/ports/nrf/modules/music/modmusic.c b/ports/nrf/modules/music/modmusic.c
index 3730b3a72c..168e7613f5 100644
--- a/ports/nrf/modules/music/modmusic.c
+++ b/ports/nrf/modules/music/modmusic.c
@@ -284,7 +284,7 @@ STATIC mp_obj_t microbit_music_stop(mp_uint_t n_args, const mp_obj_t *args) {
 #ifdef MICROPY_HW_MUSIC_PIN
         pin = mp_hal_get_pin_obj(MP_OBJ_NEW_SMALL_INT(MICROPY_HW_MUSIC_PIN));
 #else
-        mp_raise_ValueError("pin parameter not given");
+        mp_raise_ValueError(MP_ERROR_TEXT("pin parameter not given"));
 #endif
     } else {
         pin = (pin_obj_t *)args[0];
@@ -337,7 +337,7 @@ STATIC mp_obj_t microbit_music_play(mp_uint_t n_args, const mp_obj_t *pos_args,
 #ifdef MICROPY_HW_MUSIC_PIN
         pin = mp_hal_get_pin_obj(MP_OBJ_NEW_SMALL_INT(MICROPY_HW_MUSIC_PIN));
 #else
-        mp_raise_ValueError("pin parameter not given");
+        mp_raise_ValueError(MP_ERROR_TEXT("pin parameter not given"));
 #endif
     } else {
         pin = (pin_obj_t *)args[1].u_obj;
@@ -392,7 +392,7 @@ STATIC mp_obj_t microbit_music_pitch(mp_uint_t n_args, const mp_obj_t *pos_args,
 #ifdef MICROPY_HW_MUSIC_PIN
         pin = mp_hal_get_pin_obj(MP_OBJ_NEW_SMALL_INT(MICROPY_HW_MUSIC_PIN));
 #else
-        mp_raise_ValueError("pin parameter not given");
+        mp_raise_ValueError(MP_ERROR_TEXT("pin parameter not given"));
 #endif
     } else {
         pin = (pin_obj_t *)args[2].u_obj;
@@ -408,7 +408,7 @@ STATIC mp_obj_t microbit_music_pitch(mp_uint_t n_args, const mp_obj_t *pos_args,
 //TODO: pwm_release(pin->name);
     } else if (pwm_set_period_us(1000000/frequency)) {
         pwm_release(pin->pin); // TODO: remove pin setting.
-        mp_raise_ValueError("invalid pitch");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid pitch"));
     }
     if (duration >= 0) {
         // use async machinery to stop the pitch after the duration
diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
index 2ca7f2f427..9adafaa64e 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c
@@ -63,7 +63,7 @@ STATIC mp_obj_t ubluepy_characteristic_make_new(const mp_obj_type_t *type, size_
         s->p_uuid = MP_OBJ_TO_PTR(uuid_obj);
         // (void)sd_characterstic_add(s);
     } else {
-        mp_raise_ValueError("Invalid UUID parameter");
+        mp_raise_ValueError(MP_ERROR_TEXT("Invalid UUID parameter"));
     }
 
     if (args[1].u_int > 0) {
diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c
index a38136611f..7b51ce3055 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_service.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_service.c
@@ -68,13 +68,13 @@ STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_arg
         if (type > 0 &&  type <= UBLUEPY_SERVICE_PRIMARY) {
             s->type = type;
         } else {
-            mp_raise_ValueError("Invalid Service type");
+            mp_raise_ValueError(MP_ERROR_TEXT("Invalid Service type"));
         }
 
         (void)ble_drv_service_add(s);
 
     } else {
-        mp_raise_ValueError("Invalid UUID parameter");
+        mp_raise_ValueError(MP_ERROR_TEXT("Invalid UUID parameter"));
     }
 
     // clear reference to peripheral
@@ -125,7 +125,7 @@ STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) {
 
     // validate that there is an UUID object passed in as parameter
     if (!(mp_obj_is_type(uuid, &ubluepy_uuid_type))) {
-        mp_raise_ValueError("Invalid UUID parameter");
+        mp_raise_ValueError(MP_ERROR_TEXT("Invalid UUID parameter"));
     }
 
     mp_obj_t * chars     = NULL;
diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c
index cbcb100968..7b4a09dba4 100644
--- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c
+++ b/ports/nrf/modules/ubluepy/ubluepy_uuid.c
@@ -122,7 +122,7 @@ STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args,
 
             ble_drv_uuid_add_vs(buffer, &s->uuid_vs_idx);
         } else {
-            mp_raise_ValueError("Invalid UUID string length");
+            mp_raise_ValueError(MP_ERROR_TEXT("Invalid UUID string length"));
         }
     } else if (mp_obj_is_type(uuid_obj, &ubluepy_uuid_type)) {
         // deep copy instance
@@ -131,7 +131,7 @@ STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args,
         s->value[0] = p_old->value[0];
         s->value[1] = p_old->value[1];
     } else {
-        mp_raise_ValueError("Invalid UUID parameter");
+        mp_raise_ValueError(MP_ERROR_TEXT("Invalid UUID parameter"));
     }
 
     return MP_OBJ_FROM_PTR(s);
diff --git a/ports/nrf/modules/uos/microbitfs.c b/ports/nrf/modules/uos/microbitfs.c
index 776358ea35..7f16372cf2 100644
--- a/ports/nrf/modules/uos/microbitfs.c
+++ b/ports/nrf/modules/uos/microbitfs.c
@@ -389,7 +389,7 @@ STATIC mp_obj_t microbit_remove(mp_obj_t filename) {
 
 STATIC void check_file_open(file_descriptor_obj *self) {
     if (!self->open) {
-        mp_raise_ValueError("I/O operation on closed file");
+        mp_raise_ValueError(MP_ERROR_TEXT("I/O operation on closed file"));
     }
 }
 
@@ -685,7 +685,7 @@ mp_obj_t uos_mbfs_open(size_t n_args, const mp_obj_t *args) {
     }
     return res;
 mode_error:
-    mp_raise_ValueError("illegal mode");
+    mp_raise_ValueError(MP_ERROR_TEXT("illegal mode"));
 }
 
 STATIC mp_obj_t uos_mbfs_stat(mp_obj_t filename) {
diff --git a/ports/nrf/modules/uos/moduos.c b/ports/nrf/modules/uos/moduos.c
index 64119b371b..3bd4119328 100644
--- a/ports/nrf/modules/uos/moduos.c
+++ b/ports/nrf/modules/uos/moduos.c
@@ -128,7 +128,7 @@ STATIC mp_obj_t os_dupterm(mp_uint_t n_args, const mp_obj_t *args) {
         } else if (mp_obj_get_type(args[0]) == &machine_hard_uart_type) {
             MP_STATE_PORT(board_stdio_uart) = args[0];
         } else {
-            mp_raise_ValueError("need a UART object");
+            mp_raise_ValueError(MP_ERROR_TEXT("need a UART object"));
         }
         return mp_const_none;
     }
diff --git a/ports/pic16bit/modpybled.c b/ports/pic16bit/modpybled.c
index eb34865f2d..6adb2fda31 100644
--- a/ports/pic16bit/modpybled.c
+++ b/ports/pic16bit/modpybled.c
@@ -50,7 +50,7 @@ STATIC mp_obj_t pyb_led_make_new(const mp_obj_type_t *type, size_t n_args, size_
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
     mp_int_t led_id = mp_obj_get_int(args[0]);
     if (!(1 <= led_id && led_id <= NUM_LED)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("LED %d does not exist"), led_id);
     }
     return (mp_obj_t)&pyb_led_obj[led_id - 1];
 }
diff --git a/ports/pic16bit/modpybswitch.c b/ports/pic16bit/modpybswitch.c
index 924cce6ef0..7b3d0f5f52 100644
--- a/ports/pic16bit/modpybswitch.c
+++ b/ports/pic16bit/modpybswitch.c
@@ -49,7 +49,7 @@ STATIC mp_obj_t pyb_switch_make_new(const mp_obj_type_t *type, size_t n_args, si
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
     mp_int_t sw_id = mp_obj_get_int(args[0]);
     if (!(1 <= sw_id && sw_id <= NUM_SWITCH)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Switch %d does not exist", sw_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Switch %d does not exist"), sw_id);
     }
     return (mp_obj_t)&pyb_switch_obj[sw_id - 1];
 }
diff --git a/ports/stm32/accel.c b/ports/stm32/accel.c
index baf11126d6..b07791a9a0 100644
--- a/ports/stm32/accel.c
+++ b/ports/stm32/accel.c
@@ -110,7 +110,7 @@ STATIC void accel_start(void) {
     }
 
     if (ret != 0) {
-        mp_raise_msg(&mp_type_OSError, "accelerometer not found");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("accelerometer not found"));
     }
 
     // set MMA to active mode
@@ -127,7 +127,7 @@ STATIC void accel_start(void) {
     i2c_writeto(I2C1, ACCEL_ADDR, data, 1, false);
     i2c_readfrom(I2C1, ACCEL_ADDR, data, 1, true);
     if (data[0] != 0x35) {
-        mp_raise_msg(&mp_type_OSError, "accelerometer not found");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("accelerometer not found"));
     }
 
     // set operating mode (default: 8 bits, range +/-8G)
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 85e26eeada..1ecd06bca3 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -305,7 +305,7 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
     ADC_MultiModeTypeDef multimode;
     multimode.Mode = ADC_MODE_INDEPENDENT;
     if (HAL_ADCEx_MultiModeConfigChannel(&adc_obj->handle, &multimode) != HAL_OK) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Can not set multimode on ADC1 channel: %d", adc_obj->channel);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Can not set multimode on ADC1 channel: %d"), adc_obj->channel);
     }
     #endif
 }
@@ -413,20 +413,20 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
         const pin_obj_t *pin = pin_find(pin_obj);
         if ((pin->adc_num & PIN_ADC_MASK) == 0) {
             // No ADC1 function on that pin
-            mp_raise_msg_varg(&mp_type_ValueError, "pin %q does not have ADC capabilities", pin->name);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("pin %q does not have ADC capabilities"), pin->name);
         }
         channel = pin->adc_channel;
     }
 
     if (!is_adcx_channel(channel)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("not a valid ADC Channel: %d"), channel);
     }
 
 
     if (ADC_FIRST_GPIO_CHANNEL <= channel && channel <= ADC_LAST_GPIO_CHANNEL) {
         // these channels correspond to physical GPIO ports so make sure they exist
         if (pin_adc_table[channel] == NULL) {
-            mp_raise_msg_varg(&mp_type_ValueError, "channel %d not available on this board", channel);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("channel %d not available on this board"), channel);
         }
     }
 
@@ -572,10 +572,10 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
     mp_obj_get_array(buf_array_in, &nbufs, &buf_array);
 
     if (nadcs < 1) {
-        mp_raise_ValueError("need at least 1 ADC");
+        mp_raise_ValueError(MP_ERROR_TEXT("need at least 1 ADC"));
     }
     if (nadcs != nbufs) {
-        mp_raise_ValueError("length of ADC and buffer lists differ");
+        mp_raise_ValueError(MP_ERROR_TEXT("length of ADC and buffer lists differ"));
     }
 
     // Get buf for first ADC, get word size, check other buffers match in type
@@ -587,7 +587,7 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
         mp_buffer_info_t bufinfo_curr;
         mp_get_buffer_raise(buf_array[array_index], &bufinfo_curr, MP_BUFFER_WRITE);
         if ((bufinfo.len != bufinfo_curr.len) || (bufinfo.typecode != bufinfo_curr.typecode)) {
-            mp_raise_ValueError("size and type of buffers must match");
+            mp_raise_ValueError(MP_ERROR_TEXT("size and type of buffers must match"));
         }
         bufptrs[array_index] = bufinfo_curr.buf;
     }
@@ -708,7 +708,7 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
             break;
         #endif
         default:
-            mp_raise_msg_varg(&mp_type_ValueError, "resolution %d not supported", resolution);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("resolution %d not supported"), resolution);
     }
 
     for (uint32_t channel = ADC_FIRST_GPIO_CHANNEL; channel <= ADC_LAST_GPIO_CHANNEL; ++channel) {
diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c
index c5c6172f09..fe3aecdde8 100644
--- a/ports/stm32/dac.c
+++ b/ports/stm32/dac.c
@@ -118,7 +118,7 @@ STATIC uint32_t TIMx_Config(mp_obj_t timer) {
         return DAC_TRIGGER_T8_TRGO;
     #endif
     } else {
-        mp_raise_ValueError("Timer does not support DAC triggering");
+        mp_raise_ValueError(MP_ERROR_TEXT("Timer does not support DAC triggering"));
     }
 }
 
@@ -265,7 +265,7 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp
     if (args[0].u_int == 8 || args[0].u_int == 12) {
         self->bits = args[0].u_int;
     } else {
-        mp_raise_ValueError("unsupported bits");
+        mp_raise_ValueError(MP_ERROR_TEXT("unsupported bits"));
     }
 
     // set output buffer config
@@ -307,7 +307,7 @@ STATIC mp_obj_t pyb_dac_make_new(const mp_obj_type_t *type, size_t n_args, size_
         } else if (pin == pin_A5) {
             dac_id = 2;
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "Pin(%q) doesn't have DAC capabilities", pin->name);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%q) doesn't have DAC capabilities"), pin->name);
         }
     }
 
@@ -319,7 +319,7 @@ STATIC mp_obj_t pyb_dac_make_new(const mp_obj_type_t *type, size_t n_args, size_
         dac_channel = DAC_CHANNEL_2;
     #endif
     } else {
-        mp_raise_msg_varg(&mp_type_ValueError, "DAC(%d) doesn't exist", dac_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("DAC(%d) doesn't exist"), dac_id);
     }
 
     pyb_dac_obj_t *dac = &pyb_dac_obj[dac_id - 1];
diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c
index 6c186f54e7..695655f09f 100644
--- a/ports/stm32/extint.c
+++ b/ports/stm32/extint.c
@@ -207,10 +207,10 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca
         // get both the port number and line number.
         v_line = mp_obj_get_int(pin_obj);
         if (v_line < 16) {
-            mp_raise_msg_varg(&mp_type_ValueError, "ExtInt vector %d < 16, use a Pin object", v_line);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("ExtInt vector %d < 16, use a Pin object"), v_line);
         }
         if (v_line >= EXTI_NUM_VECTORS) {
-            mp_raise_msg_varg(&mp_type_ValueError, "ExtInt vector %d >= max of %d", v_line, EXTI_NUM_VECTORS);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("ExtInt vector %d >= max of %d"), v_line, EXTI_NUM_VECTORS);
         }
     } else {
         pin = pin_find(pin_obj);
@@ -222,17 +222,17 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca
         mode != GPIO_MODE_EVT_RISING &&
         mode != GPIO_MODE_EVT_FALLING &&
         mode != GPIO_MODE_EVT_RISING_FALLING) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid ExtInt Mode: %d", mode);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid ExtInt Mode: %d"), mode);
     }
     if (pull != GPIO_NOPULL &&
         pull != GPIO_PULLUP &&
         pull != GPIO_PULLDOWN) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid ExtInt Pull: %d", pull);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid ExtInt Pull: %d"), pull);
     }
 
     mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[v_line];
     if (!override_callback_obj && *cb != mp_const_none && callback_obj != mp_const_none) {
-        mp_raise_msg_varg(&mp_type_ValueError, "ExtInt vector %d is already in use", v_line);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("ExtInt vector %d is already in use"), v_line);
     }
 
     // We need to update callback atomically, so we disable the line
@@ -279,11 +279,11 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
     mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line];
     if (*cb != mp_const_none && MP_OBJ_FROM_PTR(pin) != pyb_extint_callback_arg[line]) {
         if (mp_obj_is_small_int(pyb_extint_callback_arg[line])) {
-            mp_raise_msg_varg(&mp_type_OSError, "ExtInt vector %d is already in use", line);
+            mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("ExtInt vector %d is already in use"), line);
         } else {
             const pin_obj_t *other_pin = MP_OBJ_TO_PTR(pyb_extint_callback_arg[line]);
             mp_raise_msg_varg(&mp_type_OSError,
-                "IRQ resource already taken by Pin('%q')", other_pin->name);
+                MP_ERROR_TEXT("IRQ resource already taken by Pin('%q')"), other_pin->name);
         }
     }
 
diff --git a/ports/stm32/lcd.c b/ports/stm32/lcd.c
index 85bcc28699..bfc9a0a5fd 100644
--- a/ports/stm32/lcd.c
+++ b/ports/stm32/lcd.c
@@ -218,7 +218,7 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, size_t n_args, size_
         lcd->pin_a0 = pyb_pin_Y5;
         lcd->pin_bl = pyb_pin_Y12;
     } else {
-        mp_raise_msg_varg(&mp_type_ValueError, "LCD(%s) doesn't exist", lcd_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("LCD(%s) doesn't exist"), lcd_id);
     }
 
     // init the SPI bus
diff --git a/ports/stm32/led.c b/ports/stm32/led.c
index d04557f85a..341ce71411 100644
--- a/ports/stm32/led.c
+++ b/ports/stm32/led.c
@@ -304,7 +304,7 @@ STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_
 
     // check led number
     if (!(1 <= led_id && led_id <= NUM_LEDS)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "LED(%d) doesn't exist", led_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("LED(%d) doesn't exist"), led_id);
     }
 
     // return static led object
diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c
index 71ee537349..5ba000a233 100644
--- a/ports/stm32/machine_adc.c
+++ b/ports/stm32/machine_adc.c
@@ -403,7 +403,7 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
         #endif
         } else {
             // No ADC function on given pin
-            mp_raise_msg_varg(&mp_type_ValueError, "Pin(%q) does not have ADC capabilities", pin->name);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%q) does not have ADC capabilities"), pin->name);
         }
         channel = pin->adc_channel;
 
diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c
index 1c703b1bfb..14dd88b78f 100644
--- a/ports/stm32/machine_i2c.c
+++ b/ports/stm32/machine_i2c.c
@@ -231,13 +231,13 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
             i2c_id = 4;
         #endif
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "I2C(%s) doesn't exist", port);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%s) doesn't exist"), port);
         }
     } else {
         i2c_id = mp_obj_get_int(args[ARG_id].u_obj);
         if (i2c_id < 1 || i2c_id > MP_ARRAY_SIZE(machine_hard_i2c_obj)
             || machine_hard_i2c_obj[i2c_id - 1].base.type == NULL) {
-            mp_raise_msg_varg(&mp_type_ValueError, "I2C(%d) doesn't exist", i2c_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
         }
     }
 
@@ -246,7 +246,7 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
 
     // here we would check the scl/sda pins and configure them, but it's not implemented
     if (args[ARG_scl].u_obj != MP_OBJ_NULL || args[ARG_sda].u_obj != MP_OBJ_NULL) {
-        mp_raise_ValueError("explicit choice of scl/sda is not implemented");
+        mp_raise_ValueError(MP_ERROR_TEXT("explicit choice of scl/sda is not implemented"));
     }
 
     // initialise the I2C peripheral
diff --git a/ports/stm32/machine_spi.c b/ports/stm32/machine_spi.c
index d012d70a08..cf6e96ab67 100644
--- a/ports/stm32/machine_spi.c
+++ b/ports/stm32/machine_spi.c
@@ -69,7 +69,7 @@ mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
     if (args[ARG_sck].u_obj != MP_OBJ_NULL
         || args[ARG_mosi].u_obj != MP_OBJ_NULL
         || args[ARG_miso].u_obj != MP_OBJ_NULL) {
-        mp_raise_ValueError("explicit choice of sck/mosi/miso is not implemented");
+        mp_raise_ValueError(MP_ERROR_TEXT("explicit choice of sck/mosi/miso is not implemented"));
     }
 
     // set the SPI configuration values
diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c
index daaf51b8c0..daf84caa49 100644
--- a/ports/stm32/machine_timer.c
+++ b/ports/stm32/machine_timer.c
@@ -87,7 +87,7 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
         ++args;
     }
     if (id != -1) {
-        mp_raise_ValueError("Timer doesn't exist");
+        mp_raise_ValueError(MP_ERROR_TEXT("Timer doesn't exist"));
     }
 
     if (n_args > 0 || n_kw > 0) {
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index f9fa321f21..232f3629ee 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -239,7 +239,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
 
     // static UARTs are used for internal purposes and shouldn't be reconfigured
     if (self->is_static) {
-        mp_raise_ValueError("UART is static and can't be init'd");
+        mp_raise_ValueError(MP_ERROR_TEXT("UART is static and can't be init'd"));
     }
 
     // baudrate
@@ -266,7 +266,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
         bits = UART_WORDLENGTH_7B;
     #endif
     } else {
-        mp_raise_ValueError("unsupported combination of bits and parity");
+        mp_raise_ValueError(MP_ERROR_TEXT("unsupported combination of bits and parity"));
     }
 
     // stop bits
@@ -285,7 +285,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
 
     // init UART (if it fails, it's because the port doesn't exist)
     if (!uart_init(self, baudrate, bits, parity, stop, flow)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "UART(%d) doesn't exist", self->uart_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), self->uart_id);
     }
 
     // set timeout
@@ -327,7 +327,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
         baudrate_diff = baudrate - actual_baudrate;
     }
     if (20 * baudrate_diff > actual_baudrate) {
-        mp_raise_msg_varg(&mp_type_ValueError, "set baudrate %d is not within 5%% of desired value", actual_baudrate);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("set baudrate %d is not within 5%% of desired value"), actual_baudrate);
     }
 
     return mp_const_none;
@@ -398,12 +398,12 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
             uart_id = PYB_UART_10;
         #endif
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "UART(%s) doesn't exist", port);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%s) doesn't exist"), port);
         }
     } else {
         uart_id = mp_obj_get_int(args[0]);
         if (!uart_exists(uart_id)) {
-            mp_raise_msg_varg(&mp_type_ValueError, "UART(%d) doesn't exist", uart_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), uart_id);
         }
     }
 
@@ -517,14 +517,14 @@ STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
         // Check the handler
         mp_obj_t handler = args[MP_IRQ_ARG_INIT_handler].u_obj;
         if (handler != mp_const_none && !mp_obj_is_callable(handler)) {
-            mp_raise_ValueError("handler must be None or callable");
+            mp_raise_ValueError(MP_ERROR_TEXT("handler must be None or callable"));
         }
 
         // Check the trigger
         mp_uint_t trigger = args[MP_IRQ_ARG_INIT_trigger].u_int;
         mp_uint_t not_supported = trigger & ~mp_irq_allowed;
         if (trigger != 0 && not_supported) {
-            mp_raise_msg_varg(&mp_type_ValueError, "trigger 0x%08x unsupported", not_supported);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("trigger 0x%08x unsupported"), not_supported);
         }
 
         // Reconfigure user IRQs
diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c
index 35b87e7099..6ea6c9afa3 100644
--- a/ports/stm32/modmachine.c
+++ b/ports/stm32/modmachine.c
@@ -308,7 +308,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
     } else {
         // set
         #if defined(STM32F0) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
-        mp_raise_NotImplementedError("machine.freq set not supported yet");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("machine.freq set not supported yet"));
         #else
         mp_int_t sysclk = mp_obj_get_int(args[0]);
         mp_int_t ahb = sysclk;
@@ -330,7 +330,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
         }
         int ret = powerctrl_set_sysclk(sysclk, ahb, apb1, apb2);
         if (ret == -MP_EINVAL) {
-            mp_raise_ValueError("invalid freq");
+            mp_raise_ValueError(MP_ERROR_TEXT("invalid freq"));
         } else if (ret < 0) {
             void NORETURN __fatal_error(const char *msg);
             __fatal_error("can't change freq");
diff --git a/ports/stm32/modnetwork.c b/ports/stm32/modnetwork.c
index 4419bf4768..5885082865 100644
--- a/ports/stm32/modnetwork.c
+++ b/ports/stm32/modnetwork.c
@@ -114,7 +114,7 @@ mp_obj_t mod_network_find_nic(const uint8_t *ip) {
         return nic;
     }
 
-    mp_raise_msg(&mp_type_OSError, "no available NIC");
+    mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("no available NIC"));
 }
 
 STATIC mp_obj_t network_route(void) {
@@ -184,7 +184,7 @@ mp_obj_t mod_network_nic_ifconfig(struct netif *netif, size_t n_args, const mp_o
         uint32_t start = mp_hal_ticks_ms();
         while (!dhcp_supplied_address(netif)) {
             if (mp_hal_ticks_ms() - start > 10000) {
-                mp_raise_msg(&mp_type_OSError, "timeout waiting for DHCP to get IP address");
+                mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("timeout waiting for DHCP to get IP address"));
             }
             mp_hal_delay_ms(100);
         }
diff --git a/ports/stm32/modnwcc3k.c b/ports/stm32/modnwcc3k.c
index 92e680ef72..0ff3b2d289 100644
--- a/ports/stm32/modnwcc3k.c
+++ b/ports/stm32/modnwcc3k.c
@@ -451,7 +451,7 @@ STATIC mp_obj_t cc3k_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
         ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin);
 
     if (wlan_start(0) != 0) {
-        mp_raise_msg(&mp_type_OSError, "failed to init CC3000 module");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to init CC3000 module"));
     }
 
     // set connection policy. this should be called explicitly by the user
@@ -503,7 +503,7 @@ STATIC mp_obj_t cc3k_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
 
     // connect to AP
     if (wlan_connect(sec, (char *)ssid, ssid_len, (uint8_t *)bssid, (uint8_t *)key, key_len) != 0) {
-        mp_raise_msg_varg(&mp_type_OSError, "could not connect to ssid=%s, sec=%d, key=%s\n", ssid, sec, key);
+        mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("could not connect to ssid=%s, sec=%d, key=%s\n"), ssid, sec, key);
     }
 
     return mp_const_none;
diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c
index dd24798af9..321fb62e9a 100644
--- a/ports/stm32/modpyb.c
+++ b/ports/stm32/modpyb.c
@@ -107,7 +107,7 @@ STATIC mp_obj_t pyb_repl_uart(size_t n_args, const mp_obj_t *args) {
             MP_STATE_PORT(pyb_stdio_uart) = MP_OBJ_TO_PTR(args[0]);
             uart_attach_to_repl(MP_STATE_PORT(pyb_stdio_uart), true);
         } else {
-            mp_raise_ValueError("need a UART object");
+            mp_raise_ValueError(MP_ERROR_TEXT("need a UART object"));
         }
         return mp_const_none;
     }
diff --git a/ports/stm32/modusocket.c b/ports/stm32/modusocket.c
index b7cb3371c0..f9de017e0b 100644
--- a/ports/stm32/modusocket.c
+++ b/ports/stm32/modusocket.c
@@ -432,7 +432,7 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
     }
 
     if (!have_ip) {
-        mp_raise_msg(&mp_type_OSError, "no available NIC");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("no available NIC"));
     }
 
     mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
diff --git a/ports/stm32/modutime.c b/ports/stm32/modutime.c
index 54758debaf..77ec7468c9 100644
--- a/ports/stm32/modutime.c
+++ b/ports/stm32/modutime.c
@@ -106,7 +106,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
 
     // localtime generates a tuple of len 8. CPython uses 9, so we accept both.
     if (len < 8 || len > 9) {
-        mp_raise_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len);
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9 (%d given)"), len);
     }
 
     return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
diff --git a/ports/stm32/mpthreadport.c b/ports/stm32/mpthreadport.c
index 48c2c3bf54..ecdb268468 100644
--- a/ports/stm32/mpthreadport.c
+++ b/ports/stm32/mpthreadport.c
@@ -75,7 +75,7 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
     uint32_t id = pyb_thread_new(th, stack, stack_len, entry, arg);
     if (id == 0) {
         mp_thread_mutex_unlock(&thread_mutex);
-        mp_raise_msg(&mp_type_OSError, "can't create thread");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't create thread"));
     }
 
     mp_thread_mutex_unlock(&thread_mutex);
diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c
index 8b2104a4de..19b4e786d9 100644
--- a/ports/stm32/network_lan.c
+++ b/ports/stm32/network_lan.c
@@ -100,7 +100,7 @@ STATIC mp_obj_t network_lan_status(size_t n_args, const mp_obj_t *args) {
         return MP_OBJ_NEW_SMALL_INT(eth_link_status(self->eth));
     }
 
-    mp_raise_ValueError("unknown status param");
+    mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_lan_status_obj, 1, 2, network_lan_status);
 
@@ -110,7 +110,7 @@ STATIC mp_obj_t network_lan_config(size_t n_args, const mp_obj_t *args, mp_map_t
     if (kwargs->used == 0) {
         // Get config value
         if (n_args != 2) {
-            mp_raise_TypeError("must query one param");
+            mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
         }
 
         switch (mp_obj_str_get_qstr(args[1])) {
@@ -118,12 +118,12 @@ STATIC mp_obj_t network_lan_config(size_t n_args, const mp_obj_t *args, mp_map_t
                 return mp_obj_new_bytes(&eth_netif(self->eth)->hwaddr[0], 6);
             }
             default:
-                mp_raise_ValueError("unknown config param");
+                mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
         }
     } else {
         // Set config value(s)
         if (n_args != 1) {
-            mp_raise_TypeError("can't specify pos and kw args");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
         }
 
         for (size_t i = 0; i < kwargs->alloc; ++i) {
@@ -135,7 +135,7 @@ STATIC mp_obj_t network_lan_config(size_t n_args, const mp_obj_t *args, mp_map_t
                         break;
                     }
                     default:
-                        mp_raise_ValueError("unknown config param");
+                        mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
                 }
             }
         }
diff --git a/ports/stm32/network_wiznet5k.c b/ports/stm32/network_wiznet5k.c
index f57f6a845d..c85ef5e88e 100644
--- a/ports/stm32/network_wiznet5k.c
+++ b/ports/stm32/network_wiznet5k.c
@@ -377,7 +377,7 @@ STATIC mp_obj_t wiznet5k_status(size_t n_args, const mp_obj_t *args) {
         }
     }
 
-    mp_raise_ValueError("unknown config param");
+    mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_status_obj, 1, 2, wiznet5k_status);
 
@@ -387,7 +387,7 @@ STATIC mp_obj_t wiznet5k_config(size_t n_args, const mp_obj_t *args, mp_map_t *k
     if (kwargs->used == 0) {
         // Get config value
         if (n_args != 2) {
-            mp_raise_TypeError("must query one param");
+            mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
         }
 
         switch (mp_obj_str_get_qstr(args[1])) {
@@ -397,12 +397,12 @@ STATIC mp_obj_t wiznet5k_config(size_t n_args, const mp_obj_t *args, mp_map_t *k
                 return mp_obj_new_bytes(buf, 6);
             }
             default:
-                mp_raise_ValueError("unknown config param");
+                mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
         }
     } else {
         // Set config value(s)
         if (n_args != 1) {
-            mp_raise_TypeError("can't specify pos and kw args");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
         }
 
         for (size_t i = 0; i < kwargs->alloc; ++i) {
@@ -424,7 +424,7 @@ STATIC mp_obj_t wiznet5k_config(size_t n_args, const mp_obj_t *args, mp_map_t *k
                         break;
                     }
                     default:
-                        mp_raise_ValueError("unknown config param");
+                        mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
                 }
             }
         }
diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c
index 2a2228fc04..f1c5eee850 100644
--- a/ports/stm32/pin.c
+++ b/ports/stm32/pin.c
@@ -119,7 +119,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
         mp_obj_t o = mp_call_function_1(MP_STATE_PORT(pin_class_mapper), user_obj);
         if (o != mp_const_none) {
             if (!mp_obj_is_type(o, &pin_type)) {
-                mp_raise_ValueError("Pin.mapper didn't return a Pin object");
+                mp_raise_ValueError(MP_ERROR_TEXT("Pin.mapper didn't return a Pin object"));
             }
             if (pin_class_debug) {
                 printf("Pin.mapper maps ");
@@ -176,7 +176,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
         return pin_obj;
     }
 
-    mp_raise_msg_varg(&mp_type_ValueError, "Pin(%s) doesn't exist", mp_obj_str_get_str(user_obj));
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%s) doesn't exist"), mp_obj_str_get_str(user_obj));
 }
 
 /// \method __str__()
@@ -342,7 +342,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, size_t n_args, const
     // get io mode
     uint mode = args[0].u_int;
     if (!IS_GPIO_MODE(mode)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode);
     }
 
     // get pull mode
@@ -351,7 +351,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, size_t n_args, const
         pull = mp_obj_get_int(args[1].u_obj);
     }
     if (!IS_GPIO_PULL(pull)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin pull: %d"), pull);
     }
 
     // get af (alternate function); alt-arg overrides af-arg
@@ -360,7 +360,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, size_t n_args, const
         af = args[2].u_int;
     }
     if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid pin af: %d", af);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin af: %d"), af);
     }
 
     // enable the peripheral clock for the port of this pin
diff --git a/ports/stm32/pyb_can.c b/ports/stm32/pyb_can.c
index ecba2b49bd..bb0d6754d0 100644
--- a/ports/stm32/pyb_can.c
+++ b/ports/stm32/pyb_can.c
@@ -165,7 +165,7 @@ STATIC mp_obj_t pyb_can_init_helper(pyb_can_obj_t *self, size_t n_args, const mp
     // init CAN (if it fails, it's because the port doesn't exist)
     if (!can_init(self, args[ARG_mode].u_int, args[ARG_prescaler].u_int, args[ARG_sjw].u_int,
         args[ARG_bs1].u_int, args[ARG_bs2].u_int, args[ARG_auto_restart].u_bool)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", self->can_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%d) doesn't exist"), self->can_id);
     }
 
     return mp_const_none;
@@ -194,13 +194,13 @@ STATIC mp_obj_t pyb_can_make_new(const mp_obj_type_t *type, size_t n_args, size_
             can_idx = PYB_CAN_3;
         #endif
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "CAN(%s) doesn't exist", port);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%s) doesn't exist"), port);
         }
     } else {
         can_idx = mp_obj_get_int(args[0]);
     }
     if (can_idx < 1 || can_idx > MP_ARRAY_SIZE(MP_STATE_PORT(pyb_can_obj_all))) {
-        mp_raise_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%d) doesn't exist"), can_idx);
     }
 
     pyb_can_obj_t *self;
@@ -381,7 +381,7 @@ STATIC mp_obj_t pyb_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
     pyb_buf_get_for_send(args[ARG_data].u_obj, &bufinfo, data);
 
     if (bufinfo.len > 8) {
-        mp_raise_ValueError("CAN data field too long");
+        mp_raise_ValueError(MP_ERROR_TEXT("CAN data field too long"));
     }
 
     // send the data
@@ -752,7 +752,7 @@ STATIC mp_obj_t pyb_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_ma
 
     return mp_const_none;
 error:
-    mp_raise_ValueError("CAN filter parameter error");
+    mp_raise_ValueError(MP_ERROR_TEXT("CAN filter parameter error"));
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_can_setfilter_obj, 1, pyb_can_setfilter);
 
diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c
index 09e5328cf2..2dbcea2d12 100644
--- a/ports/stm32/pyb_i2c.c
+++ b/ports/stm32/pyb_i2c.c
@@ -200,7 +200,7 @@ STATIC void i2c_set_baudrate(I2C_InitTypeDef *init, uint32_t baudrate) {
             return;
         }
     }
-    mp_raise_msg_varg(&mp_type_ValueError, "Unsupported I2C baudrate: %u", baudrate);
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Unsupported I2C baudrate: %u"), baudrate);
 }
 
 uint32_t pyb_i2c_get_baudrate(I2C_HandleTypeDef *i2c) {
@@ -690,13 +690,13 @@ STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_
             i2c_id = 4;
         #endif
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "I2C(%s) doesn't exist", port);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%s) doesn't exist"), port);
         }
     } else {
         i2c_id = mp_obj_get_int(args[0]);
         if (i2c_id < 1 || i2c_id > MP_ARRAY_SIZE(pyb_i2c_obj)
             || pyb_i2c_obj[i2c_id - 1].i2c == NULL) {
-            mp_raise_msg_varg(&mp_type_ValueError, "I2C(%d) doesn't exist", i2c_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
         }
     }
 
@@ -733,7 +733,7 @@ STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) {
     pyb_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
     if (!in_master_mode(self)) {
-        mp_raise_TypeError("I2C must be a master");
+        mp_raise_TypeError(MP_ERROR_TEXT("I2C must be a master"));
     }
 
     mp_uint_t i2c_addr = mp_obj_get_int(i2c_addr_o) << 1;
@@ -756,7 +756,7 @@ STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
     pyb_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
     if (!in_master_mode(self)) {
-        mp_raise_TypeError("I2C must be a master");
+        mp_raise_TypeError(MP_ERROR_TEXT("I2C must be a master"));
     }
 
     mp_obj_t list = mp_obj_new_list(0, NULL);
@@ -814,7 +814,7 @@ STATIC mp_obj_t pyb_i2c_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
             if (use_dma) {
                 dma_deinit(self->tx_dma_descr);
             }
-            mp_raise_TypeError("addr argument required");
+            mp_raise_TypeError(MP_ERROR_TEXT("addr argument required"));
         }
         mp_uint_t i2c_addr = args[1].u_int << 1;
         if (!use_dma) {
@@ -890,7 +890,7 @@ STATIC mp_obj_t pyb_i2c_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
     HAL_StatusTypeDef status;
     if (in_master_mode(self)) {
         if (args[1].u_int == PYB_I2C_MASTER_ADDRESS) {
-            mp_raise_TypeError("addr argument required");
+            mp_raise_TypeError(MP_ERROR_TEXT("addr argument required"));
         }
         mp_uint_t i2c_addr = args[1].u_int << 1;
         if (!use_dma) {
@@ -957,7 +957,7 @@ STATIC mp_obj_t pyb_i2c_mem_read(size_t n_args, const mp_obj_t *pos_args, mp_map
     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args), pyb_i2c_mem_read_allowed_args, args);
 
     if (!in_master_mode(self)) {
-        mp_raise_TypeError("I2C must be a master");
+        mp_raise_TypeError(MP_ERROR_TEXT("I2C must be a master"));
     }
 
     // get the buffer to read into
@@ -1025,7 +1025,7 @@ STATIC mp_obj_t pyb_i2c_mem_write(size_t n_args, const mp_obj_t *pos_args, mp_ma
     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args), pyb_i2c_mem_read_allowed_args, args);
 
     if (!in_master_mode(self)) {
-        mp_raise_TypeError("I2C must be a master");
+        mp_raise_TypeError(MP_ERROR_TEXT("I2C must be a master"));
     }
 
     // get the buffer to write from
diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c
index 4e7a4a61aa..cc9dd11636 100644
--- a/ports/stm32/pyb_spi.c
+++ b/ports/stm32/pyb_spi.c
@@ -285,7 +285,7 @@ STATIC mp_obj_t pyb_spi_send_recv(size_t n_args, const mp_obj_t *pos_args, mp_ma
             // recv argument given
             mp_get_buffer_raise(args[1].u_obj, &bufinfo_recv, MP_BUFFER_WRITE);
             if (bufinfo_recv.len != bufinfo_send.len) {
-                mp_raise_ValueError("recv must be same length as send");
+                mp_raise_ValueError(MP_ERROR_TEXT("recv must be same length as send"));
             }
             o_ret = args[1].u_obj;
         }
diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c
index 9891981b9f..6b70084762 100644
--- a/ports/stm32/rtc.c
+++ b/ports/stm32/rtc.c
@@ -609,7 +609,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
                     wut -= 0x10000;
                     if (wut > 0x10000) {
                         // wut still too large
-                        mp_raise_ValueError("wakeup value too large");
+                        mp_raise_ValueError(MP_ERROR_TEXT("wakeup value too large"));
                     }
                 }
             }
@@ -726,10 +726,10 @@ mp_obj_t pyb_rtc_calibration(size_t n_args, const mp_obj_t *args) {
                 }
                 return mp_obj_new_int(cal & 1);
             } else {
-                mp_raise_ValueError("calibration value out of range");
+                mp_raise_ValueError(MP_ERROR_TEXT("calibration value out of range"));
             }
             #else
-            mp_raise_ValueError("calibration value out of range");
+            mp_raise_ValueError(MP_ERROR_TEXT("calibration value out of range"));
             #endif
         }
         if (cal > 0) {
diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c
index c0d9df83c6..9d77722302 100644
--- a/ports/stm32/sdcard.c
+++ b/ports/stm32/sdcard.c
@@ -686,7 +686,7 @@ STATIC mp_obj_t pyb_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, si
 
     #if MICROPY_HW_ENABLE_MMCARD
     if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_MMC) {
-        mp_raise_ValueError("peripheral used by MMCard");
+        mp_raise_ValueError(MP_ERROR_TEXT("peripheral used by MMCard"));
     }
     #endif
 
@@ -704,7 +704,7 @@ STATIC mp_obj_t pyb_mmcard_make_new(const mp_obj_type_t *type, size_t n_args, si
 
     #if MICROPY_HW_ENABLE_SDCARD
     if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_SD) {
-        mp_raise_ValueError("peripheral used by SDCard");
+        mp_raise_ValueError(MP_ERROR_TEXT("peripheral used by SDCard"));
     }
     #endif
 
@@ -768,7 +768,7 @@ STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
 
     if (ret != 0) {
         m_del(uint8_t, dest, SDCARD_BLOCK_SIZE);
-        mp_raise_msg_varg(&mp_type_Exception, "sdcard_read_blocks failed [%u]", ret);
+        mp_raise_msg_varg(&mp_type_Exception, MP_ERROR_TEXT("sdcard_read_blocks failed [%u]"), ret);
     }
 
     return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest);
@@ -780,13 +780,13 @@ STATIC mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t data) {
     mp_buffer_info_t bufinfo;
     mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
     if (bufinfo.len % SDCARD_BLOCK_SIZE != 0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "writes must be a multiple of %d bytes", SDCARD_BLOCK_SIZE);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("writes must be a multiple of %d bytes"), SDCARD_BLOCK_SIZE);
     }
 
     mp_uint_t ret = sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE);
 
     if (ret != 0) {
-        mp_raise_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed [%u]", ret);
+        mp_raise_msg_varg(&mp_type_Exception, MP_ERROR_TEXT("sdcard_write_blocks failed [%u]"), ret);
     }
 
     return mp_const_none;
diff --git a/ports/stm32/servo.c b/ports/stm32/servo.c
index a368b57648..c17bf63304 100644
--- a/ports/stm32/servo.c
+++ b/ports/stm32/servo.c
@@ -204,7 +204,7 @@ STATIC mp_obj_t pyb_servo_make_new(const mp_obj_type_t *type, size_t n_args, siz
 
     // check servo number
     if (!(0 <= servo_id && servo_id < PYB_SERVO_NUM)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Servo(%d) doesn't exist", servo_id + 1);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Servo(%d) doesn't exist"), servo_id + 1);
     }
 
     // get and init servo object
@@ -262,7 +262,7 @@ STATIC mp_obj_t pyb_servo_calibration(size_t n_args, const mp_obj_t *args) {
     }
 
     // bad number of arguments
-    mp_raise_msg_varg(&mp_type_TypeError, "calibration expecting 1, 4 or 6 arguments, got %d", n_args);
+    mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("calibration expecting 1, 4 or 6 arguments, got %d"), n_args);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_servo_calibration_obj, 1, 6, pyb_servo_calibration);
 
diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c
index 50cebffa2c..5f9b1c1a28 100644
--- a/ports/stm32/spi.c
+++ b/ports/stm32/spi.c
@@ -196,7 +196,7 @@ int spi_find_index(mp_obj_t id) {
             return 6;
         #endif
         }
-        mp_raise_msg_varg(&mp_type_ValueError, "SPI(%s) doesn't exist", port);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%s) doesn't exist"), port);
     } else {
         // given an integer id
         int spi_id = mp_obj_get_int(id);
@@ -204,7 +204,7 @@ int spi_find_index(mp_obj_t id) {
             && spi_obj[spi_id - 1].spi != NULL) {
             return spi_id;
         }
-        mp_raise_msg_varg(&mp_type_ValueError, "SPI(%d) doesn't exist", spi_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id);
     }
 }
 
@@ -654,7 +654,7 @@ const spi_t *spi_from_mp_obj(mp_obj_t o) {
         machine_hard_spi_obj_t *self = MP_OBJ_TO_PTR(o);
         return self->spi;
     } else {
-        mp_raise_TypeError("expecting an SPI object");
+        mp_raise_TypeError(MP_ERROR_TEXT("expecting an SPI object"));
     }
 }
 
diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c
index 1b32d8adae..9f8b7d1b86 100644
--- a/ports/stm32/timer.c
+++ b/ports/stm32/timer.c
@@ -296,7 +296,7 @@ STATIC uint32_t compute_prescaler_period_from_freq(pyb_timer_obj_t *self, mp_obj
         if (freq <= 0) {
             goto bad_freq;
         bad_freq:
-            mp_raise_ValueError("must have positive freq");
+            mp_raise_ValueError(MP_ERROR_TEXT("must have positive freq"));
         }
         period = source_freq / freq;
     }
@@ -323,7 +323,7 @@ STATIC uint32_t compute_prescaler_period_from_freq(pyb_timer_obj_t *self, mp_obj
 STATIC uint32_t compute_prescaler_period_from_t(pyb_timer_obj_t *self, int32_t t_num, int32_t t_den, uint32_t *period_out) {
     uint32_t source_freq = timer_get_source_freq(self->tim_id);
     if (t_num <= 0 || t_den <= 0) {
-        mp_raise_ValueError("must have positive freq");
+        mp_raise_ValueError(MP_ERROR_TEXT("must have positive freq"));
     }
     uint64_t period = (uint64_t)source_freq * (uint64_t)t_num / (uint64_t)t_den;
     uint32_t prescaler = 1;
@@ -345,7 +345,7 @@ STATIC uint32_t compute_prescaler_period_from_t(pyb_timer_obj_t *self, int32_t t
                 prescaler |= period_lsb;
             }
             if (prescaler > 0x10000) {
-                mp_raise_ValueError("period too large");
+                mp_raise_ValueError(MP_ERROR_TEXT("period too large"));
             }
         }
     }
@@ -491,7 +491,7 @@ STATIC void config_deadtime(pyb_timer_obj_t *self, mp_int_t ticks, mp_int_t brk)
 
 TIM_HandleTypeDef *pyb_timer_get_handle(mp_obj_t timer) {
     if (mp_obj_get_type(timer) != &pyb_timer_type) {
-        mp_raise_ValueError("need a Timer object");
+        mp_raise_ValueError(MP_ERROR_TEXT("need a Timer object"));
     }
     pyb_timer_obj_t *self = MP_OBJ_TO_PTR(timer);
     return &self->tim;
@@ -623,12 +623,12 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
         // set prescaler and period from desired period and tick_hz scale
         init->Prescaler = compute_prescaler_period_from_t(self, args[ARG_period].u_int, args[ARG_tick_hz].u_int, &init->Period);
     } else {
-        mp_raise_TypeError("must specify either freq, period, or prescaler and period");
+        mp_raise_TypeError(MP_ERROR_TEXT("must specify either freq, period, or prescaler and period"));
     }
 
     init->CounterMode = args[ARG_mode].u_int;
     if (!IS_TIM_COUNTER_MODE(init->CounterMode)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid mode (%d)", init->CounterMode);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid mode (%d)"), init->CounterMode);
     }
 
     init->ClockDivision = args[ARG_div].u_int == 2 ? TIM_CLOCKDIVISION_DIV2 :
@@ -889,7 +889,7 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz
 
     // check if the timer exists
     if (tim_id <= 0 || tim_id > MICROPY_HW_MAX_TIMER || tim_instance_table[tim_id - 1] == 0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Timer(%d) doesn't exist", tim_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Timer(%d) doesn't exist"), tim_id);
     }
 
     pyb_timer_obj_t *tim;
@@ -1038,7 +1038,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
     mp_int_t channel = mp_obj_get_int(pos_args[1]);
 
     if (channel < 1 || channel > 4) {
-        mp_raise_msg_varg(&mp_type_ValueError, "invalid channel (%d)", channel);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid channel (%d)"), channel);
     }
 
     pyb_timer_channel_obj_t *chan = self->channel;
@@ -1091,12 +1091,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
     mp_obj_t pin_obj = args[2].u_obj;
     if (pin_obj != mp_const_none) {
         if (!mp_obj_is_type(pin_obj, &pin_type)) {
-            mp_raise_ValueError("pin argument needs to be be a Pin type");
+            mp_raise_ValueError(MP_ERROR_TEXT("pin argument needs to be be a Pin type"));
         }
         const pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj);
         const pin_af_obj_t *af = pin_find_af(pin, AF_FN_TIM, self->tim_id);
         if (af == NULL) {
-            mp_raise_msg_varg(&mp_type_ValueError, "Pin(%q) doesn't have an af for Timer(%d)", pin->name, self->tim_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%q) doesn't have an af for Timer(%d)"), pin->name, self->tim_id);
         }
         // pin.init(mode=AF_PP, af=idx)
         const mp_obj_t args2[6] = {
@@ -1177,7 +1177,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
             #endif
 
             if (!IS_TIM_OC_POLARITY(oc_config.OCPolarity)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "invalid polarity (%d)", oc_config.OCPolarity);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid polarity (%d)"), oc_config.OCPolarity);
             }
             HAL_TIM_OC_ConfigChannel(&self->tim, &oc_config, TIMER_CHANNEL(chan));
             if (chan->callback == mp_const_none) {
@@ -1206,7 +1206,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
             ic_config.ICFilter = 0;
 
             if (!IS_TIM_IC_POLARITY(ic_config.ICPolarity)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "invalid polarity (%d)", ic_config.ICPolarity);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid polarity (%d)"), ic_config.ICPolarity);
             }
             HAL_TIM_IC_ConfigChannel(&self->tim, &ic_config, TIMER_CHANNEL(chan));
             if (chan->callback == mp_const_none) {
@@ -1236,7 +1236,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
             enc_config.IC2Filter = 0;
 
             if (!IS_TIM_IC_POLARITY(enc_config.IC1Polarity)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "invalid polarity (%d)", enc_config.IC1Polarity);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid polarity (%d)"), enc_config.IC1Polarity);
             }
             // Only Timers 1, 2, 3, 4, 5, and 8 support encoder mode
             if (
@@ -1258,7 +1258,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
                 && self->tim.Instance != TIM8
                 #endif
                 ) {
-                mp_raise_msg_varg(&mp_type_ValueError, "encoder not supported on timer %d", self->tim_id);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("encoder not supported on timer %d"), self->tim_id);
             }
 
             // Disable & clear the timer interrupt so that we don't trigger
@@ -1275,7 +1275,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *pos_args, mp_ma
         }
 
         default:
-            mp_raise_msg_varg(&mp_type_ValueError, "invalid mode (%d)", chan->mode);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid mode (%d)"), chan->mode);
     }
 
     return MP_OBJ_FROM_PTR(chan);
@@ -1390,7 +1390,7 @@ STATIC mp_obj_t pyb_timer_callback(mp_obj_t self_in, mp_obj_t callback) {
         HAL_TIM_Base_Start_IT(&self->tim); // This will re-enable the IRQ
         HAL_NVIC_EnableIRQ(self->irqn);
     } else {
-        mp_raise_ValueError("callback must be None or a callable object");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be None or a callable object"));
     }
     return mp_const_none;
 }
@@ -1553,7 +1553,7 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback)
                 break;
         }
     } else {
-        mp_raise_ValueError("callback must be None or a callable object");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be None or a callable object"));
     }
     return mp_const_none;
 }
diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c
index 5c8b105f08..cd52381721 100644
--- a/ports/stm32/usb.c
+++ b/ports/stm32/usb.c
@@ -530,7 +530,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
         mp_obj_t *items;
         mp_obj_get_array(args[ARG_msc].u_obj, &msc_n, &items);
         if (msc_n > USBD_MSC_MAX_LUN) {
-            mp_raise_ValueError("too many logical units");
+            mp_raise_ValueError(MP_ERROR_TEXT("too many logical units"));
         }
         for (size_t i = 0; i < msc_n; ++i) {
             const mp_obj_type_t *type = mp_obj_get_type(items[i]);
@@ -544,7 +544,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
                 ) {
                 msc_unit[i] = type;
             } else {
-                mp_raise_ValueError("unsupported logical unit");
+                mp_raise_ValueError(MP_ERROR_TEXT("unsupported logical unit"));
             }
         }
     }
@@ -592,7 +592,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
     return mp_const_none;
 
 bad_mode:
-    mp_raise_ValueError("bad USB mode");
+    mp_raise_ValueError(MP_ERROR_TEXT("bad USB mode"));
 }
 MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj, 0, pyb_usb_mode);
 
@@ -935,7 +935,7 @@ STATIC mp_obj_t pyb_usb_hid_send(mp_obj_t self_in, mp_obj_t report_in) {
         mp_obj_t *items;
         mp_obj_get_array(report_in, &bufinfo.len, &items);
         if (bufinfo.len > sizeof(temp_buf)) {
-            mp_raise_ValueError("tuple/list too large for HID report; use bytearray instead");
+            mp_raise_ValueError(MP_ERROR_TEXT("tuple/list too large for HID report; use bytearray instead"));
         }
         for (int i = 0; i < bufinfo.len; i++) {
             temp_buf[i] = mp_obj_get_int(items[i]);
diff --git a/ports/stm32/wdt.c b/ports/stm32/wdt.c
index 1452fd6a36..d794607bc0 100644
--- a/ports/stm32/wdt.c
+++ b/ports/stm32/wdt.c
@@ -51,7 +51,7 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
 
     mp_int_t id = args[ARG_id].u_int;
     if (id != 0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "WDT(%d) doesn't exist", id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("WDT(%d) doesn't exist"), id);
     }
 
     // timeout is in milliseconds
@@ -65,9 +65,9 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
     // convert milliseconds to ticks
     timeout *= 8; // 32kHz / 4 = 8 ticks per millisecond (approx)
     if (timeout <= 0) {
-        mp_raise_ValueError("WDT timeout too short");
+        mp_raise_ValueError(MP_ERROR_TEXT("WDT timeout too short"));
     } else if (timeout > 0xfff) {
-        mp_raise_ValueError("WDT timeout too long");
+        mp_raise_ValueError(MP_ERROR_TEXT("WDT timeout too long"));
     }
     timeout -= 1;
 
diff --git a/ports/teensy/led.c b/ports/teensy/led.c
index 7c2f3d2c02..9f8c594b75 100644
--- a/ports/teensy/led.c
+++ b/ports/teensy/led.c
@@ -97,7 +97,7 @@ STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, uint n_args, uint n_
 
     // check led number
     if (!(1 <= led_id && led_id <= NUM_LEDS)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("LED %d does not exist"), led_id);
     }
 
     // return static led object
diff --git a/ports/teensy/main.c b/ports/teensy/main.c
index 142f710064..6500d46631 100644
--- a/ports/teensy/main.c
+++ b/ports/teensy/main.c
@@ -169,7 +169,7 @@ mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) {
     return mp_const_none;
 
 pin_error:
-    mp_raise_msg_varg(&mp_type_ValueError, "pin %d does not exist", pin);
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("pin %d does not exist"), pin);
 }
 
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
diff --git a/ports/teensy/servo.c b/ports/teensy/servo.c
index 33fb0c0349..222b685a4b 100644
--- a/ports/teensy/servo.c
+++ b/ports/teensy/servo.c
@@ -68,7 +68,7 @@ static mp_obj_t servo_obj_attach(mp_obj_t self_in, mp_obj_t pin_obj) {
     return mp_const_none;
 
 pin_error:
-    mp_raise_msg_varg(MP_QSTR_ValueError, "pin %d does not exist", pin);
+    mp_raise_msg_varg(MP_QSTR_ValueError, MP_ERROR_TEXT("pin %d does not exist"), pin);
 }
 
 static mp_obj_t servo_obj_detach(mp_obj_t self_in) {
@@ -215,7 +215,7 @@ mp_obj_t pyb_Servo(void) {
         self->servo_id++;
     }
     m_del_obj(pyb_servo_obj_t, self);
-    mp_raise_ValueError("No available servo ids");
+    mp_raise_ValueError(MP_ERROR_TEXT("No available servo ids"));
     return mp_const_none;
 }
 
diff --git a/ports/teensy/timer.c b/ports/teensy/timer.c
index 08dc13fab1..68dc965eb8 100644
--- a/ports/teensy/timer.c
+++ b/ports/teensy/timer.c
@@ -114,7 +114,7 @@ mp_uint_t get_prescaler_shift(mp_int_t prescaler) {
             return prescaler_shift;
         }
     }
-    mp_raise_msg_varg(&mp_type_TypeError, "prescaler must be a power of 2 between 1 and 128, not %d", prescaler);
+    mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("prescaler must be a power of 2 between 1 and 128, not %d"), prescaler);
 }
 
 /******************************************************************************/
@@ -254,7 +254,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const
         // set prescaler and period from frequency
 
         if (vals[0].u_int == 0) {
-            mp_raise_ValueError("can't have 0 frequency");
+            mp_raise_ValueError(MP_ERROR_TEXT("can't have 0 frequency"));
         }
 
         uint32_t period = MAX(1, F_BUS / vals[0].u_int);
@@ -273,15 +273,15 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const
         init->PrescalerShift = get_prescaler_shift(vals[1].u_int);
         init->Period = vals[2].u_int;
         if (!IS_FTM_PERIOD(init->Period)) {
-            mp_raise_msg_varg(&mp_type_TypeError, "period must be between 0 and 65535, not %d", init->Period);
+            mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("period must be between 0 and 65535, not %d"), init->Period);
         }
     } else {
-        mp_raise_TypeError("must specify either freq, or prescaler and period");
+        mp_raise_TypeError(MP_ERROR_TEXT("must specify either freq, or prescaler and period"));
     }
 
     init->CounterMode = vals[3].u_int;
     if (!IS_FTM_COUNTERMODE(init->CounterMode)) {
-        mp_raise_msg_varg(&mp_type_TypeError, "invalid counter mode: %d", init->CounterMode);
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("invalid counter mode: %d"), init->CounterMode);
     }
 
     // Currently core/mk20dx128.c sets SIM_SCGC6_FTM0, SIM_SCGC6_FTM1, SIM_SCGC3_FTM2
@@ -332,7 +332,7 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz
             tim->irqn = IRQ_FTM2;
             break;
         default:
-            mp_raise_msg_varg(&mp_type_ValueError, "Timer %d does not exist", tim->tim_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Timer %d does not exist"), tim->tim_id);
     }
 
     if (n_args > 1 || n_kw > 0) {
@@ -454,7 +454,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *args, mp_map_t
     mp_int_t channel = mp_obj_get_int(args[1]);
 
     if (channel < 0 || channel > 7) {
-        mp_raise_msg_varg(&mp_type_ValueError, "Invalid channel (%d)", channel);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid channel (%d)"), channel);
     }
 
     pyb_timer_channel_obj_t *chan = self->channel;
@@ -507,12 +507,12 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *args, mp_map_t
     mp_obj_t pin_obj = vals[1].u_obj;
     if (pin_obj != mp_const_none) {
         if (!mp_obj_is_type(pin_obj, &pin_type)) {
-            mp_raise_ValueError("pin argument needs to be be a Pin type");
+            mp_raise_ValueError(MP_ERROR_TEXT("pin argument needs to be be a Pin type"));
         }
         const pin_obj_t *pin = pin_obj;
         const pin_af_obj_t *af = pin_find_af(pin, AF_FN_FTM, self->tim_id);
         if (af == NULL) {
-            mp_raise_msg_varg(&mp_type_ValueError, "pin %s doesn't have an af for TIM%d", qstr_str(pin->name), self->tim_id);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("pin %s doesn't have an af for TIM%d"), qstr_str(pin->name), self->tim_id);
         }
         // pin.init(mode=AF_PP, af=idx)
         const mp_obj_t args[6] = {
@@ -569,7 +569,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *args, mp_map_t
             }
 
             if (!IS_FTM_OC_POLARITY(oc_config.OCPolarity)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "Invalid polarity (%d)", oc_config.OCPolarity);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid polarity (%d)"), oc_config.OCPolarity);
             }
             HAL_FTM_OC_ConfigChannel(&self->ftm, &oc_config, channel);
             if (chan->callback == mp_const_none) {
@@ -589,7 +589,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *args, mp_map_t
             }
 
             if (!IS_FTM_IC_POLARITY(ic_config.ICPolarity)) {
-                mp_raise_msg_varg(&mp_type_ValueError, "Invalid polarity (%d)", ic_config.ICPolarity);
+                mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid polarity (%d)"), ic_config.ICPolarity);
             }
             HAL_FTM_IC_ConfigChannel(&self->ftm, &ic_config, chan->channel);
             if (chan->callback == mp_const_none) {
@@ -601,7 +601,7 @@ STATIC mp_obj_t pyb_timer_channel(size_t n_args, const mp_obj_t *args, mp_map_t
         }
 
         default:
-            mp_raise_msg_varg(&mp_type_ValueError, "Invalid mode (%d)", chan->mode);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid mode (%d)"), chan->mode);
     }
 
     return chan;
@@ -677,7 +677,7 @@ STATIC mp_obj_t pyb_timer_callback(mp_obj_t self_in, mp_obj_t callback) {
         // start timer, so that it interrupts on overflow
         HAL_FTM_Base_Start_IT(&self->ftm);
     } else {
-        mp_raise_ValueError("callback must be None or a callable object");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be None or a callable object"));
     }
     return mp_const_none;
 }
@@ -855,7 +855,7 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback)
                 break;
         }
     } else {
-        mp_raise_ValueError("callback must be None or a callable object");
+        mp_raise_ValueError(MP_ERROR_TEXT("callback must be None or a callable object"));
     }
     return mp_const_none;
 }
diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c
index 1b74fe7d5b..fa50c6753d 100644
--- a/ports/teensy/uart.c
+++ b/ports/teensy/uart.c
@@ -287,7 +287,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, uint n_args, const mp
 
     // init UART (if it fails, it's because the port doesn't exist)
     if (!uart_init2(self)) {
-        mp_raise_msg_varg(&mp_type_ValueError, "UART port %d does not exist", self->uart_id);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART port %d does not exist"), self->uart_id);
     }
     #endif
 
@@ -334,7 +334,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, uint n_args, uint n
             o->uart_id = PYB_UART_YB;
         #endif
         } else {
-            mp_raise_msg_varg(&mp_type_ValueError, "UART port %s does not exist", port);
+            mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART port %s does not exist"), port);
         }
     } else {
         o->uart_id = mp_obj_get_int(args[0]);
@@ -410,7 +410,7 @@ STATIC mp_obj_t pyb_uart_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_ar
 
     if (status != HAL_OK) {
         // TODO really need a HardwareError object, or something
-        mp_raise_msg_varg(&mp_type_Exception, "HAL_UART_Transmit failed with code %d", status);
+        mp_raise_msg_varg(&mp_type_Exception, MP_ERROR_TEXT("HAL_UART_Transmit failed with code %d"), status);
     }
     #else
     (void)self;
@@ -457,7 +457,7 @@ STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_ar
 
     if (status != HAL_OK) {
         // TODO really need a HardwareError object, or something
-        mp_raise_msg_varg(&mp_type_Exception, "HAL_UART_Receive failed with code %d", status);
+        mp_raise_msg_varg(&mp_type_Exception, MP_ERROR_TEXT("HAL_UART_Receive failed with code %d"), status);
     }
 
     // return the received data
diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c
index 07ba3edbc5..f14852d765 100644
--- a/ports/unix/modffi.c
+++ b/ports/unix/modffi.c
@@ -148,7 +148,7 @@ STATIC ffi_type *get_ffi_type(mp_obj_t o_in) {
     }
     // TODO: Support actual libffi type objects
 
-    mp_raise_TypeError("Unknown type");
+    mp_raise_TypeError(MP_ERROR_TEXT("Unknown type"));
 }
 
 STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) {
@@ -218,7 +218,7 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in)
 
     int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
     if (res != FFI_OK) {
-        mp_raise_ValueError("Error in ffi_prep_cif");
+        mp_raise_ValueError(MP_ERROR_TEXT("Error in ffi_prep_cif"));
     }
 
     return MP_OBJ_FROM_PTR(o);
@@ -276,12 +276,12 @@ STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t
 
     int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
     if (res != FFI_OK) {
-        mp_raise_ValueError("Error in ffi_prep_cif");
+        mp_raise_ValueError(MP_ERROR_TEXT("Error in ffi_prep_cif"));
     }
 
     res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, MP_OBJ_TO_PTR(func_in), o->func);
     if (res != FFI_OK) {
-        mp_raise_ValueError("ffi_prep_closure_loc");
+        mp_raise_ValueError(MP_ERROR_TEXT("ffi_prep_closure_loc"));
     }
 
     return MP_OBJ_FROM_PTR(o);
diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c
index f5dbd9ccd3..73c5856a09 100644
--- a/ports/unix/modjni.c
+++ b/ports/unix/modjni.c
@@ -157,7 +157,7 @@ STATIC void jclass_attr(mp_obj_t self_in, qstr attr_in, mp_obj_t *dest) {
 
 STATIC mp_obj_t jclass_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     if (n_kw != 0) {
-        mp_raise_TypeError("kwargs not supported");
+        mp_raise_TypeError(MP_ERROR_TEXT("kwargs not supported"));
     }
     mp_obj_jclass_t *self = MP_OBJ_TO_PTR(self_in);
 
@@ -431,7 +431,7 @@ STATIC bool py2jvalue(const char **jtypesig, mp_obj_t arg, jvalue *out) {
         }
         out->l = NULL;
     } else {
-        mp_raise_TypeError("arg type not supported");
+        mp_raise_TypeError(MP_ERROR_TEXT("arg type not supported"));
     }
 
     *jtypesig = arg_type;
@@ -531,7 +531,7 @@ STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool
                     ret = new_jobject(res);
                 } else {
                     JJ(ReleaseStringUTFChars, name_o, decl);
-                    mp_raise_TypeError("cannot handle return type");
+                    mp_raise_TypeError(MP_ERROR_TEXT("cannot handle return type"));
                 }
 
                 JJ(ReleaseStringUTFChars, name_o, decl);
@@ -547,13 +547,13 @@ STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool
         JJ(DeleteLocalRef, meth);
     }
 
-    mp_raise_TypeError("method not found");
+    mp_raise_TypeError(MP_ERROR_TEXT("method not found"));
 }
 
 
 STATIC mp_obj_t jmethod_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     if (n_kw != 0) {
-        mp_raise_TypeError("kwargs not supported");
+        mp_raise_TypeError(MP_ERROR_TEXT("kwargs not supported"));
     }
     mp_obj_jmethod_t *self = MP_OBJ_TO_PTR(self_in);
 
@@ -599,13 +599,13 @@ STATIC void create_jvm(void) {
 
     void *libjvm = dlopen(LIBJVM_SO, RTLD_NOW | RTLD_GLOBAL);
     if (!libjvm) {
-        mp_raise_msg(&mp_type_OSError, "unable to load libjvm.so, use LD_LIBRARY_PATH");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("unable to load libjvm.so, use LD_LIBRARY_PATH"));
     }
     int (*_JNI_CreateJavaVM)(void *, void **, void *) = dlsym(libjvm, "JNI_CreateJavaVM");
 
     int st = _JNI_CreateJavaVM(&jvm, (void **)&env, &args);
     if (st < 0 || !env) {
-        mp_raise_msg(&mp_type_OSError, "unable to create JVM");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("unable to create JVM"));
     }
 
     Class_class = JJ(FindClass, "java/lang/Class");
@@ -614,26 +614,26 @@ STATIC void create_jvm(void) {
 
     jclass Object_class = JJ(FindClass, "java/lang/Object");
     Object_toString_mid = JJ(GetMethodID, Object_class, "toString",
-        "()Ljava/lang/String;");
+        MP_ERROR_TEXT("()Ljava/lang/String;"));
 
     Class_getName_mid = (*env)->GetMethodID(env, Class_class, "getName",
-        "()Ljava/lang/String;");
+        MP_ERROR_TEXT("()Ljava/lang/String;"));
     Class_getField_mid = (*env)->GetMethodID(env, Class_class, "getField",
-        "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
+        MP_ERROR_TEXT("(Ljava/lang/String;)Ljava/lang/reflect/Field;"));
     Class_getMethods_mid = (*env)->GetMethodID(env, Class_class, "getMethods",
-        "()[Ljava/lang/reflect/Method;");
+        MP_ERROR_TEXT("()[Ljava/lang/reflect/Method;"));
     Class_getConstructors_mid = (*env)->GetMethodID(env, Class_class, "getConstructors",
-        "()[Ljava/lang/reflect/Constructor;");
+        MP_ERROR_TEXT("()[Ljava/lang/reflect/Constructor;"));
     Method_getName_mid = (*env)->GetMethodID(env, method_class, "getName",
-        "()Ljava/lang/String;");
+        MP_ERROR_TEXT("()Ljava/lang/String;"));
 
     List_class = JJ(FindClass, "java/util/List");
     List_get_mid = JJ(GetMethodID, List_class, "get",
-        "(I)Ljava/lang/Object;");
+        MP_ERROR_TEXT("(I)Ljava/lang/Object;"));
     List_set_mid = JJ(GetMethodID, List_class, "set",
-        "(ILjava/lang/Object;)Ljava/lang/Object;");
+        MP_ERROR_TEXT("(ILjava/lang/Object;)Ljava/lang/Object;"));
     List_size_mid = JJ(GetMethodID, List_class, "size",
-        "()I");
+        MP_ERROR_TEXT("()I"));
     IndexException_class = JJ(FindClass, "java/lang/IndexOutOfBoundsException");
 }
 
diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c
index 492b49c8e1..d9952c540a 100644
--- a/ports/unix/modmachine.c
+++ b/ports/unix/modmachine.c
@@ -49,7 +49,7 @@
 uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) {
     uintptr_t addr = mp_obj_int_get_truncated(addr_o);
     if ((addr & (align - 1)) != 0) {
-        mp_raise_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align);
+        mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("address %08x is not aligned to %d bytes"), addr, align);
     }
     #if MICROPY_PLAT_DEV_MEM
     {
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c
index c0c1e84f2c..8bc453d428 100644
--- a/ports/unix/modusocket.c
+++ b/ports/unix/modusocket.c
@@ -576,7 +576,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) {
 
     if (res != 0) {
         // CPython: socket.gaierror
-        mp_raise_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res);
+        mp_raise_msg_varg(&mp_type_OSError, MP_ERROR_TEXT("[addrinfo error %d]"), res);
     }
     assert(addr_list);
 
diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c
index 0f16095cb3..f00c1d3422 100644
--- a/ports/zephyr/machine_i2c.c
+++ b/ports/zephyr/machine_i2c.c
@@ -68,19 +68,19 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
     struct device *dev = device_get_binding(dev_name);
 
     if (dev == NULL) {
-        mp_raise_ValueError("device not found");
+        mp_raise_ValueError(MP_ERROR_TEXT("device not found"));
     }
 
     if ((args[ARG_scl].u_obj != MP_OBJ_NULL) || (args[ARG_sda].u_obj != MP_OBJ_NULL)) {
-        mp_raise_NotImplementedError("explicit choice of scl/sda is not implemented");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("explicit choice of scl/sda is not implemented"));
     }
 
     if ((args[ARG_freq].u_obj != MP_OBJ_NULL)) {
-        mp_raise_NotImplementedError("explicit choice of freq is not implemented");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("explicit choice of freq is not implemented"));
     }
 
     if ((args[ARG_timeout].u_obj != MP_OBJ_NULL)) {
-        mp_raise_NotImplementedError("explicit choice of timeout is not implemented");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("explicit choice of timeout is not implemented"));
     }
 
     machine_hard_i2c_obj_t *self = m_new_obj(machine_hard_i2c_obj_t);
diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c
index 032be7d8e2..ad5f54baaf 100644
--- a/ports/zephyr/machine_pin.c
+++ b/ports/zephyr/machine_pin.c
@@ -74,7 +74,7 @@ STATIC mp_obj_t machine_pin_obj_init_helper(machine_pin_obj_t *self, size_t n_ar
 
     int ret = gpio_pin_configure(self->port, self->pin, mode | pull | init);
     if (ret) {
-        mp_raise_ValueError("invalid pin");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
     }
 
     return mp_const_none;
@@ -86,7 +86,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
 
     // get the wanted port
     if (!mp_obj_is_type(args[0], &mp_type_tuple)) {
-        mp_raise_ValueError("Pin id must be tuple of (\"GPIO_x\", pin#)");
+        mp_raise_ValueError(MP_ERROR_TEXT("Pin id must be tuple of (\"GPIO_x\", pin#)"));
     }
     mp_obj_t *items;
     mp_obj_get_array_fixed_n(args[0], 2, &items);
@@ -94,7 +94,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
     int wanted_pin = mp_obj_get_int(items[1]);
     struct device *wanted_port = device_get_binding(drv_name);
     if (!wanted_port) {
-        mp_raise_ValueError("invalid port");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid port"));
     }
 
     machine_pin_obj_t *pin = m_new_obj(machine_pin_obj_t);
diff --git a/ports/zephyr/modzsensor.c b/ports/zephyr/modzsensor.c
index 736cd221e8..1dbf345687 100644
--- a/ports/zephyr/modzsensor.c
+++ b/ports/zephyr/modzsensor.c
@@ -44,7 +44,7 @@ STATIC mp_obj_t sensor_make_new(const mp_obj_type_t *type, size_t n_args, size_t
     o->base.type = type;
     o->dev = device_get_binding(mp_obj_str_get_str(args[0]));
     if (o->dev == NULL) {
-        mp_raise_ValueError("dev not found");
+        mp_raise_ValueError(MP_ERROR_TEXT("dev not found"));
     }
     return MP_OBJ_FROM_PTR(o);
 }
diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c
index c592881e1b..c533cb8fd7 100644
--- a/ports/zephyr/zephyr_storage.c
+++ b/ports/zephyr/zephyr_storage.c
@@ -59,15 +59,15 @@ STATIC mp_obj_t zephyr_disk_access_make_new(const mp_obj_type_t *type, size_t n_
     self->pdrv = mp_obj_str_get_str(args[0]);
 
     if (disk_access_init(self->pdrv) != 0) {
-        mp_raise_ValueError("disk not found");
+        mp_raise_ValueError(MP_ERROR_TEXT("disk not found"));
     }
 
     if (disk_access_ioctl(self->pdrv, DISK_IOCTL_GET_SECTOR_SIZE, &self->block_size)) {
-        mp_raise_ValueError("unable to get sector size");
+        mp_raise_ValueError(MP_ERROR_TEXT("unable to get sector size"));
     }
 
     if (disk_access_ioctl(self->pdrv, DISK_IOCTL_GET_SECTOR_COUNT, &self->block_count)) {
-        mp_raise_ValueError("unable to get block count");
+        mp_raise_ValueError(MP_ERROR_TEXT("unable to get block count"));
     }
 
     return MP_OBJ_FROM_PTR(self);
@@ -162,11 +162,11 @@ STATIC mp_obj_t zephyr_flash_area_make_new(const mp_obj_type_t *type, size_t n_a
     self->block_size = mp_obj_get_int(args[1]);
 
     if (self->block_size <= 0) {
-        mp_raise_ValueError("invalid block size");
+        mp_raise_ValueError(MP_ERROR_TEXT("invalid block size"));
     }
 
     if (flash_area_open(self->id, &self->area) != 0) {
-        mp_raise_ValueError("unable to open flash area");
+        mp_raise_ValueError(MP_ERROR_TEXT("unable to open flash area"));
     }
 
     self->block_count = self->area->fa_size / self->block_size;
diff --git a/py/argcheck.c b/py/argcheck.c
index 88c4b8bf33..c333ead05b 100644
--- a/py/argcheck.c
+++ b/py/argcheck.c
@@ -41,7 +41,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
         mp_arg_error_terse_mismatch();
         #else
-        mp_raise_TypeError("function doesn't take keyword arguments");
+        mp_raise_TypeError(MP_ERROR_TEXT("function doesn't take keyword arguments"));
         #endif
     }
 
@@ -51,7 +51,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) {
             mp_arg_error_terse_mismatch();
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "function takes %d positional arguments but %d were given",
+                MP_ERROR_TEXT("function takes %d positional arguments but %d were given"),
                 n_args_min, n_args);
             #endif
         }
@@ -61,7 +61,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) {
             mp_arg_error_terse_mismatch();
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "function missing %d required positional arguments",
+                MP_ERROR_TEXT("function missing %d required positional arguments"),
                 n_args_min - n_args);
             #endif
         } else if (n_args > n_args_max) {
@@ -69,7 +69,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) {
             mp_arg_error_terse_mismatch();
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "function expected at most %d arguments, got %d",
+                MP_ERROR_TEXT("function expected at most %d arguments, got %d"),
                 n_args_max, n_args);
             #endif
         }
@@ -93,7 +93,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
                     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
                     mp_arg_error_terse_mismatch();
                     #else
-                    mp_raise_msg_varg(&mp_type_TypeError, "'%q' argument required", allowed[i].qst);
+                    mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%q' argument required"), allowed[i].qst);
                     #endif
                 }
                 out_vals[i] = allowed[i].defval;
@@ -118,7 +118,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
         mp_arg_error_terse_mismatch();
         #else
         // TODO better error message
-        mp_raise_TypeError("extra positional arguments given");
+        mp_raise_TypeError(MP_ERROR_TEXT("extra positional arguments given"));
         #endif
     }
     if (kws_found < kws->used) {
@@ -126,7 +126,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
         mp_arg_error_terse_mismatch();
         #else
         // TODO better error message
-        mp_raise_TypeError("extra keyword arguments given");
+        mp_raise_TypeError(MP_ERROR_TEXT("extra keyword arguments given"));
         #endif
     }
 }
@@ -138,11 +138,11 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args,
 }
 
 NORETURN void mp_arg_error_terse_mismatch(void) {
-    mp_raise_TypeError("argument num/types mismatch");
+    mp_raise_TypeError(MP_ERROR_TEXT("argument num/types mismatch"));
 }
 
 #if MICROPY_CPYTHON_COMPAT
 NORETURN void mp_arg_error_unimpl_kw(void) {
-    mp_raise_NotImplementedError("keyword argument(s) not yet implemented - use normal args instead");
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("keyword argument(s) not yet implemented - use normal args instead"));
 }
 #endif
diff --git a/py/bc.c b/py/bc.c
index 5b3b005b26..6385fb40b0 100644
--- a/py/bc.c
+++ b/py/bc.c
@@ -84,10 +84,10 @@ STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected,
     #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
     (void)f;
     mp_raise_msg_varg(&mp_type_TypeError,
-        "function takes %d positional arguments but %d were given", expected, given);
+        MP_ERROR_TEXT("function takes %d positional arguments but %d were given"), expected, given);
     #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
     mp_raise_msg_varg(&mp_type_TypeError,
-        "%q() takes %d positional arguments but %d were given",
+        MP_ERROR_TEXT("%q() takes %d positional arguments but %d were given"),
         mp_obj_fun_get_name(MP_OBJ_FROM_PTR(f)), expected, given);
     #endif
 }
@@ -204,7 +204,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
                 if (wanted_arg_name == arg_names[j]) {
                     if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
                         mp_raise_msg_varg(&mp_type_TypeError,
-                            "function got multiple values for argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name));
+                            MP_ERROR_TEXT("function got multiple values for argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name));
                     }
                     code_state->state[n_state - 1 - j] = kwargs[2 * i + 1];
                     goto continue2;
@@ -213,10 +213,10 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
             // Didn't find name match with positional args
             if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) {
                 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-                mp_raise_TypeError("unexpected keyword argument");
+                mp_raise_TypeError(MP_ERROR_TEXT("unexpected keyword argument"));
                 #else
                 mp_raise_msg_varg(&mp_type_TypeError,
-                    "unexpected keyword argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name));
+                    MP_ERROR_TEXT("unexpected keyword argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name));
                 #endif
             }
             mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
@@ -242,7 +242,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
         while (d < &code_state->state[n_state]) {
             if (*d++ == MP_OBJ_NULL) {
                 mp_raise_msg_varg(&mp_type_TypeError,
-                    "function missing required positional argument #%d", &code_state->state[n_state] - d);
+                    MP_ERROR_TEXT("function missing required positional argument #%d"), &code_state->state[n_state] - d);
             }
         }
 
@@ -258,7 +258,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
                     code_state->state[n_state - 1 - n_pos_args - i] = elem->value;
                 } else {
                     mp_raise_msg_varg(&mp_type_TypeError,
-                        "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i]));
+                        MP_ERROR_TEXT("function missing required keyword argument '%q'"), MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i]));
                 }
             }
         }
@@ -266,7 +266,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
     } else {
         // no keyword arguments given
         if (n_kwonly_args != 0) {
-            mp_raise_TypeError("function missing keyword-only argument");
+            mp_raise_TypeError(MP_ERROR_TEXT("function missing keyword-only argument"));
         }
         if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
             *var_pos_kw_args = mp_obj_new_dict(0);
diff --git a/py/binary.c b/py/binary.c
index bc464bc4e2..3a77849645 100644
--- a/py/binary.c
+++ b/py/binary.c
@@ -135,7 +135,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) {
     }
 
     if (size == 0) {
-        mp_raise_ValueError("bad typecode");
+        mp_raise_ValueError(MP_ERROR_TEXT("bad typecode"));
     }
 
     if (palign != NULL) {
diff --git a/py/builtinevex.c b/py/builtinevex.c
index 4e61205485..800a20223a 100644
--- a/py/builtinevex.c
+++ b/py/builtinevex.c
@@ -100,7 +100,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) {
             parse_input_kind = MP_PARSE_EVAL_INPUT;
             break;
         default:
-            mp_raise_ValueError("bad compile mode");
+            mp_raise_ValueError(MP_ERROR_TEXT("bad compile mode"));
     }
 
     mp_obj_code_t *code = m_new_obj(mp_obj_code_t);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index b700e46b63..10b91fdbf2 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -241,7 +241,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
     }
     #else
     // If we get here then the file was not frozen and we can't compile scripts.
-    mp_raise_msg(&mp_type_ImportError, "script compilation not supported");
+    mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("script compilation not supported"));
     #endif
 }
 
@@ -326,7 +326,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
 
         // We must have some component left over to import from
         if (p == this_name) {
-            mp_raise_ValueError("cannot perform relative import");
+            mp_raise_ValueError(MP_ERROR_TEXT("cannot perform relative import"));
         }
 
         uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
@@ -410,9 +410,9 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
                 if (module_obj == MP_OBJ_NULL) {
                     // couldn't find the file, so fail
                     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-                    mp_raise_msg(&mp_type_ImportError, "module not found");
+                    mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found"));
                     #else
-                    mp_raise_msg_varg(&mp_type_ImportError, "no module named '%q'", mod_name);
+                    mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), mod_name);
                     #endif
                 }
             } else {
@@ -499,7 +499,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
 mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
     // Check that it's not a relative import
     if (n_args >= 5 && MP_OBJ_SMALL_INT_VALUE(args[4]) != 0) {
-        mp_raise_NotImplementedError("relative import");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("relative import"));
     }
 
     // Check if module already exists, and return it if it does
@@ -521,9 +521,9 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
 
     // Couldn't find the module, so fail
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_msg(&mp_type_ImportError, "module not found");
+    mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found"));
     #else
-    mp_raise_msg_varg(&mp_type_ImportError, "no module named '%q'", module_name_qstr);
+    mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), module_name_qstr);
     #endif
 }
 
diff --git a/py/compile.c b/py/compile.c
index 5635a98fe1..b4ee0598fb 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -449,7 +449,7 @@ STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, as
         }
     }
 
-    compile_syntax_error(comp, (mp_parse_node_t)pns, "can't assign to expression");
+    compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("can't assign to expression"));
 }
 
 // we need to allow for a caller passing in 1 initial node (node_head) followed by an array of nodes (nodes_tail)
@@ -468,7 +468,7 @@ STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num
                 EMIT_ARG(unpack_ex, num_head + i, num_tail - i - 1);
                 have_star_index = num_head + i;
             } else {
-                compile_syntax_error(comp, nodes_tail[i], "multiple *x in assignment");
+                compile_syntax_error(comp, nodes_tail[i], MP_ERROR_TEXT("multiple *x in assignment"));
                 return;
             }
         }
@@ -594,7 +594,7 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_
     return;
 
 cannot_assign:
-    compile_syntax_error(comp, pn, "can't assign to expression");
+    compile_syntax_error(comp, pn, MP_ERROR_TEXT("can't assign to expression"));
 }
 
 // stuff for lambda and comprehensions and generators:
@@ -699,7 +699,7 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn)
 
             // check for non-default parameters given after default parameters (allowed by parser, but not syntactically valid)
             if (!comp->have_star && comp->num_default_params != 0) {
-                compile_syntax_error(comp, pn, "non-default argument follows default argument");
+                compile_syntax_error(comp, pn, MP_ERROR_TEXT("non-default argument follows default argument"));
                 return;
             }
 
@@ -828,7 +828,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
     }
 
     if (name_len != 2) {
-        compile_syntax_error(comp, name_nodes[0], "invalid micropython decorator");
+        compile_syntax_error(comp, name_nodes[0], MP_ERROR_TEXT("invalid micropython decorator"));
         return true;
     }
 
@@ -853,17 +853,17 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
     #endif
         #endif
     } else {
-        compile_syntax_error(comp, name_nodes[1], "invalid micropython decorator");
+        compile_syntax_error(comp, name_nodes[1], MP_ERROR_TEXT("invalid micropython decorator"));
     }
 
     #if MICROPY_DYNAMIC_COMPILER
     if (*emit_options == MP_EMIT_OPT_NATIVE_PYTHON || *emit_options == MP_EMIT_OPT_VIPER) {
         if (emit_native_table[mp_dynamic_compiler.native_arch] == NULL) {
-            compile_syntax_error(comp, name_nodes[1], "invalid arch");
+            compile_syntax_error(comp, name_nodes[1], MP_ERROR_TEXT("invalid arch"));
         }
     } else if (*emit_options == MP_EMIT_OPT_ASM) {
         if (emit_asm_table[mp_dynamic_compiler.native_arch] == NULL) {
-            compile_syntax_error(comp, name_nodes[1], "invalid arch");
+            compile_syntax_error(comp, name_nodes[1], MP_ERROR_TEXT("invalid arch"));
         }
     }
     #endif
@@ -1019,7 +1019,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
     return;
 
 cannot_delete:
-    compile_syntax_error(comp, (mp_parse_node_t)pn, "can't delete expression");
+    compile_syntax_error(comp, (mp_parse_node_t)pn, MP_ERROR_TEXT("can't delete expression"));
 }
 
 STATIC void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -1034,7 +1034,7 @@ STATIC void compile_break_cont_stmt(compiler_t *comp, mp_parse_node_struct_t *pn
         label = comp->continue_label;
     }
     if (label == INVALID_LABEL) {
-        compile_syntax_error(comp, (mp_parse_node_t)pns, "'break'/'continue' outside loop");
+        compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'break'/'continue' outside loop"));
     }
     assert(comp->cur_except_level >= comp->break_continue_except_level);
     EMIT_ARG(unwind_jump, label, comp->cur_except_level - comp->break_continue_except_level);
@@ -1043,7 +1043,7 @@ STATIC void compile_break_cont_stmt(compiler_t *comp, mp_parse_node_struct_t *pn
 STATIC void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
     #if MICROPY_CPYTHON_COMPAT
     if (comp->scope_cur->kind != SCOPE_FUNCTION) {
-        compile_syntax_error(comp, (mp_parse_node_t)pns, "'return' outside function");
+        compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'return' outside function"));
         return;
     }
     #endif
@@ -1201,7 +1201,7 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
     if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) {
         #if MICROPY_CPYTHON_COMPAT
         if (comp->scope_cur->kind != SCOPE_MODULE) {
-            compile_syntax_error(comp, (mp_parse_node_t)pns, "import * not at module level");
+            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("import * not at module level"));
             return;
         }
         #endif
@@ -1251,7 +1251,7 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
 
 STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, id_info_t *id_info) {
     if (id_info->kind != ID_INFO_KIND_UNDECIDED && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
-        compile_syntax_error(comp, pn, "identifier redefined as global");
+        compile_syntax_error(comp, pn, MP_ERROR_TEXT("identifier redefined as global"));
         return;
     }
     id_info->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
@@ -1268,10 +1268,10 @@ STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, id_in
         id_info->kind = ID_INFO_KIND_GLOBAL_IMPLICIT;
         scope_check_to_close_over(comp->scope_cur, id_info);
         if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
-            compile_syntax_error(comp, pn, "no binding for nonlocal found");
+            compile_syntax_error(comp, pn, MP_ERROR_TEXT("no binding for nonlocal found"));
         }
     } else if (id_info->kind != ID_INFO_KIND_FREE) {
-        compile_syntax_error(comp, pn, "identifier redefined as nonlocal");
+        compile_syntax_error(comp, pn, MP_ERROR_TEXT("identifier redefined as nonlocal"));
     }
 }
 
@@ -1280,7 +1280,7 @@ STATIC void compile_global_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_
         bool is_global = MP_PARSE_NODE_STRUCT_KIND(pns) == PN_global_stmt;
 
         if (!is_global && comp->scope_cur->kind == SCOPE_MODULE) {
-            compile_syntax_error(comp, (mp_parse_node_t)pns, "can't declare nonlocal in outer code");
+            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("can't declare nonlocal in outer code"));
             return;
         }
 
@@ -1629,7 +1629,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
         if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
             // this is a catch all exception handler
             if (i + 1 != n_except) {
-                compile_syntax_error(comp, pn_excepts[i], "default 'except' must be last");
+                compile_syntax_error(comp, pn_excepts[i], MP_ERROR_TEXT("default 'except' must be last"));
                 compile_decrease_except_level(comp);
                 return;
             }
@@ -2192,7 +2192,7 @@ STATIC void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
 }
 
 STATIC void compile_star_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
-    compile_syntax_error(comp, (mp_parse_node_t)pns, "*x must be assignment target");
+    compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("*x must be assignment target"));
 }
 
 STATIC void compile_binary_op(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -2275,7 +2275,7 @@ STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *p
         }
         if (!found) {
             compile_syntax_error(comp, (mp_parse_node_t)pns_trail[0],
-                "super() can't find self"); // really a TypeError
+                MP_ERROR_TEXT("super() can't find self")); // really a TypeError
             return;
         }
 
@@ -2352,14 +2352,14 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
             mp_parse_node_struct_t *pns_arg = (mp_parse_node_struct_t *)args[i];
             if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_star) {
                 if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) {
-                    compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple *x");
+                    compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("can't have multiple *x"));
                     return;
                 }
                 star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
                 star_args_node = pns_arg;
             } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
                 if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) {
-                    compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple **x");
+                    compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("can't have multiple **x"));
                     return;
                 }
                 star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
@@ -2367,7 +2367,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
             } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
                 if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_comp_for)) {
                     if (!MP_PARSE_NODE_IS_ID(pns_arg->nodes[0])) {
-                        compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "LHS of keyword arg must be an id");
+                        compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("LHS of keyword arg must be an id"));
                         return;
                     }
                     EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0]));
@@ -2383,11 +2383,11 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
         } else {
         normal_argument:
             if (star_flags) {
-                compile_syntax_error(comp, args[i], "non-keyword arg after */**");
+                compile_syntax_error(comp, args[i], MP_ERROR_TEXT("non-keyword arg after */**"));
                 return;
             }
             if (n_keyword > 0) {
-                compile_syntax_error(comp, args[i], "non-keyword arg after keyword arg");
+                compile_syntax_error(comp, args[i], MP_ERROR_TEXT("non-keyword arg after keyword arg"));
                 return;
             }
             compile_node(comp, args[i]);
@@ -2565,9 +2565,9 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t *
                     if (is_dict) {
                         if (!is_key_value) {
                             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-                            compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax");
+                            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax"));
                             #else
-                            compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting key:value for dict");
+                            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting key:value for dict"));
                             #endif
                             return;
                         }
@@ -2575,9 +2575,9 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t *
                     } else {
                         if (is_key_value) {
                             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-                            compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax");
+                            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax"));
                             #else
-                            compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting just a value for set");
+                            compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting just a value for set"));
                             #endif
                             return;
                         }
@@ -2706,7 +2706,7 @@ STATIC void compile_classdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
 
 STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
     if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) {
-        compile_syntax_error(comp, (mp_parse_node_t)pns, "'yield' outside function");
+        compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'yield' outside function"));
         return;
     }
     if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
@@ -2727,7 +2727,7 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
 #if MICROPY_PY_ASYNC_AWAIT
 STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pns) {
     if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) {
-        compile_syntax_error(comp, (mp_parse_node_t)pns, "'await' outside function");
+        compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'await' outside function"));
         return;
     }
     compile_atom_expr_normal(comp, pns);
@@ -2831,11 +2831,11 @@ STATIC int compile_viper_type_annotation(compiler_t *comp, mp_parse_node_t pn_an
         qstr type_name = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
         native_type = mp_native_type_from_qstr(type_name);
         if (native_type < 0) {
-            comp->compile_error = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, "unknown type '%q'", type_name);
+            comp->compile_error = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, MP_ERROR_TEXT("unknown type '%q'"), type_name);
             native_type = 0;
         }
     } else {
-        compile_syntax_error(comp, pn_annotation, "annotation must be an identifier");
+        compile_syntax_error(comp, pn_annotation, MP_ERROR_TEXT("annotation must be an identifier"));
     }
     return native_type;
 }
@@ -2846,7 +2846,7 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
 
     // check that **kw is last
     if ((comp->scope_cur->scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
-        compile_syntax_error(comp, pn, "invalid syntax");
+        compile_syntax_error(comp, pn, MP_ERROR_TEXT("invalid syntax"));
         return;
     }
 
@@ -2878,7 +2878,7 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
         } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
             if (comp->have_star) {
                 // more than one star
-                compile_syntax_error(comp, pn, "invalid syntax");
+                compile_syntax_error(comp, pn, MP_ERROR_TEXT("invalid syntax"));
                 return;
             }
             comp->have_star = true;
@@ -2912,7 +2912,7 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
     if (param_name != MP_QSTRnull) {
         id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, ID_INFO_KIND_UNDECIDED);
         if (id_info->kind != ID_INFO_KIND_UNDECIDED) {
-            compile_syntax_error(comp, pn, "argument name reused");
+            compile_syntax_error(comp, pn, MP_ERROR_TEXT("argument name reused"));
             return;
         }
         id_info->kind = ID_INFO_KIND_LOCAL;
@@ -3186,7 +3186,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
     comp->next_label = 0;
 
     if (scope->kind != SCOPE_FUNCTION) {
-        compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function");
+        compile_syntax_error(comp, MP_PARSE_NODE_NULL, MP_ERROR_TEXT("inline assembler must be a function"));
         return;
     }
 
@@ -3232,11 +3232,11 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
                     type_sig = MP_NATIVE_TYPE_UINT;
                     break;
                 default:
-                    compile_syntax_error(comp, pn_annotation, "unknown type");
+                    compile_syntax_error(comp, pn_annotation, MP_ERROR_TEXT("unknown type"));
                     return;
             }
         } else {
-            compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier");
+            compile_syntax_error(comp, pn_annotation, MP_ERROR_TEXT("return annotation must be an identifier"));
         }
     }
 
@@ -3253,7 +3253,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
         } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) {
             // not an instruction; error
         not_an_instruction:
-            compile_syntax_error(comp, nodes[i], "expecting an assembler instruction");
+            compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("expecting an assembler instruction"));
             return;
         }
 
@@ -3283,19 +3283,19 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
         // emit instructions
         if (op == MP_QSTR_label) {
             if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
-                compile_syntax_error(comp, nodes[i], "'label' requires 1 argument");
+                compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("'label' requires 1 argument"));
                 return;
             }
             uint lab = comp_next_label(comp);
             if (pass > MP_PASS_SCOPE) {
                 if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) {
-                    compile_syntax_error(comp, nodes[i], "label redefined");
+                    compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("label redefined"));
                     return;
                 }
             }
         } else if (op == MP_QSTR_align) {
             if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
-                compile_syntax_error(comp, nodes[i], "'align' requires 1 argument");
+                compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("'align' requires 1 argument"));
                 return;
             }
             if (pass > MP_PASS_SCOPE) {
@@ -3304,14 +3304,14 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
             }
         } else if (op == MP_QSTR_data) {
             if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
-                compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments");
+                compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("'data' requires at least 2 arguments"));
                 return;
             }
             if (pass > MP_PASS_SCOPE) {
                 mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
                 for (uint j = 1; j < n_args; j++) {
                     if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
-                        compile_syntax_error(comp, nodes[i], "'data' requires integer arguments");
+                        compile_syntax_error(comp, nodes[i], MP_ERROR_TEXT("'data' requires integer arguments"));
                         return;
                     }
                     mp_asm_base_data((mp_asm_base_t *)comp->emit_inline_asm,
diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c
index 7cf6f1cbb3..2853da26c5 100644
--- a/py/emitinlinethumb.c
+++ b/py/emitinlinethumb.c
@@ -99,17 +99,17 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit, mp_uint_t type_s
 
 STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) {
     if (n_params > 4) {
-        emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly");
+        emit_inline_thumb_error_msg(emit, MP_ERROR_TEXT("can only have up to 4 parameters to Thumb assembly"));
         return 0;
     }
     for (mp_uint_t i = 0; i < n_params; i++) {
         if (!MP_PARSE_NODE_IS_ID(pn_params[i])) {
-            emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
+            emit_inline_thumb_error_msg(emit, MP_ERROR_TEXT("parameters must be registers in sequence r0 to r3"));
             return 0;
         }
         const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i]));
         if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) {
-            emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
+            emit_inline_thumb_error_msg(emit, MP_ERROR_TEXT("parameters must be registers in sequence r0 to r3"));
             return 0;
         }
     }
@@ -189,7 +189,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
             if (r->reg > max_reg) {
                 emit_inline_thumb_error_exc(emit,
                     mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-                        "'%s' expects at most r%d", op, max_reg));
+                        MP_ERROR_TEXT("'%s' expects at most r%d"), op, max_reg));
                 return 0;
             } else {
                 return r->reg;
@@ -198,7 +198,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
     }
     emit_inline_thumb_error_exc(emit,
         mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-            "'%s' expects a register", op));
+            MP_ERROR_TEXT("'%s' expects a register"), op));
     return 0;
 }
 
@@ -212,7 +212,7 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp
     }
     emit_inline_thumb_error_exc(emit,
         mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-            "'%s' expects a special register", op));
+            MP_ERROR_TEXT("'%s' expects a special register"), op));
     return 0;
 }
 
@@ -231,7 +231,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars
         if (regno > 31) {
             emit_inline_thumb_error_exc(emit,
                 mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-                    "'%s' expects at most r%d", op, 31));
+                    MP_ERROR_TEXT("'%s' expects at most r%d"), op, 31));
             return 0;
         } else {
             return regno;
@@ -240,7 +240,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars
 malformed:
     emit_inline_thumb_error_exc(emit,
         mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-            "'%s' expects an FPU register", op));
+            MP_ERROR_TEXT("'%s' expects an FPU register"), op));
     return 0;
 }
 #endif
@@ -293,19 +293,19 @@ STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_par
     return reglist;
 
 bad_arg:
-    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects {r0, r1, ...}", op));
+    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects {r0, r1, ...}"), op));
     return 0;
 }
 
 STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, uint32_t fit_mask) {
     mp_obj_t o;
     if (!mp_parse_node_get_int_maybe(pn, &o)) {
-        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op));
+        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects an integer"), op));
         return 0;
     }
     uint32_t i = mp_obj_get_int_truncated(o);
     if ((i & (~fit_mask)) != 0) {
-        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer 0x%x doesn't fit in mask 0x%x", op, i, fit_mask));
+        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' integer 0x%x doesn't fit in mask 0x%x"), op, i, fit_mask));
         return 0;
     }
     return i;
@@ -329,13 +329,13 @@ STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_
     return true;
 
 bad_arg:
-    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an address of the form [a, b]", op));
+    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects an address of the form [a, b]"), op));
     return false;
 }
 
 STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
     if (!MP_PARSE_NODE_IS_ID(pn)) {
-        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op));
+        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects a label"), op));
         return 0;
     }
     qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn);
@@ -346,7 +346,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
     }
     // only need to have the labels on the last pass
     if (emit->pass == MP_PASS_EMIT) {
-        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr));
+        emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("label '%q' not defined"), label_qstr));
     }
     return 0;
 }
@@ -817,11 +817,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
     return;
 
 unknown_op:
-    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Thumb instruction '%s' with %d arguments", op_str, n_args));
+    emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("unsupported Thumb instruction '%s' with %d arguments"), op_str, n_args));
     return;
 
 branch_not_in_range:
-    emit_inline_thumb_error_msg(emit, "branch not in range");
+    emit_inline_thumb_error_msg(emit, MP_ERROR_TEXT("branch not in range"));
     return;
 }
 
diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c
index 677638277e..6cc2e4d34b 100644
--- a/py/emitinlinextensa.c
+++ b/py/emitinlinextensa.c
@@ -43,7 +43,7 @@ struct _emit_inline_asm_t {
     qstr *label_lookup;
 };
 
-STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, const char *msg) {
+STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, mp_rom_error_text_t msg) {
     *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg);
 }
 
@@ -83,17 +83,17 @@ STATIC void emit_inline_xtensa_end_pass(emit_inline_asm_t *emit, mp_uint_t type_
 
 STATIC mp_uint_t emit_inline_xtensa_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) {
     if (n_params > 4) {
-        emit_inline_xtensa_error_msg(emit, "can only have up to 4 parameters to Xtensa assembly");
+        emit_inline_xtensa_error_msg(emit, MP_ERROR_TEXT("can only have up to 4 parameters to Xtensa assembly"));
         return 0;
     }
     for (mp_uint_t i = 0; i < n_params; i++) {
         if (!MP_PARSE_NODE_IS_ID(pn_params[i])) {
-            emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5");
+            emit_inline_xtensa_error_msg(emit, MP_ERROR_TEXT("parameters must be registers in sequence a2 to a5"));
             return 0;
         }
         const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i]));
         if (!(strlen(p) == 2 && p[0] == 'a' && p[1] == '2' + i)) {
-            emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5");
+            emit_inline_xtensa_error_msg(emit, MP_ERROR_TEXT("parameters must be registers in sequence a2 to a5"));
             return 0;
         }
     }
@@ -161,19 +161,19 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
     }
     emit_inline_xtensa_error_exc(emit,
         mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
-            "'%s' expects a register", op));
+            MP_ERROR_TEXT("'%s' expects a register"), op));
     return 0;
 }
 
 STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, int min, int max) {
     mp_obj_t o;
     if (!mp_parse_node_get_int_maybe(pn, &o)) {
-        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op));
+        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects an integer"), op));
         return 0;
     }
     uint32_t i = mp_obj_get_int_truncated(o);
     if (min != max && ((int)i < min || (int)i > max)) {
-        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer %d isn't within range %d..%d", op, i, min, max));
+        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' integer %d isn't within range %d..%d"), op, i, min, max));
         return 0;
     }
     return i;
@@ -181,7 +181,7 @@ STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node
 
 STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
     if (!MP_PARSE_NODE_IS_ID(pn)) {
-        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op));
+        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects a label"), op));
         return 0;
     }
     qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn);
@@ -192,7 +192,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
     }
     // only need to have the labels on the last pass
     if (emit->pass == MP_PASS_EMIT) {
-        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr));
+        emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("label '%q' not defined"), label_qstr));
     }
     return 0;
 }
@@ -326,12 +326,12 @@ STATIC void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
     return;
 
 unknown_op:
-    emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Xtensa instruction '%s' with %d arguments", op_str, n_args));
+    emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("unsupported Xtensa instruction '%s' with %d arguments"), op_str, n_args));
     return;
 
     /*
 branch_not_in_range:
-    emit_inline_xtensa_error_msg(emit, "branch not in range");
+    emit_inline_xtensa_error_msg(emit, MP_ERROR_TEXT("branch not in range"));
     return;
     */
 }
diff --git a/py/emitnative.c b/py/emitnative.c
index 7deabe3e84..6c8e9feeba 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -841,7 +841,7 @@ STATIC vtype_kind_t load_reg_stack_imm(emit_t *emit, int reg_dest, const stack_i
         } else if (si->vtype == VTYPE_PTR_NONE) {
             emit_native_mov_reg_const(emit, reg_dest, MP_F_CONST_NONE_OBJ);
         } else {
-            mp_raise_NotImplementedError("conversion to object");
+            mp_raise_NotImplementedError(MP_ERROR_TEXT("conversion to object"));
         }
         return VTYPE_PYOBJ;
     }
@@ -1415,7 +1415,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
     DEBUG_printf("load_fast(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
     vtype_kind_t vtype = emit->local_vtype[local_num];
     if (vtype == VTYPE_UNBOUND) {
-        EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "local '%q' used before type known", qst);
+        EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("local '%q' used before type known"), qst);
     }
     emit_native_pre(emit);
     if (local_num < REG_LOCAL_NUM && CAN_USE_REGS_FOR_LOCALS(emit)) {
@@ -1590,7 +1590,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
                 }
                 default:
                     EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                        "can't load from '%q'", vtype_to_qstr(vtype_base));
+                        MP_ERROR_TEXT("can't load from '%q'"), vtype_to_qstr(vtype_base));
             }
         } else {
             // index is not an immediate
@@ -1600,7 +1600,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
             emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
             if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
                 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                    "can't load with '%q' index", vtype_to_qstr(vtype_index));
+                    MP_ERROR_TEXT("can't load with '%q' index"), vtype_to_qstr(vtype_index));
             }
             switch (vtype_base) {
                 case VTYPE_PTR8: {
@@ -1628,7 +1628,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
                 }
                 default:
                     EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                        "can't load from '%q'", vtype_to_qstr(vtype_base));
+                        MP_ERROR_TEXT("can't load from '%q'"), vtype_to_qstr(vtype_base));
             }
         }
         emit_post_push_reg(emit, VTYPE_INT, REG_RET);
@@ -1652,7 +1652,7 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num)
     } else if (emit->local_vtype[local_num] != vtype) {
         // type of local is not the same as object stored in it
         EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-            "local '%q' has type '%q' but source is '%q'",
+            MP_ERROR_TEXT("local '%q' has type '%q' but source is '%q'"),
             qst, vtype_to_qstr(emit->local_vtype[local_num]), vtype_to_qstr(vtype));
     }
 }
@@ -1753,7 +1753,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
             #endif
             if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
                 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                    "can't store '%q'", vtype_to_qstr(vtype_value));
+                    MP_ERROR_TEXT("can't store '%q'"), vtype_to_qstr(vtype_value));
             }
             switch (vtype_base) {
                 case VTYPE_PTR8: {
@@ -1819,7 +1819,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
                 }
                 default:
                     EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                        "can't store to '%q'", vtype_to_qstr(vtype_base));
+                        MP_ERROR_TEXT("can't store to '%q'"), vtype_to_qstr(vtype_base));
             }
         } else {
             // index is not an immediate
@@ -1830,7 +1830,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
             emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1);
             if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) {
                 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                    "can't store with '%q' index", vtype_to_qstr(vtype_index));
+                    MP_ERROR_TEXT("can't store with '%q' index"), vtype_to_qstr(vtype_index));
             }
             #if N_X86
             // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX)
@@ -1840,7 +1840,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
             #endif
             if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) {
                 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                    "can't store '%q'", vtype_to_qstr(vtype_value));
+                    MP_ERROR_TEXT("can't store '%q'"), vtype_to_qstr(vtype_value));
             }
             switch (vtype_base) {
                 case VTYPE_PTR8: {
@@ -1880,7 +1880,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
                 }
                 default:
                     EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                        "can't store to '%q'", vtype_to_qstr(vtype_base));
+                        MP_ERROR_TEXT("can't store to '%q'"), vtype_to_qstr(vtype_base));
             }
         }
 
@@ -2002,7 +2002,7 @@ STATIC void emit_native_jump_helper(emit_t *emit, bool cond, mp_uint_t label, bo
         }
         if (!(vtype == VTYPE_BOOL || vtype == VTYPE_INT || vtype == VTYPE_UINT)) {
             EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                "can't implicitly convert '%q' to 'bool'", vtype_to_qstr(vtype));
+                MP_ERROR_TEXT("can't implicitly convert '%q' to 'bool'"), vtype_to_qstr(vtype));
         }
     }
     // For non-pop need to save the vtype so that emit_native_adjust_stack_size
@@ -2281,7 +2281,7 @@ STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
     } else {
         adjust_stack(emit, 1);
         EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-            "unary op %q not implemented", mp_unary_op_method_name[op]);
+            MP_ERROR_TEXT("unary op %q not implemented"), mp_unary_op_method_name[op]);
     }
 }
 
@@ -2440,7 +2440,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
             // TODO other ops not yet implemented
             adjust_stack(emit, 1);
             EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                "binary op %q not implemented", mp_binary_op_method_name[op]);
+                MP_ERROR_TEXT("binary op %q not implemented"), mp_binary_op_method_name[op]);
         }
     } else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) {
         emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2);
@@ -2461,7 +2461,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
     } else {
         adjust_stack(emit, -1);
         EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-            "can't do binary op between '%q' and '%q'",
+            MP_ERROR_TEXT("can't do binary op between '%q' and '%q'"),
             vtype_to_qstr(vtype_lhs), vtype_to_qstr(vtype_rhs));
     }
 }
@@ -2639,7 +2639,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
                 break;
             default:
                 // this can happen when casting a cast: int(int)
-                mp_raise_NotImplementedError("casting");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("casting"));
         }
     } else {
         assert(vtype_fun == VTYPE_PYOBJ);
@@ -2703,7 +2703,7 @@ STATIC void emit_native_return_value(emit_t *emit) {
             emit_pre_pop_reg(emit, &vtype, return_vtype == VTYPE_PYOBJ ? REG_PARENT_RET : REG_ARG_1);
             if (vtype != return_vtype) {
                 EMIT_NATIVE_VIPER_TYPE_ERROR(emit,
-                    "return expected '%q' but got '%q'",
+                    MP_ERROR_TEXT("return expected '%q' but got '%q'"),
                     vtype_to_qstr(return_vtype), vtype_to_qstr(vtype));
             }
         }
@@ -2732,7 +2732,7 @@ STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
     vtype_kind_t vtype_exc;
     emit_pre_pop_reg(emit, &vtype_exc, REG_ARG_1); // arg1 = object to raise
     if (vtype_exc != VTYPE_PYOBJ) {
-        EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "must raise an object");
+        EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("must raise an object"));
     }
     // TODO probably make this 1 call to the runtime (which could even call convert, native_raise(obj, type))
     emit_call(emit, MP_F_NATIVE_RAISE);
@@ -2742,7 +2742,7 @@ STATIC void emit_native_yield(emit_t *emit, int kind) {
     // Note: 1 (yield) or 3 (yield from) labels are reserved for this function, starting at *emit->label_slot
 
     if (emit->do_viper_types) {
-        mp_raise_NotImplementedError("native yield");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("native yield"));
     }
     emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
 
diff --git a/py/lexer.c b/py/lexer.c
index dd77872871..062a3c5751 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -360,7 +360,7 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw) {
                             // 3MB of text; even gzip-compressed and with minimal structure, it'll take
                             // roughly half a meg of storage. This form of Unicode escape may be added
                             // later on, but it's definitely not a priority right now. -- CJA 20140607
-                            mp_raise_NotImplementedError("unicode name escapes");
+                            mp_raise_NotImplementedError(MP_ERROR_TEXT("unicode name escapes"));
                             break;
                         default:
                             if (c >= '0' && c <= '7') {
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 06bc7004c8..89e18c0fff 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -160,7 +160,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
         str[3] = (c & 0x3F) | 0x80;
         len = 4;
     } else {
-        mp_raise_ValueError("chr() arg not in range(0x110000)");
+        mp_raise_ValueError(MP_ERROR_TEXT("chr() arg not in range(0x110000)"));
     }
     // Don't intern non-ASCII chars, as they may take a lot of qstr storage uselessly
     return mp_obj_new_str((char *)str, len);
@@ -170,7 +170,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
         uint8_t str[1] = {ord};
         return mp_obj_new_str_via_qstr((char *)str, 1);
     } else {
-        mp_raise_ValueError("chr() arg not in range(256)");
+        mp_raise_ValueError(MP_ERROR_TEXT("chr() arg not in range(256)"));
     }
     #endif
 }
@@ -289,7 +289,7 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t
             if (default_elem != NULL) {
                 best_obj = default_elem->value;
             } else {
-                mp_raise_ValueError("arg is an empty sequence");
+                mp_raise_ValueError(MP_ERROR_TEXT("arg is an empty sequence"));
             }
         }
         return best_obj;
@@ -376,10 +376,10 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
     }
 
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_TypeError("ord expects a character");
+    mp_raise_TypeError(MP_ERROR_TEXT("ord expects a character"));
     #else
     mp_raise_msg_varg(&mp_type_TypeError,
-        "ord() expected a character, but string of length %d found", (int)len);
+        MP_ERROR_TEXT("ord() expected a character, but string of length %d found"), (int)len);
     #endif
 }
 MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord);
@@ -390,7 +390,7 @@ STATIC mp_obj_t mp_builtin_pow(size_t n_args, const mp_obj_t *args) {
             return mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]);
         default:
             #if !MICROPY_PY_BUILTINS_POW3
-            mp_raise_NotImplementedError("3-arg pow() not supported");
+            mp_raise_NotImplementedError(MP_ERROR_TEXT("3-arg pow() not supported"));
             #elif MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_MPZ
             return mp_binary_op(MP_BINARY_OP_MODULO, mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]), args[2]);
             #else
@@ -553,7 +553,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum);
 
 STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
     if (n_args > 1) {
-        mp_raise_TypeError("must use keyword argument for key function");
+        mp_raise_TypeError(MP_ERROR_TEXT("must use keyword argument for key function"));
     }
     mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args);
     mp_obj_list_sort(1, &self, kwargs);
diff --git a/py/modmath.c b/py/modmath.c
index 52ad0b0001..f6f43b4ad8 100644
--- a/py/modmath.c
+++ b/py/modmath.c
@@ -36,7 +36,7 @@
 #define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846)
 
 STATIC NORETURN void math_error(void) {
-    mp_raise_ValueError("math domain error");
+    mp_raise_ValueError(MP_ERROR_TEXT("math domain error"));
 }
 
 STATIC mp_obj_t math_generic_1(mp_obj_t x_obj, mp_float_t (*f)(mp_float_t)) {
@@ -223,7 +223,7 @@ STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) {
         if (base <= (mp_float_t)0.0) {
             math_error();
         } else if (base == (mp_float_t)1.0) {
-            mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
+            mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
         }
         return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base));
     }
@@ -294,7 +294,7 @@ STATIC mp_obj_t mp_math_factorial_inner(mp_uint_t start, mp_uint_t end) {
 STATIC mp_obj_t mp_math_factorial(mp_obj_t x_obj) {
     mp_int_t max = mp_obj_get_int(x_obj);
     if (max < 0) {
-        mp_raise_ValueError("negative factorial");
+        mp_raise_ValueError(MP_ERROR_TEXT("negative factorial"));
     } else if (max == 0) {
         return MP_OBJ_NEW_SMALL_INT(1);
     }
@@ -308,7 +308,7 @@ STATIC mp_obj_t mp_math_factorial(mp_obj_t x_obj) {
 STATIC mp_obj_t mp_math_factorial(mp_obj_t x_obj) {
     mp_int_t max = mp_obj_get_int(x_obj);
     if (max < 0) {
-        mp_raise_ValueError("negative factorial");
+        mp_raise_ValueError(MP_ERROR_TEXT("negative factorial"));
     } else if (max <= 1) {
         return MP_OBJ_NEW_SMALL_INT(1);
     }
diff --git a/py/modmicropython.c b/py/modmicropython.c
index a45321a64b..d7ae52cdc2 100644
--- a/py/modmicropython.c
+++ b/py/modmicropython.c
@@ -164,7 +164,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_micropython_kbd_intr_obj, mp_micropython_kbd
 #if MICROPY_ENABLE_SCHEDULER
 STATIC mp_obj_t mp_micropython_schedule(mp_obj_t function, mp_obj_t arg) {
     if (!mp_sched_schedule(function, arg)) {
-        mp_raise_msg(&mp_type_RuntimeError, "schedule queue full");
+        mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("schedule queue full"));
     }
     return mp_const_none;
 }
diff --git a/py/modstruct.c b/py/modstruct.c
index dc49e3441c..d9c60dac96 100644
--- a/py/modstruct.c
+++ b/py/modstruct.c
@@ -141,7 +141,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
             // negative offsets are relative to the end of the buffer
             offset = bufinfo.len + offset;
             if (offset < 0) {
-                mp_raise_ValueError("buffer too small");
+                mp_raise_ValueError(MP_ERROR_TEXT("buffer too small"));
             }
         }
         p += offset;
@@ -149,7 +149,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
 
     // Check that the input buffer is big enough to unpack all the values
     if (p + total_sz > end_p) {
-        mp_raise_ValueError("buffer too small");
+        mp_raise_ValueError(MP_ERROR_TEXT("buffer too small"));
     }
 
     size_t field_offset = 0;
@@ -232,7 +232,7 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
         // negative offsets are relative to the end of the buffer
         offset = (mp_int_t)bufinfo.len + offset;
         if (offset < 0) {
-            mp_raise_ValueError("buffer too small");
+            mp_raise_ValueError(MP_ERROR_TEXT("buffer too small"));
         }
     }
     byte *p = (byte *)bufinfo.buf;
@@ -242,7 +242,7 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
     // Check that the output buffer is big enough to hold all the values
     mp_int_t sz = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
     if (p + sz > end_p) {
-        mp_raise_ValueError("buffer too small");
+        mp_raise_ValueError(MP_ERROR_TEXT("buffer too small"));
     }
 
     mp_struct_pack_into_internal(args[0], p, n_args - 3, &args[3]);
diff --git a/py/modthread.c b/py/modthread.c
index 35e7d509d3..1306dc642b 100644
--- a/py/modthread.c
+++ b/py/modthread.c
@@ -235,7 +235,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
     } else {
         // positional and keyword arguments
         if (mp_obj_get_type(args[2]) != &mp_type_dict) {
-            mp_raise_TypeError("expecting a dict for keyword args");
+            mp_raise_TypeError(MP_ERROR_TEXT("expecting a dict for keyword args"));
         }
         mp_map_t *map = &((mp_obj_dict_t *)MP_OBJ_TO_PTR(args[2]))->map;
         th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used);
diff --git a/py/nativeglue.c b/py/nativeglue.c
index ee38e4dbba..eebbe18bb7 100644
--- a/py/nativeglue.c
+++ b/py/nativeglue.c
@@ -118,13 +118,13 @@ mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) {
 mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) {
     (void)n_args;
     (void)items;
-    mp_raise_msg(&mp_type_RuntimeError, "set unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("set unsupported"));
 }
 
 void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) {
     (void)self_in;
     (void)item;
-    mp_raise_msg(&mp_type_RuntimeError, "set unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("set unsupported"));
 }
 #endif
 
@@ -133,7 +133,7 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
     (void)ostart;
     (void)ostop;
     (void)ostep;
-    mp_raise_msg(&mp_type_RuntimeError, "slice unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("slice unsupported"));
 }
 #endif
 
@@ -249,22 +249,22 @@ STATIC double mp_obj_get_float_to_d(mp_obj_t o) {
 
 STATIC mp_obj_t mp_obj_new_float_from_f(float f) {
     (void)f;
-    mp_raise_msg(&mp_type_RuntimeError, "float unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
 }
 
 STATIC mp_obj_t mp_obj_new_float_from_d(double d) {
     (void)d;
-    mp_raise_msg(&mp_type_RuntimeError, "float unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
 }
 
 STATIC float mp_obj_get_float_to_f(mp_obj_t o) {
     (void)o;
-    mp_raise_msg(&mp_type_RuntimeError, "float unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
 }
 
 STATIC double mp_obj_get_float_to_d(mp_obj_t o) {
     (void)o;
-    mp_raise_msg(&mp_type_RuntimeError, "float unsupported");
+    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
 }
 
 #endif
diff --git a/py/obj.c b/py/obj.c
index b2c524786c..5d53873a0f 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -343,10 +343,10 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) {
 
     if (!mp_obj_get_float_maybe(arg, &val)) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("can't convert to float");
+        mp_raise_TypeError(MP_ERROR_TEXT("can't convert to float"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "can't convert %s to float", mp_obj_get_type_str(arg));
+            MP_ERROR_TEXT("can't convert %s to float"), mp_obj_get_type_str(arg));
         #endif
     }
 
@@ -376,10 +376,10 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
         mp_obj_complex_get(arg, real, imag);
     } else {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("can't convert to complex");
+        mp_raise_TypeError(MP_ERROR_TEXT("can't convert to complex"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "can't convert %s to complex", mp_obj_get_type_str(arg));
+            MP_ERROR_TEXT("can't convert %s to complex"), mp_obj_get_type_str(arg));
         #endif
     }
 }
@@ -394,10 +394,10 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) {
         mp_obj_list_get(o, len, items);
     } else {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("expected tuple/list");
+        mp_raise_TypeError(MP_ERROR_TEXT("expected tuple/list"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "object '%s' isn't a tuple or list", mp_obj_get_type_str(o));
+            MP_ERROR_TEXT("object '%s' isn't a tuple or list"), mp_obj_get_type_str(o));
         #endif
     }
 }
@@ -408,10 +408,10 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) {
     mp_obj_get_array(o, &seq_len, items);
     if (seq_len != len) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_ValueError("tuple/list has wrong length");
+        mp_raise_ValueError(MP_ERROR_TEXT("tuple/list has wrong length"));
         #else
         mp_raise_msg_varg(&mp_type_ValueError,
-            "requested length %d but object has length %d", (int)len, (int)seq_len);
+            MP_ERROR_TEXT("requested length %d but object has length %d"), (int)len, (int)seq_len);
         #endif
     }
 }
@@ -423,10 +423,10 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool
         i = MP_OBJ_SMALL_INT_VALUE(index);
     } else if (!mp_obj_get_int_maybe(index, &i)) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("indices must be integers");
+        mp_raise_TypeError(MP_ERROR_TEXT("indices must be integers"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "%q indices must be integers, not %s",
+            MP_ERROR_TEXT("%q indices must be integers, not %s"),
             type->name, mp_obj_get_type_str(index));
         #endif
     }
@@ -443,9 +443,9 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool
     } else {
         if (i < 0 || (mp_uint_t)i >= len) {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_msg(&mp_type_IndexError, "index out of range");
+            mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("index out of range"));
             #else
-            mp_raise_msg_varg(&mp_type_IndexError, "%q index out of range", type->name);
+            mp_raise_msg_varg(&mp_type_IndexError, MP_ERROR_TEXT("%q index out of range"), type->name);
             #endif
         }
     }
@@ -477,10 +477,10 @@ mp_obj_t mp_obj_len(mp_obj_t o_in) {
     mp_obj_t len = mp_obj_len_maybe(o_in);
     if (len == MP_OBJ_NULL) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("object has no len");
+        mp_raise_TypeError(MP_ERROR_TEXT("object has no len"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "object of type '%s' has no len()", mp_obj_get_type_str(o_in));
+            MP_ERROR_TEXT("object of type '%s' has no len()"), mp_obj_get_type_str(o_in));
         #endif
     } else {
         return len;
@@ -518,24 +518,24 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
     }
     if (value == MP_OBJ_NULL) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("object doesn't support item deletion");
+        mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item deletion"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "'%s' object doesn't support item deletion", mp_obj_get_type_str(base));
+            MP_ERROR_TEXT("'%s' object doesn't support item deletion"), mp_obj_get_type_str(base));
         #endif
     } else if (value == MP_OBJ_SENTINEL) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("object isn't subscriptable");
+        mp_raise_TypeError(MP_ERROR_TEXT("object isn't subscriptable"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "'%s' object isn't subscriptable", mp_obj_get_type_str(base));
+            MP_ERROR_TEXT("'%s' object isn't subscriptable"), mp_obj_get_type_str(base));
         #endif
     } else {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("object doesn't support item assignment");
+        mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item assignment"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "'%s' object doesn't support item assignment", mp_obj_get_type_str(base));
+            MP_ERROR_TEXT("'%s' object doesn't support item assignment"), mp_obj_get_type_str(base));
         #endif
     }
 }
@@ -597,7 +597,7 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
 
 void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
     if (!mp_get_buffer(obj, bufinfo, flags)) {
-        mp_raise_TypeError("object with buffer protocol required");
+        mp_raise_TypeError(MP_ERROR_TEXT("object with buffer protocol required"));
     }
 }
 
diff --git a/py/objarray.c b/py/objarray.c
index bbab9ad62c..f2ba0a2ced 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -422,7 +422,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
         if (mp_obj_is_type(index_in, &mp_type_slice)) {
             mp_bound_slice_t slice;
             if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
-                mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("only slices with step=1 (aka None) are supported"));
             }
             if (value != MP_OBJ_SENTINEL) {
                 #if MICROPY_PY_ARRAY_SLICE_ASSIGN
@@ -435,7 +435,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
                     mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value);
                     if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
                     compat_error:
-                        mp_raise_ValueError("lhs and rhs should be compatible");
+                        mp_raise_ValueError(MP_ERROR_TEXT("lhs and rhs should be compatible"));
                     }
                     src_len = src_slice->len;
                     src_items = src_slice->items;
@@ -453,7 +453,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
                     src_len = bufinfo.len;
                     src_items = bufinfo.buf;
                 } else {
-                    mp_raise_NotImplementedError("array/bytes required on right side");
+                    mp_raise_NotImplementedError(MP_ERROR_TEXT("array/bytes required on right side"));
                 }
 
                 // TODO: check src/dst compat
diff --git a/py/objcomplex.c b/py/objcomplex.c
index d382bc1701..74c7f486ca 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -195,13 +195,13 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo
         }
         case MP_BINARY_OP_FLOOR_DIVIDE:
         case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
-            mp_raise_TypeError("can't truncate-divide a complex number");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't truncate-divide a complex number"));
 
         case MP_BINARY_OP_TRUE_DIVIDE:
         case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
             if (rhs_imag == 0) {
                 if (rhs_real == 0) {
-                    mp_raise_msg(&mp_type_ZeroDivisionError, "complex divide by zero");
+                    mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("complex divide by zero"));
                 }
                 lhs_real /= rhs_real;
                 lhs_imag /= rhs_real;
@@ -229,7 +229,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo
                 if (rhs_imag == 0 && rhs_real >= 0) {
                     lhs_real = (rhs_real == 0);
                 } else {
-                    mp_raise_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power");
+                    mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("0.0 to a complex power"));
                 }
             } else {
                 mp_float_t ln1 = MICROPY_FLOAT_C_FUN(log)(abs1);
diff --git a/py/objdeque.c b/py/objdeque.c
index 0eb666591e..c95bdeee9e 100644
--- a/py/objdeque.c
+++ b/py/objdeque.c
@@ -102,7 +102,7 @@ STATIC mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) {
     }
 
     if (self->flags & FLAG_CHECK_OVERFLOW && new_i_put == self->i_get) {
-        mp_raise_msg(&mp_type_IndexError, "full");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("full"));
     }
 
     self->items[self->i_put] = arg;
@@ -122,7 +122,7 @@ STATIC mp_obj_t deque_popleft(mp_obj_t self_in) {
     mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in);
 
     if (self->i_get == self->i_put) {
-        mp_raise_msg(&mp_type_IndexError, "empty");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty"));
     }
 
     mp_obj_t ret = self->items[self->i_get];
diff --git a/py/objdict.c b/py/objdict.c
index 5447826a4d..2a72c62524 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -324,7 +324,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
     size_t cur = 0;
     mp_map_elem_t *next = dict_iter_next(self, &cur);
     if (next == NULL) {
-        mp_raise_msg(&mp_type_KeyError, "popitem(): dictionary is empty");
+        mp_raise_msg(&mp_type_KeyError, MP_ERROR_TEXT("popitem(): dictionary is empty"));
     }
     self->map.used--;
     mp_obj_t items[] = {next->key, next->value};
@@ -367,7 +367,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg
                 if (key == MP_OBJ_STOP_ITERATION
                     || value == MP_OBJ_STOP_ITERATION
                     || stop != MP_OBJ_STOP_ITERATION) {
-                    mp_raise_ValueError("dict update sequence has wrong length");
+                    mp_raise_ValueError(MP_ERROR_TEXT("dict update sequence has wrong length"));
                 } else {
                     mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
                 }
diff --git a/py/objfloat.c b/py/objfloat.c
index b39497b3d5..ad2cda2a87 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -260,7 +260,7 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t
         case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
             if (rhs_val == 0) {
             zero_division_error:
-                mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
+                mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
             }
             // Python specs require that x == (x//y)*y + (x%y) so we must
             // call divmod to compute the correct floor division, which
@@ -298,7 +298,7 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t
                 #if MICROPY_PY_BUILTINS_COMPLEX
                 return mp_obj_complex_binary_op(MP_BINARY_OP_POWER, lhs_val, 0, rhs_in);
                 #else
-                mp_raise_ValueError("complex values not supported");
+                mp_raise_ValueError(MP_ERROR_TEXT("complex values not supported"));
                 #endif
             }
             lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val);
diff --git a/py/objgenerator.c b/py/objgenerator.c
index dc78cd454d..e294149aca 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -174,7 +174,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
     }
     if (self->code_state.sp == self->code_state.state - 1) {
         if (send_value != mp_const_none) {
-            mp_raise_TypeError("can't send non-None value to a just-started generator");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't send non-None value to a just-started generator"));
         }
         #if MICROPY_PY_GENERATOR_PEND_THROW
         // If exception is pending (set using .pend_throw()), process it now.
@@ -199,7 +199,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
     // We set self->globals=NULL while executing, for a sentinel to ensure the generator
     // cannot be reentered during execution
     if (self->globals == NULL) {
-        mp_raise_ValueError("generator already executing");
+        mp_raise_ValueError(MP_ERROR_TEXT("generator already executing"));
     }
 
     // Set up the correct globals context for the generator and execute it
@@ -247,7 +247,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
             *ret_val = self->code_state.state[0];
             // PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError
             if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(*ret_val)), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
-                *ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator raised StopIteration");
+                *ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator raised StopIteration"));
             }
             break;
         }
@@ -328,7 +328,7 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
 
     switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) {
         case MP_VM_RETURN_YIELD:
-            mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit");
+            mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator ignored GeneratorExit"));
 
         // Swallow GeneratorExit (== successful close), and re-raise any other
         case MP_VM_RETURN_EXCEPTION:
diff --git a/py/objint.c b/py/objint.c
index d444c6c325..1a3816a9ab 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -137,9 +137,9 @@ STATIC mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
 mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
     int cl = fpclassify(val);
     if (cl == FP_INFINITE) {
-        mp_raise_msg(&mp_type_OverflowError, "can't convert inf to int");
+        mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("can't convert inf to int"));
     } else if (cl == FP_NAN) {
-        mp_raise_ValueError("can't convert NaN to int");
+        mp_raise_ValueError(MP_ERROR_TEXT("can't convert NaN to int"));
     } else {
         mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
         if (icl == MP_FP_CLASS_FIT_SMALLINT) {
@@ -156,7 +156,7 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
             return mp_obj_new_int_from_ll((long long)val);
         #endif
         } else {
-            mp_raise_ValueError("float too big");
+            mp_raise_ValueError(MP_ERROR_TEXT("float too big"));
         }
         #endif
     }
@@ -321,19 +321,19 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
 
 // This is called only with strings whose value doesn't fit in SMALL_INT
 mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) {
-    mp_raise_msg(&mp_type_OverflowError, "long int not supported in this build");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("long int not supported in this build"));
     return mp_const_none;
 }
 
 // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
 mp_obj_t mp_obj_new_int_from_ll(long long val) {
-    mp_raise_msg(&mp_type_OverflowError, "small int overflow");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow"));
     return mp_const_none;
 }
 
 // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
 mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
-    mp_raise_msg(&mp_type_OverflowError, "small int overflow");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow"));
     return mp_const_none;
 }
 
@@ -343,7 +343,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
     if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) {
         return MP_OBJ_NEW_SMALL_INT(value);
     }
-    mp_raise_msg(&mp_type_OverflowError, "small int overflow");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow"));
     return mp_const_none;
 }
 
@@ -351,7 +351,7 @@ mp_obj_t mp_obj_new_int(mp_int_t value) {
     if (MP_SMALL_INT_FITS(value)) {
         return MP_OBJ_NEW_SMALL_INT(value);
     }
-    mp_raise_msg(&mp_type_OverflowError, "small int overflow");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow"));
     return mp_const_none;
 }
 
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index c34415a93c..619b4d2b54 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -190,7 +190,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
                 #if MICROPY_PY_BUILTINS_FLOAT
                 return mp_obj_float_binary_op(op, lhs_val, rhs_in);
                 #else
-                mp_raise_ValueError("negative power with no float support");
+                mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support"));
                 #endif
             }
             long long ans = 1;
@@ -223,7 +223,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
     }
 
 zero_division:
-    mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
+    mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
 }
 
 mp_obj_t mp_obj_new_int(mp_int_t value) {
@@ -252,7 +252,7 @@ mp_obj_t mp_obj_new_int_from_ll(long long val) {
 mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
     // TODO raise an exception if the unsigned long long won't fit
     if (val >> (sizeof(unsigned long long) * 8 - 1) != 0) {
-        mp_raise_msg(&mp_type_OverflowError, "ulonglong too large");
+        mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ulonglong too large"));
     }
     mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
     o->base.type = &mp_type_int;
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 0455a58ec1..f2f0dbc3a5 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -237,7 +237,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
             case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
                 if (mpz_is_zero(zrhs)) {
                 zero_division_error:
-                    mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
+                    mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
                 }
                 mpz_t rem;
                 mpz_init_zero(&rem);
@@ -276,7 +276,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
             case MP_BINARY_OP_INPLACE_RSHIFT: {
                 mp_int_t irhs = mp_obj_int_get_checked(rhs_in);
                 if (irhs < 0) {
-                    mp_raise_ValueError("negative shift count");
+                    mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
                 }
                 if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
                     mpz_shl_inpl(&res->mpz, zlhs, irhs);
@@ -292,7 +292,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
                     #if MICROPY_PY_BUILTINS_FLOAT
                     return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in);
                     #else
-                    mp_raise_ValueError("negative power with no float support");
+                    mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support"));
                     #endif
                 }
                 mpz_pow_inpl(&res->mpz, zlhs, zrhs);
@@ -345,7 +345,7 @@ STATIC mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) {
 
 mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent,  mp_obj_t modulus) {
     if (!mp_obj_is_int(base) || !mp_obj_is_int(exponent) || !mp_obj_is_int(modulus)) {
-        mp_raise_TypeError("pow() with 3 arguments requires integers");
+        mp_raise_TypeError(MP_ERROR_TEXT("pow() with 3 arguments requires integers"));
     } else {
         mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int
         mp_obj_int_t *res_p = (mp_obj_int_t *)MP_OBJ_TO_PTR(result);
@@ -426,7 +426,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
             return value;
         } else {
             // overflow
-            mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word");
+            mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
         }
     }
 }
@@ -444,7 +444,7 @@ mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
         }
     }
 
-    mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word");
+    mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word"));
 }
 
 #if MICROPY_PY_BUILTINS_FLOAT
diff --git a/py/objlist.c b/py/objlist.c
index 38329e0e6f..8c989facc0 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -270,7 +270,7 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) {
     mp_check_self(mp_obj_is_type(args[0], &mp_type_list));
     mp_obj_list_t *self = MP_OBJ_TO_PTR(args[0]);
     if (self->len == 0) {
-        mp_raise_msg(&mp_type_IndexError, "pop from empty list");
+        mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("pop from empty list"));
     }
     size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false);
     mp_obj_t ret = self->items[index];
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index d9ee995ecf..99c019b84d 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -87,7 +87,7 @@ STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
     } else {
         // delete/store attribute
         // provide more detailed error message than we'd get by just returning
-        mp_raise_msg(&mp_type_AttributeError, "can't set attribute");
+        mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("can't set attribute"));
     }
 }
 
@@ -99,11 +99,11 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args,
         mp_arg_error_terse_mismatch();
         #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
         mp_raise_msg_varg(&mp_type_TypeError,
-            "function takes %d positional arguments but %d were given",
+            MP_ERROR_TEXT("function takes %d positional arguments but %d were given"),
             num_fields, n_args + n_kw);
         #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
         mp_raise_msg_varg(&mp_type_TypeError,
-            "%q() takes %d positional arguments but %d were given",
+            MP_ERROR_TEXT("%q() takes %d positional arguments but %d were given"),
             type->base.name, num_fields, n_args + n_kw);
         #endif
     }
@@ -124,7 +124,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args,
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
             mp_arg_error_terse_mismatch();
             #else
-            mp_raise_msg_varg(&mp_type_TypeError, "unexpected keyword argument '%q'", kw);
+            mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), kw);
             #endif
         }
         if (tuple->items[id] != MP_OBJ_NULL) {
@@ -132,7 +132,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args,
             mp_arg_error_terse_mismatch();
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "function got multiple values for argument '%q'", kw);
+                MP_ERROR_TEXT("function got multiple values for argument '%q'"), kw);
             #endif
         }
         tuple->items[id] = args[i + 1];
diff --git a/py/objobject.c b/py/objobject.c
index a05b4208f4..e2382d96a4 100644
--- a/py/objobject.c
+++ b/py/objobject.c
@@ -50,7 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__);
 
 STATIC mp_obj_t object___new__(mp_obj_t cls) {
     if (!mp_obj_is_type(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t *)MP_OBJ_TO_PTR(cls))) {
-        mp_raise_TypeError("arg must be user-type");
+        mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
     }
     // This executes only "__new__" part of instance creation.
     // TODO: This won't work well for classes with native bases.
@@ -65,7 +65,7 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(object___new___obj, MP_ROM_PTR(&object__
 #if MICROPY_PY_DELATTR_SETATTR
 STATIC mp_obj_t object___setattr__(mp_obj_t self_in, mp_obj_t attr, mp_obj_t value) {
     if (!mp_obj_is_instance_type(mp_obj_get_type(self_in))) {
-        mp_raise_TypeError("arg must be user-type");
+        mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
     }
 
     if (!mp_obj_is_str(attr)) {
@@ -80,7 +80,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(object___setattr___obj, object___setattr__);
 
 STATIC mp_obj_t object___delattr__(mp_obj_t self_in, mp_obj_t attr) {
     if (!mp_obj_is_instance_type(mp_obj_get_type(self_in))) {
-        mp_raise_TypeError("arg must be user-type");
+        mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
     }
 
     if (!mp_obj_is_str(attr)) {
@@ -89,7 +89,7 @@ STATIC mp_obj_t object___delattr__(mp_obj_t self_in, mp_obj_t attr) {
 
     mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in);
     if (mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == NULL) {
-        mp_raise_msg(&mp_type_AttributeError, "no such attribute");
+        mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
     }
     return mp_const_none;
 }
diff --git a/py/objrange.c b/py/objrange.c
index 9727d48648..4eed4b9410 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -105,7 +105,7 @@ STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t
         if (n_args == 3) {
             o->step = mp_obj_get_int(args[2]);
             if (o->step == 0) {
-                mp_raise_ValueError("zero step");
+                mp_raise_ValueError(MP_ERROR_TEXT("zero step"));
             }
         }
     }
diff --git a/py/objset.c b/py/objset.c
index b1f0ecb095..e587942a59 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -362,7 +362,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) {
     mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in);
     mp_obj_t obj = mp_set_remove_first(&self->set);
     if (obj == MP_OBJ_NULL) {
-        mp_raise_msg(&mp_type_KeyError, "pop from an empty set");
+        mp_raise_msg(&mp_type_KeyError, MP_ERROR_TEXT("pop from an empty set"));
     }
     return obj;
 }
diff --git a/py/objslice.c b/py/objslice.c
index d1c23cbf25..290c29150e 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -124,7 +124,7 @@ void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *r
     } else {
         step = mp_obj_get_int(self->step);
         if (step == 0) {
-            mp_raise_ValueError("slice step cannot be zero");
+            mp_raise_ValueError(MP_ERROR_TEXT("slice step cannot be zero"));
         }
     }
 
diff --git a/py/objstr.c b/py/objstr.c
index 38f6843ca4..0c319a7271 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -269,7 +269,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size
         mp_int_t val = mp_obj_get_int(item);
         #if MICROPY_FULL_CHECKS
         if (val < 0 || val > 255) {
-            mp_raise_ValueError("bytes value out of range");
+            mp_raise_ValueError(MP_ERROR_TEXT("bytes value out of range"));
         }
         #endif
         vstr_add_byte(&vstr, val);
@@ -278,7 +278,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size
     return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
 
 wrong_args:
-    mp_raise_TypeError("wrong number of arguments");
+    mp_raise_TypeError(MP_ERROR_TEXT("wrong number of arguments"));
 }
 
 // like strstr but with specified length and allows \0 bytes
@@ -439,7 +439,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
         if (mp_obj_is_type(index, &mp_type_slice)) {
             mp_bound_slice_t slice;
             if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) {
-                mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("only slices with step=1 (aka None) are supported"));
             }
             return mp_obj_new_str_of_type(type, self_data + slice.start, slice.stop - slice.start);
         }
@@ -479,7 +479,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
     for (size_t i = 0; i < seq_len; i++) {
         if (mp_obj_get_type(seq_items[i]) != self_type) {
             mp_raise_TypeError(
-                "join expects a list of str/bytes objects consistent with self object");
+                MP_ERROR_TEXT("join expects a list of str/bytes objects consistent with self object"));
         }
         if (i > 0) {
             required_len += sep_len;
@@ -560,7 +560,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) {
         const char *sep_str = mp_obj_str_get_data(sep, &sep_len);
 
         if (sep_len == 0) {
-            mp_raise_ValueError("empty separator");
+            mp_raise_ValueError(MP_ERROR_TEXT("empty separator"));
         }
 
         for (;;) {
@@ -659,13 +659,13 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
     mp_int_t idx = splits;
 
     if (sep == mp_const_none) {
-        mp_raise_NotImplementedError("rsplit(None,n)");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("rsplit(None,n)"));
     } else {
         size_t sep_len;
         const char *sep_str = mp_obj_str_get_data(sep, &sep_len);
 
         if (sep_len == 0) {
-            mp_raise_ValueError("empty separator");
+            mp_raise_ValueError(MP_ERROR_TEXT("empty separator"));
         }
 
         const byte *beg = s;
@@ -731,7 +731,7 @@ STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, b
     out_error:
         // not found
         if (is_index) {
-            mp_raise_ValueError("substring not found");
+            mp_raise_ValueError(MP_ERROR_TEXT("substring not found"));
         } else {
             return MP_OBJ_NEW_SMALL_INT(-1);
         }
@@ -788,7 +788,7 @@ STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) {
     size_t suffix_len;
     const char *suffix = mp_obj_str_get_data(args[1], &suffix_len);
     if (n_args > 2) {
-        mp_raise_NotImplementedError("start/end indices");
+        mp_raise_NotImplementedError(MP_ERROR_TEXT("start/end indices"));
     }
 
     if (suffix_len > str_len) {
@@ -951,7 +951,7 @@ STATIC mp_obj_t arg_as_int(mp_obj_t arg) {
 
 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
 STATIC NORETURN void terse_str_format_value_error(void) {
-    mp_raise_ValueError("bad format string");
+    mp_raise_ValueError(MP_ERROR_TEXT("bad format string"));
 }
 #else
 // define to nothing to improve coverage
@@ -973,7 +973,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
             terse_str_format_value_error();
             #else
-            mp_raise_ValueError("single '}' encountered in format string");
+            mp_raise_ValueError(MP_ERROR_TEXT("single '}' encountered in format string"));
             #endif
         }
         if (*str != '{') {
@@ -1012,14 +1012,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
                 terse_str_format_value_error();
                 #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
-                mp_raise_ValueError("bad conversion specifier");
+                mp_raise_ValueError(MP_ERROR_TEXT("bad conversion specifier"));
                 #else
                 if (str >= top) {
                     mp_raise_ValueError(
-                        "end of format while looking for conversion specifier");
+                        MP_ERROR_TEXT("end of format while looking for conversion specifier"));
                 } else {
                     mp_raise_msg_varg(&mp_type_ValueError,
-                        "unknown conversion specifier %c", *str);
+                        MP_ERROR_TEXT("unknown conversion specifier %c"), *str);
                 }
                 #endif
             }
@@ -1050,14 +1050,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
             terse_str_format_value_error();
             #else
-            mp_raise_ValueError("unmatched '{' in format");
+            mp_raise_ValueError(MP_ERROR_TEXT("unmatched '{' in format"));
             #endif
         }
         if (*str != '}') {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
             terse_str_format_value_error();
             #else
-            mp_raise_ValueError("expected ':' after format specifier");
+            mp_raise_ValueError(MP_ERROR_TEXT("expected ':' after format specifier"));
             #endif
         }
 
@@ -1071,12 +1071,12 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                     terse_str_format_value_error();
                     #else
                     mp_raise_ValueError(
-                        "can't switch from automatic field numbering to manual field specification");
+                        MP_ERROR_TEXT("can't switch from automatic field numbering to manual field specification"));
                     #endif
                 }
                 field_name = str_to_int(field_name, field_name_top, &index);
                 if ((uint)index >= n_args - 1) {
-                    mp_raise_msg(&mp_type_IndexError, "tuple index out of range");
+                    mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("tuple index out of range"));
                 }
                 arg = args[index + 1];
                 *arg_i = -1;
@@ -1093,7 +1093,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 arg = key_elem->value;
             }
             if (field_name < field_name_top) {
-                mp_raise_NotImplementedError("attributes not supported yet");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("attributes not supported yet"));
             }
         } else {
             if (*arg_i < 0) {
@@ -1101,11 +1101,11 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 terse_str_format_value_error();
                 #else
                 mp_raise_ValueError(
-                    "can't switch from manual field specification to automatic field numbering");
+                    MP_ERROR_TEXT("can't switch from manual field specification to automatic field numbering"));
                 #endif
             }
             if ((uint)*arg_i >= n_args - 1) {
-                mp_raise_msg(&mp_type_IndexError, "tuple index out of range");
+                mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("tuple index out of range"));
             }
             arg = args[(*arg_i) + 1];
             (*arg_i)++;
@@ -1209,7 +1209,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
                 terse_str_format_value_error();
                 #else
-                mp_raise_ValueError("invalid format specifier");
+                mp_raise_ValueError(MP_ERROR_TEXT("invalid format specifier"));
                 #endif
             }
 
@@ -1235,7 +1235,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
                 terse_str_format_value_error();
                 #else
-                mp_raise_ValueError("sign not allowed in string format specifier");
+                mp_raise_ValueError(MP_ERROR_TEXT("sign not allowed in string format specifier"));
                 #endif
             }
             if (type == 'c') {
@@ -1243,7 +1243,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 terse_str_format_value_error();
                 #else
                 mp_raise_ValueError(
-                    "sign not allowed with integer format specifier 'c'");
+                    MP_ERROR_TEXT("sign not allowed with integer format specifier 'c'"));
                 #endif
             }
         }
@@ -1307,7 +1307,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                     terse_str_format_value_error();
                     #else
                     mp_raise_msg_varg(&mp_type_ValueError,
-                        "unknown format code '%c' for object of type '%s'",
+                        MP_ERROR_TEXT("unknown format code '%c' for object of type '%s'"),
                         type, mp_obj_get_type_str(arg));
                     #endif
             }
@@ -1379,7 +1379,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                     terse_str_format_value_error();
                     #else
                     mp_raise_msg_varg(&mp_type_ValueError,
-                        "unknown format code '%c' for object of type '%s'",
+                        MP_ERROR_TEXT("unknown format code '%c' for object of type '%s'"),
                         type, mp_obj_get_type_str(arg));
                     #endif
             }
@@ -1391,7 +1391,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                 terse_str_format_value_error();
                 #else
                 mp_raise_ValueError(
-                    "'=' alignment not allowed in string format specifier");
+                    MP_ERROR_TEXT("'=' alignment not allowed in string format specifier"));
                 #endif
             }
 
@@ -1415,7 +1415,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
                     terse_str_format_value_error();
                     #else
                     mp_raise_msg_varg(&mp_type_ValueError,
-                        "unknown format code '%c' for object of type '%s'",
+                        MP_ERROR_TEXT("unknown format code '%c' for object of type '%s'"),
                         type, mp_obj_get_type_str(arg));
                     #endif
             }
@@ -1466,7 +1466,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
         // Dictionary value lookup
         if (*str == '(') {
             if (dict == MP_OBJ_NULL) {
-                mp_raise_TypeError("format needs a dict");
+                mp_raise_TypeError(MP_ERROR_TEXT("format needs a dict"));
             }
             const byte *key = ++str;
             while (*str != ')') {
@@ -1474,7 +1474,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
                     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
                     terse_str_format_value_error();
                     #else
-                    mp_raise_ValueError("incomplete format key");
+                    mp_raise_ValueError(MP_ERROR_TEXT("incomplete format key"));
                     #endif
                 }
                 ++str;
@@ -1538,7 +1538,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
             terse_str_format_value_error();
             #else
-            mp_raise_ValueError("incomplete format");
+            mp_raise_ValueError(MP_ERROR_TEXT("incomplete format"));
             #endif
         }
 
@@ -1546,7 +1546,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
         if (arg == MP_OBJ_NULL) {
             if (arg_i >= n_args) {
             not_enough_args:
-                mp_raise_TypeError("format string needs more arguments");
+                mp_raise_TypeError(MP_ERROR_TEXT("format string needs more arguments"));
             }
             arg = args[arg_i++];
         }
@@ -1556,14 +1556,14 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
                     size_t slen;
                     const char *s = mp_obj_str_get_data(arg, &slen);
                     if (slen != 1) {
-                        mp_raise_TypeError("%c needs int or char");
+                        mp_raise_TypeError(MP_ERROR_TEXT("%c needs int or char"));
                     }
                     mp_print_strn(&print, s, 1, flags, ' ', width);
                 } else if (arg_looks_integer(arg)) {
                     char ch = mp_obj_get_int(arg);
                     mp_print_strn(&print, &ch, 1, flags, ' ', width);
                 } else {
-                    mp_raise_TypeError("integer needed");
+                    mp_raise_TypeError(MP_ERROR_TEXT("integer needed"));
                 }
                 break;
 
@@ -1637,14 +1637,14 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
                 terse_str_format_value_error();
                 #else
                 mp_raise_msg_varg(&mp_type_ValueError,
-                    "unsupported format character '%c' (0x%x) at index %d",
+                    MP_ERROR_TEXT("unsupported format character '%c' (0x%x) at index %d"),
                     *str, *str, str - start_str);
                 #endif
         }
     }
 
     if (dict == MP_OBJ_NULL && arg_i != n_args) {
-        mp_raise_TypeError("format string didn't convert all arguments");
+        mp_raise_TypeError(MP_ERROR_TEXT("format string didn't convert all arguments"));
     }
 
     return mp_obj_new_str_from_vstr(is_bytes ? &mp_type_bytes : &mp_type_str, &vstr);
@@ -1814,7 +1814,7 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) {
     GET_STR_DATA_LEN(arg, sep, sep_len);
 
     if (sep_len == 0) {
-        mp_raise_ValueError("empty separator");
+        mp_raise_ValueError(MP_ERROR_TEXT("empty separator"));
     }
 
     mp_obj_t result[3];
@@ -2193,11 +2193,11 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) {
 
 STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in) {
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_TypeError("can't convert to str implicitly");
+    mp_raise_TypeError(MP_ERROR_TEXT("can't convert to str implicitly"));
     #else
     const qstr src_name = mp_obj_get_type(self_in)->name;
     mp_raise_msg_varg(&mp_type_TypeError,
-        "can't convert '%q' object to %q implicitly",
+        MP_ERROR_TEXT("can't convert '%q' object to %q implicitly"),
         src_name, src_name == MP_QSTR_str ? MP_QSTR_bytes : MP_QSTR_str);
     #endif
 }
diff --git a/py/objstringio.c b/py/objstringio.c
index e582fbb422..a5b463f175 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -38,7 +38,7 @@
 #if MICROPY_CPYTHON_COMPAT
 STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) {
     if (o->vstr == NULL) {
-        mp_raise_ValueError("I/O operation on closed file");
+        mp_raise_ValueError(MP_ERROR_TEXT("I/O operation on closed file"));
     }
 }
 #else
diff --git a/py/objstrunicode.c b/py/objstrunicode.c
index 69abbb8511..0dfab67a85 100644
--- a/py/objstrunicode.c
+++ b/py/objstrunicode.c
@@ -169,7 +169,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s
     if (mp_obj_is_small_int(index)) {
         i = MP_OBJ_SMALL_INT_VALUE(index);
     } else if (!mp_obj_get_int_maybe(index, &i)) {
-        mp_raise_msg_varg(&mp_type_TypeError, "string indices must be integers, not %s", mp_obj_get_type_str(index));
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("string indices must be integers, not %s"), mp_obj_get_type_str(index));
     }
     const byte *s, *top = self_data + self_len;
     if (i < 0) {
@@ -179,7 +179,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s
                 if (is_slice) {
                     return self_data;
                 }
-                mp_raise_msg(&mp_type_IndexError, "string index out of range");
+                mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("string index out of range"));
             }
             if (!UTF8_IS_CONT(*s)) {
                 ++i;
@@ -198,7 +198,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s
                 if (is_slice) {
                     return top;
                 }
-                mp_raise_msg(&mp_type_IndexError, "string index out of range");
+                mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("string index out of range"));
             }
             // Then check completion
             if (i-- == 0) {
@@ -229,7 +229,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
             ostep = slice->step;
 
             if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
-                mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("only slices with step=1 (aka None) are supported"));
             }
 
             const byte *pstart, *pstop;
diff --git a/py/objtuple.c b/py/objtuple.c
index 2d717c9e88..607937aedf 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -194,7 +194,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
         if (mp_obj_is_type(index, &mp_type_slice)) {
             mp_bound_slice_t slice;
             if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
-                mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
+                mp_raise_NotImplementedError(MP_ERROR_TEXT("only slices with step=1 (aka None) are supported"));
             }
             mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice.stop - slice.start, NULL));
             mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
diff --git a/py/objtype.c b/py/objtype.c
index 5c50696d0b..8dddcc66d2 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -377,10 +377,10 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
         }
         if (init_ret != mp_const_none) {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_TypeError("__init__() should return None");
+            mp_raise_TypeError(MP_ERROR_TEXT("__init__() should return None"));
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret));
+                MP_ERROR_TEXT("__init__() should return None, not '%s'"), mp_obj_get_type_str(init_ret));
             #endif
         }
     }
@@ -663,7 +663,7 @@ STATIC void mp_obj_instance_load_class_attr(mp_obj_t self_in, qstr attr, mp_obj_
             // the code.
             const mp_obj_t *proxy = mp_obj_property_get(member);
             if (proxy[0] == mp_const_none) {
-                mp_raise_msg(&mp_type_AttributeError, "unreadable attribute");
+                mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("unreadable attribute"));
             } else {
                 dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in);
             }
@@ -930,10 +930,10 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
     mp_obj_t call = mp_obj_instance_get_call(self_in, member);
     if (call == MP_OBJ_NULL) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("object not callable");
+        mp_raise_TypeError(MP_ERROR_TEXT("object not callable"));
         #else
         mp_raise_msg_varg(&mp_type_TypeError,
-            "'%s' object isn't callable", mp_obj_get_type_str(self_in));
+            MP_ERROR_TEXT("'%s' object isn't callable"), mp_obj_get_type_str(self_in));
         #endif
     }
     mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in);
@@ -1044,7 +1044,7 @@ STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_
             return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]);
 
         default:
-            mp_raise_TypeError("type takes 1 or 3 arguments");
+            mp_raise_TypeError(MP_ERROR_TEXT("type takes 1 or 3 arguments"));
     }
 }
 
@@ -1055,9 +1055,9 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp
 
     if (self->make_new == NULL) {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_TypeError("cannot create instance");
+        mp_raise_TypeError(MP_ERROR_TEXT("cannot create instance"));
         #else
-        mp_raise_msg_varg(&mp_type_TypeError, "cannot create '%q' instances", self->name);
+        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("cannot create '%q' instances"), self->name);
         #endif
     }
 
@@ -1121,7 +1121,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
                     if (check_for_special_accessors(MP_OBJ_NEW_QSTR(attr), dest[1])) {
                         if (self->flags & MP_TYPE_FLAG_IS_SUBCLASSED) {
                             // This class is already subclassed so can't have special accessors added
-                            mp_raise_msg(&mp_type_AttributeError, "can't add special method to already-subclassed class");
+                            mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("can't add special method to already-subclassed class"));
                         }
                         self->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS;
                     }
@@ -1180,10 +1180,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
         // (depending on the options).
         if (t->make_new == NULL || t == &mp_type_fun_bc) {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_TypeError("type isn't an acceptable base type");
+            mp_raise_TypeError(MP_ERROR_TEXT("type isn't an acceptable base type"));
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "type '%q' isn't an acceptable base type", t->name);
+                MP_ERROR_TEXT("type '%q' isn't an acceptable base type"), t->name);
             #endif
         }
         #if ENABLE_SPECIAL_ACCESSORS
@@ -1256,7 +1256,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
             #if MICROPY_MULTIPLE_INHERITANCE
             o->parent = MP_OBJ_TO_PTR(bases_tuple);
             #else
-            mp_raise_NotImplementedError("multiple inheritance not supported");
+            mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported"));
             #endif
         } else {
             #if MICROPY_PY_CLASS_BASES
@@ -1289,7 +1289,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
     const mp_obj_type_t *native_base;
     size_t num_native_bases = instance_count_native_bases(o, &native_base);
     if (num_native_bases > 1) {
-        mp_raise_TypeError("multiple bases have instance lay-out conflict");
+        mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict"));
     }
 
     mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP);
@@ -1471,7 +1471,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) {
     } else if (mp_obj_is_type(classinfo, &mp_type_tuple)) {
         mp_obj_tuple_get(classinfo, &len, &items);
     } else {
-        mp_raise_TypeError("issubclass() arg 2 must be a class or a tuple of classes");
+        mp_raise_TypeError(MP_ERROR_TEXT("issubclass() arg 2 must be a class or a tuple of classes"));
     }
 
     for (size_t i = 0; i < len; i++) {
@@ -1485,7 +1485,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) {
 
 STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) {
     if (!mp_obj_is_type(object, &mp_type_type)) {
-        mp_raise_TypeError("issubclass() arg 1 must be a class");
+        mp_raise_TypeError(MP_ERROR_TEXT("issubclass() arg 1 must be a class"));
     }
     return mp_obj_is_subclass(object, classinfo);
 }
diff --git a/py/parse.c b/py/parse.c
index 683d41d720..adddbeecd1 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -720,7 +720,7 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
                     is_int = false;
                     #if 0
                     mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
-                        "constant must be an integer");
+                        MP_ERROR_TEXT("constant must be an integer"));
                     mp_obj_exception_add_traceback(exc, parser->lexer->source_name,
                         ((mp_parse_node_struct_t *)pn1)->source_line, MP_QSTRnull);
                     nlr_raise(exc);
@@ -1155,13 +1155,13 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
         mp_obj_t exc;
         if (lex->tok_kind == MP_TOKEN_INDENT) {
             exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
-                "unexpected indent");
+                MP_ERROR_TEXT("unexpected indent"));
         } else if (lex->tok_kind == MP_TOKEN_DEDENT_MISMATCH) {
             exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
-                "unindent doesn't match any outer indent level");
+                MP_ERROR_TEXT("unindent doesn't match any outer indent level"));
         } else {
             exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
-                "invalid syntax");
+                MP_ERROR_TEXT("invalid syntax"));
         }
         // add traceback to give info about file name and location
         // we don't have a 'block' name, so just pass the NULL qstr to indicate this
diff --git a/py/parsenum.c b/py/parsenum.c
index bfad06afe0..56c818acdf 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -56,7 +56,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
     // check radix base
     if ((base != 0 && base < 2) || base > 36) {
         // this won't be reached if lex!=NULL
-        mp_raise_ValueError("int() arg 2 must be >= 2 and <= 36");
+        mp_raise_ValueError(MP_ERROR_TEXT("int() arg 2 must be >= 2 and <= 36"));
     }
 
     // skip leading space
@@ -148,11 +148,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
     {
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
         mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError,
-            "invalid syntax for integer");
+            MP_ERROR_TEXT("invalid syntax for integer"));
         raise_exc(exc, lex);
         #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
         mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError,
-            "invalid syntax for integer with base %d", base);
+            MP_ERROR_TEXT("invalid syntax for integer with base %d"), base);
         raise_exc(exc, lex);
         #else
         vstr_t vstr;
@@ -357,7 +357,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
     }
     #else
     if (imag || force_complex) {
-        raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "complex values not supported"), lex);
+        raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("complex values not supported")), lex);
     }
     #endif
     else {
@@ -365,9 +365,9 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
     }
 
 value_error:
-    raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid syntax for number"), lex);
+    raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("invalid syntax for number")), lex);
 
     #else
-    raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "decimal numbers not supported"), lex);
+    raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("decimal numbers not supported")), lex);
     #endif
 }
diff --git a/py/persistentcode.c b/py/persistentcode.c
index ace197b114..bd2232ff2a 100644
--- a/py/persistentcode.c
+++ b/py/persistentcode.c
@@ -360,7 +360,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) {
 
     #if !MICROPY_EMIT_MACHINE_CODE
     if (kind != MP_CODE_BYTECODE) {
-        mp_raise_ValueError("incompatible .mpy file");
+        mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
     }
     #endif
 
@@ -545,12 +545,12 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) {
         || MPY_FEATURE_DECODE_FLAGS(header[2]) != MPY_FEATURE_FLAGS
         || header[3] > mp_small_int_bits()
         || read_uint(reader, NULL) > QSTR_WINDOW_SIZE) {
-        mp_raise_ValueError("incompatible .mpy file");
+        mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
     }
     if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) {
         byte arch = MPY_FEATURE_DECODE_ARCH(header[2]);
         if (!MPY_FEATURE_ARCH_TEST(arch)) {
-            mp_raise_ValueError("incompatible .mpy arch");
+            mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy arch"));
         }
     }
     qstr_window_t qw;
diff --git a/py/qstr.c b/py/qstr.c
index 2b1cea405b..c14ec5ae00 100644
--- a/py/qstr.c
+++ b/py/qstr.c
@@ -201,7 +201,7 @@ qstr qstr_from_strn(const char *str, size_t len) {
         // check that len is not too big
         if (len >= (1 << (8 * MICROPY_QSTR_BYTES_IN_LEN))) {
             QSTR_EXIT();
-            mp_raise_msg(&mp_type_RuntimeError, "name too long");
+            mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("name too long"));
         }
 
         // compute number of bytes needed to intern this string
diff --git a/py/runtime.c b/py/runtime.c
index 082c9e2ac1..adb35a4b2c 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -182,9 +182,9 @@ mp_obj_t mp_load_global(qstr qst) {
         elem = mp_map_lookup((mp_map_t *)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
         if (elem == NULL) {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_msg(&mp_type_NameError, "name not defined");
+            mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined"));
             #else
-            mp_raise_msg_varg(&mp_type_NameError, "name '%q' isn't defined", qst);
+            mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst);
             #endif
         }
     }
@@ -287,17 +287,17 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
         // In this case provide a more focused error message to not confuse, e.g. chr(1.0)
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
         if (op == MP_UNARY_OP_INT) {
-            mp_raise_TypeError("can't convert to int");
+            mp_raise_TypeError(MP_ERROR_TEXT("can't convert to int"));
         } else {
-            mp_raise_TypeError("unsupported type for operator");
+            mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator"));
         }
         #else
         if (op == MP_UNARY_OP_INT) {
             mp_raise_msg_varg(&mp_type_TypeError,
-                "can't convert %s to int", mp_obj_get_type_str(arg));
+                MP_ERROR_TEXT("can't convert %s to int"), mp_obj_get_type_str(arg));
         } else {
             mp_raise_msg_varg(&mp_type_TypeError,
-                "unsupported type for %q: '%s'",
+                MP_ERROR_TEXT("unsupported type for %q: '%s'"),
                 mp_unary_op_method_name[op], mp_obj_get_type_str(arg));
         }
         #endif
@@ -393,7 +393,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
                 case MP_BINARY_OP_INPLACE_LSHIFT: {
                     if (rhs_val < 0) {
                         // negative shift not allowed
-                        mp_raise_ValueError("negative shift count");
+                        mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
                     } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
                         // left-shift will overflow, so use higher precision integer
                         lhs = mp_obj_new_int_from_ll(lhs_val);
@@ -408,7 +408,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
                 case MP_BINARY_OP_INPLACE_RSHIFT:
                     if (rhs_val < 0) {
                         // negative shift not allowed
-                        mp_raise_ValueError("negative shift count");
+                        mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
                     } else {
                         // standard precision is enough for right-shift
                         if (rhs_val >= (mp_int_t)BITS_PER_WORD) {
@@ -486,7 +486,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
                         #if MICROPY_PY_BUILTINS_FLOAT
                         return mp_obj_float_binary_op(op, lhs_val, rhs);
                         #else
-                        mp_raise_ValueError("negative power with no float support");
+                        mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support"));
                         #endif
                     } else {
                         mp_int_t ans = 1;
@@ -616,15 +616,15 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
 
 unsupported_op:
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_TypeError("unsupported type for operator");
+    mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator"));
     #else
     mp_raise_msg_varg(&mp_type_TypeError,
-        "unsupported types for %q: '%s', '%s'",
+        MP_ERROR_TEXT("unsupported types for %q: '%s', '%s'"),
         mp_binary_op_method_name[op], mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs));
     #endif
 
 zero_division:
-    mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
+    mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
 }
 
 mp_obj_t mp_call_function_0(mp_obj_t fun) {
@@ -658,10 +658,10 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons
     }
 
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_TypeError("object not callable");
+    mp_raise_TypeError(MP_ERROR_TEXT("object not callable"));
     #else
     mp_raise_msg_varg(&mp_type_TypeError,
-        "'%s' object isn't callable", mp_obj_get_type_str(fun_in));
+        MP_ERROR_TEXT("'%s' object isn't callable"), mp_obj_get_type_str(fun_in));
     #endif
 }
 
@@ -887,15 +887,15 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) {
 
 too_short:
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_ValueError("wrong number of values to unpack");
+    mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
     #else
-    mp_raise_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len);
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len);
     #endif
 too_long:
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_ValueError("wrong number of values to unpack");
+    mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
     #else
-    mp_raise_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", (int)num);
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("too many values to unpack (expected %d)"), (int)num);
     #endif
 }
 
@@ -954,9 +954,9 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) {
 
 too_short:
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_ValueError("wrong number of values to unpack");
+    mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
     #else
-    mp_raise_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len);
+    mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len);
     #endif
 }
 
@@ -992,10 +992,10 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
         const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
         if (arg0_type != self->type) {
             #if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED
-            mp_raise_TypeError("argument has wrong type");
+            mp_raise_TypeError(MP_ERROR_TEXT("argument has wrong type"));
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name);
+                MP_ERROR_TEXT("argument should be a '%q' not a '%q'"), self->type->name, arg0_type->name);
             #endif
         }
     }
@@ -1124,16 +1124,16 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
     if (dest[0] == MP_OBJ_NULL) {
         // no attribute/method called attr
         #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-        mp_raise_msg(&mp_type_AttributeError, "no such attribute");
+        mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
         #else
         // following CPython, we give a more detailed error message for type objects
         if (mp_obj_is_type(base, &mp_type_type)) {
             mp_raise_msg_varg(&mp_type_AttributeError,
-                "type object '%q' has no attribute '%q'",
+                MP_ERROR_TEXT("type object '%q' has no attribute '%q'"),
                 ((mp_obj_type_t *)MP_OBJ_TO_PTR(base))->name, attr);
         } else {
             mp_raise_msg_varg(&mp_type_AttributeError,
-                "'%s' object has no attribute '%q'",
+                MP_ERROR_TEXT("'%s' object has no attribute '%q'"),
                 mp_obj_get_type_str(base), attr);
         }
         #endif
@@ -1168,10 +1168,10 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
         }
     }
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_msg(&mp_type_AttributeError, "no such attribute");
+    mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
     #else
     mp_raise_msg_varg(&mp_type_AttributeError,
-        "'%s' object has no attribute '%q'",
+        MP_ERROR_TEXT("'%s' object has no attribute '%q'"),
         mp_obj_get_type_str(base), attr);
     #endif
 }
@@ -1213,10 +1213,10 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
 
     // object not iterable
     #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-    mp_raise_TypeError("object not iterable");
+    mp_raise_TypeError(MP_ERROR_TEXT("object not iterable"));
     #else
     mp_raise_msg_varg(&mp_type_TypeError,
-        "'%s' object isn't iterable", mp_obj_get_type_str(o_in));
+        MP_ERROR_TEXT("'%s' object isn't iterable"), mp_obj_get_type_str(o_in));
     #endif
 
 }
@@ -1236,10 +1236,10 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
             return mp_call_method_n_kw(0, 0, dest);
         } else {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_TypeError("object not an iterator");
+            mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator"));
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "'%s' object isn't an iterator", mp_obj_get_type_str(o_in));
+                MP_ERROR_TEXT("'%s' object isn't an iterator"), mp_obj_get_type_str(o_in));
             #endif
         }
     }
@@ -1272,10 +1272,10 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
             }
         } else {
             #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
-            mp_raise_TypeError("object not an iterator");
+            mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator"));
             #else
             mp_raise_msg_varg(&mp_type_TypeError,
-                "'%s' object isn't an iterator", mp_obj_get_type_str(o_in));
+                MP_ERROR_TEXT("'%s' object isn't an iterator"), mp_obj_get_type_str(o_in));
             #endif
         }
     }
@@ -1350,7 +1350,7 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
         //  test_delegating_throw_to_non_generator()
         if (mp_obj_exception_match(throw_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
             // PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError
-            *ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator raised StopIteration");
+            *ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator raised StopIteration"));
         } else {
             *ret_val = mp_make_raise_obj(throw_value);
         }
@@ -1371,7 +1371,7 @@ mp_obj_t mp_make_raise_obj(mp_obj_t o) {
         return o;
     } else {
         // o cannot be used as an exception, so return a type error (which will be raised by the caller)
-        return mp_obj_new_exception_msg(&mp_type_TypeError, "exceptions must derive from BaseException");
+        return mp_obj_new_exception_msg(&mp_type_TypeError, MP_ERROR_TEXT("exceptions must derive from BaseException"));
     }
 }
 
@@ -1409,7 +1409,7 @@ mp_obj_t mp_import_from(mp_obj_t module, qstr name) {
     if (dest[1] != MP_OBJ_NULL) {
         // Hopefully we can't import bound method from an object
     import_error:
-        mp_raise_msg_varg(&mp_type_ImportError, "cannot import name %q", name);
+        mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("cannot import name %q"), name);
     }
 
     if (dest[0] != MP_OBJ_NULL) {
@@ -1510,11 +1510,11 @@ NORETURN void m_malloc_fail(size_t num_bytes) {
     DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes);
     #if MICROPY_ENABLE_GC
     if (gc_is_locked()) {
-        mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked");
+        mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("memory allocation failed, heap is locked"));
     }
     #endif
     mp_raise_msg_varg(&mp_type_MemoryError,
-        "memory allocation failed, allocating %u bytes", (uint)num_bytes);
+        MP_ERROR_TEXT("memory allocation failed, allocating %u bytes"), (uint)num_bytes);
 }
 
 NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) {
diff --git a/py/sequence.c b/py/sequence.c
index 32de9fac40..aa25a1cfbc 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -203,7 +203,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, cons
         }
     }
 
-    mp_raise_ValueError("object not in sequence");
+    mp_raise_ValueError(MP_ERROR_TEXT("object not in sequence"));
 }
 
 mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value) {
diff --git a/py/stream.c b/py/stream.c
index f007f2bb04..8ca874de12 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -94,7 +94,7 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) {
         || ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL)
         || ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) {
         // CPython: io.UnsupportedOperation, OSError subclass
-        mp_raise_msg(&mp_type_OSError, "stream operation not supported");
+        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("stream operation not supported"));
     }
     return stream_p;
 }
diff --git a/py/vm.c b/py/vm.c
index 00958c0e79..39373e7f2c 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -342,7 +342,7 @@ FRAME_SETUP();
                     if (obj_shared == MP_OBJ_NULL) {
                         local_name_error: {
                             MARK_EXC_IP_SELECTIVE();
-                            mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment");
+                            mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, MP_ERROR_TEXT("local variable referenced before assignment"));
                             RAISE(obj);
                         }
                     }
@@ -1209,7 +1209,7 @@ unwind_jump:;
                             }
                         }
                         if (obj == MP_OBJ_NULL) {
-                            obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise");
+                            obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("no active exception to reraise"));
                             RAISE(obj);
                         }
                     } else {
@@ -1348,7 +1348,7 @@ unwind_jump:;
 #endif
                 {
 
-                    mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, "opcode");
+                    mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, MP_ERROR_TEXT("opcode"));
                     nlr_pop();
                     code_state->state[0] = obj;
                     FRAME_LEAVE();