diff --git a/Code/picocalc_helloworld/CMakeLists.txt b/Code/picocalc_helloworld/CMakeLists.txt new file mode 100644 index 0000000..d2104ac --- /dev/null +++ b/Code/picocalc_helloworld/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.13) + +include(pico_sdk_import.cmake) + +project(picocalc_helloworld C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +pico_sdk_init() + +include_directories( + ${CMAKE_CURRENT_LIST_DIR} +) + +add_subdirectory(i2ckbd) +add_subdirectory(lcdspi) + +add_executable(picocalc_helloworld + main.c + ) + +target_link_libraries(picocalc_helloworld + pico_stdlib + hardware_flash + hardware_irq + hardware_adc + hardware_pwm + hardware_i2c + hardware_spi + hardware_dma + hardware_exception + hardware_pio + pico_multicore + i2ckbd + lcdspi + + ) + +pico_enable_stdio_usb(picocalc_helloworld 0) +pico_enable_stdio_uart(picocalc_helloworld 1) + +pico_add_extra_outputs(picocalc_helloworld) diff --git a/Code/picocalc_helloworld/README.md b/Code/picocalc_helloworld/README.md new file mode 100644 index 0000000..da4a6a1 --- /dev/null +++ b/Code/picocalc_helloworld/README.md @@ -0,0 +1,14 @@ +# PicoCalc Hello World + +Demonstrate how to use spi screen and i2c keyboard on PicoCalc. + +## Building +``` +mkdir build +cd build +export PICO_SDK_PATH=/where/pico-sdk/is +cmake .. +make +``` + + diff --git a/Code/picocalc_helloworld/i2ckbd/CMakeLists.txt b/Code/picocalc_helloworld/i2ckbd/CMakeLists.txt new file mode 100644 index 0000000..d7d7a22 --- /dev/null +++ b/Code/picocalc_helloworld/i2ckbd/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) + +project(i2ckbd + VERSION 0.0.1 + DESCRIPTION "i2ckbd for picocalc." + ) + +add_library(i2ckbd INTERFACE) + +target_sources(i2ckbd INTERFACE + i2ckbd.c + ) + +target_link_libraries(i2ckbd INTERFACE pico_stdlib hardware_spi hardware_i2c) + +target_include_directories(i2ckbd INTERFACE ${CMAKE_CURRENT_LIST_DIR}) \ No newline at end of file diff --git a/Code/picocalc_helloworld/i2ckbd/i2ckbd.c b/Code/picocalc_helloworld/i2ckbd/i2ckbd.c new file mode 100644 index 0000000..ae54932 --- /dev/null +++ b/Code/picocalc_helloworld/i2ckbd/i2ckbd.c @@ -0,0 +1,57 @@ +#include +#include +#include "i2ckbd.h" + +static uint8_t i2c_inited = 0; + +void init_i2c_kbd() { + gpio_set_function(I2C_KBD_SCL, GPIO_FUNC_I2C); + gpio_set_function(I2C_KBD_SDA, GPIO_FUNC_I2C); + i2c_init(I2C_KBD_MOD, I2C_KBD_SPEED); + gpio_pull_up(I2C_KBD_SCL); + gpio_pull_up(I2C_KBD_SDA); + + i2c_inited = 1; +} + +int read_i2c_kbd() { + int retval; + static int ctrlheld = 0; + uint16_t buff = 0; + unsigned char msg[2]; + int c = -1; + msg[0] = 0x09; + + if (i2c_inited == 0) return -1; + + retval = i2c_write_timeout_us(I2C_KBD_MOD, I2C_KBD_ADDR, msg, 1, false, 500000); + if (retval == PICO_ERROR_GENERIC || retval == PICO_ERROR_TIMEOUT) { + printf("i2c write error\n"); + return -1; + } + + retval = i2c_read_timeout_us(I2C_KBD_MOD, I2C_KBD_ADDR, (unsigned char *) &buff, 2, false, 500000); + if (retval == PICO_ERROR_GENERIC || retval == PICO_ERROR_TIMEOUT) { + printf("i2c read error read\n"); + return -1; + } + + if (buff != 0) { + if (buff == 0x7e03)ctrlheld = 0; + else if (buff == 0x7e02) { + ctrlheld = 1; + } else if ((buff & 0xff) == 1) {//pressed + c = buff >> 8; + int realc = -1; + switch (c) { + default: + realc = c; + break; + } + c = realc; + if (c >= 'a' && c <= 'z' && ctrlheld)c = c - 'a' + 1; + } + return c; + } + return -1; +} \ No newline at end of file diff --git a/Code/picocalc_helloworld/i2ckbd/i2ckbd.h b/Code/picocalc_helloworld/i2ckbd/i2ckbd.h new file mode 100644 index 0000000..0281abd --- /dev/null +++ b/Code/picocalc_helloworld/i2ckbd/i2ckbd.h @@ -0,0 +1,19 @@ +#ifndef I2C_KEYBOARD_H +#define I2C_KEYBOARD_H +#include +#include +#include +#include + +#define I2C_KBD_MOD i2c1 +#define I2C_KBD_SDA 6 +#define I2C_KBD_SCL 7 + +#define I2C_KBD_SPEED 400000 // if dual i2c, then the speed of keyboard i2c should be 10khz + +#define I2C_KBD_ADDR 0x1F + +void init_i2c_kbd(); +int read_i2c_kbd(); + +#endif \ No newline at end of file diff --git a/Code/picocalc_helloworld/lcdspi/CMakeLists.txt b/Code/picocalc_helloworld/lcdspi/CMakeLists.txt new file mode 100644 index 0000000..35f4078 --- /dev/null +++ b/Code/picocalc_helloworld/lcdspi/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) + +project(lcdspi + VERSION 0.0.1 + DESCRIPTION "lcdspi for rp2040." + ) + +add_library(lcdspi INTERFACE) + +target_sources(lcdspi INTERFACE + lcdspi.c + ) + +target_link_libraries(lcdspi INTERFACE pico_stdlib hardware_spi) + +target_include_directories(lcdspi INTERFACE ${CMAKE_CURRENT_LIST_DIR}) \ No newline at end of file diff --git a/Code/picocalc_helloworld/lcdspi/fonts/font1.h b/Code/picocalc_helloworld/lcdspi/fonts/font1.h new file mode 100644 index 0000000..749ad88 --- /dev/null +++ b/Code/picocalc_helloworld/lcdspi/fonts/font1.h @@ -0,0 +1,233 @@ +// font1.c +// Font type : Full (223 characters) +// Font size : 8x12 pixels +// Memory usage : 2680 bytes +// Font adapted from: http://www.rinkydinkelectronics.com/r_fonts.php + +const unsigned char font1[] ={ + 0x08,0x0C,0x20,0xE0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(32) + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x00,0x00, // Chr$(33) ! + 0x00,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(34) " + 0x00,0x24,0x24,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x00,0x00, // Chr$(35) # + 0x00,0x10,0x3C,0x52,0x50,0x3C,0x12,0x52,0x3C,0x10,0x00,0x00, // Chr$(36) $ + 0x00,0x00,0x62,0x62,0x04,0x08,0x10,0x20,0x46,0x46,0x00,0x00, // Chr$(37) % + 0x00,0x00,0x38,0x44,0x44,0x38,0x4A,0x44,0x4C,0x3A,0x00,0x00, // Chr$(38) & + 0x00,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(39) ' + 0x00,0x0C,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x0C,0x00, // Chr$(40) ( + 0x00,0x30,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x30,0x00, // Chr$(41) ) + 0x00,0x42,0x24,0x18,0x7E,0x18,0x24,0x42,0x00,0x00,0x00,0x00, // Chr$(42) * + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, // Chr$(43) + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x08,0x10,0x00, // Chr$(44) , + 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(45) - + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00, // Chr$(46) . + 0x00,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x20,0x40,0x40,0x00, // Chr$(47) / + 0x00,0x3C,0x46,0x4E,0x4A,0x5A,0x52,0x72,0x62,0x3C,0x00,0x00, // Chr$(48) 0 + 0x00,0x10,0x30,0x50,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // Chr$(49) 1 + 0x00,0x3C,0x42,0x02,0x02,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // Chr$(50) 2 + 0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00, // Chr$(51) 3 + 0x00,0x04,0x44,0x44,0x44,0x7E,0x04,0x04,0x04,0x04,0x00,0x00, // Chr$(52) 4 + 0x00,0x7E,0x40,0x40,0x7C,0x02,0x02,0x02,0x42,0x3C,0x00,0x00, // Chr$(53) 5 + 0x00,0x18,0x20,0x40,0x40,0x7C,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(54) 6 + 0x00,0x7E,0x42,0x02,0x02,0x04,0x08,0x10,0x10,0x10,0x00,0x00, // Chr$(55) 7 + 0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(56) 8 + 0x00,0x3C,0x42,0x42,0x42,0x3E,0x02,0x04,0x08,0x30,0x00,0x00, // Chr$(57) 9 + 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x00, // Chr$(58) : + 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x08,0x10,0x00, // Chr$(59) ; + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // Chr$(60) < + 0x00,0x00,0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, // Chr$(61) = + 0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x00,0x00, // Chr$(62) > + 0x00,0x3C,0x42,0x02,0x06,0x08,0x10,0x10,0x00,0x10,0x10,0x00, // Chr$(63) ? + 0x00,0x3C,0x42,0x42,0x5E,0x56,0x5C,0x40,0x40,0x3C,0x00,0x00, // Chr$(64) @ + 0x00,0x18,0x24,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x00, // Chr$(65) A + 0x00,0x7C,0x42,0x42,0x42,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, // Chr$(66) B + 0x00,0x3C,0x42,0x40,0x40,0x40,0x40,0x40,0x42,0x3C,0x00,0x00, // Chr$(67) C + 0x00,0x78,0x44,0x42,0x42,0x42,0x42,0x42,0x44,0x78,0x00,0x00, // Chr$(68) D + 0x00,0x7E,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7E,0x00,0x00, // Chr$(69) E + 0x00,0x7E,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, // Chr$(70) F + 0x00,0x3C,0x42,0x40,0x40,0x40,0x4E,0x42,0x42,0x3E,0x00,0x00, // Chr$(71) G + 0x00,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,0x00, // Chr$(72) H + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // Chr$(73) I + 0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x42,0x3C,0x00,0x00, // Chr$(74) J + 0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00, // Chr$(75) K + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00, // Chr$(76) L + 0x00,0x42,0x66,0x66,0x5A,0x42,0x42,0x42,0x42,0x42,0x00,0x00, // Chr$(77) M + 0x00,0x42,0x62,0x62,0x52,0x5A,0x4A,0x46,0x46,0x42,0x00,0x00, // Chr$(78) N + 0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(79) O + 0x00,0x7C,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,0x00, // Chr$(80) P + 0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x4A,0x44,0x3A,0x00,0x00, // Chr$(81) Q + 0x00,0x7C,0x42,0x42,0x42,0x7C,0x48,0x44,0x42,0x42,0x00,0x00, // Chr$(82) R + 0x00,0x3C,0x42,0x40,0x60,0x18,0x04,0x02,0x42,0x3C,0x00,0x00, // Chr$(83) S + 0x00,0x7E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // Chr$(84) T + 0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(85) U + 0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x24,0x18,0x00,0x00, // Chr$(86) V + 0x00,0x42,0x42,0x42,0x42,0x42,0x5A,0x24,0x24,0x24,0x00,0x00, // Chr$(87) W + 0x00,0x42,0x42,0x24,0x24,0x18,0x24,0x24,0x42,0x42,0x00,0x00, // Chr$(88) X + 0x00,0x44,0x44,0x44,0x44,0x38,0x10,0x10,0x10,0x10,0x00,0x00, // Chr$(89) Y + 0x00,0x7E,0x02,0x02,0x04,0x18,0x20,0x40,0x40,0x7E,0x00,0x00, // Chr$(90) Z + 0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x00,0x00, // Chr$(91) [ + 0x00,0x40,0x40,0x20,0x20,0x10,0x08,0x04,0x04,0x02,0x02,0x00, // Chr$(92) backslash + 0x00,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3C,0x00,0x00, // Chr$(93) ] + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(94) ^ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00, // Chr$(95) _ + 0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(96) ` + 0x00,0x00,0x00,0x00,0x3C,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00, // Chr$(97) a + 0x00,0x40,0x40,0x40,0x7C,0x42,0x42,0x42,0x42,0x7C,0x00,0x00, // Chr$(98) b + 0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x40,0x40,0x3C,0x00,0x00, // Chr$(99) c + 0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x3E,0x00,0x00, // Chr$(100) d + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7C,0x40,0x3C,0x00,0x00, // Chr$(101) e + 0x00,0x00,0x1C,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x00,0x00, // Chr$(102) f + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3E,0x02,0x3C,0x00, // Chr$(103) g + 0x00,0x40,0x40,0x40,0x7C,0x42,0x42,0x42,0x42,0x42,0x00,0x00, // Chr$(104) h + 0x00,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // Chr$(105) i + 0x00,0x00,0x04,0x00,0x04,0x04,0x04,0x04,0x04,0x44,0x38,0x00, // Chr$(106) j + 0x00,0x40,0x40,0x40,0x44,0x48,0x70,0x50,0x48,0x44,0x00,0x00, // Chr$(107) k + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x00,0x00, // Chr$(108) l + 0x00,0x00,0x00,0x00,0x74,0x4A,0x4A,0x42,0x42,0x42,0x00,0x00, // Chr$(109) m + 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, // Chr$(110) n + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(111) o + 0x00,0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x40,0x40,0x00, // Chr$(112) p + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3C,0x06,0x00, // Chr$(113) q + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x40,0x40,0x40,0x00,0x00, // Chr$(114) r + 0x00,0x00,0x00,0x00,0x1E,0x20,0x1C,0x02,0x02,0x3C,0x00,0x00, // Chr$(115) s + 0x00,0x00,0x00,0x10,0x7C,0x10,0x10,0x10,0x10,0x08,0x00,0x00, // Chr$(116) t + 0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // Chr$(117) u + 0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00, // Chr$(118) v + 0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x5A,0x24,0x24,0x00,0x00, // Chr$(119) w + 0x00,0x00,0x00,0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00,0x00, // Chr$(120) x + 0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x3E,0x02,0x42,0x3C,0x00, // Chr$(121) y + 0x00,0x00,0x00,0x00,0x7E,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // Chr$(122) z + 0x00,0x1C,0x20,0x10,0x10,0x60,0x10,0x10,0x20,0x1C,0x00,0x00, // Chr$(123) { + 0x00,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00,0x00, // Chr$(124) | + 0x00,0x38,0x04,0x08,0x08,0x06,0x08,0x08,0x04,0x38,0x00,0x00, // Chr$(125) } + 0x00,0x22,0x5A,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(126) ~ + 0x00,0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x7E,0x00,0x00,0x00, // Chr$(127)  + 0x00,0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0xFF,0x00, // Chr$(128) € + 0x00,0xFF,0x81,0x81,0x85,0x85,0xA9,0x91,0x81,0x81,0xFF,0x00, // Chr$(129)  + 0x00,0xFF,0x81,0xA5,0xA5,0x99,0x99,0xA5,0xA5,0x81,0xFF,0x00, // Chr$(130) ‚ + 0x00,0xFF,0x81,0x81,0x81,0x99,0x99,0x81,0x81,0x81,0xFF,0x00, // Chr$(131) ƒ + 0x00,0xFF,0x81,0x81,0x81,0x81,0x81,0xBD,0x81,0x81,0xFF,0x00, // Chr$(132) „ + 0x00,0xFF,0x81,0x99,0x99,0x99,0x99,0x81,0x99,0x81,0xFF,0x00, // Chr$(133) … + 0x00,0xFF,0x81,0x99,0xA5,0x89,0x89,0x81,0x89,0x81,0xFF,0x00, // Chr$(134) † + 0x00,0x3E,0x7F,0x7F,0x6B,0x7F,0x6B,0x77,0x7F,0x3E,0x00,0x00, // Chr$(135) ‡ + 0x00,0x3E,0x63,0x41,0x55,0x41,0x55,0x49,0x63,0x3E,0x00,0x00, // Chr$(136) ˆ + 0x00,0x00,0x08,0x1C,0x3E,0x7F,0x7F,0x3E,0x1C,0x08,0x00,0x00, // Chr$(137) ‰ + 0x00,0x00,0x00,0x18,0x18,0x66,0x66,0x18,0x18,0x3C,0x00,0x00, // Chr$(138) Š + 0x00,0x00,0x00,0x18,0x3C,0x7E,0x7E,0x18,0x18,0x3C,0x00,0x00, // Chr$(139) ‹ + 0x00,0x00,0x36,0x3E,0x7F,0x7F,0x7F,0x3E,0x1C,0x08,0x00,0x00, // Chr$(140) Œ + 0xFF,0xFF,0xC3,0x81,0x99,0xBD,0xBD,0x99,0x81,0xC3,0xFF,0xFF, // Chr$(141)  + 0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00, // Chr$(142) Ž + 0x00,0x1F,0x19,0x1F,0x18,0x18,0x18,0x38,0x78,0x30,0x00,0x00, // Chr$(143)  + 0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00, // Chr$(144)  + 0x00,0x00,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,0x00, // Chr$(145) ‘ + 0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, // Chr$(146) ’ + 0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00, // Chr$(147) “ + 0x00,0x00,0x00,0x08,0x0C,0xFE,0xFE,0x0C,0x08,0x00,0x00,0x00, // Chr$(148) ” + 0x00,0x00,0x00,0x10,0x30,0x7F,0x7F,0x30,0x10,0x00,0x00,0x00, // Chr$(149) • + 0x00,0x00,0x08,0x2A,0x49,0x49,0x49,0x41,0x41,0x3E,0x00,0x00, // Chr$(150) – + 0x1C,0x22,0x41,0x5D,0x49,0x2A,0x1C,0x00,0x1C,0x00,0x1C,0x00, // Chr$(151) — + 0x18,0x18,0x00,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x18,0x00,0x00, // Chr$(152) ˜ + 0xF8,0x8C,0xBE,0x8F,0xE3,0x85,0xF5,0xF5,0xF3,0xFF,0x00,0x00, // Chr$(153) ™ + 0x00,0x18,0x24,0x42,0x42,0x42,0x7E,0x7E,0x24,0x24,0x24,0x24, // Chr$(154) š + 0x00,0x18,0x3C,0x7E,0x7E,0x7E,0x7E,0x7E,0x24,0x24,0x24,0x24, // Chr$(155) › + 0x00,0x20,0x64,0xE2,0xE9,0xE5,0xE9,0xE2,0x64,0x20,0x00,0x00, // Chr$(156) œ + 0x00,0x3F,0x4B,0x4B,0x4B,0x3B,0x0B,0x0B,0x0B,0x0B,0x00,0x00, // Chr$(157)  + 0x00,0x7E,0x44,0x48,0x6E,0x24,0x28,0x50,0x60,0x40,0x00,0x00, // Chr$(158) ž + 0x00,0x00,0x21,0x36,0x1E,0x3C,0xFE,0x1B,0x10,0x10,0x00,0x00, // Chr$(159) Ÿ + 0x00,0x3C,0x42,0x81,0xA5,0xA5,0xA5,0x81,0x42,0x3C,0x00,0x00, // Chr$(160)   + 0x00,0x3C,0x42,0x91,0x99,0x9D,0x99,0x91,0x42,0x3C,0x00,0x00, // Chr$(161) ¡ + 0x00,0x3C,0x42,0x81,0xBD,0xBD,0xBD,0x81,0x42,0x3C,0x00,0x00, // Chr$(162) ¢ + 0x00,0x00,0x38,0x44,0x44,0x44,0x3C,0x06,0x03,0x01,0x00,0x00, // Chr$(163) £ + 0x00,0x0C,0x10,0x20,0x7C,0x20,0x20,0x7C,0x20,0x10,0x0C,0x00, // Chr$(164) ¤ + 0x00,0x00,0x1A,0x26,0x42,0x81,0x42,0x42,0x42,0x7E,0x00,0x00, // Chr$(165) ¥ + 0x00,0x00,0x3C,0x24,0xFF,0x42,0x42,0x42,0x42,0x7E,0x00,0x00, // Chr$(166) ¦ + 0x00,0x18,0x66,0x42,0x81,0xC3,0xC3,0x42,0x00,0x00,0x00,0x00, // Chr$(167) § + 0x00,0x00,0xFF,0x81,0x81,0x81,0x81,0xFF,0x18,0x3C,0x00,0x00, // Chr$(168) ¨ + 0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x18,0x00,0x18,0x18,0x00,0x00, // Chr$(169) © + 0x28,0x56,0x41,0x83,0xFE,0x0C,0x10,0x10,0x20,0x00,0x00,0x00, // Chr$(170) ª + 0x00,0x30,0x48,0x48,0x48,0x4A,0x32,0x02,0x02,0x02,0x02,0x00, // Chr$(171) « + 0x18,0x24,0x66,0x5A,0x66,0x18,0x38,0x18,0x38,0x18,0x38,0x00, // Chr$(172) ¬ + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // Chr$(173) ­ + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, // Chr$(174) ® + 0xCC,0xCC,0x33,0x33,0xCC,0xCC,0x33,0x33,0xCC,0xCC,0x33,0x33, // Chr$(175) ¯ + 0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49,0x24,0x92,0x49, // Chr$(176) ° + 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA, // Chr$(177) ± + 0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6, // Chr$(178) ² + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(179) ³ + 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(180) ´ + 0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0xF8,0x18,0x18,0x18,0x18, // Chr$(181) µ + 0x66,0x66,0x66,0x66,0x66,0xE6,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(182) ¶ + 0x00,0x00,0x00,0x00,0x00,0xFE,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(183) · + 0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0xF8,0x18,0x18,0x18,0x18, // Chr$(184) ¸ + 0x66,0x66,0x66,0x66,0xE6,0x06,0x06,0xE6,0x66,0x66,0x66,0x66, // Chr$(185) ¹ + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(186) º + 0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0xE6,0x66,0x66,0x66,0x66, // Chr$(187) » + 0x66,0x66,0x66,0x66,0xE6,0x06,0x06,0xFE,0x00,0x00,0x00,0x00, // Chr$(188) ¼ + 0x66,0x66,0x66,0x66,0x66,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(189) ½ + 0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0xF8,0x00,0x00,0x00,0x00, // Chr$(190) ¾ + 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(191) ¿ + 0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(192) À + 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(193) Á + 0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(194)  + 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(195) à + 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(196) Ä + 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(197) Å + 0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x1F,0x18,0x18,0x18,0x18, // Chr$(198) Æ + 0x66,0x66,0x66,0x66,0x66,0x67,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(199) Ç + 0x66,0x66,0x66,0x66,0x67,0x60,0x60,0x7F,0x00,0x00,0x00,0x00, // Chr$(200) È + 0x00,0x00,0x00,0x00,0x7F,0x60,0x60,0x67,0x66,0x66,0x66,0x66, // Chr$(201) É + 0x66,0x66,0x66,0x66,0xE7,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, // Chr$(202) Ê + 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xE7,0x66,0x66,0x66,0x66, // Chr$(203) Ë + 0x66,0x66,0x66,0x66,0x67,0x60,0x60,0x67,0x66,0x66,0x66,0x66, // Chr$(204) Ì + 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, // Chr$(205) Í + 0x66,0x66,0x66,0x66,0xE7,0x00,0x00,0xE7,0x66,0x66,0x66,0x66, // Chr$(206) Î + 0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, // Chr$(207) Ï + 0x66,0x66,0x66,0x66,0x66,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(208) Ð + 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x18,0x18,0x18,0x18, // Chr$(209) Ñ + 0x00,0x00,0x00,0x00,0x00,0xFF,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(210) Ò + 0x66,0x66,0x66,0x66,0x66,0x7F,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(211) Ó + 0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x1F,0x00,0x00,0x00,0x00, // Chr$(212) Ô + 0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x1F,0x18,0x18,0x18,0x18, // Chr$(213) Õ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(214) Ö + 0x66,0x66,0x66,0x66,0x66,0xE7,0x66,0x66,0x66,0x66,0x66,0x66, // Chr$(215) × + 0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0xFF,0x18,0x18,0x18,0x18, // Chr$(216) Ø + 0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(217) Ù + 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18, // Chr$(218) Ú + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // Chr$(219) Û + 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // Chr$(220) Ü + 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, // Chr$(221) Ý + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, // Chr$(222) Þ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(223) ß + 0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x44,0x44,0x3A,0x00,0x00, // Chr$(224) à + 0x00,0x38,0x44,0x44,0x58,0x44,0x44,0x44,0x78,0x40,0x40,0x00, // Chr$(225) á + 0x00,0x00,0x7E,0x42,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, // Chr$(226) â + 0x00,0x00,0x00,0x00,0x7C,0x28,0x28,0x28,0x28,0x68,0x00,0x00, // Chr$(227) ã + 0x00,0x7E,0x42,0x20,0x10,0x08,0x10,0x20,0x42,0x7E,0x00,0x00, // Chr$(228) ä + 0x00,0x00,0x00,0x00,0x3E,0x48,0x44,0x44,0x44,0x38,0x00,0x00, // Chr$(229) å + 0x00,0x00,0x00,0x24,0x24,0x24,0x24,0x3C,0x42,0x40,0x80,0x00, // Chr$(230) æ + 0x00,0x00,0x00,0x00,0x44,0xA8,0x10,0x10,0x10,0x10,0x00,0x00, // Chr$(231) ç + 0x00,0x00,0x7C,0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x7C,0x00, // Chr$(232) è + 0x00,0x00,0x18,0x24,0x42,0x42,0x7E,0x42,0x42,0x24,0x18,0x00, // Chr$(233) é + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x6C,0x28,0x6C,0x00,0x00, // Chr$(234) ê + 0x00,0x00,0x00,0x1C,0x20,0x38,0x44,0x44,0x44,0x38,0x00,0x00, // Chr$(235) ë + 0x00,0x00,0x00,0x00,0x00,0x6C,0x92,0x92,0x6C,0x00,0x00,0x00, // Chr$(236) ì + 0x00,0x00,0x00,0x00,0x02,0x6C,0x9A,0xB2,0x6C,0x80,0x00,0x00, // Chr$(237) í + 0x00,0x18,0x20,0x40,0x40,0x78,0x40,0x40,0x20,0x18,0x00,0x00, // Chr$(238) î + 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x00,0x00, // Chr$(239) ï + 0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x00, // Chr$(240) ð + 0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x7C,0x00,0x00,0x00, // Chr$(241) ñ + 0x00,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x00,0x7E,0x00,0x00, // Chr$(242) ò + 0x00,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00,0x7E,0x00,0x00, // Chr$(243) ó + 0x40,0x41,0x42,0x44,0x48,0x10,0x26,0x49,0x02,0x04,0x0F,0x00, // Chr$(244) ô + 0x40,0x41,0x42,0x44,0x48,0x12,0x26,0x4A,0x0F,0x02,0x02,0x00, // Chr$(245) õ + 0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00, // Chr$(246) ö + 0x00,0x00,0x22,0x52,0x4C,0x00,0x22,0x52,0x4C,0x00,0x00,0x00, // Chr$(247) ÷ + 0x00,0x20,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(248) ø + 0x00,0x00,0x00,0x00,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(249) ù + 0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(250) ú + 0x00,0x00,0x0E,0x08,0x08,0x08,0x08,0x48,0x28,0x18,0x08,0x00, // Chr$(251) û + 0x00,0x3C,0x12,0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(252) ü + 0x00,0x18,0x24,0x08,0x10,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(253) ý + 0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00, // Chr$(254) þ + 0x00,0x00,0x10,0x54,0x28,0xC6,0x28,0x54,0x10,0x00,0x00,0x00 // Chr$(255) ÿ +}; diff --git a/Code/picocalc_helloworld/lcdspi/lcdspi.c b/Code/picocalc_helloworld/lcdspi/lcdspi.c new file mode 100644 index 0000000..1c683dc --- /dev/null +++ b/Code/picocalc_helloworld/lcdspi/lcdspi.c @@ -0,0 +1,715 @@ +#include +#include +#include + +#include +#include "hardware/timer.h" +#include +#include + +#include "lcdspi.h" +#include "i2ckbd.h" +#include "pico/multicore.h" +////////////////////**************************************fonts + +#include "fonts/font1.h" +unsigned char *MainFont = (unsigned char *) font1; + +static int gui_fcolour; +static int gui_bcolour; +static short current_x = 0, current_y = 0; // the current default position for the next char to be written +static short gui_font_width, gui_font_height; +static short hres = 0; +static short vres = 0; +static char s_height; +static char s_width; +int lcd_char_pos = 0; +unsigned char lcd_buffer[320 * 3] = {0};// 1440 = 480*3, 320*3 = 960 + +void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len) { + // Write to TX FIFO whilst ignoring RX, then clean up afterward. When RX + // is full, PL022 inhibits RX pushes, and sets a sticky flag on + // push-on-full, but continues shifting. Safe if SSPIMSC_RORIM is not set. + for (size_t i = 0; i < len; ++i) { + while (!spi_is_writable(spi)) + tight_loop_contents(); + spi_get_hw(spi)->dr = (uint32_t) src[i]; + } +} + +void __not_in_flash_func(spi_finish)(spi_inst_t *spi) { + // Drain RX FIFO, then wait for shifting to finish (which may be *after* + // TX FIFO drains), then drain RX FIFO again + while (spi_is_readable(spi)) + (void) spi_get_hw(spi)->dr; + while (spi_get_hw(spi)->sr & SPI_SSPSR_BSY_BITS) + tight_loop_contents(); + while (spi_is_readable(spi)) + (void) spi_get_hw(spi)->dr; + + // Don't leave overrun flag set + spi_get_hw(spi)->icr = SPI_SSPICR_RORIC_BITS; +} + +void set_font() { + + gui_font_width = MainFont[0]; + gui_font_height = MainFont[1]; + + s_height = vres / gui_font_height; + s_width = hres / gui_font_width; +} + +void define_region_spi(int xstart, int ystart, int xend, int yend, int rw) { + unsigned char coord[4]; + lcd_spi_lower_cs(); + gpio_put(Pico_LCD_DC, 0);//gpio_put(Pico_LCD_DC,0); + hw_send_spi(&(uint8_t) {ILI9341_COLADDRSET}, 1); + gpio_put(Pico_LCD_DC, 1); + coord[0] = xstart >> 8; + coord[1] = xstart; + coord[2] = xend >> 8; + coord[3] = xend; + hw_send_spi(coord, 4);// HAL_SPI_Transmit(&hspi3,coord,4,500); + gpio_put(Pico_LCD_DC, 0); + hw_send_spi(&(uint8_t) {ILI9341_PAGEADDRSET}, 1); + gpio_put(Pico_LCD_DC, 1); + coord[0] = ystart >> 8; + coord[1] = ystart; + coord[2] = yend >> 8; + coord[3] = yend; + hw_send_spi(coord, 4);// HAL_SPI_Transmit(&hspi3,coord,4,500); + gpio_put(Pico_LCD_DC, 0); + if (rw) { + hw_send_spi(&(uint8_t) {ILI9341_MEMORYWRITE}, 1); + } else { + hw_send_spi(&(uint8_t) {ILI9341_RAMRD}, 1); + } + gpio_put(Pico_LCD_DC, 1); +} + +void read_buffer_spi(int x1, int y1, int x2, int y2, unsigned char *p) { + int r, N, t; + unsigned char h, l; +// PInt(x1);PIntComma(y1);PIntComma(x2);PIntComma(y2);PRet(); + // make sure the coordinates are kept within the display area + if (x2 <= x1) { + t = x1; + x1 = x2; + x2 = t; + } + if (y2 <= y1) { + t = y1; + y1 = y2; + y2 = t; + } + if (x1 < 0) x1 = 0; + if (x1 >= hres) x1 = hres - 1; + if (x2 < 0) x2 = 0; + if (x2 >= hres) x2 = hres - 1; + if (y1 < 0) y1 = 0; + if (y1 >= vres) y1 = vres - 1; + if (y2 < 0) y2 = 0; + if (y2 >= vres) y2 = vres - 1; + N = (x2 - x1 + 1) * (y2 - y1 + 1) * 3; + + define_region_spi(x1, y1, x2, y2, 0); + + //spi_init(Pico_LCD_SPI_MOD, 6000000); + spi_set_baudrate(Pico_LCD_SPI_MOD, 6000000); + //spi_read_data_len(p, 1); + hw_read_spi((uint8_t *) p, 1); + r = 0; + hw_read_spi((uint8_t *) p, N); + gpio_put(Pico_LCD_DC, 0); + lcd_spi_raise_cs(); + spi_set_baudrate(Pico_LCD_SPI_MOD, LCD_SPI_SPEED); + r = 0; + + while (N) { + h = (uint8_t) p[r + 2]; + l = (uint8_t) p[r]; + p[r] = h;//(h & 0xF8); + p[r + 2] = l;//(l & 0xF8); + r += 3; + N -= 3; + } +} + +void draw_buffer_spi(int x1, int y1, int x2, int y2, unsigned char *p) { + union colourmap { + char rgbbytes[4]; + unsigned int rgb; + } c; + unsigned char q[3]; + int i, t; + if (x2 <= x1) { + t = x1; + x1 = x2; + x2 = t; + } + if (y2 <= y1) { + t = y1; + y1 = y2; + y2 = t; + } + if (x1 < 0) x1 = 0; + if (x1 >= hres) x1 = hres - 1; + if (x2 < 0) x2 = 0; + if (x2 >= hres) x2 = hres - 1; + if (y1 < 0) y1 = 0; + if (y1 >= vres) y1 = vres - 1; + if (y2 < 0) y2 = 0; + if (y2 >= vres) y2 = vres - 1; + i = (x2 - x1 + 1) * (y2 - y1 + 1); + define_region_spi(x1, y1, x2, y2, 1); + while (i--) { + c.rgbbytes[0] = *p++; //this order swaps the bytes to match the .BMP file + c.rgbbytes[1] = *p++; + c.rgbbytes[2] = *p++; + // convert the colours to 565 format + // convert the colours to 565 format +#ifdef ILI9488 + q[0] = c.rgbbytes[2]; + q[1] = c.rgbbytes[1]; + q[2] = c.rgbbytes[0]; +#endif + hw_send_spi(q, 3); + } + lcd_spi_raise_cs(); + +} + +//Print the bitmap of a char on the video output +// x, y - the top left of the char +// width, height - size of the char's bitmap +// scale - how much to scale the bitmap +// fc, bc - foreground and background colour +// bitmap - pointer to the bitmap +void draw_bitmap_spi(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap) { + int i, j, k, m, n; + char f[3], b[3]; + int vertCoord, horizCoord, XStart, XEnd, YEnd; + char *p = 0; + union colourmap { + char rgbbytes[4]; + unsigned int rgb; + } c; + + if (x1 >= hres || y1 >= vres || x1 + width * scale < 0 || y1 + height * scale < 0)return; + // adjust when part of the bitmap is outside the displayable coordinates + vertCoord = y1; + if (y1 < 0) y1 = 0; // the y coord is above the top of the screen + XStart = x1; + if (XStart < 0) XStart = 0; // the x coord is to the left of the left marginn + XEnd = x1 + (width * scale) - 1; + if (XEnd >= hres) XEnd = hres - 1; // the width of the bitmap will extend beyond the right margin + YEnd = y1 + (height * scale) - 1; + if (YEnd >= vres) YEnd = vres - 1;// the height of the bitmap will extend beyond the bottom margin + +#ifdef ILI9488 + // convert the colours to 565 format + f[0] = (fc >> 16); + f[1] = (fc >> 8) & 0xFF; + f[2] = (fc & 0xFF); + b[0] = (bc >> 16); + b[1] = (bc >> 8) & 0xFF; + b[2] = (bc & 0xFF); + +#endif + //printf("draw_bitmap_spi-> XStart %d, y1 %d, XEnd %d, YEnd %d\n",XStart,y1,XEnd,YEnd); + define_region_spi(XStart, y1, XEnd, YEnd, 1); + + n = 0; + for (i = 0; i < height; i++) { // step thru the font scan line by line + for (j = 0; j < scale; j++) { // repeat lines to scale the font + if (vertCoord++ < 0) continue; // we are above the top of the screen + if (vertCoord > vres) { // we have extended beyond the bottom of the screen + lcd_spi_raise_cs(); //set CS high + return; + } + horizCoord = x1; + for (k = 0; k < width; k++) { // step through each bit in a scan line + for (m = 0; m < scale; m++) { // repeat pixels to scale in the x axis + if (horizCoord++ < 0) continue; // we have not reached the left margin + if (horizCoord > hres) continue; // we are beyond the right margin + if ((bitmap[((i * width) + k) / 8] >> (((height * width) - ((i * width) + k) - 1) % 8)) & 1) { + hw_send_spi((uint8_t *) &f, 3); + } else { + if (bc == -1) { + c.rgbbytes[0] = p[n]; + c.rgbbytes[1] = p[n + 1]; + c.rgbbytes[2] = p[n + 2]; +#ifdef ILI9488 + b[0] = c.rgbbytes[2]; + b[1] = c.rgbbytes[1]; + b[2] = c.rgbbytes[0]; +#endif + } + hw_send_spi((uint8_t *) &b, 3); + } + n += 3; + } + } + } + } + lcd_spi_raise_cs(); //set CS high + +} + +// Draw a filled rectangle +// this is the basic drawing promitive used by most drawing routines +// x1, y1, x2, y2 - the coordinates +// c - the colour +void draw_rect_spi(int x1, int y1, int x2, int y2, int c) { + // convert the colours to 565 format + unsigned char col[3]; + if (x1 == x2 && y1 == y2) { + if (x1 < 0) return; + if (x1 >= hres) return; + if (y1 < 0) return; + if (y1 >= vres) return; + define_region_spi(x1, y1, x2, y2, 1); +#ifdef ILI9488 + col[0] = (c >> 16); + col[1] = (c >> 8) & 0xFF; + col[2] = (c & 0xFF); +#endif + hw_send_spi(col, 3); + } else { + int i, t, y; + unsigned char *p; + // make sure the coordinates are kept within the display area + if (x2 <= x1) { + t = x1; + x1 = x2; + x2 = t; + } + if (y2 <= y1) { + t = y1; + y1 = y2; + y2 = t; + } + if (x1 < 0) x1 = 0; + if (x1 >= hres) x1 = hres - 1; + if (x2 < 0) x2 = 0; + if (x2 >= hres) x2 = hres - 1; + if (y1 < 0) y1 = 0; + if (y1 >= vres) y1 = vres - 1; + if (y2 < 0) y2 = 0; + if (y2 >= vres) y2 = vres - 1; + define_region_spi(x1, y1, x2, y2, 1); +#ifdef ILI9488 + i = x2 - x1 + 1; + i *= 3; + p = lcd_buffer; + col[0] = (c >> 16); + col[1] = (c >> 8) & 0xFF; + col[2] = (c & 0xFF); + for (t = 0; t < i; t += 3) { + p[t] = col[0]; + p[t + 1] = col[1]; + p[t + 2] = col[2]; + } + for (y = y1; y <= y2; y++) { + spi_write_fast(Pico_LCD_SPI_MOD, p, i); + } +#endif + } + spi_finish(Pico_LCD_SPI_MOD); + lcd_spi_raise_cs(); +} + +/****************************************************************************************** + Print a char on the LCD display + Any characters not in the font will print as a space. + The char is printed at the current location defined by current_x and current_y +*****************************************************************************************/ +void lcd_print_char( int fc, int bc, char c, int orientation) { + unsigned char *p, *fp, *np = NULL; + int modx, mody, scale = 0x01; + int height, width; + + // to get the +, - and = chars for font 6 we fudge them by scaling up font 1 + fp = (unsigned char *) MainFont; + + height = fp[1]; + width = fp[0]; + modx = mody = 0; + //printf("fp %d, c %d ,height %d width %d\n",fp,c, height,width); + + if (c >= fp[2] && c < fp[2] + fp[3]) { + p = fp + 4 + (int) (((c - fp[2]) * height * width) / 8); + //printf("p = %d\n",p); + np = p; + + draw_bitmap_spi(current_x + modx, current_y + mody, width, height, scale, fc, bc, np); + } else { + draw_rect_spi(current_x + modx, current_y + mody, current_x + modx + (width * scale), + current_y + mody + (height * scale), bc); + } + + if (orientation == ORIENT_NORMAL) current_x += width * scale; + +} + +unsigned char scrollbuff[LCD_WIDTH * 3]; + +void scroll_lcd_spi(int lines) { + if (lines == 0)return; + if (lines >= 0) { + for (int i = 0; i < vres - lines; i++) { + read_buffer_spi(0, i + lines, hres - 1, i + lines, scrollbuff); + draw_buffer_spi(0, i, hres - 1, i, scrollbuff); + } + draw_rect_spi(0, vres - lines, hres - 1, vres - 1, gui_bcolour); // erase the lines to be scrolled off + } else { + lines = -lines; + for (int i = vres - 1; i >= lines; i--) { + read_buffer_spi(0, i - lines, hres - 1, i - lines, scrollbuff); + draw_buffer_spi(0, i, hres - 1, i, scrollbuff); + } + draw_rect_spi(0, 0, hres - 1, lines - 1, gui_bcolour); // erase the lines introduced at the top + } + +} + +void display_put_c(char c) { + // if it is printable and it is going to take us off the right hand end of the screen do a CRLF + if (c >= MainFont[2] && c < MainFont[2] + MainFont[3]) { + if (current_x + gui_font_width > hres) { + display_put_c('\r'); + display_put_c('\n'); + } + } + + // handle the standard control chars + switch (c) { + case '\b': + current_x -= gui_font_width; + //if (current_x < 0) current_x = 0; + if (current_x < 0) { //Go to end of previous line + current_y -= gui_font_height; //Go up one line + if (current_y < 0) current_y = 0; + current_x = (s_width - 1) * gui_font_width; //go to last character + } + return; + case '\r': + current_x = 0; + return; + case '\n': + current_x = 0; + current_y += gui_font_height; + if (current_y + gui_font_height >= vres) { + scroll_lcd_spi(current_y + gui_font_height - vres); + current_y -= (current_y + gui_font_height - vres); + } + return; + case '\t': + do { + display_put_c(' '); + } while ((current_x / gui_font_width) % 2);// 2 3 4 8 + return; + } + lcd_print_char(gui_fcolour, gui_bcolour, c, ORIENT_NORMAL);// print it +} + +/*** + * +****//// +char lcd_put_char(char c, int flush) { + lcd_putc(0, c); + if (isprint(c)) lcd_char_pos++; + if (c == '\r') { + lcd_char_pos = 1; + } + return c; +} + +void lcd_print_string(char *s) { + while (*s) { + if (s[1])lcd_put_char(*s, 0); + else lcd_put_char(*s, 1); + s++; + } + fflush(stdout); +} + +///////=----------------------------------------===////// +void lcd_clear() { + draw_rect_spi(0, 0, hres - 1, vres - 1, BLACK); +} + +void lcd_putc(uint8_t devn, uint8_t c) { + display_put_c(c); +} + +int lcd_getc(uint8_t devn) { + //i2c keyboard + int c = read_i2c_kbd(); + return c; +} + +unsigned char __not_in_flash_func(hw1_swap_spi)(unsigned char data_out) { + unsigned char data_in = 0; + spi_write_read_blocking(spi1, &data_out, &data_in, 1); + return data_in; +} + +void hw_read_spi(unsigned char *buff, int cnt) { + spi_read_blocking(Pico_LCD_SPI_MOD, 0xff, buff, cnt); +} + +void hw_send_spi(const unsigned char *buff, int cnt) { + + spi_write_blocking(Pico_LCD_SPI_MOD, buff, cnt); + +} + +void pin_set_bit(int pin, unsigned int offset) { + switch (offset) { + case LATCLR: + gpio_set_pulls(pin, false, false); + gpio_pull_down(pin); + gpio_put(pin, 0); + return; + case LATSET: + gpio_set_pulls(pin, false, false); + gpio_pull_up(pin); + gpio_put(pin, 1); + return; + case LATINV: + gpio_xor_mask(1 << pin); + return; + case TRISSET: + gpio_set_dir(pin, GPIO_IN); + sleep_us(2); + return; + case TRISCLR: + gpio_set_dir(pin, GPIO_OUT); + gpio_set_drive_strength(pin, GPIO_DRIVE_STRENGTH_12MA); + sleep_us(2); + return; + case CNPUSET: + gpio_set_pulls(pin, true, false); + return; + case CNPDSET: + gpio_set_pulls(pin, false, true); + return; + case CNPUCLR: + case CNPDCLR: + gpio_set_pulls(pin, false, false); + return; + case ODCCLR: + gpio_set_dir(pin, GPIO_OUT); + gpio_put(pin, 0); + sleep_us(2); + return; + case ODCSET: + gpio_set_pulls(pin, true, false); + gpio_set_dir(pin, GPIO_IN); + sleep_us(2); + return; + case ANSELCLR: + gpio_set_function(pin, GPIO_FUNC_SIO); + gpio_set_dir(pin, GPIO_IN); + return; + default: + break; + //printf("Unknown pin_set_bit command"); + } +} + +//important for read lcd memory +void reset_controller(void) { + pin_set_bit(Pico_LCD_RST, LATSET); + sleep_us(10000); + pin_set_bit(Pico_LCD_RST, LATCLR); + sleep_us(10000); + pin_set_bit(Pico_LCD_RST, LATSET); + sleep_us(200000); +} + + +void pico_lcd_init() { +#ifdef ILI9488 + reset_controller(); + + hres = 320; + vres = 320; + + spi_write_command(0xE0); // Positive Gamma Control + spi_write_data(0x00); + spi_write_data(0x03); + spi_write_data(0x09); + spi_write_data(0x08); + spi_write_data(0x16); + spi_write_data(0x0A); + spi_write_data(0x3F); + spi_write_data(0x78); + spi_write_data(0x4C); + spi_write_data(0x09); + spi_write_data(0x0A); + spi_write_data(0x08); + spi_write_data(0x16); + spi_write_data(0x1A); + spi_write_data(0x0F); + + spi_write_command(0XE1); // Negative Gamma Control + spi_write_data(0x00); + spi_write_data(0x16); + spi_write_data(0x19); + spi_write_data(0x03); + spi_write_data(0x0F); + spi_write_data(0x05); + spi_write_data(0x32); + spi_write_data(0x45); + spi_write_data(0x46); + spi_write_data(0x04); + spi_write_data(0x0E); + spi_write_data(0x0D); + spi_write_data(0x35); + spi_write_data(0x37); + spi_write_data(0x0F); + + spi_write_command(0XC0); // Power Control 1 + spi_write_data(0x17); + spi_write_data(0x15); + + spi_write_command(0xC1); // Power Control 2 + spi_write_data(0x41); + + spi_write_command(0xC5); // VCOM Control + spi_write_data(0x00); + spi_write_data(0x12); + spi_write_data(0x80); + + spi_write_command(TFT_MADCTL); // Memory Access Control + spi_write_data(0x48); // MX, BGR + + spi_write_command(0x3A); // Pixel Interface Format + spi_write_data(0x66); // 18 bit colour for SPI + + spi_write_command(0xB0); // Interface Mode Control + spi_write_data(0x00); + + spi_write_command(0xB1); // Frame Rate Control + spi_write_data(0xA0); + + spi_write_command(TFT_INVON); + + spi_write_command(0xB4); // Display Inversion Control + spi_write_data(0x02); + + spi_write_command(0xB6); // Display Function Control + spi_write_data(0x02); + spi_write_data(0x02); + spi_write_data(0x3B); + + spi_write_command(0xB7); // Entry Mode Set + spi_write_data(0xC6); + spi_write_command(0xE9); + spi_write_data(0x00); + + spi_write_command(0xF7); // Adjust Control 3 + spi_write_data(0xA9); + spi_write_data(0x51); + spi_write_data(0x2C); + spi_write_data(0x82); + + spi_write_command(TFT_SLPOUT); //Exit Sleep + sleep_ms(120); + + spi_write_command(TFT_DISPON); //Display on + sleep_ms(120); + + spi_write_command(TFT_MADCTL); + spi_write_cd(ILI9341_MEMCONTROL, 1, ILI9341_Portrait); +#endif +} + +void lcd_spi_raise_cs(void) { + gpio_put(Pico_LCD_CS, 1); +} + +void lcd_spi_lower_cs(void) { + + gpio_put(Pico_LCD_CS, 0); + +} + +void spi_write_data(unsigned char data) { + gpio_put(Pico_LCD_DC, 1); + lcd_spi_lower_cs(); + hw_send_spi(&data, 1); + lcd_spi_raise_cs(); +} + +void spi_write_data24(uint32_t data) { + uint8_t data_array[3]; + data_array[0] = data >> 16; + data_array[1] = (data >> 8) & 0xFF; + data_array[2] = data & 0xFF; + + + gpio_put(Pico_LCD_DC, 1); // Data mode + gpio_put(Pico_LCD_CS, 0); + spi_write_blocking(Pico_LCD_SPI_MOD, data_array, 3); + gpio_put(Pico_LCD_CS, 1); +} + +void spi_write_command(unsigned char data) { + gpio_put(Pico_LCD_DC, 0); + gpio_put(Pico_LCD_CS, 0); + + spi_write_blocking(Pico_LCD_SPI_MOD, &data, 1); + + gpio_put(Pico_LCD_CS, 1); +} + +void spi_write_cd(unsigned char command, int data, ...) { + int i; + va_list ap; + va_start(ap, data); + spi_write_command(command); + for (i = 0; i < data; i++) spi_write_data((char) va_arg(ap, int)); + va_end(ap); +} + +void lcd_spi_init() { + // init GPIO + gpio_init(Pico_LCD_SCK); + gpio_init(Pico_LCD_TX); + gpio_init(Pico_LCD_RX); + gpio_init(Pico_LCD_CS); + gpio_init(Pico_LCD_DC); + gpio_init(Pico_LCD_RST); + + gpio_set_dir(Pico_LCD_SCK, GPIO_OUT); + gpio_set_dir(Pico_LCD_TX, GPIO_OUT); + //gpio_set_dir(Pico_LCD_RX, GPIO_IN); + gpio_set_dir(Pico_LCD_CS, GPIO_OUT); + gpio_set_dir(Pico_LCD_DC, GPIO_OUT); + gpio_set_dir(Pico_LCD_RST, GPIO_OUT); + + // init SPI + spi_init(Pico_LCD_SPI_MOD, LCD_SPI_SPEED); + gpio_set_function(Pico_LCD_SCK, GPIO_FUNC_SPI); + gpio_set_function(Pico_LCD_TX, GPIO_FUNC_SPI); + gpio_set_function(Pico_LCD_RX, GPIO_FUNC_SPI); + gpio_set_input_hysteresis_enabled(Pico_LCD_RX, true); + + gpio_put(Pico_LCD_CS, 1); + gpio_put(Pico_LCD_RST, 1); +} + + +void lcd_init() { + lcd_spi_init(); + pico_lcd_init(); + + set_font(); + gui_fcolour = GREEN; + gui_bcolour = BLACK; + +} diff --git a/Code/picocalc_helloworld/lcdspi/lcdspi.h b/Code/picocalc_helloworld/lcdspi/lcdspi.h new file mode 100644 index 0000000..7167835 --- /dev/null +++ b/Code/picocalc_helloworld/lcdspi/lcdspi.h @@ -0,0 +1,131 @@ +#ifndef LCDSPI_H +#define LCDSPI_H +#include "pico/multicore.h" +#include + +//#define LCD_SPI_SPEED 6000000 +#define LCD_SPI_SPEED 25000000 +//#define LCD_SPI_SPEED 50000000 + +#define Pico_LCD_SCK 10 // +#define Pico_LCD_TX 11 // MOSI +#define Pico_LCD_RX 12 // MISO +#define Pico_LCD_CS 13 // +#define Pico_LCD_DC 14 +#define Pico_LCD_RST 15 + +#define ILI9488 1 +#ifdef ILI9488 +#define LCD_WIDTH 320 +#define LCD_HEIGHT 320 +#endif + +#define PIXFMT_BGR 1 + +#define TFT_SLPOUT 0x11 +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_DISPOFF 0x28 +#define TFT_DISPON 0x29 +#define TFT_MADCTL 0x36 + +#define ILI9341_MEMCONTROL 0x36 +#define ILI9341_MADCTL_MX 0x40 +#define ILI9341_MADCTL_BGR 0x08 + +#define ILI9341_COLADDRSET 0x2A +#define ILI9341_PAGEADDRSET 0x2B +#define ILI9341_MEMORYWRITE 0x2C +#define ILI9341_RAMRD 0x2E + +#define ILI9341_Portrait ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR + +#define ORIENT_NORMAL 0 + +#define RGB(red, green, blue) (unsigned int) (((red & 0b11111111) << 16) | ((green & 0b11111111) << 8) | (blue & 0b11111111)) +#define WHITE RGB(255, 255, 255) //0b1111 +#define YELLOW RGB(255, 255, 0) //0b1110 +#define LILAC RGB(255, 128, 255) //0b1101 +#define BROWN RGB(255, 128, 0) //0b1100 +#define FUCHSIA RGB(255, 64, 255) //0b1011 +#define RUST RGB(255, 64, 0) //0b1010 +#define MAGENTA RGB(255, 0, 255) //0b1001 +#define RED RGB(255, 0, 0) //0b1000 +#define CYAN RGB(0, 255, 255) //0b0111 +#define GREEN RGB(0, 255, 0) //0b0110 +#define CERULEAN RGB(0, 128, 255) //0b0101 +#define MIDGREEN RGB(0, 128, 0) //0b0100 +#define COBALT RGB(0, 64, 255) //0b0011 +#define MYRTLE RGB(0, 64, 0) //0b0010 +#define BLUE RGB(0, 0, 255) //0b0001 +#define BLACK RGB(0, 0, 0) //0b0000 +#define BROWN RGB(255, 128, 0) +#define GRAY RGB(128, 128, 128) +#define LITEGRAY RGB(210, 210, 210) +#define ORANGE RGB(0xff, 0xA5, 0) +#define PINK RGB(0xFF, 0xA0, 0xAB) +#define GOLD RGB(0xFF, 0xD7, 0x00) +#define SALMON RGB(0xFA, 0x80, 0x72) +#define BEIGE RGB(0xF5, 0xF5, 0xDC) + +//Pico spi0 or spi1 must match GPIO pins used above. +#define Pico_LCD_SPI_MOD spi1 +#define nop asm("NOP") +//xmit_byte_multi == HW1SendSPI + + +#define PORTCLR 1 +#define PORTSET 2 +#define PORTINV 3 +#define LAT 4 +#define LATCLR 5 +#define LATSET 6 +#define LATINV 7 +#define ODC 8 +#define ODCCLR 9 +#define ODCSET 10 +#define CNPU 12 +#define CNPUCLR 13 +#define CNPUSET 14 +#define CNPUINV 15 +#define CNPD 16 +#define CNPDCLR 17 +#define CNPDSET 18 + +#define ANSELCLR -7 +#define ANSELSET -6 +#define ANSELINV -5 +#define TRIS -4 +#define TRISCLR -3 +#define TRISSET -2 + +extern void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len); +extern void __not_in_flash_func(spi_finish)(spi_inst_t *spi); +extern void hw_read_spi(unsigned char *buff, int cnt); +extern void hw_send_spi(const unsigned char *buff, int cnt); +extern unsigned char __not_in_flash_func(hw1_swap_spi)(unsigned char data_out); + +extern void lcd_spi_raise_cs(void); +extern void lcd_spi_lower_cs(void); +extern void spi_write_data(unsigned char data); +extern void spi_write_command(unsigned char data); +extern void spi_write_cd(unsigned char command, int data, ...); +extern void spi_write_data24(uint32_t data); + +extern void spi_draw_pixel(uint16_t x, uint16_t y, uint16_t color) ; +extern void lcd_putc(uint8_t devn, uint8_t c); +extern int lcd_getc(uint8_t devn); +extern void lcd_sleeping(uint8_t devn); + +extern char lcd_put_char(char c, int flush); +extern void lcd_print_string(char* s); + +extern void lcd_spi_init(); +extern void lcd_init(); +extern void lcd_clear(); +extern void reset_controller(void); +extern void pin_set_bit(int pin, unsigned int offset); + + +#endif diff --git a/Code/picocalc_helloworld/main.c b/Code/picocalc_helloworld/main.c new file mode 100644 index 0000000..4a49a45 --- /dev/null +++ b/Code/picocalc_helloworld/main.c @@ -0,0 +1,38 @@ +/** + * PicoCalc Hello World + * https://www.clockworkpi.com/ + */ +#include +#include +#include "pico/stdlib.h" +#include "hardware/gpio.h" + +#include "i2ckbd.h" +#include "lcdspi.h" + +const uint LEDPIN = 25; + +int main() { + + stdio_init_all(); + + init_i2c_kbd(); + lcd_init(); + + gpio_init(LEDPIN); + gpio_set_dir(LEDPIN, GPIO_OUT); + + lcd_clear(); + lcd_print_string("Hello World"); + gpio_put(LEDPIN, 1); + sleep_ms(500); + gpio_put(LEDPIN, 0); + while (1) { + int c = lcd_getc(0); + if(c != -1 && c > 0) { + lcd_putc(0,c); + } + sleep_ms(10); + } +} + diff --git a/Code/picocalc_helloworld/pico_sdk_import.cmake b/Code/picocalc_helloworld/pico_sdk_import.cmake new file mode 100644 index 0000000..65f8a6f --- /dev/null +++ b/Code/picocalc_helloworld/pico_sdk_import.cmake @@ -0,0 +1,73 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + GIT_SUBMODULES_RECURSE FALSE + ) + else () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + endif () + + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE})