Publication
This commit is contained in:
238
arduino_commlcd/ams20x4LCD.cpp
Normal file
238
arduino_commlcd/ams20x4LCD.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include "ams20x4LCD.hpp"
|
||||
#include "amswirelib.hpp"
|
||||
|
||||
const static unsigned long rwdelay = 1000;
|
||||
|
||||
lcd20x4::lcd20x4()
|
||||
{
|
||||
int I;
|
||||
pin_RS = 0;
|
||||
pin_RW = 0;
|
||||
pin_E = 0;
|
||||
for(I=0;I<8;I++) pin_DB[I] = 0;
|
||||
}
|
||||
|
||||
lcd20x4::~lcd20x4()
|
||||
{
|
||||
int I;
|
||||
pin_RS = 0;
|
||||
pin_RW = 0;
|
||||
pin_E = 0;
|
||||
for(I=0;I<8;I++) pin_DB[I] = 0;
|
||||
}
|
||||
|
||||
void lcd20x4::setup(uint8_t RSpin, uint8_t RWpin, uint8_t Epin, const uint8_t* DBpins)
|
||||
{
|
||||
int I;
|
||||
pin_RS = RSpin;
|
||||
pin_RW = RWpin;
|
||||
pin_E = Epin;
|
||||
set_pinmode(pin_RS,1);
|
||||
set_pinmode(pin_RW,1);
|
||||
set_pinmode(pin_E,1);
|
||||
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
pin_DB[I] = DBpins[I];
|
||||
set_pinmode(pin_DB[I],1);
|
||||
}
|
||||
|
||||
cursx = 0;
|
||||
cursy = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void lcd20x4::loop()
|
||||
{
|
||||
//nothing really
|
||||
}
|
||||
|
||||
uint8_t lcd20x4::read_op(uint8_t b, uint8_t RS)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t bt = 0;
|
||||
int I;
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
set_pinmode(pin_DB[I],0);
|
||||
}
|
||||
|
||||
write_pin(pin_E,1);
|
||||
write_pin(pin_RW,1);
|
||||
write_pin(pin_RS,RS);
|
||||
delayMicroseconds(rwdelay);
|
||||
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
bt = read_pin(pin_DB[I]);
|
||||
ret = ret + bt<<I;
|
||||
}
|
||||
|
||||
delayMicroseconds(rwdelay);
|
||||
write_pin(pin_E,0);
|
||||
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
set_pinmode(pin_DB[I],1);
|
||||
}
|
||||
delayMicroseconds(rwdelay);
|
||||
return ret;
|
||||
}
|
||||
void lcd20x4::write_op(uint8_t b, uint8_t RS)
|
||||
{
|
||||
int I;
|
||||
|
||||
write_pin(pin_E,1);
|
||||
write_pin(pin_RW,0);
|
||||
write_pin(pin_RS,RS);
|
||||
delayMicroseconds(rwdelay);
|
||||
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
write_pin(pin_DB[I],(b & (1<<I))>>I);
|
||||
}
|
||||
|
||||
delayMicroseconds(rwdelay);
|
||||
write_pin(pin_E,0);
|
||||
delayMicroseconds(rwdelay);
|
||||
}
|
||||
|
||||
void lcd20x4::display_clear()
|
||||
{
|
||||
write_op(0b00000001,0);
|
||||
}
|
||||
|
||||
void lcd20x4::cursor_home()
|
||||
{
|
||||
write_op(0b00000010,0);
|
||||
cursx = 0; cursy = 0;
|
||||
}
|
||||
|
||||
void lcd20x4::entrymode(bool ID, bool S)
|
||||
{
|
||||
write_op((1<<2) | (ID<<1) | S,0);
|
||||
}
|
||||
|
||||
void lcd20x4::display_toggle(bool display, bool cursor, bool charblink)
|
||||
{
|
||||
write_op((1<<3) | (display<<2) | (cursor<<1) | charblink, 0);
|
||||
}
|
||||
|
||||
void lcd20x4::cursor_shift(bool screen_cursor, bool left_right)
|
||||
{
|
||||
write_op((1<<4) | (screen_cursor<<3) | (left_right<<2),0);
|
||||
}
|
||||
|
||||
//void lcd20x4::function_set(uint8_t q)
|
||||
//{
|
||||
// write_op((1<<5) | (q & 0b00001111) , 0);
|
||||
//}
|
||||
|
||||
//DL: data length: 0 - 4-bit, 1 - 8-bit
|
||||
//N: display lines: 0 - 1-line-mode 1 - 2-line-mode
|
||||
//F: font: 0 - 5x8 1 - 5x10
|
||||
void lcd20x4::function_set(bool DL,bool N,bool F)
|
||||
{
|
||||
write_op((1<<5)|(DL<<4)|(N<<3)|(F<<2),0);
|
||||
return;
|
||||
}
|
||||
|
||||
void lcd20x4::CGRAM_set(uint8_t Acg_6bits)
|
||||
{
|
||||
write_op((1<<6)|(Acg_6bits & 0b00111111),0);
|
||||
}
|
||||
|
||||
void lcd20x4::DDRAM_set(uint8_t Add_7bits)
|
||||
{
|
||||
write_op((1<<7)|(Add_7bits & 0b01111111),0);
|
||||
}
|
||||
|
||||
void lcd20x4::setmydefs()
|
||||
{
|
||||
write_pin(pin_E,1);
|
||||
delay(50);
|
||||
write_op(0x30,0); //wake up 0x30 0b00110000
|
||||
delay(50);
|
||||
write_op(0x30,0); //wake up
|
||||
delay(50);
|
||||
write_op(0x30,0); //wake up
|
||||
delay(50);
|
||||
//write_op(0x38,0); //function set 8-bit, 2 lines 0b00111000
|
||||
function_set(1,1,1);
|
||||
delay(50);
|
||||
//write_op(0x10,0); //set cursor? (looks like a function set to me?)
|
||||
entrymode(1,0);
|
||||
delay(50);
|
||||
//write_op(0x0c,0); //0x0c 0b00001100
|
||||
display_toggle(1,0,0);
|
||||
//write_op(0x0c,0); //0x06 0b00000110
|
||||
entrymode(1,0);
|
||||
|
||||
|
||||
|
||||
// display_clear();
|
||||
// cursor_home();
|
||||
// entrymode(1,0);
|
||||
// display_toggle(1,0,0);
|
||||
// DDRAM_set(0);
|
||||
}
|
||||
|
||||
void lcd20x4::set_pos(uint8_t x, uint8_t y)
|
||||
{
|
||||
uint8_t b;
|
||||
switch(y)
|
||||
{
|
||||
case 0: b = 0x00; break;
|
||||
case 1: b = 0x40; break;
|
||||
case 2: b = 0x14; break;
|
||||
case 3: b = 0x54; break;
|
||||
default: b = 0x00;
|
||||
}
|
||||
b += (x%20);
|
||||
DDRAM_set(b);
|
||||
}
|
||||
|
||||
void lcd20x4::write_char(char b, uint8_t x, uint8_t y)
|
||||
{
|
||||
set_pos(x,y);
|
||||
write_op((uint8_t) b, 1);
|
||||
}
|
||||
|
||||
void lcd20x4::write_char(char b)
|
||||
{
|
||||
//may have to do translation of ASCII code
|
||||
//01000001: A on the chart, 41h on ASCII chart - should be good
|
||||
//write_op((uint8_t) b,1);
|
||||
|
||||
write_char(b,cursx,cursy);
|
||||
cursx = cursx+1;
|
||||
if(cursx>=20) {cursy = (cursy+1)%4; cursx = 0;}
|
||||
}
|
||||
|
||||
void lcd20x4::newline()
|
||||
{
|
||||
cursx = 0;
|
||||
cursy = (cursy+1)%4;
|
||||
}
|
||||
|
||||
void lcd20x4::write_chars(const char *bytes)
|
||||
{
|
||||
int I;
|
||||
for(I=0;I<80;I++)
|
||||
{
|
||||
if(bytes[I]=='\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(bytes[I] == '\n')
|
||||
{
|
||||
newline();
|
||||
}
|
||||
else
|
||||
{
|
||||
write_char(bytes[I]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
78
arduino_commlcd/ams20x4LCD.hpp
Normal file
78
arduino_commlcd/ams20x4LCD.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef __AMS_20x4LCD_HPP__
|
||||
#define __AMS_20x4LCD_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
//https://electronicsforu.com/resources/learn-electronics/16x2-lcd-pinout-diagram
|
||||
// Most LCDs contain Hitachi HD4478 controller.
|
||||
// Arduino may already have a driver for this, but I need to learn
|
||||
// to write my own drivers.
|
||||
|
||||
class lcd20x4
|
||||
{
|
||||
public:
|
||||
|
||||
lcd20x4();
|
||||
~lcd20x4();
|
||||
|
||||
uint8_t cursx,cursy;
|
||||
|
||||
void setup(uint8_t RSpin, uint8_t RWpin, uint8_t Epin, const uint8_t* DBpins);
|
||||
void loop();
|
||||
|
||||
//11 pin control for 16-pin LCD screen
|
||||
uint8_t pin_RS; //pin 4 register-select
|
||||
//-0 instruction register (read), 1 data register (read/write)
|
||||
uint8_t pin_RW; //pin 5 (read-write)
|
||||
//-0 write, 1 read
|
||||
uint8_t pin_E; //pin 6 enable
|
||||
//high - enable read/write (clock for read/write?)
|
||||
uint8_t pin_DB[8]; //pins 7-14 on LCD
|
||||
//data bus
|
||||
|
||||
//blocking read/write operations
|
||||
uint8_t read_op(uint8_t b, uint8_t RS);
|
||||
void write_op(uint8_t b, uint8_t RS);
|
||||
|
||||
//control commands
|
||||
void display_clear();
|
||||
void cursor_home();
|
||||
void entrymode(bool ID, bool S); //cursor advance direction and shift mode
|
||||
//I/D - 1:increment/0:decrement S:1 display shift 0:cursor shift?
|
||||
void display_toggle(bool display, bool cursor, bool charblink);
|
||||
void cursor_shift(bool screen_cursor, bool left_right);
|
||||
|
||||
void CGRAM_set(uint8_t Acg_6bits); //sets CGRAM address - subsequent data is CG data
|
||||
//user generated characters
|
||||
void DDRAM_set(uint8_t Add_7bits); //sets DDRAM address - subsequent data is DD data
|
||||
//00 - 4F (when display not shifted)
|
||||
|
||||
//DL: data length: 0 - 4-bit, 1 - 8-bit
|
||||
//N: display lines: 0 - 1-line-mode 1 - 2-line-mode
|
||||
//F: font: 0 - 5x8 1 - 5x10
|
||||
void function_set(bool DL,bool N,bool F);
|
||||
|
||||
|
||||
|
||||
//D: display
|
||||
//C: cursor
|
||||
//B: blink
|
||||
void displayonoff(bool D, bool C, bool B);
|
||||
|
||||
|
||||
|
||||
void setmydefs(); //sets reasonable screen defaults and clears screen
|
||||
//writes a char and advances cursor
|
||||
|
||||
void set_pos(uint8_t x, uint8_t y);
|
||||
void write_char(char b, uint8_t x, uint8_t y);
|
||||
void write_char(char b);
|
||||
//clears screen and writes a string (32 bytes max)
|
||||
void write_chars(const char *bytes);
|
||||
void newline();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
50
arduino_commlcd/amsgenlib.cpp
Normal file
50
arduino_commlcd/amsgenlib.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "amsgenlib.hpp"
|
||||
|
||||
utimer::utimer()
|
||||
{
|
||||
t = micros();
|
||||
}
|
||||
|
||||
utimer::~utimer()
|
||||
{
|
||||
t = 0;
|
||||
}
|
||||
|
||||
void utimer::set()
|
||||
{
|
||||
t = micros();
|
||||
}
|
||||
|
||||
bool utimer::isafter(unsigned long N)
|
||||
{
|
||||
bool ret = 0;
|
||||
unsigned long t2,lmx;
|
||||
if(t+N<t)
|
||||
{
|
||||
//wraparound
|
||||
lmx = 0-1;
|
||||
t2 = micros();
|
||||
if(t2> ((t-lmx)+N))
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t2 = micros();
|
||||
if(t2>t+N)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void utimer::delay(unsigned long N)
|
||||
{
|
||||
while(!this->isafter(N))
|
||||
{
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
29
arduino_commlcd/amsgenlib.hpp
Normal file
29
arduino_commlcd/amsgenlib.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __AMS_GENLIB_HPP__
|
||||
#define __AMS_GENLIB_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
class utimer
|
||||
{
|
||||
public:
|
||||
|
||||
utimer();
|
||||
~utimer();
|
||||
|
||||
unsigned long t;
|
||||
|
||||
//sets the time in memory
|
||||
void set();
|
||||
|
||||
//blocking delay
|
||||
void delay(unsigned long N);
|
||||
|
||||
//is it N microseconds after the set time?
|
||||
//solves wraparound at long overflow
|
||||
bool isafter(unsigned long N);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
411
arduino_commlcd/amsswcomm.cpp
Normal file
411
arduino_commlcd/amsswcomm.cpp
Normal file
@ -0,0 +1,411 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include "amswirelib.hpp"
|
||||
#include "amsgenlib.hpp"
|
||||
|
||||
#include "amsswcomm.hpp"
|
||||
|
||||
//initialize the sw communication channel
|
||||
// each swcomm channel has 3 pins, the clock pin (controlled by the master),
|
||||
// the input pin (receiving a signal from the other device)
|
||||
// and an output pin (sending a signal to the other device)
|
||||
//Inputs:
|
||||
// ms - master or slave
|
||||
// clkpin - the clock pin number
|
||||
// outpin - the output pin number
|
||||
// inpin - the input pin number
|
||||
// divisor - how many updates to skip between clock changes
|
||||
void amsswcomm::init(uint8_t _ms, uint8_t _clkpin, uint8_t _sendpin, uint8_t _recvpin, int _divisor)
|
||||
{
|
||||
|
||||
ms = _ms;
|
||||
clkpin = _clkpin;
|
||||
sendpin = _sendpin;
|
||||
recvpin = _recvpin;
|
||||
|
||||
|
||||
divisor = _divisor;
|
||||
clockticks = 0;
|
||||
clockstate = 0;
|
||||
lastclockstate = 0;
|
||||
|
||||
if(ms==1)
|
||||
{
|
||||
//master
|
||||
set_pinmode(clkpin,1);
|
||||
set_pinmode(recvpin,0);
|
||||
set_pinmode(sendpin,1);
|
||||
|
||||
}
|
||||
else if(ms==0)
|
||||
{
|
||||
//slave
|
||||
set_pinmode(clkpin,0);
|
||||
set_pinmode(recvpin,0);
|
||||
set_pinmode(sendpin,1);
|
||||
|
||||
}
|
||||
|
||||
clearrecvqueue();
|
||||
clearsendqueue();
|
||||
|
||||
// recvmessage_size = -1;
|
||||
// sendmessage_size = -1; //no message
|
||||
// recvmessage_bit = 0;
|
||||
// sendmessage_bit = 0;
|
||||
|
||||
// sendstate = 0;
|
||||
// recvstate = 0;
|
||||
// sendbytepointer = 0;
|
||||
// recvbytepointer = 0;
|
||||
// sendbitpointer = 0;
|
||||
// recvbitpointer = 0;
|
||||
|
||||
int8_t I;
|
||||
for(I=0;I<AMSSWCOMM_BUFFSIZE;I++)
|
||||
{
|
||||
sendmessage[I] = 0;
|
||||
recvmessage[I] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amsswcomm::clearrecvqueue()
|
||||
{
|
||||
int8_t I;
|
||||
|
||||
recvmessage_size = -1;
|
||||
recvmessage_byte = 0;
|
||||
recvstate = 0;
|
||||
recvbytepointer = 0;
|
||||
recvbitpointer = 0;
|
||||
|
||||
// for speed, deal with this by sendmessage_size
|
||||
// for(I=0;I<AMSSWCOMM_BUFFSIZE;I++)
|
||||
// {
|
||||
// recvmessage[I] = 0;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amsswcomm::clearsendqueue()
|
||||
{
|
||||
int8_t I;
|
||||
|
||||
sendmessage_size = -1;
|
||||
sendmessage_byte = 0;
|
||||
sendstate = 0;
|
||||
sendbytepointer = 0;
|
||||
sendbitpointer = 0;
|
||||
|
||||
// for speed, deal with this by recvmessage_size
|
||||
// for(I=0;I<AMSSWCOMM_BUFFSIZE;I++)
|
||||
// {
|
||||
// sendmessage[I] = 0;
|
||||
// }
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amsswcomm::update_step()
|
||||
{
|
||||
|
||||
if(ms==1)
|
||||
{
|
||||
//if master
|
||||
|
||||
if(clockticks<divisor)
|
||||
{
|
||||
clockticks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
clockticks = 0;
|
||||
|
||||
lastclockstate = clockstate;
|
||||
clockstate = !lastclockstate;
|
||||
write_pin(clkpin,clockstate);
|
||||
|
||||
//update_send triggers on rising edge of clkpin
|
||||
if(clockstate==1 && lastclockstate==0)
|
||||
{
|
||||
update_send();
|
||||
}
|
||||
//update recv triggers on falling edge of clkpin
|
||||
if(clockstate==0 && lastclockstate==1)
|
||||
{
|
||||
update_recv();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else if(ms==0)
|
||||
{
|
||||
//if servant
|
||||
|
||||
//check clock every passthrough
|
||||
|
||||
lastclockstate = clockstate;
|
||||
clockstate = read_pin(clkpin);
|
||||
|
||||
//update_send triggers on rising edge of clkpin
|
||||
if(clockstate==1 && lastclockstate==1)
|
||||
{
|
||||
update_send();
|
||||
}
|
||||
//update recv triggers on falling edge of clkpin
|
||||
if(clockstate==0 && lastclockstate==1)
|
||||
{
|
||||
update_recv();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//called by update_step
|
||||
void amsswcomm::update_send()
|
||||
{
|
||||
|
||||
uint8_t bit;
|
||||
|
||||
if(sendstate==0)
|
||||
{
|
||||
//do nothing, no message
|
||||
write_pin(sendpin,0); //send zeroes until messaging
|
||||
}
|
||||
else if(sendstate==1)
|
||||
{
|
||||
//send starting byte
|
||||
sendmessage_byte = 0b0000001111111111;
|
||||
|
||||
bit = (sendmessage_byte & 1<<(9-sendbitpointer)) >> (9-sendbitpointer);
|
||||
write_pin(sendpin,bit);
|
||||
|
||||
sendbitpointer++; //advance pointer
|
||||
if(sendbitpointer>=10)
|
||||
{
|
||||
//if finished, advance state
|
||||
sendbitpointer=0;
|
||||
sendbytepointer=0;
|
||||
sendstate=2;
|
||||
}
|
||||
}
|
||||
else if(sendstate==2)
|
||||
{
|
||||
if(sendmessage_size>=0 && sendbytepointer<sendmessage_size)
|
||||
{
|
||||
sendmessage_byte = 0b0000001100000000 + sendmessage[sendbytepointer];
|
||||
|
||||
bit = (sendmessage_byte & 1<<(9-sendbitpointer)) >> (9-sendbitpointer);
|
||||
write_pin(sendpin,bit);
|
||||
|
||||
sendbitpointer++; //advance pointer
|
||||
if(sendbitpointer>=10)
|
||||
{
|
||||
//if finished, advance bytepointer
|
||||
sendbitpointer=0;
|
||||
sendbytepointer++;
|
||||
}
|
||||
if(sendbytepointer>sendmessage_size)
|
||||
{
|
||||
//if finished with message, advance state to send ending byte
|
||||
sendbitpointer=0;
|
||||
sendbytepointer=0;
|
||||
sendstate=3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//size 0 message
|
||||
sendbitpointer=0;
|
||||
sendbytepointer=0;
|
||||
sendstate=3;
|
||||
}
|
||||
}
|
||||
else if(sendstate==3)
|
||||
{
|
||||
//send ending byte
|
||||
sendmessage_byte = 0; //if zero is received for more than 10 bits, end message
|
||||
|
||||
bit = (sendmessage_byte & 1<<(9-sendbitpointer)) >> (9-sendbitpointer);
|
||||
write_pin(sendpin,bit);
|
||||
|
||||
sendbitpointer++; //advance pointer
|
||||
if(sendbitpointer>=10)
|
||||
{
|
||||
//if finished, advance state
|
||||
sendbitpointer=0;
|
||||
sendbytepointer=0;
|
||||
sendstate=4;
|
||||
}
|
||||
}
|
||||
else if(sendstate==4)
|
||||
{
|
||||
clearsendqueue();
|
||||
}
|
||||
else
|
||||
{
|
||||
//this shouldn't happen, but if it does, reset things
|
||||
clearsendqueue();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amsswcomm::update_recv()
|
||||
{
|
||||
uint8_t bit;
|
||||
|
||||
if(recvstate==0)
|
||||
{
|
||||
bit = read_pin(recvpin);
|
||||
if(bit==1)
|
||||
{
|
||||
recvstate=1; //advance to receive state
|
||||
recvbitpointer=1;
|
||||
recvmessage_byte = 0b0000001000000000; //set first leading bit
|
||||
recvbytepointer = 0;
|
||||
}
|
||||
}
|
||||
else if(recvstate==1)
|
||||
{
|
||||
bit = read_pin(recvpin);
|
||||
recvmessage_byte = recvmessage_byte + (bit<<(9-recvbitpointer));
|
||||
recvbitpointer++;
|
||||
|
||||
if(recvbitpointer>=10)
|
||||
{
|
||||
recvbitpointer = 0;
|
||||
if(recvmessage_byte = 0b0000001111111111)
|
||||
{
|
||||
recvstate = 2;
|
||||
recvmessage_byte = 0;
|
||||
recvbytepointer = 0;
|
||||
recvmessage_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//byte received not part of message or garbled message, ignore
|
||||
recvstate = 0;
|
||||
recvbytepointer = 0;
|
||||
clearrecvqueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(recvstate==2)
|
||||
{
|
||||
bit = read_pin(recvpin);
|
||||
recvmessage_byte = recvmessage_byte + (bit<<(9-recvbitpointer));
|
||||
recvbitpointer++;
|
||||
|
||||
if(recvbitpointer>=10)
|
||||
{
|
||||
if(recvmessage_byte==0)
|
||||
{
|
||||
//end of message byte has been received
|
||||
recvbitpointer = 0;
|
||||
recvbytepointer = 0;
|
||||
recvstate = 3; //has message
|
||||
recvmessage_byte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
recvbitpointer = 0;
|
||||
recvmessage[recvbytepointer] = (uint8_t)(recvmessage_byte & 0b0000000011111111);
|
||||
recvbytepointer++;
|
||||
recvmessage_size++;
|
||||
recvmessage_byte = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(recvstate==3)
|
||||
{
|
||||
//has message, do nothing and wait until message has been processed
|
||||
}
|
||||
else
|
||||
{
|
||||
clearrecvqueue();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool amsswcomm::has_message()
|
||||
{
|
||||
if(recvstate==3)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//receives the message and resets the receive queue
|
||||
//return value is message size, or -1 for no message
|
||||
int amsswcomm::recv_message(char *outputbuff, int outputbuffsize)
|
||||
{
|
||||
int ret = -1;
|
||||
int I;
|
||||
|
||||
if(has_message())
|
||||
{
|
||||
ret = recvmessage_size;
|
||||
for(I=0;I<recvmessage_size && I<outputbuffsize && I<AMSSWCOMM_BUFFSIZE; I++)
|
||||
{
|
||||
outputbuff[I] = recvmessage[I];
|
||||
}
|
||||
if(I<outputbuffsize) outputbuff[I] = 0; //NULL terminate if possible to help string logic
|
||||
|
||||
for(I=0;I<AMSSWCOMM_BUFFSIZE;I++)
|
||||
{
|
||||
recvmessage[I] = 0;
|
||||
}
|
||||
recvmessage_size = -1;
|
||||
// recvmessage_byte = 0;
|
||||
// recvstate = 0;
|
||||
// recvbytepointer = 0;
|
||||
// recvbitpointer = 0;
|
||||
clearrecvqueue();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//places a message in the send queue
|
||||
//1 - success
|
||||
//0 - failure - a message is being sent, must wait to send
|
||||
bool amsswcomm::send_message(char *inputbuff, int messagesize)
|
||||
{
|
||||
bool ret = 0;
|
||||
int I;
|
||||
|
||||
if(sendstate==0)
|
||||
{
|
||||
ret = 1;
|
||||
if(messagesize<=AMSSWCOMM_BUFFSIZE) sendmessage_size = messagesize; else sendmessage_size = AMSSWCOMM_BUFFSIZE;
|
||||
for(I=0;I<sendmessage_size;I++)
|
||||
{
|
||||
sendmessage[I] = inputbuff[I];
|
||||
}
|
||||
for(I=sendmessage_size;I<AMSSWCOMM_BUFFSIZE;I++)
|
||||
{
|
||||
sendmessage[I] = 0;
|
||||
}
|
||||
|
||||
sendstate = 1; //start sending message
|
||||
sendmessage_byte = 0;
|
||||
sendbitpointer = 0;
|
||||
sendbytepointer = 0;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
86
arduino_commlcd/amsswcomm.hpp
Normal file
86
arduino_commlcd/amsswcomm.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef __AMSSWCOMM_HPP__
|
||||
#define __AMSSWCOMM_HPP__
|
||||
|
||||
#define AMSSWCOMM_BUFFSIZE 64
|
||||
//the size of the message buffer
|
||||
|
||||
class amsswcomm
|
||||
{
|
||||
public:
|
||||
|
||||
uint8_t ms;
|
||||
uint8_t clkpin;
|
||||
uint8_t sendpin;
|
||||
uint8_t recvpin;
|
||||
|
||||
//time
|
||||
int8_t divisor;
|
||||
int8_t clockticks;
|
||||
uint8_t lastclockstate;
|
||||
uint8_t clockstate;
|
||||
|
||||
|
||||
int16_t recvmessage_size;
|
||||
uint16_t recvmessage_byte; //extended bit that is being received
|
||||
int8_t recvstate;
|
||||
//0 - no starting bit has been received
|
||||
//1 - receive message start byte
|
||||
//2 - receiving message bytes
|
||||
//3 - message received - read and/or clear
|
||||
int16_t recvbytepointer; //0 - 10, pointer to bit being received
|
||||
uint8_t recvbitpointer; //pointer to byte being received
|
||||
|
||||
int16_t sendmessage_size;
|
||||
uint16_t sendmessage_byte; //extended byte that is being sent
|
||||
int8_t sendstate;
|
||||
//0 - no message being sent
|
||||
//1 - message exists in queue, send start byte
|
||||
//2 - message exists in queue, send message bytes
|
||||
//3 - send end message byte
|
||||
//4 - clear message and reset
|
||||
int16_t sendbytepointer; //0 - 10, pointer to byte being sent
|
||||
uint8_t sendbitpointer; //pointer to byte being sent
|
||||
|
||||
|
||||
char sendmessage[AMSSWCOMM_BUFFSIZE];
|
||||
char recvmessage[AMSSWCOMM_BUFFSIZE];
|
||||
|
||||
|
||||
//initialize the sw communication channel
|
||||
// each swcomm channel has 3 pins, the clock pin (controlled by the master),
|
||||
// the input pin (receiving a signal from the other device)
|
||||
// and an output pin (sending a signal to the other device)
|
||||
//Inputs:
|
||||
// ms - master or slave
|
||||
// clkpin - the clock pin number
|
||||
// outpin - the output pin number
|
||||
// inpin - the input pin number
|
||||
void init(uint8_t _ms, uint8_t _clkpin, uint8_t _sendpin, uint8_t _recvpin, int _divisor);
|
||||
|
||||
//called on each timestep to update the state of the communicator
|
||||
void update_step();
|
||||
|
||||
//called by update_step
|
||||
void update_send();
|
||||
void update_recv();
|
||||
|
||||
//communicator has received a complete message
|
||||
//int is the size of the message, or -1 for no message received
|
||||
bool has_message();
|
||||
|
||||
//receives the message and resets the receive queue
|
||||
//return value is message size, or -1 for no message
|
||||
int recv_message(char *outputbuff, int outputbuffsize);
|
||||
|
||||
//clears a received message and prepares to receive again
|
||||
void clearrecvqueue();
|
||||
void clearsendqueue();
|
||||
|
||||
//places a message in the send queue
|
||||
//1 - success
|
||||
//0 - failure - a message is being sent, must wait to send
|
||||
bool send_message(char *inputbuff, int messagesize);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
172
arduino_commlcd/amswirelib.cpp
Normal file
172
arduino_commlcd/amswirelib.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include "amswirelib.hpp"
|
||||
|
||||
uint8_t read_portsD()
|
||||
{
|
||||
return PIND;
|
||||
}
|
||||
|
||||
uint8_t read_portsB()
|
||||
{
|
||||
return PINB;
|
||||
}
|
||||
|
||||
uint8_t read_portsC()
|
||||
{
|
||||
return PINC;
|
||||
}
|
||||
|
||||
uint8_t read_portD(uint8_t N)
|
||||
{
|
||||
return (PIND & (1<<N))>>N;
|
||||
}
|
||||
|
||||
uint8_t read_portB(uint8_t N)
|
||||
{
|
||||
return (PINB & (1<<N))>>N;
|
||||
}
|
||||
|
||||
uint8_t read_portC(uint8_t N)
|
||||
{
|
||||
return (PINC & (1<<N))>>N;
|
||||
}
|
||||
|
||||
void write_portsD(uint8_t V)
|
||||
{
|
||||
PORTD = V;
|
||||
}
|
||||
|
||||
void write_portsB(uint8_t V)
|
||||
{
|
||||
PORTB = V;
|
||||
}
|
||||
|
||||
void write_portsC(uint8_t V)
|
||||
{
|
||||
PORTC = V;
|
||||
}
|
||||
|
||||
void write_portD(uint8_t N, uint8_t V)
|
||||
{
|
||||
PORTD = (PORTD & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
|
||||
void write_portB(uint8_t N, uint8_t V)
|
||||
{
|
||||
PORTB = (PORTB & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
|
||||
void write_portC(uint8_t N, uint8_t V)
|
||||
{
|
||||
PORTC = (PORTC & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
|
||||
void set_portsmodeD(uint8_t iomode)
|
||||
{
|
||||
DDRD = iomode;
|
||||
}
|
||||
void set_portsmodeB(uint8_t iomode)
|
||||
{
|
||||
DDRB = iomode;
|
||||
}
|
||||
void set_portsmodeC(uint8_t iomode)
|
||||
{
|
||||
DDRC = iomode;
|
||||
}
|
||||
|
||||
void set_portmodeD(uint8_t N, uint8_t iomode)
|
||||
{
|
||||
DDRD = (DDRD & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
|
||||
void set_portmodeB(uint8_t N, uint8_t iomode)
|
||||
{
|
||||
DDRB = (DDRB & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
|
||||
void set_portmodeC(uint8_t N, uint8_t iomode)
|
||||
{
|
||||
DDRC = (DDRC & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
|
||||
//Numbered Pin Digital IO
|
||||
//amsPN mapping for Arduino Nano
|
||||
//0-7 - PORTD
|
||||
//8-15 - PORTB
|
||||
//16-23 - PORTC (Analog Pins)
|
||||
|
||||
//1 - output, 0 - input
|
||||
void set_pinmode(uint8_t amsPN, uint8_t iomode)
|
||||
{
|
||||
uint8_t N;
|
||||
if(amsPN>=0&&amsPN<=7)
|
||||
{
|
||||
N = amsPN-0;
|
||||
DDRD = (DDRD & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
else if(amsPN>=8 && amsPN<=15)
|
||||
{
|
||||
N = amsPN-8;
|
||||
DDRB = (DDRB & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
else if(amsPN>=16&&amsPN<=23)
|
||||
{
|
||||
N = amsPN-16;
|
||||
DDRC = (DDRC & ~(1<<N)) | ((iomode & 0x01)<<N);
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void write_pin(uint8_t amsPN, uint8_t V)
|
||||
{
|
||||
uint8_t N;
|
||||
if(amsPN>=0&&amsPN<=7)
|
||||
{
|
||||
N = amsPN-0;
|
||||
PORTD = (PORTD & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
else if(amsPN>=8 && amsPN<=15)
|
||||
{
|
||||
N = amsPN-8;
|
||||
PORTB = (PORTB & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
else if(amsPN>=16&&amsPN<=23)
|
||||
{
|
||||
N = amsPN-16;
|
||||
PORTC = (PORTC & ~(1<<N)) | ((V & 0x01)<<N);
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t read_pin(uint8_t amsPN)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t N;
|
||||
if(amsPN>=0&&amsPN<=7)
|
||||
{
|
||||
N = amsPN-0;
|
||||
ret = (PIND & (1<<N))>>N;
|
||||
}
|
||||
else if(amsPN>=8 && amsPN<=15)
|
||||
{
|
||||
N = amsPN-8;
|
||||
ret = (PINB & (1<<N))>>N;
|
||||
}
|
||||
else if(amsPN>=16&&amsPN<=23)
|
||||
{
|
||||
N = amsPN-16;
|
||||
ret = (PINC & (1<<N))>>N;
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing;
|
||||
}
|
||||
return ret;;
|
||||
}
|
45
arduino_commlcd/amswirelib.hpp
Normal file
45
arduino_commlcd/amswirelib.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef __AMS_WIRELIB_HPP__
|
||||
#define __AMS_WIRELIB_HPP__
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//Routines for fast digital read/write from the PORTs, PINs, DDRs
|
||||
//This is specific to Arduino Nano
|
||||
|
||||
uint8_t read_portsD();
|
||||
uint8_t read_portsB();
|
||||
uint8_t read_portsC();
|
||||
|
||||
uint8_t read_portD(uint8_t N);
|
||||
uint8_t read_portB(uint8_t N);
|
||||
uint8_t read_portC(uint8_t N);
|
||||
|
||||
void write_portsD(uint8_t V);
|
||||
void write_portsB(uint8_t V);
|
||||
void write_portsC(uint8_t V);
|
||||
|
||||
void write_portD(uint8_t N, uint8_t V);
|
||||
void write_portB(uint8_t N, uint8_t V);
|
||||
void write_portC(uint8_t N, uint8_t V);
|
||||
|
||||
void set_portsmodeD(uint8_t iomode);
|
||||
void set_portsmodeB(uint8_t iomode);
|
||||
void set_portsmodeC(uint8_t iomode);
|
||||
|
||||
void set_portmodeD(uint8_t N, uint8_t iomode);
|
||||
void set_portmodeB(uint8_t N, uint8_t iomode);
|
||||
void set_portmodeC(uint8_t N, uint8_t iomode);
|
||||
|
||||
//Numbered Pin Digital IO
|
||||
//amsPN mapping for Arduino Nano
|
||||
//0-7 - PORTD
|
||||
//8-15 - PORTB
|
||||
//16-23 - PORTC (Analog Pins)
|
||||
|
||||
//1 - output, 0 - input
|
||||
void set_pinmode(uint8_t amsPN, uint8_t iomode);
|
||||
uint8_t read_pin(uint8_t amsPN);
|
||||
void write_pin(uint8_t amsPN, uint8_t V);
|
||||
|
||||
#endif
|
69
arduino_commlcd/ard_commlcd.ino
Normal file
69
arduino_commlcd/ard_commlcd.ino
Normal file
@ -0,0 +1,69 @@
|
||||
//#include "ams_swserial.hpp"
|
||||
#include "amswirelib.hpp"
|
||||
#include "amsgenlib.hpp"
|
||||
#include "ams20x4LCD.hpp"
|
||||
|
||||
#include "amsswcomm.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
lcd20x4 lcd;
|
||||
amsswcomm comm;
|
||||
|
||||
char buff1[128];
|
||||
|
||||
unsigned long loopcount;
|
||||
|
||||
void setup()
|
||||
{
|
||||
const uint8_t q[8] = {9,10,21,20,19,18,17,16};
|
||||
lcd.setup(6,7,8,q);
|
||||
lcd.setmydefs();
|
||||
//initialize
|
||||
lcd.display_clear();
|
||||
lcd.cursor_home();
|
||||
lcd.write_chars("INIT");
|
||||
//set up comm as a servant receiver
|
||||
//C1 - D2 - pin 2 - using as CLK
|
||||
//C2 - D3 - pin 3 - using as sendpin
|
||||
//C3 - D4 - pin 4 - using as recvpin
|
||||
//C4 - D5 - pin 5
|
||||
// divisor = 5 ticks
|
||||
comm.init(0,2,3,4,5);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
comm.update_step();
|
||||
if(comm.has_message())
|
||||
{
|
||||
comm.recv_message(buff1,128);
|
||||
buff1[127] = 0;
|
||||
comm.send_message("ACK",4);
|
||||
lcd.display_clear();
|
||||
lcd.cursor_home();
|
||||
lcd.write_chars(buff1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void setup()
|
||||
//{
|
||||
// set_pinmode(2,1);
|
||||
// set_pinmode(3,1);
|
||||
// set_pinmode(4,1);
|
||||
// loopcount = 0;
|
||||
//}
|
||||
|
||||
//// Test pins
|
||||
//void loop()
|
||||
//{
|
||||
// delay(100);
|
||||
// write_pin(2, loopcount%2);
|
||||
// write_pin(3, (loopcount/2)%2);
|
||||
// write_pin(4, (loopcount/4)%2);
|
||||
//
|
||||
//
|
||||
// loopcount = loopcount + 1;
|
||||
// loopcount = loopcount % 16;
|
||||
//}
|
Reference in New Issue
Block a user