Left for archival purposes.

User avatar
By milikiller
#8276 Hi I making on code for software uart.

I am not good programmer in C, and my code is ugly. Basic Idea is bigbanged the Async serial data trough GPIO. Now I try only writing. Reading is not necesary for me now.

Is posible to bigbang serial data, and not stop ESP in many delay loops ? I using delay for bits timing, but if I send bigger block of data, procesor not calculate timers and PWMs

my code is look like this:
Code: Select all     platform_gpio_write(soft_uart_0_pin, 0);
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,0));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,1));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,2));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,3));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,4));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,5));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,6));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, chbit(data,7));
     delayMicroseconds(soft_uart_0_bit_time);
     platform_gpio_write(soft_uart_0_pin, 1);
     delayMicroseconds(soft_uart_0_bit_time*10);


its adaptation of my working code from AVR

Code: Select allvoid putchar_soft(char znak)
{
if (TXD == 0) { TXD = 1; delay_ms(5);}

TXD = 0;
delay_us(103);
TXD = character & 1;
delay_us(103);
TXD = character & 2;
delay_us(103);
TXD = character & 4;
delay_us(103);
TXD = character & 8;
delay_us(103);
TXD = character & 16;
delay_us(103);
TXD = character & 32;
delay_us(103);
TXD = character & 64;
delay_us(103);
TXD = character & 128;
delay_us(103);
TXD = 1;
delay_ms(2);
}


This is very ugly code... but it working... but stops timers and PWMs
User avatar
By milikiller
#9198 Hi, I write simple library for softuart on any pin... Now softuart only can send data out.

You can simply call command softuart.write(5,19200,"Hallo from Node MCU")
And text is send with selected baudrate on selected pin

Image

Baudrate can be 100-57600 baud, but 57600 is not idealy timed. But 19200 or lower baudrate is ok.

You can use it for binary data send softuart.write(5,19200,65) send byte 65 (ascii A)

you can download it here : https://github.com/milikiller/nodemcu-firmware/



Code: Select all// Module for software serial

//#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"

#include "c_types.h"
#include "c_string.h"

#define DIRECT_MODE_OUTPUT(pin)   platform_gpio_mode(pin,PLATFORM_GPIO_OUTPUT,PLATFORM_GPIO_PULLUP)
#define DIRECT_WRITE_LOW(pin)    (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
#define DIRECT_WRITE_HIGH(pin)   (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))


static inline u8 chbit(u8 data, u8 bit)
{
    if ((data & bit) != 0)
    {
       return 1;
    }
    else
    {
       return 0;
    }
}

// Function for printing individual characters
static int soft_uart_putchar_c(u8 pin, unsigned bit_time, char data)
{
   unsigned i;
   unsigned start_time = 0x7FFFFFFF & system_get_time();

   //Start Bit
   GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0);
   for(i = 0; i <= 8; i ++ )
   {
      while ((0x7FFFFFFF & system_get_time()) < (start_time + (bit_time*(i+1))))
      {
         //If system timer overflow, escape from while loop
         if ((0x7FFFFFFF & system_get_time()) < start_time){break;}
      }
      GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), chbit(data,1<<i));
   }

   // Stop bit
   while ((0x7FFFFFFF & system_get_time()) < (start_time + (bit_time*9)))
   {
      //If system timer overflow, escape from while loop
      if ((0x7FFFFFFF & system_get_time()) < start_time){break;}
   }
   GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1);

   // Delay after byte, for new sync
   os_delay_us(bit_time*6);

   return 1;
}



// Lua: write( id, baudrate, string1, [string2], ..., [stringn] )
static int softuart_write( lua_State* L )
{
  unsigned pin, baudrate, bit_time;

  const char* buf;
  size_t len, i;
  int total = lua_gettop( L ), s;
 
  pin = luaL_checkinteger( L, 1 );
  MOD_CHECK_ID( gpio, pin );

  baudrate = luaL_checkinteger( L, 2 );
  if( baudrate > 57600 )
          return luaL_error( L, "max baudrate is 57600" );

  bit_time = (1000000 / baudrate);

  if (pin >= 0)
  {
     DIRECT_WRITE_HIGH(pin);
     DIRECT_MODE_OUTPUT(pin);
     os_delay_us(bit_time*8);
  }

  for( s = 3; s <= total; s ++ )
  {
    if( lua_type( L, s ) == LUA_TNUMBER )
    {
      len = lua_tointeger( L, s );
      if( len > 255 )
        return luaL_error( L, "invalid number" );
      soft_uart_putchar_c(pin,bit_time,( u8 )len);
    }
    else
    {
      luaL_checktype( L, s, LUA_TSTRING );
      buf = lua_tolstring( L, s, &len );
      for( i = 0; i < len; i ++ )
         soft_uart_putchar_c(pin, bit_time, buf[ i ]);
    }
  }
  return 0;
}

// Module function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE softuart_map[] =
{
  { LSTRKEY( "write" ), LFUNCVAL( softuart_write ) },
#if LUA_OPTIMIZE_MEMORY > 0

#endif
  { LNILKEY, LNILVAL }
};

LUALIB_API int luaopen_softuart( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
  return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
  luaL_register( L, AUXLIB_SOFTUART, softuart_map );
  // Add constants

  return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0 
}