Fun with e-paper and Arduino using an Adafruit Grand Central M4 and IT9851

Had some fun playing around with an e-paper display this last weekend.  Chose the Adafruit Grand Central M4 (SAM51) because of the large amount of flash and SRAM, but alas it was not enough SRAM to do what I wanted to do.  This is a GDEP097TC2 e-paper display with a parallel interface, hence the use of the IT9851 controller.  This is a really beautiful display at a diagonal size of 9.7″ but a high resolution of 1200W x 825H pixels.  As seen in the pictures below it can display 16 shades of grey.

The IT8951 has the capability of updating very quickly, however we are a little limited with SPI for now.  I plan to get the I80 (parallel interface) working on the IT9851 later, but I don’t have the flat cable and connectors right now to match the I80 interface connector.  I haven’t looked into partial updates, but I believe this is also possible if there is enough SRAM to create an image buffer.  I am hoping to do this after I receive an SDRAM module.

Adruino GDEP097TC2 epaper

Was planning on creating a buffer in SRAM for the display so that the image could be edited then displayed, but due to how the IT9851 accepts data, its 4 bits per pixel (16 shades of grey) or half a byte per pixel.  Calculating this out the display is 1200W x 825H which comes out to 990,000 pixels, and we would need a buffer of 990,000 / 2 = 495,000 bytes.  The Grand Central M4 only has 256k of SRAM.  This is defiantly out, at least for now.  I have an SDRAM module on order that I am going to use to expand the memory available for a later project, listing that below if there is any interest.

https://www.waveshare.com/sdram-board-b.htm

For this the following parts are used:
+ Adafruit Grand Central M4
+ WaveShare 1200×825, 9.7inch E-Ink display HAT for Raspberry Pi
+ 2GB SD card

The Adafruit Grand Central M4 is really handy to have around for various Arduino (or Circuit Python) projects where you don’t want to worry about flash and SRAM limits (most of the time).  I would recommend picking a couple up if you are ordering anything from Adafruit and want a beefy board around to do projects in Arduino or Circuit Python.  I have not tried Circuit Python yet, but it has peaked my interest on a few occasions.

Even though we can’t load the entire image into SRAM, no worry we will work around it for this project.  We have an SD card slot on the Adafruit Grand Central M4 so we are going to use a 2GB SD card to hold the image data for us and send it to the IT8951 as we read it from the SD card.  There is a small buffer of 1200 * 54 = 64800 bytes (57 lines) to speed this up.  I believe the SD card functions are limited to 65k due to the use of a uint16_t in the read function for size.

For whatever reason I can’t figure out why the image I load into the IT8951 is reversed, it could be that the image data is reversed in the BMP file, anyway I did some fancy coding to reverse the pixels of each line as its sent to the IT8951.  This is a little wonky, but works for now.  Maybe I can somehow get the IT8951 to load the memory backwards, but I haven’t investigated too far into the IT8951’s inner workings yet.

The image data is in BMP format and has to be formatted specifically, more detail is on the WaveShare wiki at the following webpage.

https://www.waveshare.com/wiki/9.7inch_e-Paper_HAT

However, we are assuming these images are formatted correctly and we will go ahead and use the provided images and copy them to an SD card.  I would recommend a 2GB SD card, not sure if others will work.  I formatted it to FAT16, not sure if FAT32 will work so I recommend using a FAT16 format.  You could go about and find images, crop them, etc, but I am providing the three that I used for this project in the zip file below.

Let me note that I have not really cleaned up the code for reasons that I might use those function in the future or just didn’t get around to cleaning some parts.  You will find some function are not connected to anything but were used during the development cycle to test things.

m4_GDEP097TC2_hwspi_sd_202102202200.zip

Unzip this above file and place it in your Arduino sketch folder.  You should already have Arduino setup to use the Adafruit M4 Grand Central.  If not, you can review the setup procedure on their website.  The files in the “images_for_sd_card” should be copied to the SD card, then they can be deleted from the Arduino project folder if you wish, they don’t appear to harm anything by leaving them there.  Remember to change your board type to “Adafruit Grand Central M4 (SAM51)” in the tools menu.  There are no extra libraries required.

