Skip to content

Commit

Permalink
[realtek-ambz] Implement SPI library
Browse files Browse the repository at this point in the history
  • Loading branch information
kuba2k2 committed Sep 23, 2023
1 parent 8576eba commit 89f4745
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
106 changes: 106 additions & 0 deletions cores/realtek-ambz/arduino/libraries/SPI/SPI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* Copyright (c) Kuba Szczodrzyński 2023-09-23. */

#include "SPIPrivate.h"

bool SPIClass::begin() {
if (!this->setPinsPrivate(PIN_INVALID, PIN_INVALID, PIN_INVALID))
return false;

LT_DM(SPI, "Begin: sck=%d, miso=%d, mosi=%d, port=%d", this->sck, this->miso, this->mosi, this->port);

if (!this->data) {
this->data = new SPIData();
this->data->spi = SPI_DEV_TABLE[this->port].SPIx;
this->data->irq = (IRQn)SPI_DEV_TABLE[this->port].IrqNum;

switch (this->port) {
case 0:
RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);
break;
case 1:
RCC_PeriphClockCmd(APBPeriph_SPI1, APBPeriph_SPI1_CLOCK, ENABLE);
break;
}
}

Pinmux_Config(this->sck, PINMUX_FUNCTION_SPIM);
Pinmux_Config(this->miso, PINMUX_FUNCTION_SPIM);
Pinmux_Config(this->mosi, PINMUX_FUNCTION_SPIM);

SSI_InitTypeDef *init = &this->data->init;
SPI_TypeDef *spi = this->data->spi;
IRQn irq = this->data->irq;
SSI_StructInit(init);
init->SPI_Role = SSI_MASTER;

SSI_Cmd(spi, DISABLE);
SSI_Init(spi, init);
SSI_Cmd(spi, ENABLE);

// VECTOR_IrqUnRegister(irq);
// VECTOR_IrqRegister((IRQ_FUN)callback, irq, (u32)this->data, 10);
// VECTOR_IrqEn(irq, 10);

return true;
}

bool SPIClass::end() {
if (!this->data)
return true;
SPI_TypeDef *spi = this->data->spi;
IRQn irq = this->data->irq;

SSI_INTConfig(spi, BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM, DISABLE);
VECTOR_IrqDis(irq);
VECTOR_IrqUnRegister(irq);
SSI_Cmd(spi, DISABLE);

delete this->data;
this->data = nullptr;
return true;
}

void SPIClass::setFrequency(uint32_t frequency) {
if (!this->data)
return;
uint32_t maxFrequency = CPU_ClkGet(false) >> 2;
if (frequency > maxFrequency) {
LT_EM(SPI, "Clock freq too high! %lu > %lu", frequency, maxFrequency);
SSI_SetBaud(this->data->spi, maxFrequency, maxFrequency << 1);
} else {

SSI_SetBaud(this->data->spi, frequency, maxFrequency << 1);
}
this->settings._clock = frequency;
}

void SPIClass::setClockDivider(uint32_t clockDiv) {
if (!this->data)
return;
if (clockDiv < 4) {
LT_EM(SPI, "Clock div too low! %lu < 4", clockDiv);
return;
}
SSI_SetBaudDiv(this->data->spi, clockDiv << 1);
this->settings._clock = CPU_ClkGet(false) / clockDiv;
}

void SPIClass::setDataMode(uint8_t dataMode) {
if (!this->data)
return;
this->settings._dataMode = dataMode;
SSI_SetSclkPolarity(this->data->spi, (dataMode >> 1) & 0b1);
SSI_SetSclkPhase(this->data->spi, (dataMode >> 0) & 0b1);
}

uint8_t SPIClass::transfer(uint8_t data) {
while ((SPI1_DEV->SR & BIT_SR_TFNF) == 0) {}
SPI1_DEV->DR[0] = data;
while ((SPI1_DEV->SR & BIT_SR_RFNE) == 0) {}
return SPI1_DEV->DR[0];
}

void SPIClass::write(uint8_t data) {
while ((SPI1_DEV->SR & BIT_SR_TFNF) == 0) {}
SPI1_DEV->DR[0] = data;
}
12 changes: 12 additions & 0 deletions cores/realtek-ambz/arduino/libraries/SPI/SPIPrivate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* Copyright (c) Kuba Szczodrzyński 2023-09-23. */

#pragma once

#include <ArduinoPrivate.h>
#include <SPI.h>

struct SPIData {
SSI_InitTypeDef init;
SPI_TypeDef *spi;
IRQn irq;
};
1 change: 1 addition & 0 deletions cores/realtek-ambz/arduino/src/lt_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@

#define LT_ARD_HAS_SERIAL 1
#define LT_ARD_HAS_SOFTSERIAL 1
#define LT_ARD_HAS_SPI 1
#define LT_ARD_HAS_WIRE 1
#define LT_ARD_MD5_MBEDTLS 1
1 change: 1 addition & 0 deletions cores/realtek-ambz/base/sdk_extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern "C" {

int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c
void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70!
void SSI_SetBaudDiv(SPI_TypeDef *spi_dev, uint32_t ClockDivider);

#ifdef __cplusplus
} // extern "C"
Expand Down

0 comments on commit 89f4745

Please sign in to comment.