Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stefan Haun
firmware
Commits
c20bdbac
Commit
c20bdbac
authored
Aug 31, 2019
by
danb
Committed by
Rahix
Aug 31, 2019
Browse files
feat(ws2812): Add WS2812 module (aka Neopixel)
parent
668dfffb
Changes
9
Hide whitespace changes
Inline
Side-by-side
epicardium/epicardium.h
View file @
c20bdbac
...
...
@@ -138,6 +138,8 @@ typedef _Bool bool;
#define API_USB_STORAGE 0x111
#define API_USB_CDCACM 0x112
#define API_WS2812_WRITE 0x0120
/* clang-format on */
typedef
uint32_t
api_int_id_t
;
...
...
@@ -1843,4 +1845,20 @@ API(API_USB_STORAGE, int epic_usb_storage(void));
*/
API
(
API_USB_CDCACM
,
int
epic_usb_cdcacm
(
void
));
/**
* WS2812
* ======
*/
/**
* Takes a gpio pin specified with the gpio module and transmits
* the led data. The format `GG:RR:BB` is expected.
*
* :param uint8_t pin: The gpio pin to be used for data.
* :param uint8_t * pixels: The buffer, in which the pixel data is stored.
* :param uint32_t n_bytes: The size of the buffer.
*/
API
(
API_WS2812_WRITE
,
void
epic_ws2812_write
(
uint8_t
pin
,
uint8_t
*
pixels
,
uint32_t
n_bytes
));
#endif
/* _EPICARDIUM_H */
epicardium/modules/gpio.c
View file @
c20bdbac
...
...
@@ -11,7 +11,7 @@
* Despite what the schematic (currently, 2019-08-18) says these are the correct
* pins for wristband GPIO 1-4 (not 0-3 as the schematic states)
*/
static
gpio_cfg_t
gpio_configs
[]
=
{
gpio_cfg_t
gpio_configs
[]
=
{
[
EPIC_GPIO_WRISTBAND_1
]
=
{
PORT_0
,
PIN_21
,
GPIO_FUNC_OUT
,
...
...
epicardium/modules/meson.build
View file @
c20bdbac
...
...
@@ -23,4 +23,5 @@ module_sources = files(
'watchdog.c'
,
'usb.c'
,
'config.c'
,
'ws2812.c'
)
epicardium/modules/modules.h
View file @
c20bdbac
...
...
@@ -3,6 +3,7 @@
#include
"FreeRTOS.h"
#include
"semphr.h"
#include
"gpio.h"
#include
<stdint.h>
#include
<stdbool.h>
...
...
@@ -106,4 +107,8 @@ void vBhi160Task(void *pvParameters);
void
vMAX30001Task
(
void
*
pvParameters
);
void
max30001_mutex_init
(
void
);
/* ---------- GPIO --------------------------------------------------------- */
#define MAX30001_MUTEX_WAIT_MS 50
extern
gpio_cfg_t
gpio_configs
[];
#endif
/* MODULES_H */
epicardium/modules/ws2812.c
0 → 100644
View file @
c20bdbac
#include
"leds.h"
#include
"pmic.h"
#include
"FreeRTOS.h"
#include
"task.h"
#include
"epicardium.h"
#include
"max32665.h"
#include
"gpio.h"
#include
"modules.h"
#include
<stdbool.h>
#define OVERHEAD 33
#define EPIC_WS2812_ZERO_HIGH_TICKS 34 - OVERHEAD
#define EPIC_WS2812_ZERO_LOW_TICKS 86 - OVERHEAD
#define EPIC_WS2812_ONE_HIGH_TICKS 86 - OVERHEAD
#define EPIC_WS2812_ONE_LOW_TICKS 34 - OVERHEAD
#define EPIC_WS2812_RESET_TCKS 4800 - OVERHEAD
static
volatile
uint32_t
counter
=
0
;
static
inline
__attribute__
((
always_inline
))
void
epic_ws2812_delay_ticks
(
uint32_t
ticks
)
{
counter
=
ticks
;
while
(
--
counter
)
{
};
}
static
inline
__attribute__
((
always_inline
))
void
epic_ws2812_transmit_bit
(
uint32_t
pin
,
uint8_t
bit
)
{
if
(
bit
!=
0
)
{
GPIO_OutSet
(
pin
);
epic_ws2812_delay_ticks
(
EPIC_WS2812_ONE_HIGH_TICKS
);
GPIO_OutClr
(
pin
);
epic_ws2812_delay_ticks
(
EPIC_WS2812_ONE_LOW_TICKS
);
}
else
{
GPIO_OutSet
(
pin
);
epic_ws2812_delay_ticks
(
EPIC_WS2812_ZERO_HIGH_TICKS
);
GPIO_OutClr
(
pin
);
epic_ws2812_delay_ticks
(
EPIC_WS2812_ZERO_LOW_TICKS
);
}
}
static
inline
__attribute__
((
always_inline
))
void
epic_ws2812_transmit_byte
(
uint32_t
pin
,
uint8_t
byte
)
{
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b10000000
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b01000000
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00100000
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00010000
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00001000
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00000100
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00000010
);
epic_ws2812_transmit_bit
(
pin
,
byte
&
0
b00000001
);
}
void
epic_ws2812_write
(
uint8_t
pin
,
uint8_t
*
pixels
,
uint32_t
n_bytes
)
{
uint8_t
*
pixels_end
=
pixels
+
n_bytes
;
gpio_cfg_t
*
pin_cfg
=
&
gpio_configs
[
pin
];
taskENTER_CRITICAL
();
epic_gpio_set_pin_mode
(
pin
,
EPIC_GPIO_MODE_OUT
);
do
{
epic_ws2812_transmit_byte
(
pin_cfg
,
*
pixels
);
}
while
(
++
pixels
!=
pixels_end
);
GPIO_OutClr
(
pin
);
epic_ws2812_delay_ticks
(
EPIC_WS2812_RESET_TCKS
);
taskEXIT_CRITICAL
();
}
pycardium/meson.build
View file @
c20bdbac
...
...
@@ -16,7 +16,8 @@ modsrc = files(
'modules/sys_display.c'
,
'modules/utime.c'
,
'modules/vibra.c'
,
'modules/bme680.c'
'modules/bme680.c'
,
'modules/ws2812.c'
)
#################################
...
...
pycardium/modules/qstrdefs.h
View file @
c20bdbac
...
...
@@ -170,3 +170,7 @@ Q(COMMUNICATION)
Q
(
CAMP
)
Q
(
MAX30001_ECG
)
/* ws2812 */
Q
(
ws2812
)
Q
(
set_all
)
pycardium/modules/ws2812.c
0 → 100644
View file @
c20bdbac
#include
"epicardium.h"
#include
"py/obj.h"
#include
<stdlib.h>
#include
<stdio.h>
/* Define the pixel set_all function in this module */
static
mp_obj_t
mp_ws2812_set_all
(
mp_obj_t
pin
,
mp_obj_t
color_in
)
{
mp_int_t
pin_int
=
mp_obj_get_int
(
pin
);
mp_int_t
len
=
mp_obj_get_int
(
mp_obj_len
(
color_in
));
mp_int_t
pixels_len
=
len
*
3
;
uint8_t
*
pixels_arr
=
alloca
(
pixels_len
*
sizeof
(
uint8_t
));
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
mp_obj_t
color
=
mp_obj_subscr
(
color_in
,
mp_obj_new_int
(
i
),
MP_OBJ_SENTINEL
);
pixels_arr
[
i
*
3
]
=
mp_obj_get_int
(
mp_obj_subscr
(
color
,
mp_obj_new_int
(
1
),
MP_OBJ_SENTINEL
)
);
pixels_arr
[
i
*
3
+
1
]
=
mp_obj_get_int
(
mp_obj_subscr
(
color
,
mp_obj_new_int
(
0
),
MP_OBJ_SENTINEL
)
);
pixels_arr
[
i
*
3
+
2
]
=
mp_obj_get_int
(
mp_obj_subscr
(
color
,
mp_obj_new_int
(
2
),
MP_OBJ_SENTINEL
)
);
}
/* call epicardium to be fast enough */
epic_ws2812_write
(
pin_int
,
pixels_arr
,
pixels_len
);
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_2
(
ws2812_set_all_obj
,
mp_ws2812_set_all
);
/* The globals table for this module */
static
const
mp_rom_map_elem_t
ws2812_module_globals_table
[]
=
{
{
MP_ROM_QSTR
(
MP_QSTR___name__
),
MP_ROM_QSTR
(
MP_QSTR_ws2812
)
},
{
MP_ROM_QSTR
(
MP_QSTR_set_all
),
MP_ROM_PTR
(
&
ws2812_set_all_obj
)
},
};
static
MP_DEFINE_CONST_DICT
(
ws2812_module_globals
,
ws2812_module_globals_table
);
const
mp_obj_module_t
ws2812_module
=
{
.
base
=
{
&
mp_type_module
},
.
globals
=
(
mp_obj_dict_t
*
)
&
ws2812_module_globals
,
};
/* This is a special macro that will make MicroPython aware of this module */
/* clang-format off */
MP_REGISTER_MODULE
(
MP_QSTR_ws2812
,
ws2812_module
,
MODULE_WS2812_ENABLED
);
pycardium/mpconfigport.h
View file @
c20bdbac
...
...
@@ -60,6 +60,7 @@ int mp_hal_trng_read_int(void);
#define MODULE_POWER_ENABLED (1)
#define MODULE_UTIME_ENABLED (1)
#define MODULE_VIBRA_ENABLED (1)
#define MODULE_WS2812_ENABLED (1)
/*
* This port is intended to be 32-bit, but unfortunately, int32_t for
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment