diff options
Diffstat (limited to 'stmhal')
-rw-r--r-- | stmhal/boards/STM32F4DISC/staccel.py | 56 | ||||
-rw-r--r-- | stmhal/lcd.c | 77 | ||||
-rw-r--r-- | stmhal/usb.c | 14 |
3 files changed, 147 insertions, 0 deletions
diff --git a/stmhal/boards/STM32F4DISC/staccel.py b/stmhal/boards/STM32F4DISC/staccel.py new file mode 100644 index 000000000..af842ebcf --- /dev/null +++ b/stmhal/boards/STM32F4DISC/staccel.py @@ -0,0 +1,56 @@ +""" +Driver for accelerometer on STM32F4 Discover board. + +Assumes it's a LIS302DL MEMS device. + +Not currently working. + +See: + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.h + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.c + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.c + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.h + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.c + STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.h + STM32Cube_FW_F4_V1.1.0/Projects/STM32F4-Discovery/Demonstrations/Src/main.c +""" + +from pyb import Pin +from pyb import SPI + +READWRITE_CMD = const(0x80) +MULTIPLEBYTE_CMD = const(0x40) +LIS302DL_WHO_AM_I_ADDR = const(0x0f) +LIS302DL_CTRL_REG1_ADDR = const(0x20) + +class STAccel: + def __init__(self): + self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE) + self.cs_pin.high() + self.spi = SPI(1, SPI.MASTER, baudrate=328125, polarity=0, phase=1, bits=8) + + def rd(self, addr, nbytes): + if nbytes > 1: + addr |= READWRITE_CMD | MULTIPLEBYTE_CMD + else: + addr |= READWRITE_CMD + self.cs_pin.low() + self.spi.send(addr) + buf = self.spi.send_recv(bytearray(nbytes * [0])) # read data, MSB first + self.cs_pin.high() + return buf + + def wr(self, addr, buf): + if len(buf) > 1: + addr |= MULTIPLEBYTE_CMD + self.cs_pin.low() + self.spi.send(addr) + for b in buf: + self.spi.send(b) + self.cs_pin.high() + + def read_id(self): + return self.rd(LIS302DL_WHO_AM_I_ADDR, 1) + + def init(self, init_param): + self.wr(LIS302DL_CTRL_REG1_ADDR, bytearray([init_param])) diff --git a/stmhal/lcd.c b/stmhal/lcd.c index e75fb8f35..519268649 100644 --- a/stmhal/lcd.c +++ b/stmhal/lcd.c @@ -46,6 +46,42 @@ #include "font_petme128_8x8.h" #include "lcd.h" +/// \moduleref pyb +/// \class LCD - LCD control for the LCD touch-sensor pyskin +/// +/// The LCD class is used to control the LCD on the LCD touch-sensor pyskin, +/// LCD32MKv1.0. The LCD is a 128x32 pixel monochrome screen, part NHD-C12832A1Z. +/// +/// The pyskin must be connected in either the X or Y positions, and then +/// an LCD object is made using: +/// +/// lcd = pyb.LCD('X') # if pyskin is in the X position +/// lcd = pyb.LCD('Y') # if pyskin is in the Y position +/// +/// Then you can use: +/// +/// lcd.light(True) # turn the backlight on +/// lcd.write('Hello world!\n') # print text to the screen +/// +/// This driver implements a double buffer for setting/getting pixels. +/// For example, to make a bouncing dot, try: +/// +/// x = y = 0 +/// dx = dy = 1 +/// while True: +/// # update the dot's position +/// x += dx +/// y += dy +/// +/// # make the dot bounce of the edges of the screen +/// if x <= 0 or x >= 127: dx = -dx +/// if y <= 0 or y >= 31: dy = -dy +/// +/// lcd.fill(0) # clear the buffer +/// lcd.pixel(x, y, 1) # draw the dot +/// lcd.show() # show the buffer +/// pyb.delay(50) # pause for 50ms + #define LCD_INSTR (0) #define LCD_DATA (1) @@ -158,6 +194,10 @@ STATIC void lcd_write_strn(pyb_lcd_obj_t *lcd, const char *str, unsigned int len } } +/// \classmethod \constructor(skin_position) +/// +/// Construct an LCD object in the given skin position. `skin_position` can be 'X' or 'Y', and +/// should match the position where the LCD pyskin is plugged in. STATIC mp_obj_t pyb_lcd_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -288,6 +328,11 @@ STATIC mp_obj_t pyb_lcd_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const return lcd; } +/// \method command(instr_data, buf) +/// +/// Send an arbitrary command to the LCD. Pass 0 for `instr_data` to send an +/// instruction, otherwise pass 1 to send data. `buf` is a buffer with the +/// instructions/data to send. STATIC mp_obj_t pyb_lcd_command(mp_obj_t self_in, mp_obj_t instr_data_in, mp_obj_t val) { pyb_lcd_obj_t *self = self_in; @@ -308,6 +353,9 @@ STATIC mp_obj_t pyb_lcd_command(mp_obj_t self_in, mp_obj_t instr_data_in, mp_obj } STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_lcd_command_obj, pyb_lcd_command); +/// \method contrast(value) +/// +/// Set the contrast of the LCD. Valid values are between 0 and 47. STATIC mp_obj_t pyb_lcd_contrast(mp_obj_t self_in, mp_obj_t contrast_in) { pyb_lcd_obj_t *self = self_in; int contrast = mp_obj_get_int(contrast_in); @@ -322,6 +370,9 @@ STATIC mp_obj_t pyb_lcd_contrast(mp_obj_t self_in, mp_obj_t contrast_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_contrast_obj, pyb_lcd_contrast); +/// \method light(value) +/// +/// Turn the backlight on/off. True or 1 turns it on, False or 0 turns it off. STATIC mp_obj_t pyb_lcd_light(mp_obj_t self_in, mp_obj_t value) { pyb_lcd_obj_t *self = self_in; if (mp_obj_is_true(value)) { @@ -333,6 +384,9 @@ STATIC mp_obj_t pyb_lcd_light(mp_obj_t self_in, mp_obj_t value) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_light_obj, pyb_lcd_light); +/// \method write(str) +/// +/// Write the string `str` to the screen. It will appear immediately. STATIC mp_obj_t pyb_lcd_write(mp_obj_t self_in, mp_obj_t str) { pyb_lcd_obj_t *self = self_in; uint len; @@ -342,6 +396,11 @@ STATIC mp_obj_t pyb_lcd_write(mp_obj_t self_in, mp_obj_t str) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_write_obj, pyb_lcd_write); +/// \method fill(colour) +/// +/// Fill the screen with the given colour (0 or 1 for white or black). +/// +/// This method writes to the hidden buffer. Use `show()` to show the buffer. STATIC mp_obj_t pyb_lcd_fill(mp_obj_t self_in, mp_obj_t col_in) { pyb_lcd_obj_t *self = self_in; int col = mp_obj_get_int(col_in); @@ -354,6 +413,11 @@ STATIC mp_obj_t pyb_lcd_fill(mp_obj_t self_in, mp_obj_t col_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_fill_obj, pyb_lcd_fill); +/// \method get(x, y) +/// +/// Get the pixel at the position `(x, y)`. Returns 0 or 1. +/// +/// This method reads from the visible buffer. STATIC mp_obj_t pyb_lcd_get(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { pyb_lcd_obj_t *self = self_in; int x = mp_obj_get_int(x_in); @@ -368,6 +432,11 @@ STATIC mp_obj_t pyb_lcd_get(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_lcd_get_obj, pyb_lcd_get); +/// \method pixel(x, y, colour) +/// +/// Set the pixel at `(x, y)` to the given colour (0 or 1). +/// +/// This method writes to the hidden buffer. Use `show()` to show the buffer. STATIC mp_obj_t pyb_lcd_pixel(uint n_args, const mp_obj_t *args) { pyb_lcd_obj_t *self = args[0]; int x = mp_obj_get_int(args[1]); @@ -384,6 +453,11 @@ STATIC mp_obj_t pyb_lcd_pixel(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_lcd_pixel_obj, 4, 4, pyb_lcd_pixel); +/// \method text(str, x, y, colour) +/// +/// Draw the given text to the position `(x, y)` using the given colour (0 or 1). +/// +/// This method writes to the hidden buffer. Use `show()` to show the buffer. STATIC mp_obj_t pyb_lcd_text(uint n_args, const mp_obj_t *args) { // extract arguments pyb_lcd_obj_t *self = args[0]; @@ -428,6 +502,9 @@ STATIC mp_obj_t pyb_lcd_text(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_lcd_text_obj, 5, 5, pyb_lcd_text); +/// \method show() +/// +/// Show the hidden buffer on the screen. STATIC mp_obj_t pyb_lcd_show(mp_obj_t self_in) { pyb_lcd_obj_t *self = self_in; memcpy(self->pix_buf, self->pix_buf2, LCD_PIX_BUF_BYTE_SIZE); diff --git a/stmhal/usb.c b/stmhal/usb.c index a7c3add53..7db8ca218 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -137,6 +137,13 @@ void usb_hid_send_report(uint8_t *buf) { /******************************************************************************/ // Micro Python bindings for USB VCP +/// \moduleref pyb +/// \class USB_VCP - USB virtual comm port +/// +/// The USB_VCP class allows creation of an object representing the USB +/// virtual comm port. It can be used to read and write data over USB to +/// the connected host. + typedef struct _pyb_usb_vcp_obj_t { mp_obj_base_t base; } pyb_usb_vcp_obj_t; @@ -147,6 +154,8 @@ STATIC void pyb_usb_vcp_print(void (*print)(void *env, const char *fmt, ...), vo print(env, "USB_VCP()"); } +/// \classmethod \constructor() +/// Create a new USB_VCP object. STATIC mp_obj_t pyb_usb_vcp_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); @@ -245,10 +254,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_usb_vcp___exit___obj, 4, 4, pyb_u STATIC const mp_map_elem_t pyb_usb_vcp_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_usb_vcp_send_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_usb_vcp_recv_obj }, + /// \method read([nbytes]) { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, + /// \method readall() { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj }, + /// \method readline() { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj}, + /// \method write(buf) { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, + /// \method close() { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&mp_identity_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_identity_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___enter__), (mp_obj_t)&mp_identity_obj }, |