You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I have implemented u8x8_byte_stm32f4_hw_spi using the libopencm3 SPI calls. However, there may be a few wrinkles in my code as I am not an experienced C programmer. Also, as far as I can see, _hw_ calls are only inside the Arduino/CPP tree, am I right? Code is as follows:
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/gpio.h>
uint8_t u8x8_gpio_and_delay_stm32f4(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
uint8_t u8x8_byte_stm32f4_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
static void spi_setup(void) {
rcc_periph_clock_enable(RCC_SPI2);
rcc_periph_clock_enable(RCC_GPIOB);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO13|GPIO15 ); // SCK, MOSI - leaving out NSS
gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO13|GPIO15);
gpio_set_af(GPIOB, GPIO_AF5, GPIO13|GPIO15);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12 ); // this is software driven NSS
gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO12);
gpio_set(GPIOB,GPIO12); // CS disable
spi_reset(SPI2);
spi_enable_software_slave_management(SPI2); // SPI hw not managing CS pin
spi_set_nss_high(SPI2);
spi_disable_ss_output(SPI2);
spi_init_master(SPI2,SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); // unknown max clock speed, FPCLK_DIV_8 (about 2MHz?) seems to work
spi_enable(SPI2);
}
uint8_t u8x8_byte_stm32f4_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
static unsigned bitsleft;
static uint8_t retaindata,datacommandbit;
switch(msg)
{
case U8X8_MSG_BYTE_INIT:
spi_setup();
break;
case U8X8_MSG_BYTE_SET_DC:
datacommandbit=arg_int;
break;
case U8X8_MSG_BYTE_START_TRANSFER:
if (u8x8->display_info->chip_enable_level) {
gpio_set(GPIOB, GPIO12); // NSS: select SPI
} else {
gpio_clear(GPIOB,GPIO12);
};
bitsleft=0;
break;
case U8X8_MSG_BYTE_SEND: // implementing 9-bit-SPI, sending 8 bits, retaining 1 bit every cycle, until the 8th cycle
for (int i=0; i<arg_int; i++) {
uint8_t currentbyte,senddata;
currentbyte=*(uint8_t *)(arg_ptr+i);
senddata=(retaindata<<(8-bitsleft))|(datacommandbit << (7-bitsleft));
retaindata=currentbyte;
if (bitsleft < 7) senddata|=(currentbyte>>(bitsleft+1));
spi_send(SPI2,senddata);
bitsleft++;
if (bitsleft==8) {
spi_send(SPI2,retaindata);
bitsleft=0;
}
}
break;
case U8X8_MSG_BYTE_END_TRANSFER:
if (bitsleft) {
spi_send(SPI2,retaindata<<(8-bitsleft));
bitsleft=0;
}
while ((SPI_SR(SPI2) & SPI_SR_BSY)); // wait till all data is sent
if (u8x8->display_info->chip_disable_level) {
gpio_set(GPIOB, GPIO12); // NSS: select SPI
} else {
gpio_clear(GPIOB,GPIO12);
};
break;
default:
return 0;
}
return 1;
}
I implemented the u8x8_gpio_and_delay_stm32f4 with a stupid asm("nop"). (Yes and I know better). Also, a U8X8_MSG_GPIO_RESET was implemented, using port B bit 0.
So, does this code fit in u8g2 somewhere? If yes, how about the hardware choices? Using SPI2 instead of SPI1 is such a choice, also using GPIO12 for software CS and GPIO0 for reset is arbitrary. I'm not sure how to make this flexible - probably with some preprocessor wizardry? I'll be happy to make the above code a pull request if anyone can tell me where it would fit.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I have implemented u8x8_byte_stm32f4_hw_spi using the libopencm3 SPI calls. However, there may be a few wrinkles in my code as I am not an experienced C programmer. Also, as far as I can see, _hw_ calls are only inside the Arduino/CPP tree, am I right? Code is as follows:
I implemented the u8x8_gpio_and_delay_stm32f4 with a stupid asm("nop"). (Yes and I know better). Also, a U8X8_MSG_GPIO_RESET was implemented, using port B bit 0.
So, does this code fit in u8g2 somewhere? If yes, how about the hardware choices? Using SPI2 instead of SPI1 is such a choice, also using GPIO12 for software CS and GPIO0 for reset is arbitrary. I'm not sure how to make this flexible - probably with some preprocessor wizardry? I'll be happy to make the above code a pull request if anyone can tell me where it would fit.
Beta Was this translation helpful? Give feedback.
All reactions