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...
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
Code: Select all
// 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();
}
}
1.) I will #include our new Arduino.h file in serisman's main.c before any other inludes:
Code: Select all
#include "Arduino.h" // Implement the construct of setup() and loop()
#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"
Code: Select all
// 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();
Code: Select all
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();
// Send the keypad keymaps to the UART (if it changed)
if (keypad_changed()) {
uart_print("keymap: ");
for (uint8_t i=0; i<4; i++) {
u8_to_bin_str(str_buf, keypad_get_keymap(i), 5);
uart_print(str_buf); uart_print(" ");
}
uart_println("");
}
// Send the name of any just pressed/released buttons to the UART
for (uint8_t col=0; col<4; col++) {
for (uint8_t row=0; row<8; row++) {
uint8_t mask = util_bit_to_mask[row];
if (keypad_just_pressed(col, mask)) {
uart_print("key pressed: "); uart_println(keypad_get_button_name(col, mask));
}
if (keypad_just_released(col, mask)) {
uart_print("key released: "); uart_println(keypad_get_button_name(col, mask));
}
}
}
// Display Hello World!
display_set_cursor(3,17);
display_print("Hello World!");
// THE CODE CONTINUES UNTIL THE LASTS }
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:
COMPILE
Code: Select all
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
LINK
Code: Select all
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
Code: Select all
packihx main.ihx >Hello-World.hex
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 old device until I own it. Anyway, it has been a rainy day and I am satisfied with my efforts.
Ray