C library for the Basic Atom Pro 28 and Pro 40

I have written a C library that supports the Basic Atom Pro 28 and Pro 40 modules.
Printf and sprintf are supported.

Drivers/interfaces exist for the following hardware:

Battery interface using ADC.
BlinkM I2C LED display module.
CMPS03 I2C compass module.
DIPswitch interface using the I2C PCF8574 I2C chip.
DS1307 I2C clock chip.
DS1631 I2C temperature chip.
I2C EEPROM (internal and external).
IRCM I2C Infrared communications module.
ISD5216 I2C digital recording chip.
ISD17240 SPI digital recording chip.
Latch interface using the I2C PCF8574 I2C chip.
LCD2s I2C LCD display.
LED interface using the I2C PCF8574 I2C chip.
Maestro serial controlled servo controller. Serial bit bang or hardware supported.
MD22 I2C motor controller.
MP3 serial controller uMP3 and rMP3 players from Rogue Robotics. Both devices can be used simultaneously. Serial bit bang or hardware supported.
PCF8573 I2C clock chip.
PS2C SPI PS2 controller (LynxMotion RC01).
RLY08 I2C relay controller module.
SP03 I2C text-to-speech module.
SRF04 TTL-controller sonar module. I use 6 on a single board that multiplexes the signals using an I2C PCF8574 and two 4066 chips.
SRF08 I2C sonar module. I currently use 4 of these.
uCAM serial-controlled camera module. Serial bit bang or hardware supported.
VRBot serial-controlled voice recognition unit. Serial bit bang or hardware supported. Needs receive latch to catch replies if using bit-bang.

I have all of these devices working together on my 1/10 scale Hummer H2 autonomous vehicle.

-Bob
BAP.zip (334 KB)

Sounds great, I would love to play with it. I have several other projects going on, so I won’t be able to do very much at first.

Note: this forum now allows you to upload files. It is much nicer than trying to put all of the sources in to a post. Likewise I believe the Basic Micro Forum also allows you to upload files.

Kurt

Interesting!

Thanks for making it available, I’m looking forward to studying it.

I’d like to see more use of the built-in peripherals, and not so much bit-bang. But that’s just personal preference. Using the peripherals with interrupts can make them real time, and code won’t have to wait.

NASA CLIPS. Isn’t that from like '85?

Alan KM6VV

I agree about less bit-banging. I recently added COM/COM2 and ADC using the hardware modules.
I am working on hardware IIC. The BAP has no hardware SPI, so it’s bit-bang or nothing.

I am learning the Hitach H300 interrupt system and have made some fair progress on the BAP28.
Once interrupt processing is stable, I intend to add hardware, interrupt driven queues to the COM ports.
I will also add interrupt support to the timers and try to add accurate timing for pulsein, rctime, pwm, etc.

Yep, same CLIPS. I first started programming with CLIPS in 1987 and have been using it on and off ever since.
I have always wanted to create an autonomous robot driven by an AI engine. And now it’s working :smiley:
CLIPS is still widely in use and 6.30 was updated in April 2008.

-Bob

Thanks for the information. I look forward to your next release.

Interesting to hear that CLIPS had been around that long. NASA is just down the street from me (at least the Moffett campus).

Alan KM6VV

I will take a look. I earlier did some playing with some C projects on the Bap28, including a simple Hello World, where I did have code for a TimerA interrupt to keep a clock for a wait function. I also had PS2 code running and I also had some I2C code running that was using the built-in support. I was about to adapt it to be sync but never got there.

Let me know if any of this would be helpful or not.

Kurt

Thanks Kurt, all quite helpful, I am very familiar with your C examples :slight_smile: Thank you so much for showing us how to program the chip in C. I leaned heavily on your samples of how to access IO pins, timers, etc. You got me curious about accessing the Hitachi hardware from C by proving it could be done. Thanks again for all your posts on the subject. Truly an inspiration that helped me decide to tackle the core C library. There is no way I would have even started if you hadn’t broken that barrier.

After inspecting the new vects.c and interrupts.c files produced by Studio 1.0.0.20, I was able to get timer interrupts to work for the BAP 28 and the BAP 40.

The latest code has been uploaded to my initial post.

-Bob

Actually it does have SPI. The TX/RX pins combined with SCK3 can be used for SPI communications. I used it to drive our 32x32 fullcolor LED Matrix you can find on Youtube.