I first wrote this with the software SPI library, hence it is still present, but switched over to hardware SPI later on, it works much smoother.  The IT9851 supports up to 24Mhz SPI speed, but high speed SPI does not appear to like these long wires, connectors, and other stuff, so its throttled back to 12Mhz, do experiment with it though if you wish.  Also it is purposely not using the default SPI interface to leave it free for other things, the SERCOM6 interface is being used for the SPI interface, it is trivial to change it back by changing the various options in the software_spi.h file as shown below, uncomment only one of these.

//#define USE_SOFTWARE_SPI 1
//#define USE_HARDWARE_SPI_DEFAULT 1
#define USE_HARDWARE_SPI_SERCOM6 1

Now on to the wiring, it is trivial to also find the wiring information in the files software_spi.h and IT8951.h files.  The wiring is listed below, also note the IT8951 board DOES need 5V for power, but the logic is 3.3V.

Arduino digital IO function
6 IT8951 RST
7 IT8951 HRDY
8 IT8951 CS
47 IT8951 MISO
48 IT8951 MOSI
49 IT8951 CLK
5V IT8951 5V
GND IT8951 GND

Do make sure you are connecting to the “digital” pins and not the “analog” pins as I did the first time and couldn’t figure out why it wasn’t working.

That’s about it, connect things up, insert the SD card, load the Arduino code and that should be about it.  Below are some more pictures.

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

nRF9160 ESP32-CAM JPEG image uploader through LTE

This is a guide in progress and is no where near complete, but did want to get some initial information and links to the project files up while I work on the rest of the guide.

Have been working on a few project involving the nRF9160 lately and am trying to get support added into TinyGSM for the nRF9160, there is a discussion over here that I started for that at the address below.

https://github.com/vshymanskyy/TinyGSM/issues/486

Feel free to join in and help out of you have interest in using TinyGSM with the nRF9160.

This project uses an ESP32-CAM development board to take pictures and use the Feather nRF9160 to upload the JPEG images to a server through a form post to a PHP script.  The images can then be immediately viewed in a web browser.

Also this project will also need a SIM card that will allow it to connect to an LTE network.  These JPEG images can be up to 10k in size and will easily eat through a SIM card that does not have enough data.  I just bought a prepaid data only LTE SIM card at a local shop and it works fine, but the LTE network you are connecting to needs to have either NB-IoT or LTE-M support.  It is possible to “borrow” the SIM card from your cell phone too.

Also you will need to know the SIM card’s APN information, if the nRF9160 does not automatically figure it out.  For the few SIM cards I have been working with I have had to manually specify the APN information and sometimes authentication information as well.  More on that later.

esp32_nrf9160_camera_http

A note about the ESP32-CAM, so far I have run into one that was a little glitchy, it would be unstable and freeze/reset randomly.  These ESP32-CAM boards are pretty cheap so I would grab a couple from different vendors, they are common to find on Amazon.  They also should come with the camera, double check that it does.

Here are the three main parts and some links:

ESP32-CAM (the ESP32-CAM board plus camera, I have had good luck with HiLetgo)
+ https://www.amazon.com/HiLetgo-ESP32-CAM-Development-Bluetooth-Raspberry/dp/B07RXPHYNM
+ https://www.amazon.com/ESP32-CAM-Bluetooth-Camera-Module-Development/dp/B07S5PVZKV
Feather nRF9160 (board containing the new LTE radio from Nordic)
https://www.jaredwolff.com/store/nrf9160-feather/
FTDI 3V3 cable (to program the ESP32-CAM, make sure it is 3V3)
https://www.amazon.com/Converter-Terminated-Galileo-BeagleBone-Minnowboard/dp/B06ZYPLFNB
https://www.digikey.com/en/products/detail/ftdi-future-technology-devices-international-ltd/TTL-234X-3V3/6823715

 

esp32_nrf9160_camera_http
esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

Here is how to wire it all up.  There are some pictures to show the wiring if its easier to visualize, and below the pictures are tables with the pinout details.

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

There are two buttons also visible, the top button is a “take picture” button, shorted so pictures are automatically taken.  The bottom button is the “bootloader” button.  Press this button and hold it while pressing the reset button (on the bottom side of the ESP32-CAM board).  After the ESP32-CAM reset button is pressed release the “bootloader” button.  Wiring between the nRF9160 and the ESP32-CAM and pinout descriptions is shown below.

Feather nRF9160  ESP32-CAM
Pin Desciption Pin Desciption
 RST  reset IO15 nRF9160 reset
 D5  UART2 RX  IO12 UART TX
 D7  UART2 TX  IO13 UART RX
Feather nRF9160
Pin Desciption Info
 GND ground connect to the common ground
 RST reset connect to ESP32-CAM pin IO015
 D5 UART2 RX connect to ESP32-CAM pin IO12
 D7 UART2 TX connect to ESP32-CAM pin IO13
ESP32-CAM
Pin Desciption Info
 5V0 5.0v power input connect to FTDI pin 3 (red)
 GND GND connect to the common ground
 U0R UART0 RX connect to FTDI pin 4 (orange)
 U0T UART0 TX connect to FTDI pin 5 (yellow)
 IO0 GPIO D0 bootloader enable pin, active low
 IO12 GPIO D12 connect to nRF9160 pin D5
 IO13 GPIO D13 connect to nRF9160 pin D7
 IO14 GPIO D14 “take picture” switch, active low
 IO14 GPIO D15 connect to nRF9160 pin RST
FTDI 3V3 6-pin connector
Pin Description Info
 1 (black) GND connect to the common ground
 2 (brown)  CTS#  not used
 3 (red)  5V0  connect to ESP32-CAM 5V0 pin
 4 (orange)  TXD  connect to ESP32-CAM U0R pin
 5 (yellow)  RXD  connect to ESP32-CAM U0T pin
 6 (green)  RTS#  not used

Please do make sure the FTDI cable you are using is a 3.3v version.  The signal lines will be 3.3v but red pin will still have 5.0v on it.  We will power the ESP32-CAM 3V3 regulator from with the 5.0v on the FTDI cable.  Also notice the nRF9160 has its own USB cable, it is powered from that cable.  Since there is no pin on the Feather nRF9160 that we can use to power the Feather nRF9160 we are powering the Feather nRF9160 with a second USB cable.

The Arduino hardware support and some libraries will also need to be installed, to install the Arduino library for the ESP32-CAM open up the Arduino preferences add the following URL to the “Additional Boards Manager URLs box, there is a button to the right that will open up a text box to easily add more than one URL.

https://dl.espressif.com/dl/package_esp32_index.json

esp32_nrf9160_camera_http

Press the “OK” buttons and then open up the “Board Manger” from the “Tools” “board” menu.

esp32_nrf9160_camera_http

Type “esp32” into the search box and install the “esp32” board package.  This will add support for many ESP32 based boards including the “AI Thinker ESP32-CAM.” the board that we are working with.  Be sure to select the board after installing it.

There are a couple other libraries that can be installed through the “Library Manager” if they are not installed, these are:
+ StreamDebugger
+ Time

Additionally, we use TinyGSM, but the version in the Library Manager does not have nRF9160 support, please download that from here and extract the contents into the “library” folder, generally located in “My Documents/Arduino/libraries”.

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/TinyGSM_20210203.zip

Also grab the Arduino sketch from the below link, unzip this in your Arduino sketch folder.

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/esp32_nrf9160_camera_http_20210203.zip

These next steps will involve getting the Feather nRF9160 programmed so it will work with TinyGSM (as a AT command driven serial LTE modem).  Getting the nRF9160 programmed might take a little patience.  I found the easiest way is to use “nrfjprog” from Nordic, however, there are GUI based programming tools available also.

I have not had luck with the bootloader for the Feather nRF9160 as the hex file we will load is a little too big.  We may need to use a hardware JLink programmer, or an nRF9160DK, I also hear an nRF53 series DK will also work. A 6-pin TagConnect cable will also be required to connect the Feather nRF9160 programming pins to the programmer.

For the TagConnect, there are a couple routes to go, this cable should connect directly to the nRF9160DK but I have not personally tested it.  Also the smaller thinner wires might break easier with heavy use.

https://www.tag-connect.com/product/tc2030-ctx-nl-6-pin-no-legs-cable-with-10-pin-micro-connector-for-cortex-processors

The connector that I have is the the following, I made an adapter board so I can use it for other projects in the future.  The pins on this connector are routed straight through, pin-for-pin.  There are links to a couple other useful items that can be used to make the adapter board.

https://www.tag-connect.com/product/tc2030-idc-nl
https://www.adafruit.com/product/2743
https://www.adafruit.com/product/1675

The TagConnect cables are not cheap, but are very useful to have around, I am seeing more and more development boards with TagConnect pads.  If you are buying one I would recommend grabbing both of the generic 6-pin and 10-pin versions for future use, these two links below.

