extras/softuart: add initial port
This is a initial port of esp8266-software-uart [1] and for now it only supports one RX port with 8n1. 1 https://github.com/plieningerweb/esp8266-software-uart
This commit is contained in:
parent
54ce6bbe1c
commit
cd43eb4311
4 changed files with 238 additions and 0 deletions
23
extras/softuart/LICENSE
Normal file
23
extras/softuart/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@web.de>
|
||||
Copyright (c) 2015 plieningerweb
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
10
extras/softuart/component.mk
Normal file
10
extras/softuart/component.mk
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Component makefile for extras/softuart
|
||||
|
||||
# expected anyone using this driver includes it as 'softuart/softuart.h'
|
||||
INC_DIRS += $(softuart_ROOT)..
|
||||
|
||||
# args for passing into compile rule generation
|
||||
softuart_SRC_DIR = $(softuart_ROOT)
|
||||
|
||||
$(eval $(call component_compile_rules,softuart))
|
||||
|
||||
118
extras/softuart/softuart.c
Normal file
118
extras/softuart/softuart.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Softuart
|
||||
*
|
||||
* Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@web.de>
|
||||
*
|
||||
* This code is based on Softuart from here [1] and reworked to
|
||||
* fit into esp-open-rtos. For now only the RX part is ported.
|
||||
* Also the configuration of the pin is for now hardcoded.
|
||||
*
|
||||
* it fits my needs to read the GY-GPS6MV2 module with 9600 8n1
|
||||
*
|
||||
* Original Copyright:
|
||||
* Copyright (c) 2015 plieningerweb
|
||||
*
|
||||
* MIT Licensed as described in the file LICENSE
|
||||
*
|
||||
* 1 https://github.com/plieningerweb/esp8266-software-uart
|
||||
*/
|
||||
|
||||
#include "softuart.h"
|
||||
#include <stdint.h>
|
||||
#include <esp/gpio.h>
|
||||
#include <espressif/esp_common.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static softuart s;
|
||||
|
||||
void handle_rx(uint8_t gpio_num)
|
||||
{
|
||||
// Disable interrupt
|
||||
gpio_set_interrupt(rx_pin, GPIO_INTTYPE_NONE, handle_rx);
|
||||
|
||||
// Wait till start bit is half over so we can sample the next one in the center
|
||||
sdk_os_delay_us(s.bit_time/2);
|
||||
|
||||
// Now sample bits
|
||||
unsigned i;
|
||||
unsigned d = 0;
|
||||
unsigned start_time = 0x7FFFFFFF & sdk_system_get_time();
|
||||
|
||||
for(i = 0; i < 8; i ++ )
|
||||
{
|
||||
while ((0x7FFFFFFF & sdk_system_get_time()) < (start_time + (s.bit_time*(i+1))))
|
||||
{
|
||||
// If system timer overflow, escape from while loop
|
||||
if ((0x7FFFFFFF & sdk_system_get_time()) < start_time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Shift d to the right
|
||||
d >>= 1;
|
||||
|
||||
// Read bit
|
||||
if(gpio_read(rx_pin))
|
||||
{
|
||||
// If high, set msb of 8bit to 1
|
||||
d |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
// Store byte in buffer
|
||||
// If buffer full, set the overflow flag and return
|
||||
uint8_t next = (s.buffer.receive_buffer_tail + 1) % SOFTUART_MAX_RX_BUFF;
|
||||
if (next != s.buffer.receive_buffer_head)
|
||||
{
|
||||
// save new data in buffer: tail points to where byte goes
|
||||
s.buffer.receive_buffer[s.buffer.receive_buffer_tail] = d; // save new byte
|
||||
s.buffer.receive_buffer_tail = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.buffer.buffer_overflow = 1;
|
||||
}
|
||||
|
||||
// Wait for stop bit
|
||||
sdk_os_delay_us(s.bit_time);
|
||||
// Done
|
||||
// Reenable interrupt
|
||||
gpio_set_interrupt(rx_pin, GPIO_INTTYPE_EDGE_NEG, handle_rx);
|
||||
}
|
||||
|
||||
bool softuart_init(uint32_t baudrate)
|
||||
{
|
||||
if (baudrate == 0)
|
||||
return false;
|
||||
|
||||
// Calculate bit_time
|
||||
s.bit_time = (1000000 / baudrate);
|
||||
if ( ((100000000 / baudrate) - (100*s.bit_time)) > 50 )
|
||||
s.bit_time++;
|
||||
|
||||
gpio_enable(rx_pin, GPIO_INPUT);
|
||||
gpio_set_pullup(rx_pin, true, false);
|
||||
// Set up the interrupt handler to get the startbit
|
||||
gpio_set_interrupt(rx_pin, GPIO_INTTYPE_EDGE_NEG, handle_rx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read data from buffer
|
||||
uint8_t softuart_read()
|
||||
{
|
||||
// Empty buffer?
|
||||
if (s.buffer.receive_buffer_head == s.buffer.receive_buffer_tail)
|
||||
return 0;
|
||||
|
||||
// Read from "head"
|
||||
uint8_t d = s.buffer.receive_buffer[s.buffer.receive_buffer_head]; // grab next byte
|
||||
s.buffer.receive_buffer_head = (s.buffer.receive_buffer_head + 1) % SOFTUART_MAX_RX_BUFF;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Is data in buffer available?
|
||||
bool softuart_available()
|
||||
{
|
||||
return (s.buffer.receive_buffer_tail + SOFTUART_MAX_RX_BUFF - s.buffer.receive_buffer_head) % SOFTUART_MAX_RX_BUFF;
|
||||
}
|
||||
87
extras/softuart/softuart.h
Normal file
87
extras/softuart/softuart.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Softuart for esp-open-rtos
|
||||
*
|
||||
* Copyright (C) 2016 Bernhard Guillon <Bernhard.Guillon@web.de>
|
||||
*
|
||||
* This code is based on Softuart from here [1] and reworked to
|
||||
* fit into esp-open-rtos. For now only the RX part is ported.
|
||||
* Also the configuration of the pin is for now hardcoded.
|
||||
*
|
||||
* it fits my needs to read the GY-GPS6MV2 module with 9600 8n1
|
||||
*
|
||||
* Original Copyright:
|
||||
* Copyright (c) 2015 plieningerweb
|
||||
*
|
||||
* MIT Licensed as described in the file LICENSE
|
||||
*
|
||||
* 1 https://github.com/plieningerweb/esp8266-software-uart
|
||||
*/
|
||||
#ifndef SOFTUART_H_
|
||||
#define SOFTUART_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// FIXME: for now you need to provide the gpio number for RX here
|
||||
#define rx_pin 13
|
||||
|
||||
#define SOFTUART_MAX_RX_BUFF 64
|
||||
#define SOFTUART_GPIO_COUNT 16
|
||||
|
||||
/**
|
||||
* Private data buffer
|
||||
*/
|
||||
typedef struct softuart_buffer_t
|
||||
{
|
||||
char receive_buffer[SOFTUART_MAX_RX_BUFF];
|
||||
uint8_t receive_buffer_tail;
|
||||
uint8_t receive_buffer_head;
|
||||
uint8_t buffer_overflow;
|
||||
} softuart_buffer_t;
|
||||
|
||||
/**
|
||||
* Private softuart descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pin_rx; //!< This value is ignored by now but planned to get added again
|
||||
volatile softuart_buffer_t buffer; //!< Internal buffer
|
||||
uint16_t bit_time; //!< Time for one bit, filled by softuart
|
||||
} softuart;
|
||||
|
||||
/**
|
||||
* Initialize software uart and setup interrup handlers
|
||||
*
|
||||
* FIXME: For now you will have to set up the
|
||||
* rx_pin and handle_rx your self.
|
||||
*
|
||||
* @param baudrate actual baudrate
|
||||
* @return true if no errors occured otherwise false
|
||||
*/
|
||||
bool softuart_init(uint32_t baudrate);
|
||||
|
||||
/**
|
||||
* Check if data is available
|
||||
* @return true if data is available otherwise false
|
||||
*/
|
||||
bool softuart_available();
|
||||
|
||||
/**
|
||||
* Read current byte from internal buffer if available.
|
||||
*
|
||||
* NOTE: This call is non blocking.
|
||||
* NOTE: You have to check softuart_available first.
|
||||
* @return current byte
|
||||
*/
|
||||
uint8_t softuart_read();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SOFTUART_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue