I thought you guys might find the code interesting, so I'm uploading it to our GitHub repo as I go This is very early and very still-in-process.
Here are the first few hundred lines of code:
https://github.com/netduino/GoBus
Description
The RS-232 module takes care of its GPIO initialization, and then calls a GoBus init routine. The GoBus code handles all SPI traffic and will set a flag when a complete frame is received. The module code will then retrieve the GoBus frame, call its appropriate function, and then return a response to the caller.
Current state
The current code I uploaded is early, and there is a lot I still need to pull in from our codebase. But it's an early sneak peek. [In the gobus.c file, you'll notice that it fills up the buffer there--but nothing is reading from that buffer quite yet. The SPI/UART/GPIO initialization is complete however.]
SPI RX buffer filling:
/* SPI interrupt handler */ #pragma vector = SPI_vector __interrupt void SPI_IRQHandler( void ) { if(SPI->SR & SPI_SR_RXNE) { /* SPI 1-byte (register) receive buffer is filled */ if (_rxFrameBufferIndex < FRAME_SIZE - 1) { _rxFrameBuffer[_rxFrameBufferIndex++] = SPI->DR; } } }The module startup code:
/* initialize our clock (8MHz = HSE 8MHz / 1) */ MasterClock_Initialize(); /* turn off all peripheral clocks; we'll enable the ones we need after this. */ STM8S_DisableAllPeripheralClocksAfterReset(); /* initialize all of our module's unused GPIOs to input mode, pull-up enabled, interrupt disabled */ GPIO_InitializeToSafeDefaults(); /* configure our module-specific pins */ GPIO_Configure(); /* configure our module's non-GPIO peripherals */ /* UART peripheral */ UART_Initialize(); /* enable our UART */ UART_Enable(); /* configure GoBus SPI slave transport */ GoBus_Initialize(); /* important: after initializing all peripherals and features, enable interrupts */ __enable_interrupt();Some of the nitty-gritty behind the scenes... This is the clock initialization routine; we have one version for an external 8MHz clock (included here) and one version for using the built-in lower-accuracy 8MHz clock. We need the external clock on the RS-232 module for UART bps accuracy.
void MasterClock_Initialize( void ) { /* configure master clock as: (HSE 8MHz / 1) */ /* configure HSE as clock master */ CLK->SWR = CKL_SWR_SWI_HSE; /* wait for the target clock source (HSE) to be ready; we are now for the switch */ while (!(CLK->SWCR & CLK_SWCR_SWIF)); /* clear the SWIF flag */ CLK->SWCR &= ~CLK_SWCR_SWIF; /* switch master clock to HSE */ CLK->SWCR |= CLK_SWCR_SWEN; /* wait for master clock switch to complete */ while (CLK->SWCR & CLK_SWCR_SWBSY); /* stop switching the clock */ CLK->SWCR &= ~CLK_SWCR_SWEN; /* disable HSI */ CLK->ICKR &= ~CLK_ICKR_HSIEN; }What's next?
The next step is to set the appropriate FrameReceived flag in our SPI receive function, parse the buffer in the main function loop, and then free up the RX buffer once the command is processed (so that another frame can be received). Then we need to add in the error checking code, the error recovery code, and the code which lets data flow in the other direction. And the module-specific code that lights up the ACT LED.
After that is done, I'll wrap things up by adding in GoBus enumeration and any required basic informational frames. And then we will ship a GoBus driver, flash a bunch of modules, and make this first GoBus 1.5 module available for order.
Modularization
BTW, one of the goals with the new code is to modularize the peripherals a bit--so that it is easy for third parties to make GoBus-compliant modules (which work on Netduino Go, Netduino 3 and via GoBus hubs). You can see some of that in the current code but there is more work to do before we get to that point.
If you have any questions on how the STM8S firmware is being designed, just let me know!
Chris