Commit db68f1c0 authored by Jake Read's avatar Jake Read

add apaports, all functioning

parent 4eba831a
......@@ -38,6 +38,8 @@ SUBDIRS := \
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../apahandler.c \
../apaport.c \
../board_driver_serial.c \
../board_driver_usb.c \
../clock_init.c \
......@@ -60,6 +62,8 @@ ASM_SRCS +=
OBJS += \
apahandler.o \
apaport.o \
board_driver_serial.o \
board_driver_usb.o \
clock_init.o \
......@@ -75,6 +79,8 @@ sam_ba_usb.o \
uartport.o
OBJS_AS_ARGS += \
apahandler.o \
apaport.o \
board_driver_serial.o \
board_driver_usb.o \
clock_init.o \
......@@ -90,6 +96,8 @@ sam_ba_usb.o \
uartport.o
C_DEPS += \
apahandler.d \
apaport.d \
board_driver_serial.d \
board_driver_usb.d \
clock_init.d \
......@@ -105,6 +113,8 @@ sam_ba_usb.d \
uartport.d
C_DEPS_AS_ARGS += \
apahandler.d \
apaport.d \
board_driver_serial.d \
board_driver_usb.d \
clock_init.d \
......@@ -157,6 +167,10 @@ LINKER_SCRIPT_DEP+= \
......
......@@ -2,6 +2,10 @@
# Automatically-generated file. Do not edit or delete the file
################################################################################
apahandler.c
apaport.c
board_driver_serial.c
board_driver_usb.c
......
/*
* apahandler.c
*
* Created: 3/12/2018 11:55:30 AM
* Author: Jake
*/
#include "hardware.h"
#include "apahandler.h"
void apa_handle_packet(uint8_t *packet, uint8_t length){
// dirty debug reply
// through packet
int i = 0;
int apa_handler_state = APA_HANDLER_OUTSIDE;
while(i < length){ // prep for the messy double switch :|
switch (apa_handler_state){
case APA_HANDLER_OUTSIDE:
if (packet[i] == APA_END_ROUTE_DELIMITER){
apa_handler_state = APA_HANDLER_INSIDE;
} else {
//
}
i ++;
break;
case APA_HANDLER_INSIDE:
switch (packet[i]){
case DELIM_KEY_TEST:
apa_return_packet(packet, length);
pin_toggle(&stlErr);
i ++;
break;
default:
// probably an error
i ++;
break;
} // end interior switch
break;
default:
// throw err
break;
} // end y/n switch
}
}
void apa_return_packet(uint8_t *packet, uint8_t length){
//uart_sendchar_buffered(ups[1], 120);
//uart_sendchars_buffered(ups[1], packet, length);
uint8_t ackpack[length];
ackpack[0] = length;
// find route header
int i = 2;
int stop = 0;
while(i < length){
if(packet[i] == APA_END_ROUTE_DELIMITER){
stop = i;
break;
}
i ++;
}
// do the business
if(!stop){
// error if stop == 0
} else {
// 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] = APA_END_ROUTE_DELIMITER;
for(int u = stop; u < length; u ++){
ackpack[u] = packet[u];
}
uart_sendchars_buffered(ups[ackpack[1]], ackpack, length);
// 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
/*
* apahandler.h
*
* Created: 3/12/2018 11:55:40 AM
* Author: Jake
*/
#ifndef APAHANDLER_H_
#define APAHANDLER_H_
#include "sam.h"
#define APA_HANDLER_OUTSIDE 0
#define APA_HANDLER_INSIDE 1
#define DELIM_KEY_TEST 127 // toggles a light, to test network
#define DELIM_KEY_STEPS 128 // steps (steps) uint32_t, speed (steps/s) uint32_t, dir uint8_t
#define DELIM_KEY_BLOCK 129 // is 32 bit int
void apa_handle_packet(uint8_t *packet, uint8_t length);
void apa_return_packet(uint8_t *packet, uint8_t length);
#endif /* APAHANDLER_H_ */
\ No newline at end of file
/*
* apaport.c
*
* Created: 2/23/2018 9:17:48 AM
* Author: Jake
*/
#include "apaport.h"
#include "hardware.h"
apaport_t apaport_new(uint8_t portnum, uartport_t *uart, pin_t *stlr, pin_t *stlb){
apaport_t apap;
apap.uart = uart;
apap.portnum = portnum;
apap.stlr = stlr; // dangerous because stlr is def'nd in hardware.h as well - watch your namespaces
apap.stlb = stlb;
return apap;
}
void apaport_reset(apaport_t *apap){
apap->packet_num = 0;
apap->packets_ready = 0;
apap->packet_state = APAPORT_OUTSIDE_PACKET;
apap->packet_position = 0;
pin_set(apap->stlr);
pin_set(apap->stlb);
}
void apaport_scan(apaport_t *apap, uint32_t maxpackets){
// scan through for completely received packets
while(apap->packets_ready <= maxpackets){
// check that we have bytes to read out of the buffer
if(rb_empty(apap->uart->rbrx)){
pin_set(apap->stlb);
break;
}
// pull bytes out of buffer into the packet structure
apap->packets[apap->packet_num][apap->packet_position] = rb_get(apap->uart->rbrx);
apap->packet_position ++;
// now segment, point to them
if(apap->packet_position >= apap->packets[apap->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)
apap->packet_num = (apap->packet_num + 1) % APAPORT_NUM_STATIC_PACKETS; // inc. and loop
// packets_ready is the number of ready-state packets in that buffer (array)
apap->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
apap->packet_position = 0;
}
}
// end 1st scan for packets, now we know we have apaport->packet_num packets completely received
// now we handle those packets
while(apap->packets_ready > 0){
// the particular packet index
uint32_t p = (apap->packet_num + APAPORT_NUM_STATIC_PACKETS - apap->packets_ready) % APAPORT_NUM_STATIC_PACKETS;
// first we shift the old pointer out (p[1] is, at the moment, the port the last node tx'd on)
apapacket_shift_pointer(apap->packets[p], apap->portnum);
// now p[1] is next port
// now to handle
// [p][0] is length of packet
if(apap->packets[p][1] == APA_ROUTE_POINTER){
apa_handle_packet(apap->packets[p], apap->packets[p][0]);
} else if(apap->packets[p][1] == APA_ROUTE_FLOOD){
// loop through bytes to find pointer and increment
// now ship it out on all ports
for(int i = 0; i < APAPORT_NUM_PORTS; i ++){
if(i == apap->portnum){
// don't flood back
} else {
uart_sendchars_buffered(ups[i], apap->packets[p], apap->packets[p][0]);
}
}
} else {
// packet is for a particular port,
if(apap->packets[p][1] > APAPORT_NUM_PORTS){
// port does not exist, throw error
// pin_clear(&stlr);
} else {
uart_sendchars_buffered(ups[apap->packets[p][1]], apap->packets[p], apap->packets[p][0]);
}
}
// debug reply (at the moment, reply is handled in apa_handle_packet
// uart_sendchars_buffered(apap->uart, apap->packets[p], apap->packets[p][0]);
apap->packets_ready --;
}
}
void apapacket_shift_pointer(uint8_t *packet, uint8_t portnum){
int i = 2;
while(i < packet[0]){ // while less than length
if(packet[i] == APA_END_ROUTE_DELIMITER){
// put our port in tail
packet[i-1] = portnum;
break;
} else {
// shift 'em down
packet[i-1] = packet[i];
}
i ++;
}
}
void apaport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength){
// 1st byte is port out
// not yet implemented, using apa_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
/*
* apaport.h
*
* Created: 2/23/2018 9:17:34 AM
* Author: Jake
*/
#ifndef APAPORT_H_
#define APAPORT_H_
#include "apahandler.h"
#include "uartport.h"
#include "pin.h"
#define APAPORT_NUM_STATIC_PACKETS 3
#define APAPORT_NUM_PORTS 6
#define APAPORT_OUTSIDE_PACKET 0
#define APAPORT_INSIDE_PACKET 1
#define APA_END_ROUTE_DELIMITER 255
#define APA_ROUTE_POINTER 254
#define APA_ROUTE_FLOOD 253
typedef struct{
uartport_t *uart;
pin_t *stlr;
pin_t *stlb;
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[APAPORT_NUM_STATIC_PACKETS][256]; // packets for handling by app
}apaport_t;
apaport_t apaport_new(uint8_t portnum, uartport_t *uart, pin_t *stlr, pin_t *stlb);
void apaport_reset(apaport_t *apap);
void apaport_scan(apaport_t *apap, uint32_t maxpackets);
void apapacket_shift_pointer(uint8_t *packet, uint8_t portnum);
void apaport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength);
#endif /* APAPORT_H_ */
\ No newline at end of file
......@@ -14,6 +14,7 @@
#include "pin.h"
#include "ringbuffer.h"
#include "uartport.h"
#include "apaport.h"
// For if-case init
......@@ -60,8 +61,10 @@ ringbuffer_t up0rbtx;
uartport_t up0;
pin_t up0stlb;
pin_t up0stlr;
apaport_t apap0;
pin_t up0stlb; // on receive
pin_t up0stlr; // on transmit
/*
......@@ -76,6 +79,8 @@ ringbuffer_t up1rbtx;
uartport_t up1;
apaport_t apap1;
pin_t up1stlb;
pin_t up1stlr;
......@@ -91,6 +96,8 @@ ringbuffer_t up2rbtx;
uartport_t up2;
apaport_t apap2;
pin_t up2stlb;
pin_t up2stlr;
......@@ -106,6 +113,8 @@ ringbuffer_t up3rbtx;
uartport_t up3;
apaport_t apap3;
pin_t up3stlb;
pin_t up3stlr;
......@@ -121,6 +130,8 @@ ringbuffer_t up4rbtx;
uartport_t up4;
apaport_t apap4;
pin_t up4stlb;
pin_t up4stlr;
......@@ -136,10 +147,12 @@ ringbuffer_t up5rbtx;
uartport_t up5;
apaport_t apap5;
pin_t up5stlb;
pin_t up5stlr;
// pointers to uarports
// pointers to uartports
#define NUM_UPS 6
uartport_t *ups[NUM_UPS];
......
......@@ -77,7 +77,7 @@ void uarts_init(void){
rb_init(&up0rbrx);
rb_init(&up0rbtx);
// init uart
up0 = uart_new(SERCOM0, &PORT->Group[0], &up0rbrx, &up0rbtx, 5, 4);
up0 = uart_new(SERCOM0, &PORT->Group[0], &up0rbrx, &up0rbtx, &up0stlr, &up0stlb, 5, 4);
MCLK->APBAMASK.bit.SERCOM0_ = 1;
uart_init(&up0, 7, SERCOM0_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -89,7 +89,7 @@ void uarts_init(void){
rb_init(&up1rbrx);
rb_init(&up1rbtx);
// init uart
up1 = uart_new(SERCOM1, &PORT->Group[0], &up1rbrx, &up1rbtx, 1, 0);
up1 = uart_new(SERCOM1, &PORT->Group[0], &up1rbrx, &up1rbtx, &up1stlr, &up1stlb, 1, 0);
MCLK->APBAMASK.bit.SERCOM1_ = 1;
uart_init(&up1, 7, SERCOM1_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -101,7 +101,7 @@ void uarts_init(void){
rb_init(&up2rbrx);
rb_init(&up2rbtx);
// init uart
up2 = uart_new(SERCOM2, &PORT->Group[0], &up2rbrx, &up2rbtx, 8, 9);
up2 = uart_new(SERCOM2, &PORT->Group[0], &up2rbrx, &up2rbtx, &up2stlr, &up2stlb, 8, 9);
MCLK->APBBMASK.bit.SERCOM2_ = 1;
uart_init(&up2, 7, SERCOM2_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -113,7 +113,7 @@ void uarts_init(void){
rb_init(&up3rbrx);
rb_init(&up3rbtx);
// init uart
up3 = uart_new(SERCOM3, &PORT->Group[0], &up3rbrx, &up3rbtx, 16, 17);
up3 = uart_new(SERCOM3, &PORT->Group[0], &up3rbrx, &up3rbtx, &up3stlr, &up3stlb, 16, 17);
MCLK->APBBMASK.bit.SERCOM3_ = 1;
uart_init(&up3, 7, SERCOM3_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -125,7 +125,7 @@ void uarts_init(void){
rb_init(&up4rbrx);
rb_init(&up4rbtx);
// init uart
up4 = uart_new(SERCOM4, &PORT->Group[0], &up4rbrx, &up4rbtx, 12, 13);
up4 = uart_new(SERCOM4, &PORT->Group[0], &up4rbrx, &up4rbtx, &up4stlr, &up4stlb, 12, 13);
MCLK->APBDMASK.bit.SERCOM4_ = 1;
uart_init(&up4, 7, SERCOM4_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -137,7 +137,7 @@ void uarts_init(void){
rb_init(&up5rbrx);
rb_init(&up5rbtx);
// uart init
up5 = uart_new(SERCOM5, &PORT->Group[0], &up5rbrx, &up5rbtx, 22, 23);
up5 = uart_new(SERCOM5, &PORT->Group[0], &up5rbrx, &up5rbtx, &up5stlr, &up5stlb, 22, 23);
MCLK->APBDMASK.bit.SERCOM5_ = 1;
uart_init(&up5, 7, SERCOM5_GCLK_ID_CORE, BAUD_SYSTEM, HARDWARE_ON_PERIPHERAL_D);
......@@ -151,6 +151,26 @@ void uarts_init(void){
ups[5] = &up5;
}
void apaports_init(void){
apap0 = apaport_new(0, &up0, &up0stlr, &up0stlb);
apaport_reset(&apap0);
apap1 = apaport_new(1, &up1, &up1stlr, &up1stlb);
apaport_reset(&apap1);
apap2 = apaport_new(2, &up2, &up2stlr, &up2stlb);
apaport_reset(&apap2);
apap3 = apaport_new(3, &up3, &up3stlr, &up3stlb);
apaport_reset(&apap3);
apap4 = apaport_new(4, &up4, &up4stlr, &up4stlb);
apaport_reset(&apap4);
apap5 = apaport_new(5, &up5, &up5stlr, &up5stlb);
apaport_reset(&apap5);
}
static volatile bool main_b_cdc_enable = false;
int main(void)
......@@ -166,6 +186,9 @@ int main(void)
// init uartports
uarts_init();
// init apaports
apaports_init();
// pointer to the USB struct in sam_ba_usb.h
P_USB_CDC pCdc;
......@@ -191,6 +214,16 @@ int main(void)
// loops on this
while(1){
sam_ba_monitor_run();
apaport_scan(&apap0, 2);
apaport_scan(&apap1, 2);
apaport_scan(&apap2, 2);
apaport_scan(&apap3, 2);
apaport_scan(&apap4, 2);
apaport_scan(&apap5, 2);
/*
while(!rb_empty(up0.rbrx)){
uart_sendchar_buffered(&up0, rb_get(up0.rbrx));
}
......@@ -214,6 +247,7 @@ int main(void)
while(!rb_empty(up5.rbrx)){
uart_sendchar_buffered(&up5, rb_get(up5.rbrx));
}
*/
//uart_sendchars_buffered(&up0, &testUart, 3);
// apaport loops
}
......
......@@ -159,6 +159,18 @@
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="apahandler.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="apahandler.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="apaport.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="apaport.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="board_definitions.h">
<SubType>compile</SubType>
</Compile>
......
......@@ -8,7 +8,7 @@
#include "uartport.h"
#include "hardware.h"
uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, uint32_t rx_pin, uint32_t tx_pin){
uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, pin_t *stlr, pin_t *stlb, uint32_t rx_pin, uint32_t tx_pin){
uartport_t uart;
// pointers to com and port
......@@ -19,6 +19,10 @@ uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer
uart.rbrx = rbrx;
uart.rbtx = rbtx;
// and lights!
uart.stlr = stlr;
uart.stlb = stlb;
// pins
uart.pinrx = rx_pin;
uart.pinrx_bm = (uint32_t)(1 << rx_pin);
......@@ -78,19 +82,23 @@ void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t
void uart_sendchar_polled(uartport_t *uart, uint8_t data){
while(!uart->com->USART.INTFLAG.bit.DRE);
uart->com->USART.DATA.reg = data;
pin_clear(uart->stlr);
}
void uart_sendchar_buffered(uartport_t *uart, uint8_t data){
rb_putchar(uart->rbtx, data); // dump it in there
pin_clear(uart->stlr);
uart->com->USART.INTENSET.bit.DRE = 1; // set up the volley
}
void uart_sendchars_buffered(uartport_t *uart, uint8_t *data, uint8_t length){
rb_putdata(uart->rbtx, data, length);
pin_clear(uart->stlr);
uart->com->USART.INTENSET.bit.DRE = 1;
}
void uart_rxhandler(uartport_t *uart){
pin_clear(uart->stlb);
uint8_t data = uart->com->USART.DATA.reg;
rb_putchar(uart->rbrx, data);
}
......@@ -100,5 +108,6 @@ void uart_txhandler(uartport_t *uart){
uart->com->USART.DATA.reg = rb_get(uart->rbtx);
} else {
uart->com->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
pin_set(uart->stlr);
}
}
\ No newline at end of file
......@@ -30,7 +30,7 @@ typedef struct{
uint16_t baud;
}uartport_t;
uartport_t uart_new(Sercom *com, PortGroup *port, ringbuffer_t *rbrx, ringbuffer_t *rbtx, uint32_t rx_pin, uint32_t tx_pin);
uartport_t uart_new(