https://www.tag-connect.com/product/tc2030-idc-nl
https://www.tag-connect.com/product/tc2050-idc-nl-10-pin-no-legs-cable-with-ribbon-connector

There two files to program, one is to update the nRF9160’s baseband (modem) firmware, the other is to program the actual nRF9160’s main MCU.  If the nRF9160DK is being used instead of the Feather nRF9160 there is one additional hex file to program for the nRF9160DK’s “board controller” nRF52840.

 

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/nrf9160_baseband_20210203.zip

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/nrf9160_firmware_20210203.zip

Detailed instructions for programming the nRF9160 is a discussion in itself and I will write up another post with all the details about how to program the three types of nRF9160 boards that I have run into so far.

There are details in the baseband zip file on how to program the baseband, along with the firmware files in the firmware zip file.  For the firmware files there are many to choose from, for the Feather nRF9160 to program it through the nrfjprog utility or the GUI programmer) it would be serial_lte_modem_circuitdojo_feather_nrf9160_115200_merged.hex, 115200 referring to the speed the UART is running at.

For the time being the programming of the nRF9160 is a little above the scope of this guide and will cover it in another post and link to it here when that post is finished.  For now try to search online to get setup for programming.

Setting up the sketch

Lets go back now to the Arduino IDE and load the sketch, there are a couple things we will need to setup.  First will be the APN information for your SIM card, the APN name and then authentication if required,  TinyGSM is setup to use CHAP now, it can be changed over to PAP if necessary.

esp32_nrf9160_camera_http

Next we need to decide where we are going to send the images to, this is setup at the top of the sketch.  The “UPLOAD_TOKEN” and “UPLOAD_MESSAGE” are not used, but left in as placeholders for some kind of authentication system later.

esp32_nrf9160_camera_http

Here is a simple upload.php that can receive the uploaded images.

<?php
$uploadfile = "";
echo "Receiving file [";
echo $_FILES["imageFile"]["name"];
echo "]\r\n";
if(strlen(basename($_FILES["imageFile"]["name"])) > 0)
{
 $uploadfile = basename($_FILES["imageFile"]["name"]);
 if(move_uploaded_file($_FILES["imageFile"]["tmp_name"], $uploadfile))
 {
 echo "saved ";
 } else {
 echo "error moving file";
 }
} else {
 echo "error image data does not exist";
}
?>

After this build and program the ESP32-CAM.  If everything is setup right you should see the Feather nRF9160 connect to the LTE network and see images being uploaded.  It takes time to connect (6 seconds alone for the Feather nRF9160 hardware reset to finish).

There is a lot more detail I want to add to this but going to post this guide up as it is now and add the rest of the information in a little bit.  The required files and source code are all linked above and that is mostly what I wanted to get posted up while I finish fixing up this guide.

Simple CC1350 blink example

I started working with a CC1310 at work again and we have a need to be able to update the CC1310 MCU flash memory through the JTAG (SWD) connection from the STM32F401Re main MCU.

The board that I have to develop this on is not quite the CC1310, but a CC1350, which is close enough to do the code development, then port it to the CC1310 after.

TI CC1350 LaunchPad
TI CC1350 LaunchPad

What is a CC1310? This is an ARM based sub-gigahertz RF microcontroller by Texas Instruments that enables communication in the 779-928 MHz range.  More detailed information is on TI’s website at this link.

The CC1350 is nearly identical with the addition of a 2.4Ghz radio as well to allow communication over BLE (or other protocols).

The CC1310 from TI is a nice low power RF part, I wish it offered more than 128K FLASH.  It barely has enough space to run the wireless stack and some simple application logic, much less than is required.

Initially we wanted to go with the CC1350 as it has both radios in it, but, the severe limitation of FLASH to 128K does not allow both stacks to coexist together.  The sub-giga stack that we are using takes up nearly the full 128K as is… which leaves no room for a BLE stack.

The question that bothers us is how to field update this MCU after distribution to the customer.  There is a built in ROM boot loader which is able to update the firmware, but it would be nice to be able to recover the MCU from whatever state it is in… make it unbrickable.  Therefore connecting the STM32F401RE to the CC1310 with a SWD connection would allow the STM32F401RE to issue JTAG commands to the CC1310 just like a debug interface, and reprogram the it as well.

