SHIELD-Malb41k1/SPI/slave/slave.ino
stud130312 7658cd2db5 end
2024-02-12 11:46:28 +03:00

425 lines
9.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "SPISlave.h"
// #include <GyverOLED.h>
#include <GyverOLED.h>
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
#define DDR_SPI DDRB
#define DD_MOSI PB3
#define DD_MISO PB4
#define DD_SCK PB5
#define DD_SS PB2
// GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
static int index = 0;
static int arIndex = 0;
static char data[64];
// void SPI_SlaveInit(void)
// {
// DDR_SPI = (1 << DD_MISO);
// SPCR = (1 << SPE) | (1 << SPIE);
// }
// biblary
// внутренние константы
#define OLED_WIDTH 128
#define OLED_HEIGHT_64 0x12
#define OLED_64 0x3F
#define OLED_32 0x1F
#define OLED_DISPLAY_OFF 0xAE
#define OLED_DISPLAY_ON 0xAF
#define OLED_COMMAND_MODE 0x00
#define OLED_ONE_COMMAND_MODE 0x80
#define OLED_DATA_MODE 0x40
#define OLED_ONE_DATA_MODE 0xC0
#define OLED_ADDRESSING_MODE 0x20
#define OLED_HORIZONTAL 0x00
#define OLED_VERTICAL 0x01
#define OLED_NORMAL_V 0xC8
#define OLED_FLIP_V 0xC0
#define OLED_NORMAL_H 0xA1
#define OLED_FLIP_H 0xA0
#define OLED_CONTRAST 0x81
#define OLED_SETCOMPINS 0xDA
#define OLED_SETVCOMDETECT 0xDB
#define OLED_CLOCKDIV 0xD5
#define OLED_SETMULTIPLEX 0xA8
#define OLED_COLUMNADDR 0x21
#define OLED_PAGEADDR 0x22
#define OLED_CHARGEPUMP 0x8D
#define OLED_NORMALDISPLAY 0xA6
#define OLED_INVERTDISPLAY 0xA7
#define BUFSIZE_128x64 (128*64/8)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
const uint8_t _maxRow = 7;
const uint8_t _maxY = SCREEN_HEIGHT - 1;
const uint8_t _maxX = SCREEN_WIDTH - 1;
// ========== I2C ==========
#define I2C_FREQ 100000UL
void i2c_begin(uint8_t address)
{
TWBR = ((F_CPU / I2C_FREQ) - 16) / 2; // Расчет предделителя для заданной частоты
TWAR = (address << 1); // Установка адреса устройства
}
void i2c_endTransaction()
{
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP
}
void i2c_beginTransmission(uint8_t address)
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Отправка условия START
while (!(TWCR & (1 << TWINT))); // Ожидание завершения START
TWDR = (address << 1); // Отправка адреса устройства
TWCR = (1 << TWINT) | (1 << TWEN); // Отправка адреса
while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи адреса
}
void i2c_write(uint8_t data)
{
TWDR = data; // Запись данных
TWCR = (1 << TWINT) | (1 << TWEN); // Отправка данных
while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных
}
// ========== Sender ==========
uint8_t _writes = 0;
void sendData(uint8_t data) {
sendByteRaw(data);
_writes++;
if (_writes >= 16) {
endTransm();
beginData();
}
}
void sendByteRaw(uint8_t data) {
i2c_write(data);
}
void sendCommand(uint8_t cmd1) {
beginOneCommand();
sendByteRaw(cmd1);
endTransm();
}
void sendCommand(uint8_t cmd1, uint8_t cmd2) {
beginCommand();
sendByteRaw(cmd1);
sendByteRaw(cmd2);
endTransm();
}
void setWindow(int x0, int y0, int x1, int y1) {
beginCommand();
sendByteRaw(OLED_COLUMNADDR);
sendByteRaw(constrain(x0, 0, _maxX));
sendByteRaw(constrain(x1, 0, _maxX));
sendByteRaw(OLED_PAGEADDR);
sendByteRaw(constrain(y0, 0, _maxRow));
sendByteRaw(constrain(y1, 0, _maxRow));
endTransm();
}
void beginData() {
startTransm();
sendByteRaw(OLED_DATA_MODE);
}
void beginCommand() {
startTransm();
sendByteRaw(OLED_COMMAND_MODE);
}
void beginOneCommand() {
startTransm();
sendByteRaw(OLED_ONE_COMMAND_MODE);
}
void endTransm() {
i2c_endTransaction();
_writes = 0;
}
void startTransm() {
i2c_beginTransmission(OLED_ADDR);
}
void oled_init(){
i2c_begin(OLED_ADDR);
beginCommand();
// 15
sendData(OLED_DISPLAY_OFF);
sendData(OLED_CLOCKDIV);
sendData(0x80);
sendData(OLED_CHARGEPUMP);
sendData(0x14);
sendData(OLED_ADDRESSING_MODE);
sendData(OLED_VERTICAL);
sendData(OLED_NORMAL_H);
sendData(OLED_NORMAL_V);
sendData(OLED_CONTRAST);
sendData(0x7F);
sendData(OLED_SETVCOMDETECT);
sendData(0x40);
sendData(OLED_NORMALDISPLAY);
sendData(OLED_DISPLAY_ON);
// 15
endTransm();
beginCommand();
sendData(OLED_SETCOMPINS);
sendData(OLED_HEIGHT_64);
sendData(OLED_SETMULTIPLEX);
sendData(OLED_64);
endTransm();
}
ISR(SPI_STC_vect)
{
char received = SPDR;
data[index] = received;
index++;
}
void setup()
{
Serial.begin(9600);
SPI_SlaveInit();
oled_init();
oled.fill(0);
oled.setScale(3);
oled.home();
Serial.println();
Serial.println("Initialization ");
}
void SetCommand(char *data2, int length){
char command = data2[0];
// Отрезать 1 элемент от оставшихся
Serial.print("\nReceived command: ");
Serial.println(command, HEX);
switch (command){
case 1:
AllClear(&data2[1], length-1);
break;
case 2:
SetPage(&data2[1], length-1);
break;
// case 6:
// PrintMassive(&data2[1], length-1);
// break;
case 4:
AddSymbol(&data2[1], length-1);
break;
case 5:
DelSymbol(&data2[1], length-1);
break;
case 6:
DrawPixel(&data2[1], length-1);
PrintMassive(&data2[1], length-1);
break;
case 7:
DrawLine(&data2[1], length-1);
break;
case 8:
DrawCircle(&data2[1], length-1);
break;
case 9:
DrawRectangle(&data2[1], length-1);
break;
}
}
void PrintMassive(uint8_t *symbols, int lenght){
Serial.print("Received Add: ");
// oled.setScale(3); // масштаб текста (1..4)
// oled.home(); // курсор в 0,0
// oled.print("Привет!");
for(int i = 0; i < lenght - 1; i++) {
char str[3];
sprintf(str, "%01X", symbols[i]);
Serial.print(str);
Serial.print(" ");
}
}
// Another
// command 1
void AllClear(char *symbols, int lenght){
int param = symbols[0];
if (param == 1){
oled.fill(0);
}
else{
oled.fill(255);
}
}
// command 2
void SetPage(char *symbols, int lenght){
int x = symbols[0];
int y = symbols[1];
oled.setCursor(x,y);
}
// command 4
void AddSymbol(char *symbols, int lenght) {
for (int i = 0; i < lenght - 1; i++) {
oled.print(symbols[i]);
}
}
// command 5
void DelSymbol(char *symbols, int lenght) {
for (int i = 0; i < lenght - 1; i++) {
oled.print(symbols[i]);
}
}
// command 6
void DrawPixel(char *symbols, int lenght){
int x = symbols[0];
int y = symbols[1];
int color = symbols[2];
oled.dot(x,y,color);
}
// command 7
void DrawLine(char *symbols, int lenght){
int x = symbols[0];
int y = symbols[1];
int x1 = symbols[2];
int y1 = symbols[3];
int color = symbols[4];
oled.line(x,y,x1,y1,color);
}
// command 8
void DrawCircle(char *symbols, int lenght){
int x = symbols[0];
int y = symbols[1];
int r = symbols[2];
int color = symbols[3];
oled.circle(x,y,r,color);
}
// command 9
void DrawRectangle(char *symbols, int lenght){
int x = symbols[0];
int y = symbols[1];
int x1 = symbols[2];
int y1 = symbols[3];
int color = symbols[4];
oled.rect(x,y,x1,y1,color);
}
// Функция для вычисления контрольной суммы XOR
// char CRC8(char *data, int length) {
// char crc = 0x00;
// char poly = 0x07; // полином для CRC8
// for (int i = 0; i < length-2; i++) {
// crc ^= data[i]; // XOR текущего байта с crc
// for (int j = 0; j < length; j++) {
// if (crc & 0x80) { // если старший бит crc равен 1
// crc = (crc << 1) ^ poly; // сдвигаем crc на 1 бит влево и XOR с полиномом
// } else {
// crc <<= 1; // иначе просто сдвигаем на 1 бит влево
// }
// }
// }
// return crc;
// }
// Вывод массива
void arrayOut(uint8_t *arr, int size){
Serial.print("Array: ");
for(int i = 0; i < size;i++){
char str[3];
sprintf(str, "%02X", arr[i]);
Serial.print(str);
Serial.print(" ");
}
Serial.println(".");
}
// Проверка массива на ноль
// char checkArray(char *arr, int size) {
// for (int i = 0; i < size; i++) {
// if (arr[i] != 0) {
// return 1;
// }
// }
// return 0;
// }
// TODO: где то длина массива неправильно летит
void loop() {
if(PINB & (1 << 2)){
if(index > 0){
arrayOut(data, index);
char sum = 0;
sum = crc8(data, index-1);
char checkNull = 0;
char last_1 = data[index - 1];
Serial.println(sum, HEX);
if (last_1 == sum){
Serial.println();
Serial.println("Старт вывода массивов");
Serial.println(sum, HEX);
SetCommand(data, index);
// oled.print(data[0]);
Serial.println("Стоп вывода массивов");
index = 0;
return;
}else{
Serial.println("Nothing ...");
index = 0;
}
}
}
}