diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile index c430e4761704beffd30893aaf7e410bb43c1d9c2..fdc3c7424782c7830aef674a56500499014614b1 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile +++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/Makefile @@ -45,10 +45,12 @@ C_SRCS += \ ../Device_Startup/system_samd51.c \ ../main.c \ ../pin.c \ +../ringbuffer.c \ ../sam_ba_cdc.c \ ../sam_ba_monitor.c \ ../sam_ba_serial.c \ -../sam_ba_usb.c +../sam_ba_usb.c \ +../uartport.c PREPROCESSING_SRCS += @@ -65,10 +67,12 @@ Device_Startup/startup_samd51.o \ Device_Startup/system_samd51.o \ main.o \ pin.o \ +ringbuffer.o \ sam_ba_cdc.o \ sam_ba_monitor.o \ sam_ba_serial.o \ -sam_ba_usb.o +sam_ba_usb.o \ +uartport.o OBJS_AS_ARGS += \ board_driver_serial.o \ @@ -78,10 +82,12 @@ Device_Startup/startup_samd51.o \ Device_Startup/system_samd51.o \ main.o \ pin.o \ +ringbuffer.o \ sam_ba_cdc.o \ sam_ba_monitor.o \ sam_ba_serial.o \ -sam_ba_usb.o +sam_ba_usb.o \ +uartport.o C_DEPS += \ board_driver_serial.d \ @@ -91,10 +97,12 @@ Device_Startup/startup_samd51.d \ Device_Startup/system_samd51.d \ main.d \ pin.d \ +ringbuffer.d \ sam_ba_cdc.d \ sam_ba_monitor.d \ sam_ba_serial.d \ -sam_ba_usb.d +sam_ba_usb.d \ +uartport.d C_DEPS_AS_ARGS += \ board_driver_serial.d \ @@ -104,10 +112,12 @@ Device_Startup/startup_samd51.d \ Device_Startup/system_samd51.d \ main.d \ pin.d \ +ringbuffer.d \ sam_ba_cdc.d \ sam_ba_monitor.d \ sam_ba_serial.d \ -sam_ba_usb.d +sam_ba_usb.d \ +uartport.d OUTPUT_FILE_PATH +=mkrouter-v06.elf @@ -143,6 +153,10 @@ LINKER_SCRIPT_DEP+= \ + + + + diff --git a/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk index 076dc79f97e6694e90e95a3a8badf2416f58dba5..d406fcafcbee6196ac6b20a452cd51430e99949c 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk +++ b/embedded/mkrouter-v06/mkrouter-v06/Debug/makedep.mk @@ -16,6 +16,8 @@ main.c pin.c +ringbuffer.c + sam_ba_cdc.c sam_ba_monitor.c @@ -24,3 +26,5 @@ sam_ba_serial.c sam_ba_usb.c +uartport.c + diff --git a/embedded/mkrouter-v06/mkrouter-v06/hardware.h b/embedded/mkrouter-v06/mkrouter-v06/hardware.h index fdf9962a468bedba82fa5b2c8c473fbb1d3506f8..419516020757a63bc07b4844c069012ff6082438 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/hardware.h +++ b/embedded/mkrouter-v06/mkrouter-v06/hardware.h @@ -12,6 +12,20 @@ #define HARDWARE_H_ #include "pin.h" +#include "ringbuffer.h" +#include "uartport.h" + +// For if-case init + +#define HARDWARE_IS_APBA 0 +#define HARDWARE_IS_APBB 1 +#define HARDWARE_IS_APBC 2 +#define HARDWARE_IS_APBD 3 + +#define HARDWARE_ON_PERIPHERAL_A 0x0 +#define HARDWARE_ON_PERIPHERAL_B 0x1 +#define HARDWARE_ON_PERIPHERAL_C 0x2 +#define HARDWARE_ON_PERIPHERAL_D 0x3 /* USB PINS @@ -39,6 +53,10 @@ UP0STLB PB22 (on receive) UP0STLR PB31 (on transmit) */ +ringbuffer_t up0rbrx; +ringbuffer_t up0rbtx; + +uartport_t up0; pin_t up0stlb; pin_t up0stlr; @@ -51,6 +69,10 @@ UP1STLB PA20 UP1STLR PA21 */ +ringbuffer_t up1rbrx; +ringbuffer_t up1rbtx; + +uartport_t up1; pin_t up1stlb; pin_t up1stlr; @@ -62,6 +84,10 @@ UP2STLB PB16 UP2STLR PB17 */ +ringbuffer_t up2rbrx; +ringbuffer_t up2rbtx; + +uartport_t up2; pin_t up2stlb; pin_t up2stlr; @@ -73,6 +99,10 @@ UP3STLB PA18 UP3STLR PA19 */ +ringbuffer_t up3rbrx; +ringbuffer_t up3rbtx; + +uartport_t up3; pin_t up3stlb; pin_t up3stlr; @@ -84,6 +114,10 @@ UP4STLB PA14 UP4STLR PA15 */ +ringbuffer_t up4rbrx; +ringbuffer_t up4rbtx; + +uartport_t up4; pin_t up4stlb; pin_t up4stlr; @@ -95,9 +129,16 @@ UP5STLB PB13 UP5STLR PB14 */ +ringbuffer_t up5rbrx; +ringbuffer_t up5rbtx; + +uartport_t up5; pin_t up5stlb; pin_t up5stlr; +// pointers to uarports +#define NUM_UPS 6 +uartport_t *ups[NUM_UPS]; #endif /* HARDWARE_H_ */ \ No newline at end of file diff --git a/embedded/mkrouter-v06/mkrouter-v06/main.c b/embedded/mkrouter-v06/mkrouter-v06/main.c index eee87c24c3946c2eb89983788e5ef518d1a613ba..5df55ee8c4573c3cea2201ce621c598c463108da 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/main.c +++ b/embedded/mkrouter-v06/mkrouter-v06/main.c @@ -69,6 +69,60 @@ void lights_init(void){ pin_set(&up5stlr); } +void uarts_init(void){ + // don't forget to also add the handler + NVIC_EnableIRQ(SERCOM0_0_IRQn); + NVIC_EnableIRQ(SERCOM0_2_IRQn); + + // init rbs + rb_init(&up0rbrx); + rb_init(&up0rbtx); + + // init uart + up0 = uart_new(SERCOM0, &PORT->Group[0], &up0rbrx, &up0rbtx, 5, 4); + MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; + uart_init(&up0, 7, SERCOM0_GCLK_ID_CORE, 63018, HARDWARE_ON_PERIPHERAL_D); + + + + // init rbs + rb_init(&up1rbrx); + rb_init(&up1rbtx); + + + + // init rbs + rb_init(&up2rbrx); + rb_init(&up2rbtx); + + + + + // init rbs + rb_init(&up3rbrx); + rb_init(&up3rbtx); + + + + + // init rbs + rb_init(&up4rbrx); + rb_init(&up4rbtx); + + + // init rbs + rb_init(&up5rbrx); + rb_init(&up5rbtx); + + // now pack all into ups + ups[0] = &up0; + ups[1] = &up1; + ups[2] = &up2; + ups[3] = &up3; + ups[4] = &up4; + ups[5] = &up5; +} + static volatile bool main_b_cdc_enable = false; int main(void) @@ -81,6 +135,9 @@ int main(void) __enable_irq(); lights_init(); + + // init uartports + uarts_init(); // pointer to the USB struct in sam_ba_usb.h P_USB_CDC pCdc; @@ -94,22 +151,26 @@ int main(void) /* Replace with your application code */ while (1) { - // waits for config to config if(pCdc->IsConfigured(pCdc) != 0){ main_b_cdc_enable = true; - pin_clear(&stlUsb); } + uint8_t testUart[3] = {12,24,48}; + // if config is config, and port is opened if(main_b_cdc_enable){ sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC); // loops on this while(1){ sam_ba_monitor_run(); - // @ HERE: understand how this /\ runs, looks through buffer etc... - // do the same for (1) bytes -> uart - // (2) for packet searching + for(int i = 0; i < NUM_UPS; i ++){ + while(!rb_empty(up0.rbrx)){ + uart_sendchar_buffered(&up0, rb_get(up0.rbrx)); + } + } + //uart_sendchars_buffered(&up0, &testUart, 3); + // apaport loops } } @@ -138,3 +199,11 @@ void SysTick_Handler(void){ */ // monitor_sys_tick } + +void SERCOM0_0_Handler(void){ + uart_txhandler(&up0); +} + +void SERCOM0_2_Handler(void){ + uart_rxhandler(&up0); +} \ No newline at end of file diff --git a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj index 26fc1eba881cceb7a30e7d3b790814a68cfd3c71..88e975f1dbbf0d66173f6dd00e3d70524ae8d92f 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj +++ b/embedded/mkrouter-v06/mkrouter-v06/mkrouter-v06.cproj @@ -195,6 +195,12 @@ <Compile Include="pin.h"> <SubType>compile</SubType> </Compile> + <Compile Include="ringbuffer.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="ringbuffer.h"> + <SubType>compile</SubType> + </Compile> <Compile Include="sam_ba_cdc.c"> <SubType>compile</SubType> </Compile> @@ -219,6 +225,12 @@ <Compile Include="sam_ba_usb.h"> <SubType>compile</SubType> </Compile> + <Compile Include="uartport.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="uartport.h"> + <SubType>compile</SubType> + </Compile> </ItemGroup> <ItemGroup> <Folder Include="Device_Startup\" /> diff --git a/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..eeb5367b5c96b6b701ed74827c3d608dd1297e32 --- /dev/null +++ b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.c @@ -0,0 +1,71 @@ +/* + * ringbuffer.c + * + * Created: 2/7/2018 11:39:44 AM + * Author: Jake + */ + +#include "ringbuffer.h" + +uint8_t rb_init(ringbuffer_t *rb){ + rb->size = RINGBUFFER_SIZE; // stuck with this, due to not having malloc, wall of skill + //rb->buffer = malloc(size); + rb_reset(rb); + return 1; +} + +uint8_t rb_reset(ringbuffer_t *rb){ + if(rb){ + rb->head = 0; + rb->tail = 0; + return 1; + } else { + return 0; + } +} + +uint8_t rb_empty(ringbuffer_t *rb){ + return (rb->head == rb->tail); +} + +uint8_t rb_full(ringbuffer_t *rb){ + // read from tail, update at head + // if head is 'just behind' tail (in ring) we have no extra space: the + return ((rb->head + 1) % rb->size) == rb->tail; +} + +uint8_t rb_freespace(ringbuffer_t *rb){ + if(rb->head >= rb->tail){ + return rb->size - (rb->head - rb->tail); + } else { + return rb->tail - rb->head - 1; + } +} + +uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data){ + rb->buffer[rb->head] = data; + rb->head = (rb->head + 1) % rb->size; // increment and loop about + return 1; +} + +uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size){ + /* + if(rb_freespace(rb) >= size){ + // rb_freespace, not working? + return 0; + } else { + */ + for(int i = 0; i < size; i ++){ + rb_putchar(rb, data[i]); + } + + return 1; + //} +} + +uint8_t rb_get(ringbuffer_t *rb){ + uint8_t data = rb->buffer[rb->tail]; + rb->tail = (rb->tail + 1) % rb->size; + return data; +} + diff --git a/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.h b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..889caf979a5507fdc801c147712e75a3f6279000 --- /dev/null +++ b/embedded/mkrouter-v06/mkrouter-v06/ringbuffer.h @@ -0,0 +1,44 @@ +/* + * ringbuffer.h + * + * Created: 2/7/2018 11:39:54 AM + * Author: Jake + */ + +#ifndef RINGBUFFER_H_ +#define RINGBUFFER_H_ + +/* +a ringbuffer, +s/o https://github.com/dhess/c-ringbuf +s/o https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc +s/o https://www.downtowndougbrown.com/2013/01/microcontrollers-interrupt-safe-ring-buffers/ +*/ + +#include "sam.h" + +#include <stdlib.h> // for size_t + +#define RINGBUFFER_SIZE 256 + +typedef struct{ + uint8_t buffer[256]; // static! big enough + size_t head; + size_t tail; + size_t size; +} ringbuffer_t; + +uint8_t rb_init(ringbuffer_t *rb); + +uint8_t rb_reset(ringbuffer_t *rb); + +uint8_t rb_empty(ringbuffer_t *rb); +uint8_t rb_full(ringbuffer_t *rb); +uint8_t rb_freespace(ringbuffer_t *rb); + +uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data); +uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size); + +uint8_t rb_get(ringbuffer_t *rb); + +#endif /* RINGBUFFER_H_ */ \ No newline at end of file diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c index 79c5ede56024ba151ddee101371786e4fb97ffa5..c5c486988050a9609319f8893ef35f3242664f27 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c +++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.c @@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "sam_ba_cdc.h" //#include "board_driver_led.h" +#include "hardware.h" + const char RomBOOT_Version[] = SAM_BA_VERSION; const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]"; @@ -277,19 +279,33 @@ static void sam_ba_monitor_loop(void) { // get bytes, handle.. length = sam_ba_getdata(ptr_monitor_if, data, SIZEBUFMAX); + pin_clear(&stlPacket); + if(length > 0 && !usbComOpen){ usbComOpen = 1; + pin_clear(&stlUsb); } // reply sam_ba_putdata(ptr_monitor_if, data, length); + // have to implement APA code here? and watch for multipackets? + for(int i = 0; i < length; i ++, ptr++){ + // apa + } + pin_set(&stlPacket); + // dirt nasty heartbeat + /* if(!(tick % 100000)){ sam_ba_putdata(ptr_monitor_if, &data_out, 3); } tick ++; - + */ +} + +void sam_ba_port_put_data(uint8_t *data, uint32_t length){ + sam_ba_putdata(ptr_monitor_if, data, length); } void sam_ba_monitor_sys_tick(void) @@ -308,6 +324,7 @@ void sam_ba_monitor_sys_tick(void) */ void sam_ba_monitor_run(void) { + /* uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 }; PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ]; PAGES = NVMCTRL->PARAM.bit.NVMP; @@ -315,8 +332,7 @@ void sam_ba_monitor_run(void) ptr_data = NULL; command = 'z'; - while (1) - { - sam_ba_monitor_loop(); - } + */ + + sam_ba_monitor_loop(); } diff --git a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h index 6cfa4db0358f6231cbc70cf1439b3a4e049a4326..d42375b562bd1e07fcc7c84fbff4bade7a092d36 100644 --- a/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h +++ b/embedded/mkrouter-v06/mkrouter-v06/sam_ba_monitor.h @@ -57,6 +57,8 @@ void sam_ba_monitor_sys_tick(void); */ void sam_ba_monitor_run(void); +void sam_ba_port_put_data(uint8_t *data, uint32_t length); + /** * \brief * diff --git a/embedded/mkrouter-v06/mkrouter-v06/uartport.c b/embedded/mkrouter-v06/mkrouter-v06/uartport.c new file mode 100644 index 0000000000000000000000000000000000000000..aef6907118cad57688c1143ca1bf3d52e56c0a55 --- /dev/null +++ b/embedded/mkrouter-v06/mkrouter-v06/uartport.c @@ -0,0 +1,104 @@ +/* + * uartport.c + * + * Created: 2/6/2018 10:48:26 AM + * Author: Jake + */ + +#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; + + // pointers to com and port + uart.com = com; + uart.port = port; + + // add ringbuffers + uart.rbrx = rbrx; + uart.rbtx = rbtx; + + // pins + uart.pinrx = rx_pin; + uart.pinrx_bm = (uint32_t)(1 << rx_pin); + uart.pintx = tx_pin; + uart.pintx_bm = (uint32_t)(1 << tx_pin); + + return uart; +} + +void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud, uint32_t peripheral){ + // rx pin setups + uart->port->DIRCLR.reg = uart->pinrx_bm; + uart->port->PINCFG[uart->pinrx].bit.PMUXEN = 1; + if(uart->pinrx % 2){ // yes if odd + uart->port->PMUX[uart->pinrx >> 1].reg |= PORT_PMUX_PMUXO(peripheral); + } else { + uart->port->PMUX[uart->pinrx >> 1].reg |= PORT_PMUX_PMUXE(peripheral); + } + // tx pin setups + uart->port->DIRSET.reg = uart->pintx_bm; + uart->port->PINCFG[uart->pintx].bit.PMUXEN = 1; + if(uart->pintx % 2){ // yes if odd + uart->port->PMUX[uart->pintx >> 1].reg |= PORT_PMUX_PMUXO(peripheral); + } else { + uart->port->PMUX[uart->pintx >> 1].reg |= PORT_PMUX_PMUXE(peripheral); + } + + // unmask the clock + // -> have to do this manually b/c unfavourable api + GCLK->GENCTRL[gclknum].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN; + while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(gclknum)); + GCLK->PCHCTRL[gclkidcore].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclknum); + // now the sercom + while(uart->com->USART.SYNCBUSY.bit.ENABLE); + uart->com->USART.CTRLA.bit.ENABLE = 0; + while(uart->com->USART.SYNCBUSY.bit.SWRST); + uart->com->USART.CTRLA.bit.SWRST = 1; + while(uart->com->USART.SYNCBUSY.bit.SWRST); + while(uart->com->USART.SYNCBUSY.bit.SWRST || SERCOM5->USART.SYNCBUSY.bit.ENABLE); + + uart->com->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0); + while(uart->com->USART.SYNCBUSY.bit.CTRLB); + uart->com->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0); + /* + BAUD = 65536*(1-S*(fBAUD/fref)) + where S is samples per bit, 16 for async uart + where fBAUD is the rate that you want + where fref is the peripheral clock from GCLK, in this case (and most) 48MHz + */ + uart->com->USART.BAUD.reg = baud; + while(uart->com->USART.SYNCBUSY.bit.ENABLE); + uart->com->USART.CTRLA.bit.ENABLE = 1; + + uart->com->USART.INTENSET.bit.RXC = 1; // set receive interrupt on, see 34.6.4.2 +} + +void uart_sendchar_polled(uartport_t *uart, uint8_t data){ + while(!uart->com->USART.INTFLAG.bit.DRE); + uart->com->USART.DATA.reg = data; +} + +void uart_sendchar_buffered(uartport_t *uart, uint8_t data){ + rb_putchar(uart->rbtx, data); // dump it in there + 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); + uart->com->USART.INTENSET.bit.DRE = 1; +} + +void uart_rxhandler(uartport_t *uart){ + uint8_t data = uart->com->USART.DATA.reg; + rb_putchar(uart->rbrx, data); +} + +void uart_txhandler(uartport_t *uart){ + if(!rb_empty(uart->rbtx)){ + uart->com->USART.DATA.reg = rb_get(uart->rbtx); + } else { + uart->com->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE; + } +} \ No newline at end of file diff --git a/embedded/mkrouter-v06/mkrouter-v06/uartport.h b/embedded/mkrouter-v06/mkrouter-v06/uartport.h new file mode 100644 index 0000000000000000000000000000000000000000..be3da1592b7f9086e0d55cc0e224bf2ca7db5cb7 --- /dev/null +++ b/embedded/mkrouter-v06/mkrouter-v06/uartport.h @@ -0,0 +1,44 @@ +/* + * uartport.h + * + * Created: 2/6/2018 10:47:56 AM + * Author: Jake + */ + +#ifndef UARTPORT_H_ +#define UARTPORT_H_ + +#include "sam.h" +#include "ringbuffer.h" +#include "pin.h" + +typedef struct{ + Sercom *com; + PortGroup *port; + + uint32_t pinrx; + uint32_t pinrx_bm; + uint32_t pintx; + uint32_t pintx_bm; + + ringbuffer_t *rbrx; + ringbuffer_t *rbtx; + + pin_t *stlr; + pin_t *stlb; + + 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); + +void uart_init(uartport_t *uart, uint32_t gclknum, uint32_t gclkidcore, uint16_t baud, uint32_t peripheral); + +void uart_sendchar_polled(uartport_t *uart, uint8_t data); +void uart_sendchar_buffered(uartport_t *uart, uint8_t data); +void uart_sendchars_buffered(uartport_t *uart, uint8_t *data, uint8_t length); + +void uart_rxhandler(uartport_t *uart); +void uart_txhandler(uartport_t *uart); + +#endif /* UARTPORT_H_ */ \ No newline at end of file