The trouble, the CC1310’s FLASH can not be directly accessed over JTAG, it turns out that only the MCU itself can reprogram the FLASH.  However, we can load something into SRAM and direct the CC1310 to execute it by JTAG.  Therefore if we load some simple logic into SRAM, along with a chunk of data to be programmed into FLASH this becomes possible.  With only 20K of SRAM on the CC1310 (CC1350) this becomes nearly impossible to run any really complicated logic in SRAM, but all we need to do is copy something from SRAM into FLASH.  Ideally if we made some logic that allowed reception of data over the USART to be written into FLASH that might go much faster, which is now the ROM boot loader works to my knowledge.

In order to facilitate this, I needed to do some learning of how to write code for the CC1310 (CC1350) that didn’t require TI’s RTOS to run, even completely stripped down the RTOS will not fit in SRAM.

I has a lot of trouble locating information on how to write code for the CC1310 (CC1350) outside of the RTOS, and it is not officially supported by TI, so I would like to share the progress of this project as it may provide assistance to others in the future.

First of all the needed tools and software list:

About the tidrivers, they will most likely be auto installed with Code Composer Studio 7 (CCS7), and a different version most likely will work, but be sure to correct the paths in some of the instructions to match.  If the paths are not correct there will be trouble with building and linking since the required files can not be found.

After CCS7 is installed, open it and let it update any files it recommends.  CCS7 is basically a highly customized version of Eclipse, but the nice thing is that all tool chains and required files are self contained, at least on the OSX version.

Create a new CCS project from the file menu.
Create a new CCS project from the file menu.

Now that CCS7 is all updated create a new CCS project from the file menu.

 

This will bring up a new project details dialog, fill in the details as shown, feel free to rename the project to something of your liking.

New CCS project details.
New CCS project details.
New CSS project details.
New CSS project details.
CC1350_blink project.
CC1350_blink project.

Now we should have a new project created as shown on the right.

Open up the main.c file by double clicking on it and we will add the code necessary to blink the LEDs on the LaunchPad.

CC13150_blink empty main.c.
CC13150_blink empty main.c.

Shown to the left is what your main.c should look like after just creating the project, just the main function.

 

 

 

What we are going to create is a simple LED blink program.  It is simple to turn on and off an LED with just a while loop with a delay loop, but, a while loop is not very feasible for a real project so we are going to create it with a timer interrupt.

Let’s create the function to first setup the timer.

/*
 *  ======== timer_setup ========
 *  Function to setup the GPT0 timer.
 *  Using GPT0 timer A, periodic mode
 *  Interrupt callback to ISR_TimerInterrupt_Handler
 */
void timer_setup(void)
{
    // Power on periperal domain
    PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // Power on the TIMER0 peripheral
    PRCMPeripheralRunEnable(PRCM_PERIPH_TIMER0);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // Enable TIMER0 to continue counting while the MCU sleeps
    PRCMPeripheralSleepEnable(PRCM_PERIPH_TIMER0);

    // Configure the TIMER0
    TimerConfigure(GPT0_BASE, TIMER_CFG_A_PERIODIC);
    // Set initial timer value
    TimerLoadSet(GPT0_BASE, TIMER_A, 0xFFFFFF);
    // Set prescaler
    TimerPrescaleSet(GPT0_BASE, TIMER_A, 0x000000FF);//255
    // Timer to count on positive clock edge
    TimerEventControl(GPT0_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);
    // Be sure the interrupt is clear to start
    TimerIntClear(GPT0_BASE,TIMER_TIMA_TIMEOUT);
    // Assign the interrupt handler
    TimerIntRegister(GPT0_BASE, TIMER_A, ISR_TimerInterrupt_Handler);
    // Enable the interrupt
    TimerIntEnable(GPT0_BASE,TIMER_TIMA_TIMEOUT);
    // Enable the timer
    TimerEnable(GPT0_BASE,TIMER_A);
}

Next lets add the interrupt handler function.

/*
 *  ======== ISR_TimerInterrupt_Handler ========
 *  Interrupt handler to service the TIMER_TIMA_TIMEOUT interrupt.
 */
void ISR_TimerInterrupt_Handler(void)
{
    // clear interrupt flag
    TimerIntClear(GPT0_BASE, TIMER_TIMA_TIMEOUT);
    // toggle the red LED
    GPIO_toggleDio(IOID_6);
    // toggle the green LED
    GPIO_toggleDio(IOID_7);
}

Add the function to setup the LEDs.

/*
 *  ======== led_setup ========
 *  Setup the red and green LEDs
 */