Nathan, thanks for the heads-up on the SPI using the COM port and clock. Now I see how the clock pin can be used to drive hardware SPI.
I am working on getting the LynxMotion PS2 controller working with hardware SPI.
Since I’m using the BAP40, I can use the second hardware COM port for this, and still have a COM port free. :stuck_out_tongue:

Sounds like you are having fun!

I have been playing around as well. I have used some bits and pieces of the stuff you have done so far. I will go back and integrate your stuff with my current stuff.

I do have the PS2 working using the normal IO pins doing my own SPI implementation (. Currently using your high/low functions for this, but will change to use some additional stuff I have. That is I created the equivalent of the porttable and I pass in a pin number and it returns back a byte pointer to the appropriate PDR io register and a byte mask. Then in my loop I can simply or in or and out the appropriate bit, which is quicker. I use this in my C implement ion of TASerout function (soon TAserin). Also create my own version IOPrintf function with a simple Printf implentation… Still needs a little speed up… Tested at 9600 and 38400, will soon test at 115200.

What am I up to? I have ported the phoenix 2.0 code to C and am trying to get it it to run on the Bap28… Now debugging the Math…

Kurt

Hi Kurt. Yeah, I’m having fun for sure. I think the Basic Micro Pro 40 is just great, and finally programming it in C just tops all.
What you are doing with the porttable is exactly what the bit-banging stuff needs to boost performance (and higher baud rates). I’ll hold off on what I was working on related to this, and just get the code from you when you feel it is ready? I would also like to have that printf code if you don’t mind me being code greedy 8)

I did update my SPI code to work with the LynxMotion PS2 controller, and it seems to handle read/write on the same operation. I’m working on using the COM port with the CLK as a hardware SPI as suggested by Nathan.

Perhaps you could create a library post and put your code there? I’m sure I want to integrate what you have in with mine, and I don’t mind experimental code. I’ll study it and get what I can. I have converted my main autonomous robot to my C library, so my main focus will be on C from here out. So it could really use the performance boost it’ll get from your code.

-Bob

You’ve ported Phoenix 2.0 to C? Good show! I was working on that for my hexapod, and will probably also do for 'quad. I’d much rather program in C. Just a few peripheral routines I’d miss.

Alan KM6VV

Just a quick note. I have uploaded my almost current sources for the phoenix running C on the Bap28. The code needs some cleanup. IE remove the library type code from the app specific code. Also need to look through your stuff and see if I should merge the stuff in. What I have not uploaded yet is specific to the phoenix. That is I merged in my later phoenix code that now allows the BAP to talk the SSC-32 in binary mode.

Have you done any updates?

Kurt

I did post an update on 4/15 for the hardware I2C and a revamp of the software I2C function signatures, so that they would match the hardware I2C signatures, minus the I/O pin parameters (as they are not needed). And some timer stuff for the COM read timeouts. Integrated the interrupt headers and code to use the defines as provided by BasicMicro.

After inspecting the Phoenix code (thanks for the upload!), I don’t think any of my recent changes are for anything you are using.

I’ll be making these updates to my C library from your Phoenix code:
pin I/O code (I2C and COM) to use the PI_ macros
hardware timer-based software COM timing
interrupt enable/disable interface
PS2 controller _ps2packet usage. that was a nice touch! I only ported my Basic code to C and have not yet actually converted the C code to really use the C features of structs, etc. I am slowing converting these pieces, so this code helps with that effort.
ioprintf to use the abstracted message interface, which will route to a hardware or software COM port (via the revised serial library) and/or the LCD display.

-Bob

HI Bob,

Sounds great!

I have started to cleanup some of my C code. For example moved all of my IO pin handling code into files (iopins.cpp/H), I have taken a first pass in converting all of your functions over to the tables. I also extended the tables, to include another byte per pin, One nibble is used to say if the pin has a pull-up control register associated with it (PUCR) and the lower nibble if it it has a Port Mode register associated with it(PMR). I then change the function input to take an optional parameter fPullup=false that allows the API to set the associated bit in PUCR. There are a couple of cases I have not gotten yet, that is that you can set a pull-up on Bap io in 8, but it is not on the primary pin we normally use. May add some special case code, but right now for example the function input looks like:

[code]void input (u8 _bpin, bool fPullup)
{
// Lets use our table to do the work for us…
if (_bpin < (sizeof(g_PortTable)/sizeof(PORTITEM)))
{
// Ok lets get the port table item…
PORTITEM pi = g_PortTable[_bpin];

	// Make sure it is a valid one...
	if (pi.pPDR)
	{
		// See if there is a PMR register associated with this pin.
		if ((pi.bPU_PM) & 0xf)
		{
			volatile register unsigned char *pPMR = &IO.PMR1.BYTE + (pi.bPU_PM & 0xf) - 1;	// get the right PMR register
			*pPMR &= ~(pi.bMask);
		}
		
		// Next lets update PDR/PCR...
		u8 bIOPortIndex = (pi.pPDR - &IO.PDR1.BYTE);
		volatile unsigned char *pPCR = &IO.PCR1 + bIOPortIndex;
		bap_bpcrshadowregs[bIOPortIndex] &= ~(pi.bMask);				// Update shadow mask to say that the pin is now an input pin
		*pPCR = bap_bpcrshadowregs[bIOPortIndex];
		
		// Now lets see if we have a PUCR register (pull-up) to update for this pin
		if ((pi.bPU_PM) >> 4)
		{
			volatile register unsigned char *pPUCR = &IO.PUCR1.BYTE + (pi.bPU_PM >> 4) - 1;	// get the right PUCR register
			if (fPullup)
				*pPUCR |= pi.bMask;
			else
				*pPUCR &= ~(pi.bMask);
		}
		
	}
}	

} [/code]

I also redid the high, low and in functions to use the macros and I added the function toggle, as I do this a lot when I am debugging code.

[code]void toggle (u8 _bpin)
{
// Lets use our table to do the work for us…
if (_bpin < (sizeof(g_PortTable)/sizeof(PORTITEM)))
{
// Ok lets get the port table item…
PORTITEM pi = g_PortTable[_bpin];

	// Make sure it is a valid one...
	if (pi.pPDR)
		PI_TOGGLE(pi);
}

}
[/code]

Currently I am playing with the code in hsio.cpp/h to add interrupt support, such that I will able to queue up both input and output data and process them in the background. My queues will probalby start off at 64 bytes each like I think they are in basic. Once I get this up and running I will port over my XBEE support to C…

Let me know if you want me to post up any more details/code before I finish this part (probably a few days).

Kurt

Nice. I implemented the P0-P31 enumerations, revised the PORTTABLE to support the BAP40 and updated the high/low functions to use your PI macros.
Tested the software I2C, SPI, COM on the BAP28 and the BAP40 and they worked fine. The more we abstract this the easier it is to support both chips, so thanks for the code updates.

I’m taking the toggle and input functions from your post and revising the output function to work similarly to the input function (using PORTTABLE).

I’m holding off on any COM work while you work out the interrupt queue, as I only use the COM ports in a limited manner for my projects, and what I need is working fine at the moment.

FYI, I’ve renamed my library files to be .c rather than .cpp as I am not actually using any C++ at this point.

-Bob

I have added a few devices to the C library.

ISD17240
ISD digital recording device from Winbond.
SPI-controlled interface using the same SPI library as the LynxMotion PS2 controller.

Maestro
Serial-controlled servo controller from Pololu.

uCam
Serial-controlled camera device from 4D Systems. This driver is currently under development.

VRBot
Serial-controlled voice-recognition module from Veear.

I have created a simple IObridge program that you can use for pass-through serial communications to connected devices without having to change pins.
I use it to run the various Windows GUI config/test programs that need a serial port. I program the bridge to connect the serial device TTL pins through the DB9 port and I can then use the DB9 port from Windows, etc, with any connected TTL device without changing any pins. And this provides built-in TTL/RS232 conversion. This means I can run the various Windows GUI serial-based programs without opening up my robot.

-Bob

I have completed the uCam ‘C’ driver.

The driver supports having the uCam take a picture and hold it in the uCam buffer.
The packet size used to chop up the image is configurable.
The image size and number of packets needed to retrieve is returned to the caller.
The image can then be requested one packet at a time until all packets have been collected, writing the packets to the caller file system.
I am storing the jpeg image on a PlayStation Portable (PSP2000) and viewing it from there.

-Bob

That sounds cool. Can you show a picture?

For my senior design project, I am useing a Rover Kit from lynxmotion and I am trying to program the basic atom pro28 on the bot board using C++ instead of basic. So far I have veen unsuccessful as I am not communicating with the pins on the Bot Board.

I tried using the C library posted but I do not see what ports on the Basic atom pro 28 correlates to the pins on the bot II board.