Repurpose CC2533 hardware and treat it like an Arduino

Years back, I made some statement about "Arduino" being a mindset and not just an atmega processor or ArduinoIDE. I forget the context, I was 10 years younger, but I think I will stand by that statement. For your consideration:

SMART Response PE is a surplus RF device used in school systems for remote test and quiz taking. These are older tech and one finds them on eBay constantly. They are based (my units) on a TI CC2533 microcontroller with 4K of SRAM and 64K of flash and 1K words of eeprom. The CC2533 has RF but the default stack is Zigbee and I am not going to discuss that here.

The candy bar-ish enclosure runs from 2 AA batteries and the LCD is not backlit, but usable and the sample code has all of the LCD basic requirements already written: init(), clear(), line, text, inverse, etc. The default font is 5x7.

What I am going to discuss is how I am playing around with this device as-if it were an Arduino board.

Some background and things I needed to gather:
99% of this effort was done by github user: serisman and his github is located
H-E-R-E
You will need everything from that repository.

You will need the free opensource compiler/linker SDCC which can be found on the Internet. I am running it on Windows 10 64-bit, latest patches.

I strongly recommend you purchase a Texas Instrument CC Debugger ... it provides a remarkably error free upload solution, much like Arduino ISP. I found one in the U.S. for shipping and it cost me $8 delivered... consult eBay or your choice for such device clones.

A quick review:

  • we have code
  • we have a compiler/linker
  • we have a way to upload to the device over USB
  • we assume we purchased a device or two...

Treat it like an Arduino
Many new users of Arduino know little about the under-the-hood stuff. Old people like myself came from a C programming background, through a C++ era, and into Arduino. We instinctively know that C programs all have a "main" section, but we forget about it when we use ArduinoIDE. Under the hood, Arduino has a "main" section but it stays hidden. What I am going to do is to take the CC2533 C code, section main.c from github, and modify that just a bit to make it look like it is Arduino style.

I will create a new file and call it Arduino.h

// Arduino-like include to implement setup() and loop() under SDCC
// These forward declarations avoid SDCC warnings!
void setup( void );
void loop( void );

void main() {
  setup();

  while (1) {
    loop();
  }
}

Now, over in serisman's main.c code, I will make a few changes to how he structured things:

  1. I will #include our new Arduino.h file
#include "Arduino.h"
#include "hal.h"
#include "util.h"
#include "string_utils.h"
#include "clock.h"
#include "uart.h"
#include "display.h"
#include "keypad.h"
#include "bitmaps.h"
  1. I will prototype all of the forward declarations (done automagically by Arduino!)
// forward declarations
void nextFrame();
void showTitle(uint8_t cur);
void moveCursor(uint8_t num);
void nextTitleFrame();
void drawLogo();
void drawTitleMenu();
void drawMenuCursor(uint8_t num);
void showStats();
void nextStatsFrame();
void loadStats();
void saveStats();
void resetStats();
void drawStats();
void drawStatsMenu();
void startPlaying();
void nextPlayFrame();
void nextCorrectFrame();
void nextDeadFrame();
void drawScore();
void drawHangman();
void drawWord();
void drawKeyboard();
void drawCorrect();
void drawDead();
void scoreResponse(char letter);
void pickAWord();
void uart_println(char *str);
extern uint8_t display_frame_count;
void uart_enable();
void uart_disable();
void uart_init();
void uart_print(char *str);
void u32_to_str(char __xdata *str_buf, uint32_t ul);
bool display_next_frame();
bool display_every_x_frames(uint8_t frames);
bool display_next_frame();
  1. I will restructure serisman's setup and loop to look like:
void setup() {
  oscillator_32mhz();
  clock_init();
  ENABLE_INTERRUPTS
  uart_init();
  uart_println("Hello World!");

  display_init();
  display_set_frame_rate(FPS);
}