void led_setup(void)
{
    // Power on periperal domain
    PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    while(PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON);

    // Power on the GPIO peripheral
    PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // enable output for the red LED
    GPIO_setOutputEnableDio(IOID_6, GPIO_OUTPUT_ENABLE);
    // turn on the red LED
    GPIO_setDio(IOID_6);

    // enable output for the green LED
    GPIO_setOutputEnableDio(IOID_7, GPIO_OUTPUT_ENABLE);
    //turn off the green LED
    GPIO_clearDio(IOID_7);
}

Add the main function.

/*
 *  ======== main ========
 *  Main function
 */
int main(void) {
    // setup the LEDs
    led_setup();

    // setup the timer
    timer_setup();

    // enable the master interrupt
    IntMasterEnable();

    // loop forever waiting for an interrupt
    for(;;);

    return 0;
}

Take care of defines and includes at the top of main.c.

#include &amp;amp;amp;amp;amp;lt;stdlib.h&amp;amp;amp;amp;amp;gt;
#include "driverlib/gpio.h"
#include "driverlib/ioc.h"
#include "driverlib/prcm.h"
#include "driverlib/timer.h"
#include "driverlib/sys_ctrl.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"

void led_setup(void);
void ISR_TimerInterrupt_Handler(void);
void timer_setup(void);

Putting it all together we have the complete main.c file.

/*
 * main.c
 */
#include &amp;amp;amp;amp;amp;lt;stdlib.h&amp;amp;amp;amp;amp;gt;
#include "driverlib/gpio.h"
#include "driverlib/ioc.h"
#include "driverlib/prcm.h"
#include "driverlib/timer.h"
#include "driverlib/sys_ctrl.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"

void led_setup(void);
void ISR_TimerInterrupt_Handler(void);
void timer_setup(void);

/*
 *  ======== main ========
 *  Main function
 */
int main(void) {
    // setup the LEDs
    led_setup();

    // setup the timer
    timer_setup();

    // enable the master interrupt
    IntMasterEnable();

    // loop forever waiting for an interrupt
    for(;;);

    return 0;
}

/*
 *  ======== led_setup ========
 *  Setup the red and green LEDs
 */
void led_setup(void)
{
    // Power on periperal domain
    PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    while(PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON);

    // Power on the GPIO peripheral
    PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // enable output for the red LED
    GPIO_setOutputEnableDio(IOID_6, GPIO_OUTPUT_ENABLE);
    // turn on the red LED
    GPIO_setDio(IOID_6);

    // enable output for the green LED
    GPIO_setOutputEnableDio(IOID_7, GPIO_OUTPUT_ENABLE);
    //turn off the green LED
    GPIO_clearDio(IOID_7);
}

/*
 *  ======== ISR_TimerInterrupt_Handler ========
 *  Interrupt handler to service the TIMER_TIMA_TIMEOUT interrupt.
 */
void ISR_TimerInterrupt_Handler(void)
{
    // clear interrupt flag
    TimerIntClear(GPT0_BASE, TIMER_TIMA_TIMEOUT);
    // toggle the red LED
    GPIO_toggleDio(IOID_6);
    // toggle the green LED
    GPIO_toggleDio(IOID_7);
}

/*
 *  ======== timer_setup ========
 *  Function to setup the GPT0 timer.
 *  Using GPT0 timer A, periodic mode
 *  Interrupt callback to ISR_TimerInterrupt_Handler
 */
void timer_setup(void)
{
    // Power on periperal domain
    PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // Power on the TIMER0 peripheral
    PRCMPeripheralRunEnable(PRCM_PERIPH_TIMER0);
    PRCMLoadSet();
    while ( !PRCMLoadGet() );

    // Enable TIMER0 to continue counting while the MCU sleeps
    PRCMPeripheralSleepEnable(PRCM_PERIPH_TIMER0);

    // Configure the TIMER0
    TimerConfigure(GPT0_BASE, TIMER_CFG_A_PERIODIC);
    // Set initial timer value
    TimerLoadSet(GPT0_BASE, TIMER_A, 0xFFFFFF);
    // Set prescaler
    TimerPrescaleSet(GPT0_BASE, TIMER_A, 0x000000FF);//255
    // Timer to count on positive clock edge
    TimerEventControl(GPT0_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);
    // Be sure the interrupt is clear to start
    TimerIntClear(GPT0_BASE,TIMER_TIMA_TIMEOUT);
    // Assign the interrupt handler
    TimerIntRegister(GPT0_BASE, TIMER_A, ISR_TimerInterrupt_Handler);
    // Enable the interrupt
    TimerIntEnable(GPT0_BASE,TIMER_TIMA_TIMEOUT);
    // Enable the timer
    TimerEnable(GPT0_BASE,TIMER_A);
}

