In early May, I became the proud owner of the
LDM-MCp debug kit. For a couple of months he was gathering dust on the table, there was a lot of work, a vacation was brewing. When he returned, with new forces, a bright head and a zeal to feel something, to do something, but definitely not a job, the hands themselves reached for a new toy. Put the SDK under Linux, everything is connected.
First quest
Immediately after connecting, the system happily discovered a paired FTDI device, creating two ttyUSBx devices at once. And here is the dilemma - either to use the Serial-console, or to be able to upload the firmware, - the bundled bootloader works directly with the FTDI device. I had to draw
scripts on my knee for the “correct” loading of the ftdi_sio module. Nakedness has proven itself in the use of Python
bindings to the ftd2xx library. The general essence comes down to unloading the module, blocking the FTDI used for the firmware, and simultaneously loading the module back with it. Then the nuclear module can block the remaining FTDI for the UART.
Hello, world! - too trite
A simple “Hello, world!” With flashing LEDs started working immediately, it was only found that after flashing with the Linux mc-ploader, you also need to reset the board or wait until the WDT works.
Once in the winter I ordered a pair of
SPY -
screens HY28A for myself , but with our mail they arrived only in May. Here and the decision itself came - to start from the screen. Armed with a SYSCLK DX USB logic analyzer, it is useful to study specs on the GPIO and SPIx registers in the MCp processor and to pick around using the SPI examples.
')
Sound setting
On the LDM board, two of the three SPIs were already involved. One under the ADC, the second under the microSD slot. All MCp peripherals consist of GPIO registers that also have alternative functions, be it a network interface (MAC / MDIO), UART, USB, or I2C.
First of all, it is necessary to configure an alternative function for the remaining unused SPI0 via bit fields. To work, we need to include a pair of header files:
#include <HDL51001_ccf.h> #include <spi.h> … GPIOB->BPS = 0x07F;
Here we have defined alternative functions for pin 0-9 GPIOB, corresponding to SCK, MOSI, MISO, SS0, SS1 and SS2. Another pair of SEL_IN / SCK_IN is used only in slave mode.
Now we need to set the parameters of the SPI bus itself:
SPI0->SS = 0x07;
So, what is the SPIxCR register? I will note the most interesting fields for us:
Bit | Value | Description |
---|
29 | one | Polarization. SCK standby status. We use the HIGH signal. |
28 | one | Phase clock. We read data in a downturn. |
27 | 0 | The prohibition of the divider at 16. We want maximum speed. With a processor frequency of 80 MHz, the SPI bus frequency will be 20 MHz |
26 | one | The bit sequence in transmission is LSB or MSB. We use MSB. |
25 | one | The operation mode of our SPI: “0” is slave, “1” is master. |
24 | one | This bit includes an SPI block. |
23-20 | 0111 | The length of the data word. We want 8 bits (0x3 - 0xf - 4-16 bits respectively). For 32 bits, the field value must be zero. |
19-16 | 0001 | Sets the prescaler mode. At zero, there were problems with the clock signal. T.ch. I chose "1". |
To select the slave, SS0-SS2 lines are used. The active state is LOW. Sampling is done through the SPIxSS register: “1” sets the value HIGH, and “0” sets the value LOW.
SPI configuration is more or less sorted out. We turn to the display.
Pinout is pretty simple. We need to connect pins 3v3_IN, GND, SCK, CS, SDO (aka MISO), SDI (aka MOSI) and nRESET with BL_CTRL. Using the BL_CTRL line and PWM, you can control the brightness of the LED backlight. Illumination and so weak, t.ch. just feed it from 3v3. The nRESET signal line is used during the screen reset / initialization procedure. To do this, we need to configure another GPIO output:
GPIOB->DIR |= 0x100;
Now we are ready to do some SPI work.
SPI: First Steps
To transmit something, we must announce our intentions. For this, before each sending of commands, we need to select a slave device. We have one - LCD. The command to write to the SPI port for our 8-bit packages will look like this:
#define SPI_CS_LOW SPI0->SS = 0x06 #define SPI_CS_HI SPI0->SS = 0x07 int SPI_WRITE(int data) { SPI0->TX = ((uint32_t)data) << 24; /* */ while(SPI_ST_TIP(SPI0) == 1); /* */ /* , (SPI_ST_NF) */ while(SPI_ST_NE(SPI0) == 0); /* * RX. * , , * . */ return SPI0->RX; }
I will not go into the details of the screen initialization - this is also the setting / removal of the active nRESET signal, this is also the multiple write / read commands from the SPI. All this can be viewed in the source code lcd-ili9320.c in the function
LCD_init .
Working with LCD is reduced to issuing commands for setting the position (X, Y) or limiting the scanning area, and then the sequentially recorded data will fill the specified area. For example, drawing rectangles is done by sequentially writing
WxH color value words, thereby optimizing the number of commands issued. SPI - the bus is not fast, slave devices can operate at frequencies up to 25 MHz. Therefore, to show the video does not work, for this purpose it is necessary to use a parallel bus. There is no double buffer either. Everything that is issued by SPI is recorded in the internal memory of the display driver and is displayed on the screen during subsequent scanning. Welcome to the days of Turbo Pascal with the graph module! T.ch. The screen in SPI mode is good for displaying statics or rarely changing pictures.
In my test program, I generated fonts and a picture in the RLE sequence using the
lcd-image-converter program. True, we had to modify the algorithm for generating RLE-sequences, the most optimal when working with 32-bit words. The original code gave out something “inedible”.
Having overlaid everything with functions for drawing sectors, circles, rectangles with straight lines, you can get the following result: