diff --git a/lvgl_tft/hx8357.c b/lvgl_tft/hx8357.c index a22287b..d7faf42 100644 --- a/lvgl_tft/hx8357.c +++ b/lvgl_tft/hx8357.c @@ -49,7 +49,7 @@ typedef struct { static void hx8357_send_cmd(uint8_t cmd); static void hx8357_send_data(void * data, uint16_t length); static void hx8357_send_color(void * data, uint16_t length); - +static void hx8357_reset(void); /********************** * INITIALIZATION ARRAYS @@ -156,44 +156,31 @@ static uint8_t displayType = HX8357D; void hx8357_init(void) { - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(HX8357_DC); - gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT); + hx8357_reset(); -#if HX8357_USE_RST - gpio_pad_select_gpio(HX8357_RST); - gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("Initialization."); - //Reset the display - gpio_set_level(HX8357_RST, 0); - vTaskDelay(10 / portTICK_RATE_MS); - gpio_set_level(HX8357_RST, 1); - vTaskDelay(120 / portTICK_RATE_MS); -#endif + //Send all the commands + const uint8_t *addr = (displayType == HX8357B) ? initb : initd; + uint8_t cmd, x, numArgs; + while((cmd = *addr++) > 0) { // '0' command ends list + x = *addr++; + numArgs = x & 0x7F; + if (cmd != 0xFF) { // '255' is ignored + if (x & 0x80) { // If high bit set, numArgs is a delay time + hx8357_send_cmd(cmd); + } else { + hx8357_send_cmd(cmd); + hx8357_send_data((void *) addr, numArgs); + addr += numArgs; + } + } + if (x & 0x80) { // If high bit set... + vTaskDelay(numArgs * 5 / portTICK_RATE_MS); // numArgs is actually a delay time (5ms units) + } + } - LV_LOG_INFO("Initialization."); - - //Send all the commands - const uint8_t *addr = (displayType == HX8357B) ? initb : initd; - uint8_t cmd, x, numArgs; - while((cmd = *addr++) > 0) { // '0' command ends list - x = *addr++; - numArgs = x & 0x7F; - if (cmd != 0xFF) { // '255' is ignored - if (x & 0x80) { // If high bit set, numArgs is a delay time - hx8357_send_cmd(cmd); - } else { - hx8357_send_cmd(cmd); - hx8357_send_data((void *) addr, numArgs); - addr += numArgs; - } - } - if (x & 0x80) { // If high bit set... - vTaskDelay(numArgs * 5 / portTICK_RATE_MS); // numArgs is actually a delay time (5ms units) - } - } - - hx8357_set_rotation(1); + hx8357_set_rotation(1); #if HX8357_INVERT_COLORS hx8357_send_cmd(HX8357_INVON); @@ -286,3 +273,13 @@ static void hx8357_send_color(void * data, uint16_t length) gpio_set_level(HX8357_DC, 1); /*Data mode*/ disp_spi_send_colors(data, length); } + +static void hx8357_reset(void) +{ +#if HX8357_USE_RST + gpio_set_level(HX8357_RST, 0); + vTaskDelay(10 / portTICK_RATE_MS); + gpio_set_level(HX8357_RST, 1); + vTaskDelay(120 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/ili9481.c b/lvgl_tft/ili9481.c index 565182d..d4b1a93 100644 --- a/lvgl_tft/ili9481.c +++ b/lvgl_tft/ili9481.c @@ -35,6 +35,7 @@ static void ili9481_set_orientation(uint8_t orientation); static void ili9481_send_cmd(uint8_t cmd); static void ili9481_send_data(void * data, uint16_t length); static void ili9481_send_color(void * data, uint16_t length); +static void ili9481_reset(void); /********************** * STATIC VARIABLES @@ -70,27 +71,10 @@ void ili9481_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ILI9481_DC); - gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT); - -#if ILI9481_USE_RST - gpio_pad_select_gpio(ILI9481_RST); - gpio_set_direction(ILI9481_RST, GPIO_MODE_OUTPUT); - - //Reset the display - gpio_set_level(ILI9481_RST, 0); - vTaskDelay(100 / portTICK_RATE_MS); - gpio_set_level(ILI9481_RST, 1); - vTaskDelay(100 / portTICK_RATE_MS); -#endif + ili9481_reset(); LV_LOG_INFO("Initialization."); - // Exit sleep - ili9481_send_cmd(0x01); /* Software reset */ - vTaskDelay(100 / portTICK_RATE_MS); - //Send all the commands uint16_t cmd = 0; while (ili_init_cmds[cmd].databytes!=0xff) { @@ -108,7 +92,8 @@ void ili9481_init(void) // Flush function based on mvturnho repo void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); + /* 3 is number of bytes in lv_color_t */ + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 3; lv_color16_t *buffer_16bit = (lv_color16_t *) color_map; uint8_t *mybuf; @@ -159,7 +144,9 @@ void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col /*Memory write*/ ili9481_send_cmd(ILI9481_CMD_MEMORY_WRITE); - ili9481_send_color((void *) mybuf, size * 3); + ili9481_send_color((void *) mybuf, size); + + /* FIXME: Can we free the memory even when it's being transferred? */ heap_caps_free(mybuf); } @@ -203,3 +190,17 @@ static void ili9481_set_orientation(uint8_t orientation) ili9481_send_cmd(ILI9481_CMD_MEMORY_ACCESS_CONTROL); ili9481_send_data((void *) &data[orientation], 1); } + +static void ili9481_reset(void) +{ +#if ILI9481_USE_RST + gpio_set_level(ILI9481_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ILI9481_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#else + // Exit sleep, software reset + ili9481_send_cmd(0x01); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/ili9486.c b/lvgl_tft/ili9486.c index 2283e54..f7b08a7 100644 --- a/lvgl_tft/ili9486.c +++ b/lvgl_tft/ili9486.c @@ -35,7 +35,7 @@ static void ili9486_set_orientation(uint8_t orientation); static void ili9486_send_cmd(uint8_t cmd); static void ili9486_send_data(void * data, uint16_t length); static void ili9486_send_color(void * data, uint16_t length); - +static void ili9486_reset(void); /********************** * STATIC VARIABLES **********************/ @@ -50,77 +50,62 @@ static void ili9486_send_color(void * data, uint16_t length); void ili9486_init(void) { - lcd_init_cmd_t ili_init_cmds[]={ - {0x11, {0}, 0x80}, - {0x3A, {0x55}, 1}, - {0x2C, {0x44}, 1}, - {0xC5, {0x00, 0x00, 0x00, 0x00}, 4}, - {0xE0, {0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98, 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00}, 15}, - {0XE1, {0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00}, 15}, - {0x20, {0}, 0}, /* display inversion OFF */ - {0x36, {0x48}, 1}, - {0x29, {0}, 0x80}, /* display on */ - {0x00, {0}, 0xff}, - }; + lcd_init_cmd_t ili_init_cmds[]={ + {0x11, {0}, 0x80}, + {0x3A, {0x55}, 1}, + {0x2C, {0x44}, 1}, + {0xC5, {0x00, 0x00, 0x00, 0x00}, 4}, + {0xE0, {0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98, 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00}, 15}, + {0XE1, {0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00}, 15}, + {0x20, {0}, 0}, /* display inversion OFF */ + {0x36, {0x48}, 1}, + {0x29, {0}, 0x80}, /* display on */ + {0x00, {0}, 0xff}, + }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ILI9486_DC); - gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT); + ili9486_reset(); -#if ILI9486_USE_RST - gpio_pad_select_gpio(ILI9486_RST); - gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("ILI9486 Initialization."); - //Reset the display - gpio_set_level(ILI9486_RST, 0); - vTaskDelay(100 / portTICK_RATE_MS); - gpio_set_level(ILI9486_RST, 1); - vTaskDelay(100 / portTICK_RATE_MS); -#endif - - LV_LOG_INFO("ILI9486 Initialization."); - - //Send all the commands - uint16_t cmd = 0; - while (ili_init_cmds[cmd].databytes!=0xff) { - ili9486_send_cmd(ili_init_cmds[cmd].cmd); - ili9486_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); - if (ili_init_cmds[cmd].databytes & 0x80) { - vTaskDelay(100 / portTICK_RATE_MS); - } - cmd++; - } + //Send all the commands + uint16_t cmd = 0; + while (ili_init_cmds[cmd].databytes!=0xff) { + ili9486_send_cmd(ili_init_cmds[cmd].cmd); + ili9486_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F); + if (ili_init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } ili9486_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); } void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint8_t data[4] = {0}; - uint32_t size = 0; + uint8_t data[4] = {0}; + /* 2 is the number of bytes in color depth */ + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2; - /*Column addresses*/ - ili9486_send_cmd(0x2A); - data[0] = (area->x1 >> 8) & 0xFF; - data[1] = area->x1 & 0xFF; - data[2] = (area->x2 >> 8) & 0xFF; - data[3] = area->x2 & 0xFF; - ili9486_send_data(data, 4); + /*Column addresses*/ + ili9486_send_cmd(0x2A); + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = area->x1 & 0xFF; + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = area->x2 & 0xFF; + ili9486_send_data(data, 4); - /*Page addresses*/ - ili9486_send_cmd(0x2B); - data[0] = (area->y1 >> 8) & 0xFF; - data[1] = area->y1 & 0xFF; - data[2] = (area->y2 >> 8) & 0xFF; - data[3] = area->y2 & 0xFF; - ili9486_send_data(data, 4); + /*Page addresses*/ + ili9486_send_cmd(0x2B); + data[0] = (area->y1 >> 8) & 0xFF; + data[1] = area->y1 & 0xFF; + data[2] = (area->y2 >> 8) & 0xFF; + data[3] = area->y2 & 0xFF; + ili9486_send_data(data, 4); - /*Memory write*/ - ili9486_send_cmd(0x2C); - - size = lv_area_get_width(area) * lv_area_get_height(area); - - ili9486_send_color((void*) color_map, size * 2); + /*Memory write*/ + ili9486_send_cmd(0x2C); + ili9486_send_color((void*) color_map, size); } /********************** @@ -128,30 +113,30 @@ void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col **********************/ static void ili9486_send_cmd(uint8_t cmd) { - uint8_t to16bit[] = { - 0x00, cmd - }; + uint8_t to16bit[] = { + 0x00, cmd + }; - disp_wait_for_pending_transactions(); - gpio_set_level(ILI9486_DC, 0); /*Command mode*/ - disp_spi_send_data(to16bit, sizeof to16bit); + disp_wait_for_pending_transactions(); + gpio_set_level(ILI9486_DC, 0); /*Command mode*/ + disp_spi_send_data(to16bit, sizeof to16bit); } static void ili9486_send_data(void * data, uint16_t length) { - uint32_t i; - uint8_t to16bit[32]; - uint8_t * dummy = data; + uint32_t i; + uint8_t to16bit[32]; + uint8_t * dummy = data; - for(i=0; i < (length); i++) - { - to16bit[2*i+1] = dummy[i]; - to16bit[2*i] = 0x00; - } + for(i=0; i < (length); i++) + { + to16bit[2*i+1] = dummy[i]; + to16bit[2*i] = 0x00; + } - disp_wait_for_pending_transactions(); - gpio_set_level(ILI9486_DC, 1); /*Data mode*/ - disp_spi_send_data(to16bit, (length*2)); + disp_wait_for_pending_transactions(); + gpio_set_level(ILI9486_DC, 1); /*Data mode*/ + disp_spi_send_data(to16bit, (length*2)); } static void ili9486_send_color(void * data, uint16_t length) @@ -179,3 +164,13 @@ static void ili9486_set_orientation(uint8_t orientation) ili9486_send_cmd(0x36); ili9486_send_data((void *) &data[orientation], 1); } + +static void ili9486_reset(void) +{ +#if ILI9486_USE_RST + gpio_set_level(ILI9486_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ILI9486_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/sh1107.c b/lvgl_tft/sh1107.c index 84ab65c..76e9044 100644 --- a/lvgl_tft/sh1107.c +++ b/lvgl_tft/sh1107.c @@ -34,6 +34,7 @@ typedef struct { static void sh1107_send_cmd(uint8_t cmd); static void sh1107_send_data(void * data, uint16_t length); static void sh1107_send_color(void * data, uint16_t length); +static void sh1107_reset(void); static lv_coord_t get_display_ver_res(lv_disp_drv_t *disp_drv); static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv); @@ -93,31 +94,18 @@ void sh1107_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(SH1107_DC); - gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT); + sh1107_reset(); -#if SH1107_USE_RST - gpio_pad_select_gpio(SH1107_RST); - gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT); - - //Reset the display - gpio_set_level(SH1107_RST, 0); - vTaskDelay(100 / portTICK_RATE_MS); - gpio_set_level(SH1107_RST, 1); - vTaskDelay(100 / portTICK_RATE_MS); -#endif - - //Send all the commands - uint16_t cmd = 0; - while (init_cmds[cmd].databytes!=0xff) { - sh1107_send_cmd(init_cmds[cmd].cmd); - sh1107_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes&0x1F); - if (init_cmds[cmd].databytes & 0x80) { - vTaskDelay(100 / portTICK_RATE_MS); - } - cmd++; - } + //Send all the commands + uint16_t cmd = 0; + while (init_cmds[cmd].databytes!=0xff) { + sh1107_send_cmd(init_cmds[cmd].cmd); + sh1107_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes&0x1F); + if (init_cmds[cmd].databytes & 0x80) { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } } void sh1107_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, @@ -257,3 +245,13 @@ static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv) return val; } + +static void sh1107_reset(void) +{ +#if SH1107_USE_RST + gpio_set_level(SH1107_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(SH1107_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} diff --git a/lvgl_tft/st7735s.c b/lvgl_tft/st7735s.c index c2786a1..83835c6 100644 --- a/lvgl_tft/st7735s.c +++ b/lvgl_tft/st7735s.c @@ -39,6 +39,7 @@ static void st7735s_send_cmd(uint8_t cmd); static void st7735s_send_data(void * data, uint16_t length); static void st7735s_send_color(void * data, uint16_t length); static void st7735s_set_orientation(uint8_t orientation); +static void st7735s_reset(void); #ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 static void axp192_write_byte(uint8_t addr, uint8_t data); @@ -98,20 +99,7 @@ void st7735s_init(void) {0, {0}, 0xff} }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ST7735S_DC); - gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT); - -#if ST7735S_USE_RST - gpio_pad_select_gpio(ST7735S_RST); - gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT); - - //Reset the display - gpio_set_level(ST7735S_RST, 0); - vTaskDelay(100 / portTICK_RATE_MS); - gpio_set_level(ST7735S_RST, 1); - vTaskDelay(100 / portTICK_RATE_MS); -#endif + st7735s_reset(); LV_LOG_INFO("ST7735S initialization."); @@ -137,29 +125,29 @@ void st7735s_init(void) void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) { - uint8_t data[4]; + uint8_t data[4] = {0}; - /*Column addresses*/ - st7735s_send_cmd(0x2A); - data[0] = (area->x1 >> 8) & 0xFF; - data[1] = (area->x1 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); - data[2] = (area->x2 >> 8) & 0xFF; - data[3] = (area->x2 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); - st7735s_send_data(data, 4); + /*Column addresses*/ + st7735s_send_cmd(0x2A); + data[0] = (area->x1 >> 8) & 0xFF; + data[1] = (area->x1 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); + data[2] = (area->x2 >> 8) & 0xFF; + data[3] = (area->x2 & 0xFF) + (st7735s_portrait_mode ? COLSTART : ROWSTART); + st7735s_send_data(data, 4); - /*Page addresses*/ - st7735s_send_cmd(0x2B); - data[0] = (area->y1 >> 8) & 0xFF; - data[1] = (area->y1 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); - data[2] = (area->y2 >> 8) & 0xFF; - data[3] = (area->y2 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); - st7735s_send_data(data, 4); + /*Page addresses*/ + st7735s_send_cmd(0x2B); + data[0] = (area->y1 >> 8) & 0xFF; + data[1] = (area->y1 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); + data[2] = (area->y2 >> 8) & 0xFF; + data[3] = (area->y2 & 0xFF) + (st7735s_portrait_mode ? ROWSTART : COLSTART); + st7735s_send_data(data, 4); - /*Memory write*/ - st7735s_send_cmd(0x2C); + /*Memory write*/ + st7735s_send_cmd(0x2C); - uint32_t size = lv_area_get_width(area) * lv_area_get_height(area); - st7735s_send_color((void*)color_map, size * 2); + uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2; + st7735s_send_color((void*)color_map, size); } void st7735s_sleep_in() @@ -227,6 +215,16 @@ static void st7735s_set_orientation(uint8_t orientation) st7735s_send_data((void *) &data[orientation], 1); } +static void st7735s_reset(void) +{ +#if ST7735S_USE_RST + gpio_set_level(ST7735S_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ST7735S_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +} + #ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192 static void axp192_write_byte(uint8_t addr, uint8_t data) diff --git a/lvgl_tft/st7796s.c b/lvgl_tft/st7796s.c index 75e9bd2..90e0d8c 100644 --- a/lvgl_tft/st7796s.c +++ b/lvgl_tft/st7796s.c @@ -36,6 +36,7 @@ static void st7796s_set_orientation(uint8_t orientation); static void st7796s_send_cmd(uint8_t cmd); static void st7796s_send_data(void *data, uint16_t length); static void st7796s_send_color(void *data, uint16_t length); +static void st7796s_reset(void); /********************** * STATIC VARIABLES @@ -79,37 +80,24 @@ void st7796s_init(void) {0, {0}, 0xff}, }; - //Initialize non-SPI GPIOs - gpio_pad_select_gpio(ST7796S_DC); - gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT); + st7796s_reset(); -#if ST7796S_USE_RST - gpio_pad_select_gpio(ST7796S_RST); - gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT); + LV_LOG_INFO("Initialization."); - //Reset the display - gpio_set_level(ST7796S_RST, 0); - vTaskDelay(100 / portTICK_RATE_MS); - gpio_set_level(ST7796S_RST, 1); - vTaskDelay(100 / portTICK_RATE_MS); -#endif + //Send all the commands + uint16_t cmd = 0; + while (init_cmds[cmd].databytes != 0xff) + { + st7796s_send_cmd(init_cmds[cmd].cmd); + st7796s_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes & 0x1F); + if (init_cmds[cmd].databytes & 0x80) + { + vTaskDelay(100 / portTICK_RATE_MS); + } + cmd++; + } - LV_LOG_INFO("Initialization."); - - //Send all the commands - uint16_t cmd = 0; - while (init_cmds[cmd].databytes != 0xff) - { - st7796s_send_cmd(init_cmds[cmd].cmd); - st7796s_send_data(init_cmds[cmd].data, init_cmds[cmd].databytes & 0x1F); - if (init_cmds[cmd].databytes & 0x80) - { - vTaskDelay(100 / portTICK_RATE_MS); - } - cmd++; - } - - st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); + st7796s_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION); #if ST7796S_INVERT_COLORS == 1 st7796s_send_cmd(0x21); @@ -210,3 +198,13 @@ static void st7796s_set_orientation(uint8_t orientation) st7796s_send_cmd(0x36); st7796s_send_data((void *)&data[orientation], 1); } + +static void st7796s_reset(void) +{ +#if ST7796S_USE_RST + gpio_set_level(ST7796S_RST, 0); + vTaskDelay(100 / portTICK_RATE_MS); + gpio_set_level(ST7796S_RST, 1); + vTaskDelay(100 / portTICK_RATE_MS); +#endif +}