Before we can build the file we have a little housekeeping and settings to configure. We need to copy some startup files into our project from the CC1350 drivers folder.

On Mac OSX these are by default located at the following path:

/Applications/ti/tirtos_cc13xx_cc26xx_2_20_01_08/products/cc13xxware_2_04_02_17240/startup_files/ccfg.c

and

/Applications/ti/tirtos_cc13xx_cc26xx_2_20_01_08/products/cc13xxware_2_04_02_17240/startup_files/startup_ccs.c

Drag and drop these into our project as shown in the image below.

CC1350 startup files location.
CC1350 startup files location.
Drag and drop to copy ccfg.c from the CC1350 drivers folder to the project.
Drag and drop to copy ccfg.c from the CC1350 drivers folder to the project.
Copy into project confirmation dialog, choose copy and press OK.
Copy into project confirmation dialog, choose copy and press OK.
CC1350_blink project after copying in the ccfg.c and startup_css.c files.
CC1350_blink project after copying in the ccfg.c and startup_css.c files.

Next we need to open up the project properties and make some additions and changes to the project settings.  Since we created an empty project some compiler and linker settings are not present that need to be.

Right click the CC1350_blink project and click on Properties to bring up the project settings.
Right click the CC1350_blink project and click on Properties to bring up the project settings.

We are presented with the following dialog.

Open up Resource and select Linked Resources.
Open up Resource and select Linked Resources.

We are going to add a new entry, click New… and enter the following information.  This is a variable pointing to the CC1350 driver library required for building.

Name:CC13XXWARE

Location:/Applications/ti/tirtos_cc13xx_cc26xx_2_20_01_08/products/cc13xxware_2_04_02_17240

Enter the following information for the CC13XXWARE variable and click OK.
Enter the following information for the CC13XXWARE variable and click OK.

This should now show up in the list as in the below image.

Linked Resources after adding the CC13XXWARE variable.
Linked Resources after adding the CC13XXWARE variable.

Next click on the ARM Compiler and click on Edit Flags.

Open up Build, ARM Compiler and click on Edit Flags.
Open up Build, ARM Compiler and click on Edit Flags.

Replace the contents with the following test that includes the path for the CC13XXWARE drivers and click OK.

-mv7M3 --code_state=16 -me --include_path="${PROJECT_ROOT}" --include_path="${PROJECT_LOC}" --include_path="${CC13XXWARE}" --include_path="${CG_TOOL_ROOT}/include" -g --c99 --gcc --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --abi=eabi
Paste in the settings that include the CC13XXWARE drivers.
Paste in the settings that include the CC13XXWARE drivers.

You should now have a screen that looks like this.

ARM Compiler settings with updated Build Flags.
ARM Compiler settings with updated Build Flags.

Next click on the ARM Linker and update the linker flags in there and press OK.

Open up Build, ARM Linker and click on Edit Flags.
Open up Build, ARM Linker and click on Edit Flags.
-m"${ProjName}.map" --heap_size=0 --stack_size=256 -i"${CG_TOOL_ROOT}/lib" -i"${CG_TOOL_ROOT}/include" --reread_libs --diag_suppress=16002-D --diag_suppress=10247-D --diag_suppress=10325-D --diag_suppress=10229-D --diag_wrap=off --display_error_number --warn_sections --xml_link_info="${ProjName}_linkInfo.xml" --rom_model
Paste in the settings.
Paste in the settings.

The ARM Linker screen should now look like this.

ARM Linker settings with updated Build Flags.
ARM Linker settings with updated Build Flags.

Finally we need to add a search path to the linker so it can find the CC13XXWARE drivers.  Open up the ARM Linker and add the include path as shown below.

Open up the ARM Linker and click on File Search Path.
Open up the ARM Linker and click on File Search Path.

Under Include library file or command file as input click the + button and add the following text.

Add new and level up buttons.
Add new and level up buttons.

“${CC13XXWARE}/driverlib/bin/ccs/driverlib.lib”

Add the path for the CC13XXWARE drivers to the ARM Linker include library file list.
Add the path for the CC13XXWARE drivers to the ARM Linker include library file list.

Click on the up arrow to bring it to the top of the list, then press OK to save and close project settings dialog.

Click the level up button to bring the CC13XXWARE to the top of the list as shown.
Click the level up button to bring the CC13XXWARE to the top of the list as shown.

Now, build the project by right clicking it and choosing Clean Project (just to be sure everything is clean), then choose Build Project.

Build the CC1350_blink project by clicking Clean Project followed by Build Project.
Build the CC1350_blink project by clicking Clean Project followed by Build Project.

Next, ensure your CC1350 is plugged into your USB port, and choose Debug As.

Upload the project to the CC1350 by choosing Debug As, Code Composer Debug Session.
Upload the project to the CC1350 by choosing Debug As, Code Composer Debug Session.

Finally, press the play button to run the code.

Press the run button to start running the code on the CC1350 MCU.
Press the run button to start running the code on the CC1350 MCU.

If everything goes correctly you should see a red LED and green LED flashing on the CC1350 LaunchPad as seen in the image at the top of the page.

This answers the questions about how to make a simple lightweight program for the CC1350, next is to add the logic to copy data from SRAM to FLASH and run this program completely from SRAM.

HID 125Khz ICカードリーダー

今回、マイクロコントローラーのシステムについて書きたいと思います。5年前に私が作ったものですが、現在でもまだ使えます。

ドアアクセスコントローラー(door access controller)は、ICカードに入っている個人番号を読み取って、EEPROMメモリに入っているカード番号リストを照合して、ドアを開けるシステムです。

大学生のときにアマチュア無線クラブに参加していました。クラブのメンバーがクラブ室に入れるようにこのICカードシステムを入り口に付けていました。

動き方は、ICカードをリーダーにかざすとカードの番号を読み取って、マイクロコントローラーに送信します。EEPROMメモリに登録されたカード番号と合致したら、リレー(電磁継電器)に信号が送られて、ドアが開きます。

使っているパーツは、Microchip PIC16F88 8ビットマイクロコントローラー、Microchip 24LC64 IIC EEPROMメモリ、MAX232 RS232ドライバ、4Mhz 水晶(セラミック発振子)です。

読み取れるカードは、HID 125Khz ICカードです。マイクロコントローラーにアセンブリ言語で組み込んだプログラムに入っています。Githubにasmファイル(アセンブリソースコード)をアップしてあります。 https://github.com/aldras/pic_hidreader

後で回路図とPCBレイアウトをアップします。


リンク


画像 Pictures

HID 125Kz card reader - all
HID 125Khz card reader setup
HID 125Kz card reader - PCB - top
PCB
HID 125Kz card reader - PCB - top
PCB
HID 125Kz card reader - PCB - bottom
PCB bottom
HID 125Kz card reader - reader - inside
HID reader inside
HID 125Kz card reader - reader - front
HID reader
HID 125Kz card reader - reader - bottom
HID reader bottom

This time I would like to share a project from 5 years ago that I did while at the university.  The project is a proximity door access controller.  This consists if a HID card reader connected to a PIC 16F77 microcontroller.

The main parts of the PCB consist of the Microchip PIC 16F88 microcontroller, a Microchip 24LC64 64kbit (8k byte) IIC EEPROM memory chip, a MAX232 RS3232 level shifter, and the 4Mhz clock crystal.

The setup basically works like this… a card is read by the card reader, the card number is sent to the microcontroller by the Wiegand interface.  The microcontroller searches the memory chip for the card number, if the card number is found it turns on a relay for a couple seconds.  If the card is not found the buzzer on the card reader is turned on for a few seconds.

The microcontroller can be connected to a PC through the RS232 serial connection (9600 baud 8N1 no parity) to log the cards read, add cards and delete cards.

The HID reader (purchased from a online Ebay auction) is connected to the PIC microcontroller by a three wire Weigand interface (0 data, 1 data, and ground).  More information can be found in this wikipedia article https://en.wikipedia.org/wiki/Wiegand_interface.

There is also general information about proximity cards here https://en.wikipedia.org/wiki/Proximity_card.

I have uploaded the assembly program to Github, feel free to download, use it, and modify it to your needs if you find it useful.  https://github.com/aldras/pic_hidreader.

I will be uploading a schematic soon as well, the connections to the microcontroller are in the asm file on Github, but to make it easier to understand I will try to get a schematic uploaded soon.


Links