mirror of
https://github.com/nodemcu/nodemcu-firmware.git
synced 2025-01-30 21:12:55 +08:00
526d21dab4
The PR removed the bulk of non-newlib headers from the NodeMCU source base. app/libc has now been cut down to the bare minimum overrides to shadow the corresponding functions in the SDK's libc. The old c_xyz.h headerfiles have been nuked in favour of the standard <xyz.h> headers, with a few exceptions over in sdk-overrides. Again, shipping a libc.a without headers is a terrible thing to do. We're still living on a prayer that libc was configured the same was as a default-configured xtensa gcc toolchain assumes it is. That part I cannot do anything about, unfortunately, but it's no worse than it has been before. This enables our source files to compile successfully using the standard header files, and use the typical malloc()/calloc()/realloc()/free(), the strwhatever()s and memwhatever()s. These end up, through macro and linker magic, mapped to the appropriate SDK or ROM functions.
114 lines
2.9 KiB
C
114 lines
2.9 KiB
C
#include "module.h"
|
|
#include "lauxlib.h"
|
|
#include "platform.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "user_interface.h"
|
|
|
|
static inline uint32_t _getCycleCount(void) {
|
|
uint32_t cycles;
|
|
__asm__ __volatile__("rsr %0,ccount":"=a" (cycles));
|
|
return cycles;
|
|
}
|
|
|
|
// This algorithm reads the cpu clock cycles to calculate the correct
|
|
// pulse widths. It works in both 80 and 160 MHz mode.
|
|
static void ICACHE_RAM_ATTR tm1829_write_to_pin(uint8_t pin, uint8_t *pixels, uint32_t length) {
|
|
uint8_t *p, *end;
|
|
|
|
p = pixels;
|
|
end = p + length;
|
|
|
|
const uint32_t t0l = (1000 * system_get_cpu_freq()) / 3333; // 0.390us (spec=0.35 +- 0.15)
|
|
const uint32_t t1l = (1000 * system_get_cpu_freq()) / 1250; // 0.800us (spec=0.70 +- 0.15)
|
|
|
|
const uint32_t ttot = (1000 * system_get_cpu_freq()) / 800; // 1.25us
|
|
|
|
while (p != end) {
|
|
register int i;
|
|
|
|
register uint8_t pixel = *p++;
|
|
|
|
ets_intr_lock();
|
|
|
|
for (i = 7; i >= 0; i--) {
|
|
register uint32_t pin_mask = 1 << pin;
|
|
|
|
// Select low time
|
|
register uint32_t tl = ((pixel >> i) & 1) ? t1l : t0l;
|
|
register uint32_t t1, t2;
|
|
|
|
register uint32_t t = _getCycleCount();
|
|
|
|
t1 = t + tl;
|
|
t2 = t + ttot;
|
|
|
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin_mask); // Set pin low
|
|
while (_getCycleCount() < t1);
|
|
|
|
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin_mask); // Set pin high
|
|
while (_getCycleCount() < t2);
|
|
}
|
|
|
|
ets_intr_unlock();
|
|
}
|
|
}
|
|
|
|
// Lua: tm1829.write(pin, "string")
|
|
// Byte triples in the string are interpreted as R G B values and sent to the hardware as G R B.
|
|
// WARNING: this function scrambles the input buffer :
|
|
// a = string.char(255,0,128)
|
|
// tm1829.write(3,a)
|
|
// =a.byte()
|
|
// (0,255,128)
|
|
static int ICACHE_FLASH_ATTR tm1829_write(lua_State* L)
|
|
{
|
|
const uint8_t pin = luaL_checkinteger(L, 1);
|
|
size_t length;
|
|
const char *rgb = luaL_checklstring(L, 2, &length);
|
|
|
|
// dont modify lua-internal lstring - make a copy instead
|
|
char *buffer = (char *)malloc(length);
|
|
|
|
// Ignore incomplete Byte triples at the end of buffer
|
|
length -= length % 3;
|
|
|
|
// Copy payload and make sure first byte is < 0xFF (triggers
|
|
// constant current command, instead of PWM duty command)
|
|
size_t i;
|
|
for (i = 0; i < length; i += 3) {
|
|
buffer[i] = rgb[i];
|
|
buffer[i + 1] = rgb[i + 1];
|
|
buffer[i + 2] = rgb[i + 2];
|
|
|
|
// Check for first byte
|
|
if (buffer[i] == 0xff)
|
|
buffer[i] = 0xfe;
|
|
}
|
|
|
|
// Initialize the output pin and wait a bit
|
|
platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
|
|
platform_gpio_write(pin, 1);
|
|
|
|
// Send the buffer
|
|
tm1829_write_to_pin(pin_num[pin], (uint8_t*) buffer, length);
|
|
|
|
os_delay_us(500); // reset time
|
|
|
|
free(buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
LROT_BEGIN(tm1829)
|
|
LROT_FUNCENTRY( write, tm1829_write )
|
|
LROT_END( tm1829, NULL, 0 )
|
|
|
|
|
|
int luaopen_tm1829(lua_State *L) {
|
|
// TODO: Make sure that the GPIO system is initialized
|
|
return 0;
|
|
}
|
|
|
|
NODEMCU_MODULE(TM1829, "tm1829", tm1829, luaopen_tm1829);
|