void loop() {
  uint32_t millis;

// Wait until its time to render our next frame
  if (!display_next_frame())
    return;

// Poll the keypad (disable/enable UART to reduce shared pin conflicts)
  uart_disable();
  keypad_poll();
  uart_enable();

// code continues ... until "}"

Essentially that is all of the code changes.

I am using NotePad++ as my editor. We do not have an IDE, so I need to be able to manage my compile, link, binary to Intel HEX formatting. This is the job of a batch file (or if you want, a Makefile.) For demonstration purposes, I will do a three (3) batch files as the concept is far more familiar to most Arduino users:

1. Compile

REM /-------------------------------------------------COMPILE-----------------------------------------
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clear_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 _delay_loop_8.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 _delay_loop_16.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 _delay_loop_32.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clock.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clock_delay_ms.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clock_long_delay_ms.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clock_micros.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 clock_millis.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_bitmap.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_char.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_circle.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_fast_hline.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_fast_vline.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_line.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_pixel.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_draw_rect.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_every_x_frames.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_fill_rect.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_get_screen_ptr.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_next_frame.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_print.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_set_cursor.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 display_set_frame_rate.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 eeprom.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 i2c_master.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_any_pressed.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_changed.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_get_button_name.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_get_keymap.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_get_previous_keymap.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_just_pressed.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_just_released.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_poll.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 keypad_pressed.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 reverse_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 spi_master.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 str_to_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 u8_to_bin_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 u8_to_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 u32_to_str.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 uart.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 uart_print.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 uart_println.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 uart_put_char.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 uc1701.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 util_bit_to_mask.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 util_mask_to_bit.c
sdcc -mmcs51 -c --std-sdcc11 --opt-code-size -DCC2533 -DF_CPU=32000000 main.c

2. Link

sdcc -mmcs51 --xram-loc 0x0000 --xram-size 0x0F00 main.rel clock_millis.rel display.rel display_draw_bitmap.rel display_print.rel display_set_cursor.rel display_set_frame_rate.rel keypad_any_pressed.rel keypad_changed.rel keypad_get_button_name.rel keypad_get_keymap.rel keypad_just_pressed.rel keypad_just_released.rel keypad_poll.rel keypad_pressed.rel u8_to_bin_str.rel uc1701.rel util_bit_to_mask.rel display_draw_char.rel display_get_screen_ptr.rel keypad_get_previous_keymap.rel util_mask_to_bit.rel keypad.rel clock.rel clock_delay_ms.rel clock_long_delay_ms.rel clock_micros.rel _delay_loop_16.rel spi_master.rel  u8_to_str.rel display_fill_rect.rel display_draw_line.rel display_draw_fast_vline.rel str_to_str.rel display_draw_pixel.rel reverse_str.rel display_every_x_frames.rel display_draw_circle.rel display_draw_fast_hline.rel clear_str.rel eeprom.rel i2c_master.rel _delay_loop_8.rel display_next_frame.rel uart.rel uart_print.rel uart_println.rel uart_put_char.rel u32_to_str.rel 

3. Convert

packihx main.ihx >Hello-World.hex

All that is necessary is to download a copy of the free TI utility Smart RF Flash Programmer
Select the "old" version not the newest 2.x

SUMMARY
My total cost investment was $10 U.S.D. $2 for the SMART Response PE unit from eBay and $8 for the CC Debugger clone.

I have shown how convoluted C code for old non-Arduino hardware can be utilized and reprogrammed without radically changing your Arduino mindset.
To put this in prospective, the converted unit is battery powered, has a keyboard option, has a rudimentary LCD display, and has a very convenient carrying case ... no 3D printing required.

What do I intend to do with this thing? With 2x the UNO SRAM and 40K of flash left over and 1K of eeprom, surely I can find something to do productive. Or, maybe the endgame is just the satisfaction to hacking this device until I own it. Anyway, it has been a rainy day and I am satisfied with my efforts.

Ray

Processing: Clean.batch...
Processing: compile.batch...
Processing: Go.batch...
Processing: link.batch...

1 Like