summaryrefslogtreecommitdiff
path: root/stmhal
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal')
-rw-r--r--stmhal/boards/STM32F4DISC/staccel.py56
-rw-r--r--stmhal/lcd.c77
-rw-r--r--stmhal/usb.c14
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 },