Skip to content
Snippets Groups Projects
Commit 00acef89 authored by Jake Read's avatar Jake Read
Browse files

split to 23

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 662 additions and 0 deletions
jake/
**.elf
**.hex
**.bin
**.lss
**.map
**.srec
**.o
**.d
**.DS_Store
**.b#*
**.s#*
**/ASF/
**.atsln
**.atsuo
**.cproj
**.componentinfo.xml
**.vs
**/Debug/
**/Device_Startup
js/node_modules/
sim/js_code.txt
sim/TinyNets/nbproject/
\ No newline at end of file
# AutomataKit Stepper23
This is a motor driver for Nema 23 size Stepper Motors, which extends the [automatakit](https://gitlab.cba.mit.edu/jakeread/automatakit) architecture.
The board receives commands from an automatakit network and faithfully executes them, replying when complete.
![board](/images/fab-front.jpg)
![board](/images/fab-back.jpg)
## Development Notes
See [circuit chatter](/circuit) and [programming chatter](/embedded).
# Viable Commands
### Test
Keycode: **127**
- to test networking, this will reply with a payload packet containing ```127, 12, 24, 48``` and will toggle an LED on the board
### Reset
Keycode: **128**
- issues a software microcontroller reset
- if the microcontroller is already hung up, this will not work
### Step Trapezoid
Keycode: **131**
Arguments: <Steps to Make, int32_t> | <Entry Speed, steps/s, uint32_t> | <Acceleration Rate, steps/s/s, uint32_t> | <Acceleration Length, steps to accelerate for, uint32_t> | <Decceleration Length, steps to deccelerate after, uint32_t>
- the stepper will load this block into its stepping buffer, and if the buffer is empty will execute the trapezoid. on it's completion, the stepper will reply with an acknowledgement
# Reproducing This Work
All automatakit works are open source, and while we cannot sell you boards, if you have an interesting application, get in touch to ask about collaborating.
To reproduce boards and load code, see the document ['Reproducing Automatakit Work'](https://gitlab.cba.mit.edu/jakeread/automatakit/reproducing)
\ No newline at end of file
# AutomataKit Stepper23 Circuit Design
![schematic](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/schematic.png)
![routing](https://gitlab.cba.mit.edu/jakeread/mkstepper/raw/master/images/routed.png)
The circuit uses an ATXmega256A3U microcontroller and a TMC262 step gate-driver, with STI STL40C30H3ll P/N Pair Half Bridges to do the business. Between the driver and microcontroller are an SPI bus, to configure the driver, a diagnosis line, and step, direction, and enable lines.
The Half-Bridges benefit from a heatsink mounted beneath them (heat is conducted through the IC's large bottom contacts, and through vias into the coppler plane below, and are rated to ~ 8A of current, but care needs to be taken to cool them down under these conditions. I have measured 110c board temperature at 1.5A without any heatsinking or airflow.
Power is bussed into the board with two M3 Screw Terminals. The board is not polarity protected. Data is delivered on two Automatakit Ports, which each include a data line (uart TX / RX) and clock lines (CLKIN and CLKOUT).
This diff is collapsed.
This diff is collapsed.
File added
File added
[Eagle]
Version="09 00 00"
Platform="Windows"
Globals="Globals"
Desktop="Desktop"
[Globals]
AutoSaveProject=1
UsedLibraryUrn="urn:adsk.eagle:library:217"
UsedLibraryUrn="urn:adsk.eagle:library:325"
UsedLibraryUrn="urn:adsk.eagle:library:371"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/connector.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/fab.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/lights.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/microcontrollers.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/motors.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/passives.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/power.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/sensor.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFun-Connectors.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/jake/tag-connect-2050.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Comparators.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Digital.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/FilterProducts.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Misc.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Opamps.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Optos.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/PAsystem.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/PowerProducts.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/References.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/SpecialFunctions.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/capmeter.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/diode.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-spice-simulation.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-supply.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/rload.lbr"
UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr"
UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr"
[Win_1]
Type="Library Editor"
Number=3
File="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/power.lbr"
View="-17.9019 -28.255 28.0619 27.747"
WireWidths=" 0.0762 0.1016 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524 0.127"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778 1.27"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635 1 0.65 0.65 1"
WireBend=0
WireBendSet=0
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=0
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=94
[Win_2]
Type="Schematic Editor"
Number=1
File="atkstepper23.sch"
View="25.599 215.424 140.52 289.478"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
WireBend=4
WireBendSet=31
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=0
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=97
Views=" 1: 25.599 215.424 140.52 289.478"
Sheet="1"
[Win_3]
Type="Board Editor"
Number=2
File="atkstepper23.brd"
View="12.552 -19.0104 103.119 77.4063"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.254 0.508 1.016 1.27 2.54 0.8128 0.6096 0.4064 0.2032 0.3048 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0"
ViaDrills=" 0.2 0.25 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35 0.3"
HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35"
TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778"
PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27"
PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0"
DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13"
DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0"
DimensionExtLengths=" 1.27 2.54 1 2 3 0"
DimensionExtOffsets=" 1.27 2.54 1 2 3 0"
SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635"
WireBend=3
WireBendSet=0
WireCap=1
MiterStyle=0
PadShape=0
ViaShape=1
PolygonPour=0
PolygonRank=1
PolygonThermals=1
PolygonOrphans=0
TextRatio=8
DimensionUnit=1
DimensionPrecision=2
DimensionShowUnit=0
PinDirection=3
PinFunction=0
PinLength=2
PinVisible=3
SwapLevel=0
ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=1
[Win_4]
Type="Control Panel"
Number=0
[Desktop]
Screen="3840 1080"
Window="Win_1"
Window="Win_2"
Window="Win_3"
Window="Win_4"
File added
File added
File added
File added
File added
# AutomataKit Stepper23 Embedded Notes
Firmware for the board follows the [automatakit](https://gitlab.cba.mit.edu/jakeread/automatakit) architecture, and is available here for perusal.
Communication is handled asynchronously: bytes received on the UART are loaded into a ringbuffer, where they are later parsed in to packets. Parsing happens as oven as possible.
Two hardware timers run step timing, one fires every time a step is to be taken, and another fires when acceleration needs to happen, the 2nd timer changes the period of the 1st.
\ No newline at end of file
/*
* atkhandler.c
*
* Created: 3/12/2018 11:55:30 AM
* Author: Jake
*/
#include "hardware.h"
#include "atkhandler.h"
int32_t steps;
void atk_handle_packet(uint8_t *packet, uint8_t length){
// dirty debug reply
//atk_return_packet(packet, length);
// through packet
int i = 0;
int atk_handler_state = ATK_HANDLER_OUTSIDE;
uint8_t testReply[4] = {127, 12, 24, 48};
while(i < length){ // prep for the messy double switch :|
switch (atk_handler_state){
case ATK_HANDLER_OUTSIDE:
if (packet[i] == ATK_END_ROUTE_DELIMITER){
atk_handler_state = ATK_HANDLER_INSIDE;
}
i ++;
break;
case ATK_HANDLER_INSIDE:
switch (packet[i]){
case DELIM_KEY_TEST:
pin_toggle(&stlerr);
// see the packet, make sure you're not doing something else with this light
atk_reply_packet(packet, testReply, 4);
i ++;
break;
case DELIM_KEY_RESET:
CCP = CCP_IOREG_gc;
RST.CTRL = RST_SWRST_bm;
break;
case DELIM_KEY_TRAPEZOID:
//pin_toggle(&stlerr);
if(i + 12 > length){
i ++;
} else {
// in steps (discrete)
steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4];
// in steps/s
uint32_t entryspeed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8];
// in steps/min/s
uint32_t accel = ((int32_t)packet[i+9] << 24) | ((int32_t)packet[i+10] << 16) | ((int32_t)packet[i+11] << 8) | (int32_t)packet[i+12];
// in steps/min
uint32_t accellength = ((int32_t)packet[i+13] << 24) | ((int32_t)packet[i+14] << 16) | ((int32_t)packet[i+15] << 8) | (int32_t)packet[i+16];
// in steps/min
uint32_t deccellength = ((int32_t)packet[i+17] << 24) | ((int32_t)packet[i+18] << 16) | (int32_t)(packet[i+19] << 8) | (int32_t)packet[i+20];
// do the business
i += 21;
stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength);
}
break;
case DELIM_KEY_WAIT:
if(i + 8 > length){
i ++;
} else {
steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4];
// in steps/s
uint32_t speed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8];
i += 8;
stepper_new_wait(packet, &stepper, steps, speed);
}
default:
// probably an error
i ++;
break;
} // end interior switch
break;
default :
// throw err
break;
} // end y/n switch
}
}
// HERE return with address header, or from old packet with new data
uint8_t ackPack[256];
void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength){
// find address chunk in opPacket
int i = 2;
int stop = 0;
while(i < opPacket[0]){
if(opPacket[i] == ATK_END_ROUTE_DELIMITER){
stop = i;
break;
}
i ++;
}
uint8_t ackLength = stop + replyLength + 1;
ackPack[0] = ackLength;
if(stop){
// reverse the address header
for(int a = stop - 1, b = 1; a >= 1; a--, b++){
ackPack[b] = opPacket[a];
}
// and append the end block
ackPack[stop] = ATK_END_ROUTE_DELIMITER;
// now fill with provided reply data
for(int u = 0; u <= replyLength; u ++){
ackPack[u + stop + 1] = replyData[u];
}
// checking the port exists, send it out
if(ackPack[1] >= SYSTEM_NUM_UPS){
ackPack[1] = SYSTEM_NUM_UPS - 1;
}
uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]);//ups[ackPack[1]], ackPack, ackLength);
}
}
void atk_return_packet(uint8_t *packet, uint8_t length){
//uart_sendchar_buffered(ups[1], 120);
//uart_sendchars_buffered(ups[1], packet, length);
// using this placeholder
ackPack[0] = length;
// find route header
int i = 2;
int stop = 0;
while(i < length){
if(packet[i] == ATK_END_ROUTE_DELIMITER){
stop = i;
break;
}
i ++;
}
// do the business
if(stop){
// reverse the address header
for(int a = stop - 1, b = 1; a >= 1; a--, b++){
ackPack[b] = packet[a];
}
// fill the rest with same packet data
ackPack[stop] = ATK_END_ROUTE_DELIMITER;
for(int u = stop; u < length; u ++){
ackPack[u] = packet[u];
}
// checking the packet exists, send it out
if(ackPack[1] >= SYSTEM_NUM_UPS){
ackPack[1] = SYSTEM_NUM_UPS - 1;
}
uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]);
// NOW:
// looking for justice: why no return packet on double length hop?
// debug with 2nd ftdi
//uart_sendchar_buffered(ups[1], 121);
//uart_sendchars_buffered(ups[1], ackpack, length);
}
}
\ No newline at end of file
/*
* atkhandler.h
*
* Created: 3/12/2018 11:55:40 AM
* Author: Jake
*/
#ifndef ATKHANDLER_H_
#define ATKHANDLER_H_
#include <avr/io.h>
#define ATK_HANDLER_OUTSIDE 0
#define ATK_HANDLER_INSIDE 1
#define DELIM_KEY_TEST 127 // toggles a light, to test network
#define DELIM_KEY_RESET 128
#define DELIM_KEY_TRAPEZOID 131
#define DELIM_KEY_WAIT 132
void atk_handle_packet(uint8_t *packet, uint8_t length);
void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength);
void atk_return_packet(uint8_t *packet, uint8_t length);
#endif /* atkHANDLER_H_ */
\ No newline at end of file
/*
* atkport.c
*
* Created: 2/23/2018 9:17:48 AM
* Author: Jake
*/
#include "atkport.h"
#include "hardware.h"
#include "fastmath.h"
void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart){
atkp->uart = uart;
atkp->portnum = portnum;
atkport_reset(atkp);
}
void atkport_reset(atkport_t *atkp){
atkp->packet_num = 0;
atkp->packets_ready = 0;
atkp->packet_state = ATKPORT_OUTSIDE_PACKET;
atkp->packet_position = 0;
pin_set(atkp->uart->stlrx);
pin_set(atkp->uart->stltx);
}
void atkport_scan(atkport_t *atkp, uint32_t maxpackets){
// scan through for completely received packets
while(atkp->packets_ready <= maxpackets){
// check that we have bytes to read out of the buffer
if(atkp->uart->rbrx->head == atkp->uart->rbrx->tail){ // direct access, rather than through rbempty() shaves 2us
pin_set(atkp->uart->stlrx);
break;
} else {
// pull bytes out of buffer into the packet structure
atkp->packets[atkp->packet_num][atkp->packet_position] = rb_get(atkp->uart->rbrx);
atkp->packet_position ++;
// now segment, point to them
if(atkp->packet_position >= atkp->packets[atkp->packet_num][0]){
// length is 1st byte, like array[n] not array[n-1]
// now volley for next pass
// packet_num is index of head of packet buffer (just an array)
atkp->packet_num = fastModulo((atkp->packet_num + 1), ATKPORT_NUM_STATIC_PACKETS); // inc. and loop
// packets_ready is the number of ready-state packets in that buffer (array)
atkp->packets_ready ++;
// the position, in bytes, where we are currently operating.
// at this point, we have come to the end, so we're resetting counter for the next
atkp->packet_position = 0;
}
}
}
// end 1st scan for packets, now we know we have atkport->packet_num packets completely received
// now we handle those packets
while(atkp->packets_ready > 0){
// the particular packet index
uint32_t p = fastModulo((atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready), ATKPORT_NUM_STATIC_PACKETS); //(atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready) % ATKPORT_NUM_STATIC_PACKETS;
// first we shift the old pointer out (p[1] is, at the moment, the port the last node tx'd on)
atkpacket_shift_pointer(atkp->packets[p], atkp->portnum);
// now p[1] is next port
// now to handle
// [p][0] is length of packet
if(atkp->packets[p][1] == ATK_ROUTE_POINTER){
atk_handle_packet(atkp->packets[p], atkp->packets[p][0]);
} else if(atkp->packets[p][1] == ATK_ROUTE_FLOOD){
// loop through bytes to find pointer and increment
// now ship it out on all ports
for(int i = 0; i < ATKPORT_NUM_PORTS; i ++){
if(i == atkp->portnum){
// don't flood back
} else {
uart_sendchars_buffered(ups[i], atkp->packets[p], atkp->packets[p][0]);
}
}
} else {
// packet is for a particular port,
if(atkp->packets[p][1] > ATKPORT_NUM_PORTS){
// port does not exist, throw error
// pin_clear(&stlerr);
} else {
// debug option
//uart_sendchars_buffered(&upU, atkp->packets[p], atkp->packets[p][0]);
uart_sendchars_buffered(ups[atkp->packets[p][1]], atkp->packets[p], atkp->packets[p][0]);
}
}
// debug reply (at the moment, reply is handled in atk_handle_packet
// uart_sendchars_buffered(atkp->uart, atkp->packets[p], atkp->packets[p][0]);
atkp->packets_ready --;
}
}
void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum){
int i = 2;
while(i < packet[0]){ // while less than length
if(packet[i] == ATK_END_ROUTE_DELIMITER){
// put our port in tail
packet[i-1] = portnum;
break;
} else {
// shift 'em down
packet[i-1] = packet[i];
}
i ++;
}
}
void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength){
// 1st byte is port out
// not yet implemented, using atk_return_packet ... all of these could be cleaner
}
// UNIT TESTS:
/*
flood packets
multiple receptions? handle in app?
packets no end addr bar delimiter, packets no pointer, general white noise
packets varying length
packets wrong length ? very hard to catch w/o hella state ... timeout?
packets no end addr delimiter?
packets to ports not existing
// next: write javascript terminal packet builder for unit tests!
*/
\ No newline at end of file
/*
* atkport.h
*
* Created: 2/23/2018 9:17:34 AM
* Author: Jake
*/
#ifndef ATKPORT_H_
#define ATKPORT_H_
#include "uartport.h"
#include "pin.h"
#define ATKPORT_NUM_STATIC_PACKETS 8
#define ATKPORT_NUM_PORTS 6
#define ATKPORT_OUTSIDE_PACKET 0
#define ATKPORT_INSIDE_PACKET 1
#define ATK_END_ROUTE_DELIMITER 255
#define ATK_ROUTE_POINTER 254
#define ATK_ROUTE_FLOOD 253
typedef struct{
uartport_t *uart;
uint8_t portnum; // which port are we
uint32_t packet_num;
uint32_t packet_position;
uint32_t packets_ready;
uint32_t packet_state;
uint8_t packets[ATKPORT_NUM_STATIC_PACKETS][256]; // packets for handling by app
}atkport_t;
void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart);
void atkport_reset(atkport_t *atkp);
void atkport_scan(atkport_t *atkp, uint32_t maxpackets);
void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum);
void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength);
#endif /* atkPORT_H_ */
\ No newline at end of file
/*
* fastmath.c
*
* Created: 6/20/2018 12:38:38 PM
* Author: Jake
*/
int fastModulo(int dividend, int divisor){
// divisor must be a power of 2!
return dividend & (divisor - 1);
}
\ No newline at end of file
/*
* fastmath.h
*
* Created: 6/20/2018 12:35:50 PM
* Author: Jake
*/
#ifndef FASTMATH_H_
#define FASTMATH_H_
int fastModulo(int dividend, int divisor);
#endif /* FASTMATH_H_ */
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment