From 39c6c59868032973a5f661353df9b6dcae643c70 Mon Sep 17 00:00:00 2001 From: Damien Date: Sat, 9 Nov 2013 20:15:48 +0000 Subject: [PATCH] STM: add LCD functions for pixel access; add RNG Py bindings. --- stm/lcd.c | 110 ++++++++++++++++++++++++++++++++++++++++-------- stm/lcd.h | 1 - stm/main.c | 31 +++++++++----- stm/mpyconfig.h | 2 + 4 files changed, 114 insertions(+), 30 deletions(-) diff --git a/stm/lcd.c b/stm/lcd.c index ee4f4da4e0..28064c24bf 100644 --- a/stm/lcd.c +++ b/stm/lcd.c @@ -1,10 +1,16 @@ #include #include +#include "nlr.h" #include "misc.h" +#include "mpyconfig.h" +#include "parse.h" +#include "compile.h" +#include "runtime.h" + #include "systick.h" -#include "lcd.h" #include "font_petme128_8x8.h" +#include "lcd.h" #define PYB_LCD_PORT (GPIOA) #define PYB_LCD_CS1_PIN (GPIO_Pin_0) @@ -80,14 +86,83 @@ static void lcd_data_out(uint8_t i) { } */ +// writes 8 vertical pixels +// pos 0 is upper left, pos 1 is 8 pixels to right of that, pos 128 is 8 pixels below that +py_obj_t lcd_draw_pixel_8(py_obj_t py_pos, py_obj_t py_val) { + int pos = py_obj_get_int(py_pos); + int val = py_obj_get_int(py_val); + int page = pos / 128; + int offset = pos - (page * 128); + lcd_out(LCD_INSTR, 0xb0 | page); // page address set + lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper + lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower + lcd_out(LCD_DATA, val); // write data + return py_const_none; +} + #define LCD_BUF_W (16) #define LCD_BUF_H (4) -char lcd_buffer[LCD_BUF_W * LCD_BUF_H]; +char lcd_char_buffer[LCD_BUF_W * LCD_BUF_H]; int lcd_line; int lcd_column; int lcd_next_line; +#define LCD_PIX_BUF_SIZE (128 * 32 / 8) +byte lcd_pix_buf[LCD_PIX_BUF_SIZE]; +byte lcd_pix_buf2[LCD_PIX_BUF_SIZE]; + +py_obj_t lcd_pix_clear(void) { + memset(lcd_pix_buf, 0, LCD_PIX_BUF_SIZE); + memset(lcd_pix_buf2, 0, LCD_PIX_BUF_SIZE); + return py_const_none; +} + +py_obj_t lcd_pix_get(py_obj_t py_x, py_obj_t py_y) { + int x = py_obj_get_int(py_x); + int y = py_obj_get_int(py_y); + if (0 <= x && x <= 127 && 0 <= y && y <= 31) { + uint byte_pos = x + 128 * ((uint)y >> 3); + if (lcd_pix_buf[byte_pos] & (1 << (y & 7))) { + return py_obj_new_int(1); + } + } + return py_obj_new_int(0); +} + +py_obj_t lcd_pix_set(py_obj_t py_x, py_obj_t py_y) { + int x = py_obj_get_int(py_x); + int y = py_obj_get_int(py_y); + if (0 <= x && x <= 127 && 0 <= y && y <= 31) { + uint byte_pos = x + 128 * ((uint)y >> 3); + lcd_pix_buf2[byte_pos] |= 1 << (y & 7); + } + return py_const_none; +} + +py_obj_t lcd_pix_reset(py_obj_t py_x, py_obj_t py_y) { + int x = py_obj_get_int(py_x); + int y = py_obj_get_int(py_y); + if (0 <= x && x <= 127 && 0 <= y && y <= 31) { + uint byte_pos = x + 128 * ((uint)y >> 3); + lcd_pix_buf2[byte_pos] &= ~(1 << (y & 7)); + } + return py_const_none; +} + +py_obj_t lcd_pix_show(void) { + memcpy(lcd_pix_buf, lcd_pix_buf2, LCD_PIX_BUF_SIZE); + for (uint page = 0; page < 4; page++) { + lcd_out(LCD_INSTR, 0xb0 | page); // page address set + lcd_out(LCD_INSTR, 0x10); // column address set upper; 0 + lcd_out(LCD_INSTR, 0x00); // column address set lower; 0 + for (uint i = 0; i < 128; i++) { + lcd_out(LCD_DATA, lcd_pix_buf[i + 128 * page]); + } + } + return py_const_none; +} + void lcd_init(void) { // set the outputs high PYB_LCD_PORT->BSRRL = PYB_LCD_CS1_PIN; @@ -132,11 +207,21 @@ void lcd_init(void) { } for (int i = 0; i < LCD_BUF_H * LCD_BUF_W; i++) { - lcd_buffer[i] = ' '; + lcd_char_buffer[i] = ' '; } lcd_line = 0; lcd_column = 0; lcd_next_line = 0; + + // Python interface + py_obj_t m = py_module_new(); + rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_2(lcd_draw_pixel_8)); + rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_0(lcd_pix_clear)); + rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_2(lcd_pix_get)); + rt_store_attr(m, qstr_from_str_static("set"), rt_make_function_2(lcd_pix_set)); + rt_store_attr(m, qstr_from_str_static("reset"), rt_make_function_2(lcd_pix_reset)); + rt_store_attr(m, qstr_from_str_static("show"), rt_make_function_0(lcd_pix_show)); + rt_store_name(qstr_from_str_static("lcd"), m); } void lcd_print_str(const char *str) { @@ -155,10 +240,10 @@ void lcd_print_strn(const char *str, unsigned int len) { } else { lcd_line = LCD_BUF_H - 1; for (int i = 0; i < LCD_BUF_W * (LCD_BUF_H - 1); i++) { - lcd_buffer[i] = lcd_buffer[i + LCD_BUF_W]; + lcd_char_buffer[i] = lcd_char_buffer[i + LCD_BUF_W]; } for (int i = 0; i < LCD_BUF_W; i++) { - lcd_buffer[LCD_BUF_W * (LCD_BUF_H - 1) + i] = ' '; + lcd_char_buffer[LCD_BUF_W * (LCD_BUF_H - 1) + i] = ' '; } redraw_min = 0; redraw_max = LCD_BUF_W * LCD_BUF_H; @@ -174,7 +259,7 @@ void lcd_print_strn(const char *str, unsigned int len) { str -= 1; len += 1; } else { - lcd_buffer[lcd_line * LCD_BUF_W + lcd_column] = *str; + lcd_char_buffer[lcd_line * LCD_BUF_W + lcd_column] = *str; lcd_column += 1; int max = lcd_line * LCD_BUF_W + lcd_column; if (max > redraw_max) { @@ -193,7 +278,7 @@ void lcd_print_strn(const char *str, unsigned int len) { lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower last_page = page; } - int chr = lcd_buffer[i]; + int chr = lcd_char_buffer[i]; if (chr < 32 || chr > 126) { chr = 127; } @@ -207,14 +292,3 @@ void lcd_print_strn(const char *str, unsigned int len) { sys_tick_delay_ms(200); } } - -// writes 8 vertical pixels -// pos 0 is upper left, pos 1 is 8 pixels to right of that, pos 128 is 8 pixels below that -void lcd_draw_pixel_8(int pos, int val) { - int page = pos / 128; - int offset = pos - (page * 128); - lcd_out(LCD_INSTR, 0xb0 | page); // page address set - lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper - lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower - lcd_out(LCD_DATA, val); // write data -} diff --git a/stm/lcd.h b/stm/lcd.h index 56c541698e..7b243ee7e3 100644 --- a/stm/lcd.h +++ b/stm/lcd.h @@ -1,4 +1,3 @@ void lcd_init(void); void lcd_print_str(const char *str); void lcd_print_strn(const char *str, unsigned int len); -void lcd_draw_pixel_8(int pos, int val); diff --git a/stm/main.c b/stm/main.c index 4184b389ca..a1b8e668f0 100644 --- a/stm/main.c +++ b/stm/main.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "std.h" @@ -613,13 +614,6 @@ py_obj_t pyb_rtc_read(void) { return py_const_none; } -py_obj_t pyb_lcd8(py_obj_t pos, py_obj_t val) { - int pos_val = py_obj_get_int(pos); - int val_val = py_obj_get_int(val); - lcd_draw_pixel_8(pos_val, val_val); - return py_const_none; -} - void file_obj_print(py_obj_t o) { FIL *fp; py_user_get_data(o, (machine_uint_t*)&fp, NULL); @@ -695,6 +689,10 @@ py_obj_t pyb_io_open(py_obj_t o_filename, py_obj_t o_mode) { return py_obj_new_user(&file_obj_info, (machine_uint_t)fp, 0); } +py_obj_t pyb_rng_get(void) { + return py_obj_new_int(RNG_GetRandomNumber() >> 16); +} + int main(void) { // TODO disable JTAG @@ -736,9 +734,6 @@ int main(void) { soft_reset: - // LCD init - lcd_init(); - // GC init gc_init(&_heap_start, (void*)HEAP_END); @@ -746,6 +741,9 @@ soft_reset: qstr_init(); rt_init(); + // LCD init + lcd_init(); + // servo servo_init(); @@ -755,6 +753,12 @@ soft_reset: // timer timer_init(); + // RNG + { + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); + RNG_Cmd(ENABLE); + } + // add some functions to the python namespace { py_obj_t m = py_module_new(); @@ -774,7 +778,7 @@ soft_reset: rt_store_attr(m, qstr_from_str_static("uout"), rt_make_function_1(pyb_usart_send)); rt_store_attr(m, qstr_from_str_static("uin"), rt_make_function_0(pyb_usart_receive)); rt_store_attr(m, qstr_from_str_static("ustat"), rt_make_function_0(pyb_usart_status)); - rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_2(pyb_lcd8)); + rt_store_attr(m, qstr_from_str_static("rng"), rt_make_function_0(pyb_rng_get)); rt_store_name(qstr_from_str_static("pyb"), m); rt_store_name(qstr_from_str_static("open"), rt_make_function_2(pyb_io_open)); @@ -1148,3 +1152,8 @@ double sqrt(double x) { // TODO return 0.0; } + +machine_float_t machine_sqrt(machine_float_t x) { + // TODO + return x; +} diff --git a/stm/mpyconfig.h b/stm/mpyconfig.h index 06a4bd8e02..3fa3ac6524 100644 --- a/stm/mpyconfig.h +++ b/stm/mpyconfig.h @@ -14,3 +14,5 @@ typedef int32_t machine_int_t; // must be pointer size typedef uint32_t machine_uint_t; // must be pointer size typedef void *machine_ptr_t; // must be of pointer size typedef float machine_float_t; + +machine_float_t machine_sqrt(machine_float_t x);